> 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 */
 
 /** @} */

Reply via email to