> Making SNI support configurable at runtime also seems a more attractive
> solution to me - it would basically mean that in ssl_init_ctx(), the SNI
> callback is not registered unless it's explicitly configured. I would
> suggest using something like
>
> SSLEnableSNI port [port] ...
>
> which would be used as a per-server directive (i.e. not within vhosts,
> only globally) and enable SNI on the specified ports.
Attached is a proof of concept for such an "SSLEnableSNI" config
directive (for 2.2.x only).
Will need more fine-tuning, most likely, but I would appreciate to get
feedback whether this is considered a feasible approach - thanks.
Kaspar
Index: httpd-2.2.x/modules/ssl/ssl_private.h
===================================================================
--- httpd-2.2.x/modules/ssl/ssl_private.h (revision 663014)
+++ httpd-2.2.x/modules/ssl/ssl_private.h (working copy)
@@ -35,6 +35,7 @@
#include "http_connection.h"
#include "http_request.h"
#include "http_protocol.h"
+#include "http_vhost.h"
#include "util_script.h"
#include "util_filter.h"
#include "util_ebcdic.h"
@@ -371,6 +372,9 @@ typedef struct {
#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
const char *szCryptoDevice;
#endif
+#ifndef OPENSSL_NO_TLSEXT
+ apr_array_header_t *aSNIPorts;
+#endif
struct {
void *pV1, *pV2, *pV3, *pV4, *pV5, *pV6, *pV7, *pV8, *pV9, *pV10;
} rCtx;
@@ -513,6 +517,7 @@ const char *ssl_cmd_SSLOptions(cmd_parm
const char *ssl_cmd_SSLRequireSSL(cmd_parms *, void *);
const char *ssl_cmd_SSLRequire(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLUserName(cmd_parms *, void *, const char *);
+const char *ssl_cmd_SSLEnableSNI(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLProxyEngine(cmd_parms *cmd, void *dcfg, int flag);
const char *ssl_cmd_SSLProxyProtocol(cmd_parms *, void *, const char *);
@@ -555,6 +560,9 @@ int ssl_callback_NewSessionCach
SSL_SESSION *ssl_callback_GetSessionCacheEntry(SSL *, unsigned char *, int,
int *);
void ssl_callback_DelSessionCacheEntry(SSL_CTX *, SSL_SESSION *);
void ssl_callback_LogTracingState(MODSSL_INFO_CB_ARG_TYPE, int, int);
+#ifndef OPENSSL_NO_TLSEXT
+int ssl_callback_ServerNameIndication(SSL *, int *, modssl_ctx_t *);
+#endif
/** Session Cache Support */
void ssl_scache_init(server_rec *, apr_pool_t *);
Index: httpd-2.2.x/modules/ssl/ssl_engine_init.c
===================================================================
--- httpd-2.2.x/modules/ssl/ssl_engine_init.c (revision 663014)
+++ httpd-2.2.x/modules/ssl/ssl_engine_init.c (working copy)
@@ -355,6 +355,50 @@ static void ssl_init_server_check(server
}
}
+#ifndef OPENSSL_NO_TLSEXT
+static void ssl_init_ctx_tls_extensions(server_rec *s,
+ apr_pool_t *p,
+ apr_pool_t *ptemp,
+ modssl_ctx_t *mctx)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(s);
+ SSLModConfigRec *mc = myModConfig(s);
+ BOOL enable_sni = FALSE;
+ int i;
+
+ /*
+ * Configure TLS extensions support
+ */
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ "Configuring TLS extension handling");
+
+ /*
+ * Server name indication (SNI)
+ */
+
+ /* check if SNI should be enabled on this port */
+ for (i = 0; i < mc->aSNIPorts->nelts; i++) {
+ if (s->addrs->host_port == ((int *)mc->aSNIPorts->elts)[i])
+ enable_sni = TRUE;
+ }
+
+ if (enable_sni == TRUE) {
+ if (!SSL_CTX_set_tlsext_servername_callback(mctx->ssl_ctx,
+ ssl_callback_ServerNameIndication) ||
+ !SSL_CTX_set_tlsext_servername_arg(mctx->ssl_ctx, mctx)) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ "Unable to initialize TLS servername extension "
+ "callback (incompatible OpenSSL version?)");
+ ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
+ ssl_die();
+ }
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ "TLS SNI support enabled for %s",
+ ssl_util_vhostid(p, s));
+ }
+}
+#endif
+
static void ssl_init_ctx_protocol(server_rec *s,
apr_pool_t *p,
apr_pool_t *ptemp,
@@ -687,6 +731,9 @@ static void ssl_init_ctx(server_rec *s,
if (mctx->pks) {
/* XXX: proxy support? */
ssl_init_ctx_cert_chain(s, p, ptemp, mctx);
+#ifndef OPENSSL_NO_TLSEXT
+ ssl_init_ctx_tls_extensions(s, p, ptemp, mctx);
+#endif
}
}
@@ -1036,9 +1083,19 @@ void ssl_init_CheckServers(server_rec *b
klen = strlen(key);
if ((ps = (server_rec *)apr_hash_get(table, key, klen))) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
+ ap_log_error(APLOG_MARK,
+#ifdef OPENSSL_NO_TLSEXT
+ APLOG_WARNING,
+#else
+ APLOG_DEBUG,
+#endif
+ 0,
base_server,
+#ifdef OPENSSL_NO_TLSEXT
"Init: SSL server IP/port conflict: "
+#else
+ "Init: SSL server IP/port overlap: "
+#endif
"%s (%s:%d) vs. %s (%s:%d)",
ssl_util_vhostid(p, s),
(s->defn_name ? s->defn_name : "unknown"),
@@ -1055,8 +1112,14 @@ void ssl_init_CheckServers(server_rec *b
if (conflict) {
ap_log_error(APLOG_MARK, APLOG_WARNING, 0, base_server,
+#ifdef OPENSSL_NO_TLSEXT
"Init: You should not use name-based "
"virtual hosts in conjunction with SSL!!");
+#else
+ "Init: Name-based SSL virtual hosts only "
+ "work for clients with TLS server name indication "
+ "support (RFC 4366)");
+#endif
}
}
@@ -1221,6 +1284,7 @@ apr_status_t ssl_init_ModuleKill(void *d
{
SSLSrvConfigRec *sc;
server_rec *base_server = (server_rec *)data;
+ SSLModConfigRec *mc = myModConfig(base_server);
server_rec *s;
/*
@@ -1245,6 +1309,11 @@ apr_status_t ssl_init_ModuleKill(void *d
ssl_init_ctx_cleanup_server(sc->server);
}
+ /*
+ * Clear the list of SNI enabled ports
+ */
+ mc->aSNIPorts->nelts = 0;
+
return APR_SUCCESS;
}
Index: httpd-2.2.x/modules/ssl/ssl_engine_config.c
===================================================================
--- httpd-2.2.x/modules/ssl/ssl_engine_config.c (revision 663014)
+++ httpd-2.2.x/modules/ssl/ssl_engine_config.c (working copy)
@@ -75,6 +75,9 @@ SSLModConfigRec *ssl_config_global_creat
#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
mc->szCryptoDevice = NULL;
#endif
+#ifndef OPENSSL_NO_TLSEXT
+ mc->aSNIPorts = apr_array_make(pool, 5, sizeof(int));
+#endif
memset(mc->pTmpKeys, 0, sizeof(mc->pTmpKeys));
@@ -1243,6 +1246,33 @@ const char *ssl_cmd_SSLProtocol(cmd_parm
return ssl_cmd_protocol_parse(cmd, arg, &sc->server->protocol);
}
+const char *ssl_cmd_SSLEnableSNI(cmd_parms *cmd, void *dcfg,
+ const char *arg)
+{
+ SSLModConfigRec *mc = myModConfig(cmd->server);
+ const char *err;
+ int port = atoi(arg);
+ int i, *New;
+
+ if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
+ return err;
+ }
+
+ if (!apr_isdigit(arg[0]))
+ return "SSLEnableSNI: port number must be numeric";
+
+ /* make sure we don't add duplicates */
+ for (i = 0; i < mc->aSNIPorts->nelts; i++) {
+ if (port == ((int *)mc->aSNIPorts->elts)[i])
+ return NULL;
+ }
+
+ New = apr_array_push(mc->aSNIPorts);
+ *New = port;
+
+ return NULL;
+}
+
const char *ssl_cmd_SSLProxyEngine(cmd_parms *cmd, void *dcfg, int flag)
{
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Index: httpd-2.2.x/modules/ssl/ssl_engine_vars.c
===================================================================
--- httpd-2.2.x/modules/ssl/ssl_engine_vars.c (revision 663014)
+++ httpd-2.2.x/modules/ssl/ssl_engine_vars.c (working copy)
@@ -320,6 +320,12 @@ static char *ssl_var_lookup_ssl(apr_pool
else if (ssl != NULL && strcEQ(var, "COMPRESS_METHOD")) {
result = ssl_var_lookup_ssl_compress_meth(ssl);
}
+#ifndef OPENSSL_NO_TLSEXT
+ else if (ssl != NULL && strcEQ(var, "TLS_SNI")) {
+ result = apr_pstrdup(p, SSL_get_servername(ssl,
+ TLSEXT_NAMETYPE_host_name));
+ }
+#endif
return result;
}
Index: httpd-2.2.x/modules/ssl/ssl_engine_kernel.c
===================================================================
--- httpd-2.2.x/modules/ssl/ssl_engine_kernel.c (revision 663014)
+++ httpd-2.2.x/modules/ssl/ssl_engine_kernel.c (working copy)
@@ -31,6 +31,9 @@
#include "ssl_private.h"
static void ssl_configure_env(request_rec *r, SSLConnRec *sslconn);
+#ifndef OPENSSL_NO_TLSEXT
+static int ssl_find_vhost(void *servername, conn_rec *c, server_rec *s);
+#endif
/*
* Post Read Request Handler
@@ -39,6 +42,9 @@ int ssl_hook_ReadReq(request_rec *r)
{
SSLConnRec *sslconn = myConnConfig(r->connection);
SSL *ssl;
+#ifndef OPENSSL_NO_TLSEXT
+ const char *servername;
+#endif
if (!sslconn) {
return DECLINED;
@@ -87,6 +93,14 @@ int ssl_hook_ReadReq(request_rec *r)
if (!ssl) {
return DECLINED;
}
+#ifndef OPENSSL_NO_TLSEXT
+ if (!r->hostname &&
+ (servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) {
+ /* Use the SNI extension as the hostname if no Host: header was sent */
+ r->hostname = apr_pstrdup(r->pool, servername);
+ ap_update_vhost_from_headers(r);
+ }
+#endif
SSL_set_app_data2(ssl, r);
/*
@@ -252,7 +266,7 @@ int ssl_hook_Access(request_rec *r)
* has to enable this via ``SSLOptions +OptRenegotiate''. So we do no
* implicit optimizations.
*/
- if (dc->szCipherSuite) {
+ if (dc->szCipherSuite || (r->server != r->connection->base_server)) {
/* remember old state */
if (dc->nOptions & SSL_OPT_OPTRENEGOTIATE) {
@@ -267,7 +281,10 @@ int ssl_hook_Access(request_rec *r)
}
/* configure new state */
- if (!modssl_set_cipher_list(ssl, dc->szCipherSuite)) {
+ if ((dc->szCipherSuite &&
+ !modssl_set_cipher_list(ssl, dc->szCipherSuite)) ||
+ (sc->server->auth.cipher_suite &&
+ !modssl_set_cipher_list(ssl, sc->server->auth.cipher_suite))) {
ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
r->server,
"Unable to reconfigure (per-directory) "
@@ -334,8 +351,13 @@ int ssl_hook_Access(request_rec *r)
sk_SSL_CIPHER_free(cipher_list_old);
}
- /* tracing */
if (renegotiate) {
+#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
+ if (sc->cipher_server_pref == TRUE) {
+ SSL_set_options(ssl, SSL_OP_CIPHER_SERVER_PREFERENCE);
+ }
+#endif
+ /* tracing */
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
"Reconfigured cipher suite will force renegotiation");
}
@@ -353,14 +375,16 @@ int ssl_hook_Access(request_rec *r)
* currently active/remembered verify depth (because this means more
* restriction on the certificate chain).
*/
- if (dc->nVerifyDepth != UNSET) {
+ if ((dc->nVerifyDepth != UNSET) ||
+ (sc->server->auth.verify_depth != 1)) {
/* XXX: doesnt look like sslconn->verify_depth is actually used */
if (!(n = sslconn->verify_depth)) {
sslconn->verify_depth = n = sc->server->auth.verify_depth;
}
/* determine whether a renegotiation has to be forced */
- if (dc->nVerifyDepth < n) {
+ if (((dc->nVerifyDepth != UNSET) && (dc->nVerifyDepth < n)) ||
+ (sc->server->auth.verify_depth < n)) {
renegotiate = TRUE;
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
"Reduced client verification depth will force "
@@ -382,18 +406,22 @@ int ssl_hook_Access(request_rec *r)
* verification but at least skip the I/O-intensive renegotation
* handshake.
*/
- if (dc->nVerifyClient != SSL_CVERIFY_UNSET) {
+ if ((dc->nVerifyClient != SSL_CVERIFY_UNSET) ||
+ (sc->server->auth.verify_mode != SSL_CVERIFY_UNSET)) {
/* remember old state */
verify_old = SSL_get_verify_mode(ssl);
/* configure new state */
verify = SSL_VERIFY_NONE;
- if (dc->nVerifyClient == SSL_CVERIFY_REQUIRE) {
+ if ((dc->nVerifyClient == SSL_CVERIFY_REQUIRE) ||
+ (sc->server->auth.verify_mode == SSL_CVERIFY_REQUIRE)) {
verify |= SSL_VERIFY_PEER_STRICT;
}
if ((dc->nVerifyClient == SSL_CVERIFY_OPTIONAL) ||
- (dc->nVerifyClient == SSL_CVERIFY_OPTIONAL_NO_CA))
+ (dc->nVerifyClient == SSL_CVERIFY_OPTIONAL_NO_CA) ||
+ (sc->server->auth.verify_mode == SSL_CVERIFY_OPTIONAL) ||
+ (sc->server->auth.verify_mode == SSL_CVERIFY_OPTIONAL_NO_CA))
{
verify |= SSL_VERIFY_PEER;
}
@@ -491,6 +519,40 @@ int ssl_hook_Access(request_rec *r)
"Changed client verification locations will force "
"renegotiation");
}
+#else
+#ifndef OPENSSL_NO_TLSEXT
+#define MODSSL_CFG_CA_NE(f, sc1, sc2) \
+ (sc1->server->auth.f && \
+ (!sc2->server->auth.f || \
+ sc2->server->auth.f && strNE(sc1->server->auth.f, sc2->server->auth.f)))
+
+ /* If we're handling a request for a vhost other than the default one,
+ * then we need to make sure that client authentication is properly
+ * enforced. For clients supplying an SNI extension, the peer certificate
+ * verification has happened in the handshake already (and r->server
+ * has been set to r->connection->base_server). For non-SNI requests,
+ * an additional check is needed here. If client authentication is
+ * configured as mandatory, then we can only proceed if the CA list
+ * doesn't have to be changed (SSL_set_cert_store() would be required
+ * for this).
+ */
+ if ((r->server != r->connection->base_server) &&
+ (verify & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) &&
+ renegotiate &&
+ !(SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) {
+ SSLSrvConfigRec *bssc = mySrvConfig(r->connection->base_server);
+
+ if (MODSSL_CFG_CA_NE(ca_cert_file, sc, bssc) ||
+ MODSSL_CFG_CA_NE(ca_cert_path, sc, bssc)) {
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
+ "Non-default virtual host with SSLVerify set to 'require' "
+ "and VirtualHost-specific CA certificate list is only "
+ "supported for clients with TLS server name indication "
+ "(SNI) support");
+ return HTTP_FORBIDDEN;
+ }
+ }
+#endif /* OPENSSL_NO_TLSEXT */
#endif /* HAVE_SSL_SET_CERT_STORE */
/* If a renegotiation is now required for this location, and the
@@ -666,8 +728,10 @@ int ssl_hook_Access(request_rec *r)
/*
* Finally check for acceptable renegotiation results
*/
- if (dc->nVerifyClient != SSL_CVERIFY_NONE) {
- BOOL do_verify = (dc->nVerifyClient == SSL_CVERIFY_REQUIRE);
+ if ((dc->nVerifyClient != SSL_CVERIFY_NONE) ||
+ (sc->server->auth.verify_mode != SSL_CVERIFY_NONE)) {
+ BOOL do_verify = ((dc->nVerifyClient == SSL_CVERIFY_REQUIRE) ||
+ (sc->server->auth.verify_mode ==
SSL_CVERIFY_REQUIRE));
if (do_verify && (SSL_get_verify_result(ssl) != X509_V_OK)) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
@@ -997,6 +1061,9 @@ int ssl_hook_Fixup(request_rec *r)
SSLDirConfigRec *dc = myDirConfig(r);
apr_table_t *env = r->subprocess_env;
char *var, *val = "";
+#ifndef OPENSSL_NO_TLSEXT
+ const char *servername;
+#endif
STACK_OF(X509) *peer_certs;
SSL *ssl;
int i;
@@ -1018,6 +1085,13 @@ int ssl_hook_Fixup(request_rec *r)
/* the always present HTTPS (=HTTP over SSL) flag! */
apr_table_setn(env, "HTTPS", "on");
+#ifndef OPENSSL_NO_TLSEXT
+ /* add content of SNI TLS extension (if supplied with ClientHello) */
+ if ((servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) {
+ apr_table_set(env, "SSL_TLS_SNI", servername);
+ }
+#endif
+
/* standard SSL environment variables */
if (dc->nOptions & SSL_OPT_STDENVVARS) {
for (i = 0; ssl_hook_Fixup_vars[i]; i++) {
@@ -1166,8 +1240,8 @@ int ssl_callback_SSLVerify(int ok, X509_
SSL *ssl = X509_STORE_CTX_get_ex_data(ctx,
SSL_get_ex_data_X509_STORE_CTX_idx());
conn_rec *conn = (conn_rec *)SSL_get_app_data(ssl);
- server_rec *s = conn->base_server;
request_rec *r = (request_rec *)SSL_get_app_data2(ssl);
+ server_rec *s = r ? r->server : conn->base_server;
SSLSrvConfigRec *sc = mySrvConfig(s);
SSLDirConfigRec *dc = r ? myDirConfig(r) : NULL;
@@ -1290,7 +1364,10 @@ int ssl_callback_SSLVerify(int ok, X509_
int ssl_callback_SSLVerify_CRL(int ok, X509_STORE_CTX *ctx, conn_rec *c)
{
- server_rec *s = c->base_server;
+ SSL *ssl = X509_STORE_CTX_get_ex_data(ctx,
+
SSL_get_ex_data_X509_STORE_CTX_idx());
+ request_rec *r = (request_rec *)SSL_get_app_data2(ssl);
+ server_rec *s = r ? r->server : c->base_server;
SSLSrvConfigRec *sc = mySrvConfig(s);
SSLConnRec *sslconn = myConnConfig(c);
modssl_ctx_t *mctx = myCtxConfig(sslconn, sc);
@@ -1810,3 +1887,141 @@ void ssl_callback_LogTracingState(MODSSL
}
}
+#ifndef OPENSSL_NO_TLSEXT
+/*
+ * This callback function is executed when OpenSSL encounters an extended
+ * client hello with a server name indication extension ("SNI", cf. RFC 4366).
+ */
+int ssl_callback_ServerNameIndication(SSL *ssl, int *al, modssl_ctx_t *mctx)
+{
+ const char *servername =
+ SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
+
+ if (servername) {
+ conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
+ if (c) {
+ if (ap_vhost_iterate_given_conn(c, ssl_find_vhost,
+ (void *)servername)) {
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
+ "SSL virtual host for servername %s found",
+ servername);
+ return SSL_TLSEXT_ERR_OK;
+ }
+ else {
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
+ "No matching SSL virtual host for servername "
+ "%s found (using default/first virtual host)",
+ servername);
+ return SSL_TLSEXT_ERR_ALERT_WARNING;
+ }
+ }
+ }
+
+ return SSL_TLSEXT_ERR_NOACK;
+}
+
+/*
+ * Find a (name-based) SSL virtual host where either the ServerName
+ * or one of the ServerAliases matches the supplied name (to be used
+ * with ap_vhost_iterate_given_conn())
+ */
+static int ssl_find_vhost(void *servername, conn_rec *c, server_rec *s)
+{
+ SSLSrvConfigRec *sc;
+ SSL *ssl;
+ BOOL found = FALSE;
+ apr_array_header_t *names;
+ int i;
+
+ /* check ServerName */
+ if (!strcasecmp(servername, s->server_hostname)) {
+ found = TRUE;
+ }
+
+ /*
+ * if not matched yet, check ServerAlias entries
+ * (adapted from vhost.c:matches_aliases())
+ */
+ if (!found) {
+ names = s->names;
+ if (names) {
+ char **name = (char **)names->elts;
+ for (i = 0; i < names->nelts; ++i) {
+ if (!name[i])
+ continue;
+ if (!strcasecmp(servername, name[i])) {
+ found = TRUE;
+ break;
+ }
+ }
+ }
+ }
+
+ /* if still no match, check ServerAlias entries with wildcards */
+ if (!found) {
+ names = s->wild_names;
+ if (names) {
+ char **name = (char **)names->elts;
+ for (i = 0; i < names->nelts; ++i) {
+ if (!name[i])
+ continue;
+ if (!ap_strcasecmp_match(servername, name[i])) {
+ found = TRUE;
+ break;
+ }
+ }
+ }
+ }
+
+ /* set SSL_CTX (if matched) */
+ if (found && (ssl = ((SSLConnRec *)myConnConfig(c))->ssl) &&
+ (sc = mySrvConfig(s))) {
+ SSL_set_SSL_CTX(ssl, sc->server->ssl_ctx);
+ /*
+ * SSL_set_SSL_CTX() only deals with the server cert,
+ * so we need to duplicate a few additional settings
+ * from the ctx by hand
+ */
+ SSL_set_options(ssl, SSL_CTX_get_options(ssl->ctx));
+ if ((SSL_get_verify_mode(ssl) == SSL_VERIFY_NONE) ||
+ (SSL_num_renegotiations(ssl) == 0)) {
+ /*
+ * Only initialize the verification settings from the ctx
+ * if they are not yet set, or if we're called when a new
+ * SSL connection is set up (num_renegotiations == 0).
+ * Otherwise, we would possibly reset a per-directory
+ * configuration which was put into effect by ssl_hook_Access.
+ */
+ SSL_set_verify(ssl, SSL_CTX_get_verify_mode(ssl->ctx),
+ SSL_CTX_get_verify_callback(ssl->ctx));
+ }
+
+ /*
+ * We also need to make sure that the correct mctx
+ * (accessed through the c->base_server->module_config vector)
+ * is assigned to the connection - the CRL callback e.g.
+ * makes use of it for retrieving its store (mctx->crl).
+ * Since logging in callbacks uses c->base_server in many
+ * cases, it also ensures that these messages are routed
+ * to the proper log.
+ */
+ c->base_server = s;
+
+ /*
+ * There is one special filter callback, which is set
+ * very early depending on the base_server's log level.
+ * If this is not the first vhost we're now selecting
+ * (and the first vhost doesn't use APLOG_DEBUG), then
+ * we need to set that callback here.
+ */
+ if (c->base_server->loglevel >= APLOG_DEBUG) {
+ BIO_set_callback(SSL_get_rbio(ssl), ssl_io_data_cb);
+ BIO_set_callback_arg(SSL_get_rbio(ssl), (void *)ssl);
+ }
+
+ return 1;
+ }
+
+ return 0;
+}
+#endif
Index: httpd-2.2.x/modules/ssl/mod_ssl.c
===================================================================
--- httpd-2.2.x/modules/ssl/mod_ssl.c (revision 663014)
+++ httpd-2.2.x/modules/ssl/mod_ssl.c (working copy)
@@ -145,6 +145,11 @@ static const command_rec ssl_config_cmds
"Use the server's cipher ordering preference")
SSL_CMD_ALL(UserName, TAKE1,
"Set user name to SSL variable value")
+#ifndef OPENSSL_NO_TLSEXT
+ SSL_CMD_SRV(EnableSNI, ITERATE,
+ "List of ports where support for TLS server name indication
(SNI) "
+ "is to be enabled (`port [port] ...')")
+#endif
/*
* Proxy configuration for remote SSL connections
Index: httpd-2.2.x/modules/ssl/ssl_toolkit_compat.h
===================================================================
--- httpd-2.2.x/modules/ssl/ssl_toolkit_compat.h (revision 663014)
+++ httpd-2.2.x/modules/ssl/ssl_toolkit_compat.h (working copy)
@@ -264,6 +264,12 @@ typedef void (*modssl_popfree_fn)(char *
#define SSL_SESS_CACHE_NO_INTERNAL SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
#endif
+#ifndef OPENSSL_NO_TLSEXT
+#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
+#define OPENSSL_NO_TLSEXT
+#endif
+#endif
+
#endif /* SSL_TOOLKIT_COMPAT_H */
/** @} */