Restore ssl_callback_ServerNameIndication() even with OpenSSL 1.1.1+, which
depends on its return value (OK/NOACK), mainly on session resumption, for
SSL_get_servername() to consider or ignore the SNI (returning NULL thus
making SSLStrictSNIVHostCheck fail for possibly legitimate cases).
This means that init_vhost() should accurately return whether the SNI exists
in the configured vhosts, even when it's called multiple times (e.g. first
from ClientHello callback and then from SNI callback), so save that state in
sslconn->vhost_found and reuse it.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@
1868743 13f79535-47bb-0310-9956-
ffa450edef68
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01893)
"Configuring TLS extension handling");
-#if OPENSSL_VERSION_NUMBER < 0x10101000L || defined(LIBRESSL_VERSION_NUMBER)
/*
* The Server Name Indication (SNI) provided by the ClientHello can be
* used to select the right (name-based-)vhost and its SSL configuration
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
return ssl_die(s);
}
-#else
+
+#if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
/*
* The ClientHello callback also allows to retrieve the SNI, but since it
* runs at the earliest possible connection stage we can even set the TLS
if (c) {
SSLConnRec *sslcon = myConnConfig(c);
-
- if (sslcon->server != c->base_server) {
- /* already found the vhost */
- return APR_SUCCESS;
+
+ if (sslcon->vhost_found) {
+ /* already found the vhost? */
+ return sslcon->vhost_found > 0 ? APR_SUCCESS : APR_NOTFOUND;
}
+ sslcon->vhost_found = -1;
if (!servername) {
servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(02043)
"SSL virtual host for servername %s found",
servername);
-
+
+ sslcon->vhost_found = +1;
return APR_SUCCESS;
}
else if (ssl_is_challenge(c, servername, &cert, &key)) {
return APR_NOTFOUND;
}
-#if OPENSSL_VERSION_NUMBER < 0x10101000L || defined(LIBRESSL_VERSION_NUMBER)
/*
* This callback function is executed when OpenSSL encounters an extended
* client hello with a server name indication extension ("SNI", cf. RFC 6066).
return (status == APR_SUCCESS)? SSL_TLSEXT_ERR_OK : SSL_TLSEXT_ERR_NOACK;
}
-#else /* OPENSSL_VERSION_NUMBER < 0x10101000L */
+
+#if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
/*
- * This callback function when the ClientHello is received.
+ * This callback function is called when the ClientHello is received.
*/
int ssl_callback_ClientHello(SSL *ssl, int *al, void *arg)
{
const char *cipher_suite; /* cipher suite used in last reneg */
int service_unavailable; /* thouugh we negotiate SSL, no requests will be served */
+ int vhost_found; /* whether we found vhost from SNI already */
} SSLConnRec;
/* BIG FAT WARNING: SSLModConfigRec has unusual memory lifetime: it is
void ssl_callback_DelSessionCacheEntry(SSL_CTX *, SSL_SESSION *);
void ssl_callback_Info(const SSL *, int, int);
#ifdef HAVE_TLSEXT
-#if OPENSSL_VERSION_NUMBER < 0x10101000L || defined(LIBRESSL_VERSION_NUMBER)
int ssl_callback_ServerNameIndication(SSL *, int *, modssl_ctx_t *);
-#else
-int ssl_callback_ClientHello(SSL *, int *, void *);
#endif
+#if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
+int ssl_callback_ClientHello(SSL *, int *, void *);
#endif
#ifdef HAVE_TLS_SESSION_TICKETS
int ssl_callback_SessionTicket(SSL *, unsigned char *, unsigned char *,