Commit 173609d6 authored by Nikos Mavrogiannopoulos's avatar Nikos Mavrogiannopoulos Committed by David Woodhouse

Advertise the hostname we connect using SNI.

This would provide the server with more information on the
connection that can be used to distinguish between different
servers (https and vpn), or even different vpn server configurations.
It is conditionally enabled when compiled with gnutls 3.2.9 or later
where the %COMPAT keyword ensures that the client hello size is
outside the F5 firewall black hole range.

[dwmw2: Make string_is_hostname() accept NULL, cosmetic changes]
Signed-off-by: default avatarNikos Mavrogiannopoulos <>
Signed-off-by: default avatarDavid Woodhouse <>
parent a53ae46c
......@@ -1795,6 +1795,7 @@ static int verify_peer(gnutls_session_t session)
return err;
/* The F5 firewall is confused when the TLS client hello is between
* 256 and 512 bytes. By disabling several TLS options we force the
* client hello to be < 256 bytes. We don't do that in gnutls versions
......@@ -1923,6 +1924,13 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
if (vpninfo->my_pkey == OPENCONNECT_TPM_PKEY)
gnutls_sign_callback_set(vpninfo->https_sess, gtls2_tpm_sign_cb, vpninfo);
/* We depend on 3.2.9 because that has the workaround for the
obnoxious F5 firewall that drops packets of certain sizes */
if (gnutls_check_version("3.2.9") &&
gnutls_server_name_set(vpninfo->https_sess, GNUTLS_NAME_DNS,
if (vpninfo->pfs) {
......@@ -472,6 +472,7 @@ int cstp_reconnect(struct openconnect_info *vpninfo);
void cstp_free_splits(struct openconnect_info *vpninfo);
/* ssl.c */
unsigned string_is_hostname(const char* str);
int connect_https_socket(struct openconnect_info *vpninfo);
int request_passphrase(struct openconnect_info *vpninfo, const char *label,
char **response, const char *fmt, ...);
......@@ -1361,6 +1361,14 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
BIO_set_nbio(https_bio, 1);
SSL_set_bio(https_ssl, https_bio, https_bio);
#if 0
/* Should be enabled on openssl versions that support
SSL_set_tlsext_host_name() after the F5 firewall workaround
is enabled */
if (string_is_hostname(vpninfo->hostname))
SSL_set_tlsext_host_name(https_ssl, vpninfo->hostname);
vpn_progress(vpninfo, PRG_INFO, _("SSL negotiation with %s\n"),
......@@ -89,6 +89,21 @@ static int cancellable_connect(struct openconnect_info *vpninfo, int sockfd,
return getpeername(sockfd, (void *)&peer, &peerlen);
/* checks whether the provided string is an IP or a hostname.
unsigned string_is_hostname(const char *str)
struct in_addr buf;
/* We don't use inet_pton() because an IPv6 literal is likely to
be encased in []. So just check for a colon, which shouldn't
occur in hostnames anyway. */
if (!str || inet_aton(str, &buf) || strchr(str, ':'))
return 0;
return 1;
int connect_https_socket(struct openconnect_info *vpninfo)
int ssl_sock = -1;
......@@ -32,6 +32,8 @@
<li>Add padding when sending password, to avoid leakage of password
and username length.</li>
<li>Add support for DTLS 1.2 and AES-GCM when connecting to ocserv.</li>
<li>Add support for server name indication when compiled with GnuTLS
<li><b><a href="">OpenConnect v5.03</a></b>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment