Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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: Nikos Mavrogiannopoulos <nmav@gnutls.org>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
  • Loading branch information
nmav authored and David Woodhouse committed Mar 3, 2014
1 parent a53ae46 commit 173609d
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 0 deletions.
8 changes: 8 additions & 0 deletions gnutls.c
Expand Up @@ -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
Expand Down Expand Up @@ -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);
#endif
/* 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") &&
string_is_hostname(vpninfo->hostname))
gnutls_server_name_set(vpninfo->https_sess, GNUTLS_NAME_DNS,
vpninfo->hostname,
strlen(vpninfo->hostname));

if (vpninfo->pfs) {
prio = DEFAULT_PRIO":-RSA";
Expand Down
1 change: 1 addition & 0 deletions openconnect-internal.h
Expand Up @@ -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, ...);
Expand Down
8 changes: 8 additions & 0 deletions openssl.c
Expand Up @@ -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);
#endif

vpn_progress(vpninfo, PRG_INFO, _("SSL negotiation with %s\n"),
vpninfo->hostname);

Expand Down
15 changes: 15 additions & 0 deletions ssl.c
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions www/changelog.xml
Expand Up @@ -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
3.2.9+.</li>
</ul><br/>
</li>
<li><b><a href="ftp://ftp.infradead.org/pub/openconnect/openconnect-5.03.tar.gz">OpenConnect v5.03</a></b>
Expand Down

0 comments on commit 173609d

Please sign in to comment.