Index: /server/common/patches/httpd-2.2.x-sni.patch
===================================================================
--- /server/common/patches/httpd-2.2.x-sni.patch	(revision 1114)
+++ /server/common/patches/httpd-2.2.x-sni.patch	(revision 1115)
@@ -1,9 +1,10 @@
-httpd-2.2.x-sni.patch - server name indication support for Apache 2.2
-(see RFC 4366, "Transport Layer Security (TLS) Extensions")
+http://sni.velox.ch/httpd-2.2.11-sni.20090427.patch - server name indication
+support for mod_ssl / Apache 2.2.11 (RFC 4366, section 3.1)
 
-Last updated 2009-04-08
+Last updated 2009-04-27, by Kaspar Brand.
+Provided AS IS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND.
 
-based on a patch from the EdelKey project
-(http://www.edelweb.fr/EdelKey/files/apache-2.2.0+0.9.9+servername.patch)
+Based on a patch from the EdelKey project (http://www.edelweb.fr/EdelKey/files/),
+includes further improvements by Ruediger Pluem (from httpd trunk).
 
 Needs openssl-SNAP-20060330 / OpenSSL 0.9.8f or later
@@ -12,8 +13,8 @@
 at compile time ("./config enable-tlsext").
 
-Index: httpd-2.2.x/modules/ssl/ssl_private.h
+Index: httpd-2.2.11/modules/ssl/ssl_private.h
 ===================================================================
---- httpd-2.2.x/modules/ssl/ssl_private.h	(revision 763153)
-+++ httpd-2.2.x/modules/ssl/ssl_private.h	(working copy)
+--- httpd-2.2.11/modules/ssl/ssl_private.h	(revision 768863)
++++ httpd-2.2.11/modules/ssl/ssl_private.h	(working copy)
 @@ -35,6 +35,7 @@
  #include "http_connection.h"
@@ -24,5 +25,43 @@
  #include "util_filter.h"
  #include "util_ebcdic.h"
-@@ -562,6 +563,9 @@ int          ssl_callback_NewSessionCacheEntry(SSL
+@@ -129,6 +130,9 @@ ap_set_module_config(c->conn_config, &ssl_module,
+ #define mySrvConfig(srv) (SSLSrvConfigRec *)ap_get_module_config(srv->module_config,  &ssl_module)
+ #define myDirConfig(req) (SSLDirConfigRec *)ap_get_module_config(req->per_dir_config, &ssl_module)
+ #define myModConfig(srv) (mySrvConfig((srv)))->mc
++#define mySrvFromConn(c) (myConnConfig(c))->server
++#define mySrvConfigFromConn(c) mySrvConfig(mySrvFromConn(c))
++#define myModConfigFromConn(c) myModConfig(mySrvFromConn(c))
+ 
+ #define myCtxVarSet(mc,num,val)  mc->rCtx.pV##num = val
+ #define myCtxVarGet(mc,num,type) (type)(mc->rCtx.pV##num)
+@@ -347,6 +351,7 @@ typedef struct {
+     int is_proxy;
+     int disabled;
+     int non_ssl_request;
++    server_rec *server;
+ } SSLConnRec;
+ 
+ typedef struct {
+@@ -449,6 +454,9 @@ struct SSLSrvConfigRec {
+     BOOL             cipher_server_pref;
+     modssl_ctx_t    *server;
+     modssl_ctx_t    *proxy;
++#ifndef OPENSSL_NO_TLSEXT
++    ssl_enabled_t    strict_sni_vhost_check;
++#endif
+ };
+ 
+ /**
+@@ -513,6 +521,9 @@ const char  *ssl_cmd_SSLOptions(cmd_parms *, void
+ 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 *);
++#ifndef OPENSSL_NO_TLSEXT
++const char  *ssl_cmd_SSLStrictSNIVHostCheck(cmd_parms *cmd, void *dcfg, int flag);
++#endif
+ 
+ const char  *ssl_cmd_SSLProxyEngine(cmd_parms *cmd, void *dcfg, int flag);
+ const char  *ssl_cmd_SSLProxyProtocol(cmd_parms *, void *, const char *);
+@@ -555,6 +566,9 @@ int          ssl_callback_NewSessionCacheEntry(SSL
  SSL_SESSION *ssl_callback_GetSessionCacheEntry(SSL *, unsigned char *, int, int *);
  void         ssl_callback_DelSessionCacheEntry(SSL_CTX *, SSL_SESSION *);
@@ -34,8 +73,8 @@
  /**  Session Cache Support  */
  void         ssl_scache_init(server_rec *, apr_pool_t *);
-Index: httpd-2.2.x/modules/ssl/ssl_engine_init.c
+Index: httpd-2.2.11/modules/ssl/ssl_engine_init.c
 ===================================================================
---- httpd-2.2.x/modules/ssl/ssl_engine_init.c	(revision 763153)
-+++ httpd-2.2.x/modules/ssl/ssl_engine_init.c	(working copy)
+--- httpd-2.2.11/modules/ssl/ssl_engine_init.c	(revision 768863)
++++ httpd-2.2.11/modules/ssl/ssl_engine_init.c	(working copy)
 @@ -358,6 +358,33 @@ static void ssl_init_server_check(server_rec *s,
      }
@@ -118,8 +157,167 @@
  }
  
-Index: httpd-2.2.x/modules/ssl/ssl_engine_vars.c
+Index: httpd-2.2.11/modules/ssl/ssl_engine_config.c
 ===================================================================
---- httpd-2.2.x/modules/ssl/ssl_engine_vars.c	(revision 763153)
-+++ httpd-2.2.x/modules/ssl/ssl_engine_vars.c	(working copy)
+--- httpd-2.2.11/modules/ssl/ssl_engine_config.c	(revision 768863)
++++ httpd-2.2.11/modules/ssl/ssl_engine_config.c	(working copy)
+@@ -169,6 +169,9 @@ static SSLSrvConfigRec *ssl_config_server_new(apr_
+     sc->vhost_id_len           = 0;     /* set during module init */
+     sc->session_cache_timeout  = UNSET;
+     sc->cipher_server_pref     = UNSET;
++#ifndef OPENSSL_NO_TLSEXT
++    sc->strict_sni_vhost_check = SSL_ENABLED_UNSET;
++#endif
+ 
+     modssl_ctx_init_proxy(sc, p);
+ 
+@@ -257,6 +260,9 @@ void *ssl_config_server_merge(apr_pool_t *p, void
+     cfgMergeBool(proxy_enabled);
+     cfgMergeInt(session_cache_timeout);
+     cfgMergeBool(cipher_server_pref);
++#ifndef OPENSSL_NO_TLSEXT
++    cfgMerge(strict_sni_vhost_check, SSL_ENABLED_UNSET);
++#endif
+ 
+     modssl_ctx_cfg_merge_proxy(base->proxy, add->proxy, mrg->proxy);
+ 
+@@ -1411,6 +1417,17 @@ const char *ssl_cmd_SSLUserName(cmd_parms *cmd, vo
+     return NULL;
+ }
+ 
++#ifndef OPENSSL_NO_TLSEXT
++const char  *ssl_cmd_SSLStrictSNIVHostCheck(cmd_parms *cmd, void *dcfg, int flag)
++{
++    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
++
++    sc->strict_sni_vhost_check = flag ? SSL_ENABLED_TRUE : SSL_ENABLED_FALSE;
++
++    return NULL;
++}
++#endif
++
+ void ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s)
+ {
+     if (!ap_exists_config_define("DUMP_CERTS")) {
+Index: httpd-2.2.11/modules/ssl/ssl_engine_io.c
+===================================================================
+--- httpd-2.2.11/modules/ssl/ssl_engine_io.c	(revision 768863)
++++ httpd-2.2.11/modules/ssl/ssl_engine_io.c	(working copy)
+@@ -695,7 +695,7 @@ static apr_status_t ssl_io_input_read(bio_filter_i
+                  */
+                 ap_log_cerror(APLOG_MARK, APLOG_INFO, inctx->rc, c,
+                               "SSL library error %d reading data", ssl_err);
+-                ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, c->base_server);
++                ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, mySrvFromConn(c));
+ 
+             }
+             if (inctx->rc == APR_SUCCESS) {
+@@ -799,7 +799,7 @@ static apr_status_t ssl_filter_write(ap_filter_t *
+              */
+             ap_log_cerror(APLOG_MARK, APLOG_INFO, outctx->rc, c,
+                           "SSL library error %d writing data", ssl_err);
+-            ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, c->base_server);
++            ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, mySrvFromConn(c));
+         }
+         if (outctx->rc == APR_SUCCESS) {
+             outctx->rc = APR_EGENERAL;
+@@ -861,7 +861,7 @@ static apr_status_t ssl_io_filter_error(ap_filter_
+             ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, f->c,
+                          "SSL handshake failed: HTTP spoken on HTTPS port; "
+                          "trying to send HTML error page");
+-            ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, f->c->base_server);
++            ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, sslconn->server);
+ 
+             sslconn->non_ssl_request = 1;
+             ssl_io_filter_disable(sslconn, f);
+@@ -971,11 +971,11 @@ static apr_status_t ssl_filter_io_shutdown(ssl_fil
+     SSL_smart_shutdown(ssl);
+ 
+     /* and finally log the fact that we've closed the connection */
+-    if (c->base_server->loglevel >= APLOG_INFO) {
++    if (mySrvFromConn(c)->loglevel >= APLOG_INFO) {
+         ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c,
+                       "Connection closed to child %ld with %s shutdown "
+                       "(server %s)",
+-                      c->id, type, ssl_util_vhostid(c->pool, c->base_server));
++                      c->id, type, ssl_util_vhostid(c->pool, mySrvFromConn(c)));
+     }
+ 
+     /* deallocate the SSL connection */
+@@ -1021,21 +1021,23 @@ static int ssl_io_filter_connect(ssl_filter_ctx_t
+ {
+     conn_rec *c         = (conn_rec *)SSL_get_app_data(filter_ctx->pssl);
+     SSLConnRec *sslconn = myConnConfig(c);
+-    SSLSrvConfigRec *sc = mySrvConfig(c->base_server);
++    SSLSrvConfigRec *sc;
+     X509 *cert;
+     int n;
+     int ssl_err;
+     long verify_result;
++    server_rec *server;
+ 
+     if (SSL_is_init_finished(filter_ctx->pssl)) {
+         return APR_SUCCESS;
+     }
+ 
++    server = mySrvFromConn(c);
+     if (sslconn->is_proxy) {
+         if ((n = SSL_connect(filter_ctx->pssl)) <= 0) {
+             ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c,
+                           "SSL Proxy connect failed");
+-            ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, c->base_server);
++            ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, server);
+             /* ensure that the SSL structures etc are freed, etc: */
+             ssl_filter_io_shutdown(filter_ctx, c, 1);
+             return HTTP_BAD_GATEWAY;
+@@ -1092,8 +1094,8 @@ static int ssl_io_filter_connect(ssl_filter_ctx_t
+             ap_log_cerror(APLOG_MARK, APLOG_INFO, rc, c,
+                           "SSL library error %d in handshake "
+                           "(server %s)", ssl_err,
+-                          ssl_util_vhostid(c->pool, c->base_server));
+-            ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, c->base_server);
++                          ssl_util_vhostid(c->pool, server));
++            ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, server);
+ 
+         }
+         if (inctx->rc == APR_SUCCESS) {
+@@ -1102,6 +1104,7 @@ static int ssl_io_filter_connect(ssl_filter_ctx_t
+ 
+         return ssl_filter_io_shutdown(filter_ctx, c, 1);
+     }
++    sc = mySrvConfig(sslconn->server);
+ 
+     /*
+      * Check for failed client authentication
+@@ -1127,7 +1130,7 @@ static int ssl_io_filter_connect(ssl_filter_ctx_t
+                           "accepting certificate based on "
+                           "\"SSLVerifyClient optional_no_ca\" "
+                           "configuration");
+-            ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, c->base_server);
++            ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, server);
+         }
+         else {
+             const char *error = sslconn->verify_error ?
+@@ -1137,7 +1140,7 @@ static int ssl_io_filter_connect(ssl_filter_ctx_t
+             ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c,
+                          "SSL client authentication failed: %s",
+                          error ? error : "unknown");
+-            ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, c->base_server);
++            ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, server);
+ 
+             return ssl_filter_io_shutdown(filter_ctx, c, 1);
+         }
+@@ -1809,7 +1812,7 @@ long ssl_io_data_cb(BIO *bio, int cmd,
+         return rc;
+     if ((c = (conn_rec *)SSL_get_app_data(ssl)) == NULL)
+         return rc;
+-    s = c->base_server;
++    s = mySrvFromConn(c);
+ 
+     if (   cmd == (BIO_CB_WRITE|BIO_CB_RETURN)
+         || cmd == (BIO_CB_READ |BIO_CB_RETURN) ) {
+Index: httpd-2.2.11/modules/ssl/ssl_engine_vars.c
+===================================================================
+--- httpd-2.2.11/modules/ssl/ssl_engine_vars.c	(revision 768863)
++++ httpd-2.2.11/modules/ssl/ssl_engine_vars.c	(working copy)
 @@ -320,6 +320,12 @@ static char *ssl_var_lookup_ssl(apr_pool_t *p, con
      else if (ssl != NULL && strcEQ(var, "COMPRESS_METHOD")) {
@@ -135,8 +333,17 @@
  }
  
-Index: httpd-2.2.x/modules/ssl/ssl_engine_kernel.c
+@@ -589,7 +595,7 @@ static char *ssl_var_lookup_ssl_cert_verify(apr_po
+     vrc   = SSL_get_verify_result(ssl);
+     xs    = SSL_get_peer_certificate(ssl);
+ 
+-    if (vrc == X509_V_OK && verr == NULL && vinfo == NULL && xs == NULL)
++    if (vrc == X509_V_OK && verr == NULL && xs == NULL)
+         /* no client verification done at all */
+         result = "NONE";
+     else if (vrc == X509_V_OK && verr == NULL && vinfo == NULL && xs != NULL)
+Index: httpd-2.2.11/modules/ssl/ssl_engine_kernel.c
 ===================================================================
---- httpd-2.2.x/modules/ssl/ssl_engine_kernel.c	(revision 763153)
-+++ httpd-2.2.x/modules/ssl/ssl_engine_kernel.c	(working copy)
+--- httpd-2.2.11/modules/ssl/ssl_engine_kernel.c	(revision 768863)
++++ httpd-2.2.11/modules/ssl/ssl_engine_kernel.c	(working copy)
 @@ -31,6 +31,9 @@
  #include "ssl_private.h"
@@ -159,5 +366,5 @@
      if (!sslconn) {
          return DECLINED;
-@@ -87,6 +93,34 @@ int ssl_hook_ReadReq(request_rec *r)
+@@ -87,6 +93,51 @@ int ssl_hook_ReadReq(request_rec *r)
      if (!ssl) {
          return DECLINED;
@@ -190,18 +397,51 @@
 +        }
 +    }
++    else if ((((mySrvConfig(r->server))->strict_sni_vhost_check
++                == SSL_ENABLED_TRUE)
++             || (mySrvConfig(sslconn->server))->strict_sni_vhost_check
++                == SSL_ENABLED_TRUE)
++             && r->connection->vhost_lookup_data) {
++        /*
++         * We are using a name based configuration here, but no hostname was
++         * provided via SNI. Don't allow that if are requested to do strict
++         * checking. Check whether this strict checking was setup either in the
++         * server config we used for handshaking or in our current server.
++         * This should avoid insecure configuration by accident.
++         */
++        ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
++                     "No hostname was provided via SNI for a name based"
++                     " virtual host");
++        return HTTP_FORBIDDEN;
++    }
 +#endif
      SSL_set_app_data2(ssl, r);
  
      /*
-@@ -252,7 +286,7 @@ int ssl_hook_Access(request_rec *r)
+@@ -155,10 +206,11 @@ static void ssl_configure_env(request_rec *r, SSLC
+  */
+ int ssl_hook_Access(request_rec *r)
+ {
+-    SSLDirConfigRec *dc = myDirConfig(r);
+-    SSLSrvConfigRec *sc = mySrvConfig(r->server);
+-    SSLConnRec *sslconn = myConnConfig(r->connection);
+-    SSL *ssl            = sslconn ? sslconn->ssl : NULL;
++    SSLDirConfigRec *dc         = myDirConfig(r);
++    SSLSrvConfigRec *sc         = mySrvConfig(r->server);
++    SSLConnRec *sslconn         = myConnConfig(r->connection);
++    SSL *ssl                    = sslconn ? sslconn->ssl : NULL;
++    server_rec *handshakeserver = sslconn ? sslconn->server : NULL;
+     SSL_CTX *ctx = NULL;
+     apr_array_header_t *requires;
+     ssl_require_t *ssl_requires;
+@@ -252,7 +304,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)) {
++    if (dc->szCipherSuite || (r->server != handshakeserver)) {
          /* remember old state */
  
          if (dc->nOptions & SSL_OPT_OPTRENEGOTIATE) {
-@@ -267,7 +301,10 @@ int ssl_hook_Access(request_rec *r)
+@@ -267,7 +319,10 @@ int ssl_hook_Access(request_rec *r)
          }
  
@@ -215,5 +455,5 @@
                           r->server,
                           "Unable to reconfigure (per-directory) "
-@@ -334,8 +371,13 @@ int ssl_hook_Access(request_rec *r)
+@@ -334,8 +389,13 @@ int ssl_hook_Access(request_rec *r)
              sk_SSL_CIPHER_free(cipher_list_old);
          }
@@ -230,5 +470,11 @@
                           "Reconfigured cipher suite will force renegotiation");
          }
-@@ -353,19 +395,15 @@ int ssl_hook_Access(request_rec *r)
+@@ -348,24 +408,22 @@ int ssl_hook_Access(request_rec *r)
+      * function and not by OpenSSL internally (and our function is aware of
+      * both the per-server and per-directory contexts). So we cannot ask
+      * OpenSSL about the currently verify depth. Instead we remember it in our
+-     * ap_ctx attached to the SSL* of OpenSSL.  We've to force the
++     * SSLConnRec attached to the SSL* of OpenSSL.  We've to force the
+      * renegotiation if the reconfigured/new verify depth is less than the
       * currently active/remembered verify depth (because this means more
       * restriction on the certificate chain).
@@ -247,9 +493,11 @@
 -                         "renegotiation");
 -        }
-+    n = sslconn->verify_depth;
++    n = sslconn->verify_depth ?
++        sslconn->verify_depth :
++        (mySrvConfig(handshakeserver))->server->auth.verify_depth;
++    /* determine the new depth */
 +    sslconn->verify_depth = (dc->nVerifyDepth != UNSET) ?
 +                            dc->nVerifyDepth : sc->server->auth.verify_depth;
-+    if ((sslconn->verify_depth < n) ||
-+        ((n == 0) && (sc->server->auth.verify_depth == 0))) {
++    if (sslconn->verify_depth < n) {
 +        renegotiate = TRUE;
 +        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
@@ -259,5 +507,5 @@
  
      /*
-@@ -382,18 +420,22 @@ int ssl_hook_Access(request_rec *r)
+@@ -382,18 +440,22 @@ int ssl_hook_Access(request_rec *r)
       * verification but at least skip the I/O-intensive renegotation
       * handshake.
@@ -285,46 +533,51 @@
              verify |= SSL_VERIFY_PEER;
          }
-@@ -491,6 +533,40 @@ int ssl_hook_Access(request_rec *r)
-                      "Changed client verification locations will force "
-                      "renegotiation");
-     }
-+#else
-+#ifndef OPENSSL_NO_TLSEXT
+@@ -430,6 +492,45 @@ int ssl_hook_Access(request_rec *r)
+                              renegotiate_quick ? "quick " : "");
+              }
+         }
++        /* 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 == handshakeserver). 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 (OpenSSL doesn't provide
++         * an option to change the list for an existing session).
++         */
++        if ((r->server != handshakeserver)
++            && renegotiate
++            && ((verify & SSL_VERIFY_PEER) ||
++                (verify & SSL_VERIFY_FAIL_IF_NO_PEER_CERT))) {
++            SSLSrvConfigRec *hssc = mySrvConfig(handshakeserver);
++
 +#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;
++            (sc1->server->auth.f && \
++             (!sc2->server->auth.f || \
++              strNE(sc1->server->auth.f, sc2->server->auth.f)))
++
++            if (MODSSL_CFG_CA_NE(ca_cert_file, sc, hssc) ||
++                MODSSL_CFG_CA_NE(ca_cert_path, sc, hssc)) {
++                if (verify & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
++                    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 available to clients with TLS server "
++                         "name indication (SNI) support");
++                    modssl_set_verify(ssl, verify_old, NULL);
++                    return HTTP_FORBIDDEN;
++                } else
++                    /* let it pass, possibly with an "incorrect" peer cert,
++                     * so make sure the SSL_CLIENT_VERIFY environment variable
++                     * will indicate partial success only, later on.
++                     */
++                    sslconn->verify_info = "GENEROUS";
++            }
 +        }
-+    }
-+#endif /* OPENSSL_NO_TLSEXT */
- #endif /* HAVE_SSL_SET_CERT_STORE */
- 
-     /* If a renegotiation is now required for this location, and the
-@@ -675,8 +751,10 @@ int ssl_hook_Access(request_rec *r)
+     }
+ 
+     /*
+@@ -666,8 +767,10 @@ int ssl_hook_Access(request_rec *r)
          /*
           * Finally check for acceptable renegotiation results
@@ -339,5 +592,5 @@
              if (do_verify && (SSL_get_verify_result(ssl) != X509_V_OK)) {
                  ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
-@@ -1006,6 +1084,9 @@ int ssl_hook_Fixup(request_rec *r)
+@@ -997,6 +1100,9 @@ int ssl_hook_Fixup(request_rec *r)
      SSLDirConfigRec *dc = myDirConfig(r);
      apr_table_t *env = r->subprocess_env;
@@ -349,5 +602,5 @@
      SSL *ssl;
      int i;
-@@ -1027,6 +1108,13 @@ int ssl_hook_Fixup(request_rec *r)
+@@ -1018,6 +1124,13 @@ int ssl_hook_Fixup(request_rec *r)
      /* the always present HTTPS (=HTTP over SSL) flag! */
      apr_table_setn(env, "HTTPS", "on");
@@ -363,5 +616,23 @@
      if (dc->nOptions & SSL_OPT_STDENVVARS) {
          for (i = 0; ssl_hook_Fixup_vars[i]; i++) {
-@@ -1175,8 +1263,8 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX
+@@ -1105,7 +1218,7 @@ int ssl_hook_Fixup(request_rec *r)
+ RSA *ssl_callback_TmpRSA(SSL *ssl, int export, int keylen)
+ {
+     conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
+-    SSLModConfigRec *mc = myModConfig(c->base_server);
++    SSLModConfigRec *mc = myModConfigFromConn(c);
+     int idx;
+ 
+     ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
+@@ -1137,7 +1250,7 @@ RSA *ssl_callback_TmpRSA(SSL *ssl, int export, int
+ DH *ssl_callback_TmpDH(SSL *ssl, int export, int keylen)
+ {
+     conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
+-    SSLModConfigRec *mc = myModConfig(c->base_server);
++    SSLModConfigRec *mc = myModConfigFromConn(c);
+     int idx;
+ 
+     ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
+@@ -1166,8 +1279,8 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX
      SSL *ssl = X509_STORE_CTX_get_ex_data(ctx,
                                            SSL_get_ex_data_X509_STORE_CTX_idx());
@@ -369,9 +640,9 @@
 -    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;
++    server_rec *s       = r ? r->server : mySrvFromConn(conn);
  
      SSLSrvConfigRec *sc = mySrvConfig(s);
      SSLDirConfigRec *dc = r ? myDirConfig(r) : NULL;
-@@ -1299,7 +1387,10 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX
+@@ -1290,7 +1403,10 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX
  
  int ssl_callback_SSLVerify_CRL(int ok, X509_STORE_CTX *ctx, conn_rec *c)
@@ -381,9 +652,45 @@
 +                                          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;
++    server_rec *s       = r ? r->server : mySrvFromConn(c);
      SSLSrvConfigRec *sc = mySrvConfig(s);
      SSLConnRec *sslconn = myConnConfig(c);
      modssl_ctx_t *mctx  = myCtxConfig(sslconn, sc);
-@@ -1819,3 +1910,141 @@ void ssl_callback_LogTracingState(MODSSL_INFO_CB_A
+@@ -1515,7 +1631,7 @@ static void modssl_proxy_info_log(server_rec *s,
+ int ssl_callback_proxy_cert(SSL *ssl, MODSSL_CLIENT_CERT_CB_ARG_TYPE **x509, EVP_PKEY **pkey)
+ {
+     conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
+-    server_rec *s = c->base_server;
++    server_rec *s = mySrvFromConn(c);
+     SSLSrvConfigRec *sc = mySrvConfig(s);
+     X509_NAME *ca_name, *issuer;
+     X509_INFO *info;
+@@ -1613,7 +1729,7 @@ int ssl_callback_NewSessionCacheEntry(SSL *ssl, SS
+ {
+     /* Get Apache context back through OpenSSL context */
+     conn_rec *conn      = (conn_rec *)SSL_get_app_data(ssl);
+-    server_rec *s       = conn->base_server;
++    server_rec *s       = mySrvFromConn(conn);
+     SSLSrvConfigRec *sc = mySrvConfig(s);
+     long timeout        = sc->session_cache_timeout;
+     BOOL rc;
+@@ -1661,7 +1777,7 @@ SSL_SESSION *ssl_callback_GetSessionCacheEntry(SSL
+ {
+     /* Get Apache context back through OpenSSL context */
+     conn_rec *conn = (conn_rec *)SSL_get_app_data(ssl);
+-    server_rec *s  = conn->base_server;
++    server_rec *s  = mySrvFromConn(conn);
+     SSL_SESSION *session;
+ 
+     /*
+@@ -1739,7 +1855,7 @@ void ssl_callback_LogTracingState(MODSSL_INFO_CB_A
+         return;
+     }
+ 
+-    s = c->base_server;
++    s = mySrvFromConn(c);
+     if (!(sc = mySrvConfig(s))) {
+         return;
+     }
+@@ -1810,3 +1926,138 @@ void ssl_callback_LogTracingState(MODSSL_INFO_CB_A
      }
  }
@@ -434,4 +741,5 @@
 +    apr_array_header_t *names;
 +    int i;
++    SSLConnRec *sslcon;
 +
 +    /* check ServerName */
@@ -476,5 +784,6 @@
 +
 +    /* set SSL_CTX (if matched) */
-+    if (found && (ssl = ((SSLConnRec *)myConnConfig(c))->ssl) &&
++    sslcon = myConnConfig(c);
++    if (found && (ssl = sslcon->ssl) &&
 +        (sc = mySrvConfig(s))) {
 +        SSL_set_SSL_CTX(ssl, sc->server->ssl_ctx);
@@ -499,13 +808,8 @@
 +
 +        /*
-+         * 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.
++         * Save the found server into our SSLConnRec for later
++         * retrieval
 +         */
-+        c->base_server = s;
++        sslcon->server = s;
 +
 +        /*
@@ -516,5 +820,5 @@
 +         * we need to set that callback here.
 +         */
-+        if (c->base_server->loglevel >= APLOG_DEBUG) {
++        if (s->loglevel >= APLOG_DEBUG) {
 +            BIO_set_callback(SSL_get_rbio(ssl), ssl_io_data_cb);
 +            BIO_set_callback_arg(SSL_get_rbio(ssl), (void *)ssl);
@@ -527,8 +831,129 @@
 +}
 +#endif
-Index: httpd-2.2.x/modules/ssl/ssl_toolkit_compat.h
+Index: httpd-2.2.11/modules/ssl/mod_ssl.c
 ===================================================================
---- httpd-2.2.x/modules/ssl/ssl_toolkit_compat.h	(revision 763153)
-+++ httpd-2.2.x/modules/ssl/ssl_toolkit_compat.h	(working copy)
+--- httpd-2.2.11/modules/ssl/mod_ssl.c	(revision 768863)
++++ httpd-2.2.11/modules/ssl/mod_ssl.c	(working copy)
+@@ -145,6 +145,10 @@ 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(StrictSNIVHostCheck, FLAG,
++                "Strict SNI virtual host checking")
++#endif
+ 
+     /*
+      * Proxy configuration for remote SSL connections
+@@ -295,6 +299,8 @@ static SSLConnRec *ssl_init_connection_ctx(conn_re
+ 
+     sslconn = apr_pcalloc(c->pool, sizeof(*sslconn));
+ 
++    sslconn->server = c->base_server;
++
+     myConnConfigSet(c, sslconn);
+ 
+     return sslconn;
+@@ -302,9 +308,10 @@ static SSLConnRec *ssl_init_connection_ctx(conn_re
+ 
+ int ssl_proxy_enable(conn_rec *c)
+ {
+-    SSLSrvConfigRec *sc = mySrvConfig(c->base_server);
++    SSLSrvConfigRec *sc;
+ 
+     SSLConnRec *sslconn = ssl_init_connection_ctx(c);
++    sc = mySrvConfig(sslconn->server);
+ 
+     if (!sc->proxy_enabled) {
+         ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c,
+@@ -322,10 +329,16 @@ int ssl_proxy_enable(conn_rec *c)
+ 
+ int ssl_engine_disable(conn_rec *c)
+ {
+-    SSLSrvConfigRec *sc = mySrvConfig(c->base_server);
++    SSLSrvConfigRec *sc;
+ 
+-    SSLConnRec *sslconn;
++    SSLConnRec *sslconn = myConnConfig(c);
+ 
++    if (sslconn) {
++        sc = mySrvConfig(sslconn->server);
++    }
++    else {
++        sc = mySrvConfig(c->base_server);
++    }
+     if (sc->enabled == SSL_ENABLED_FALSE) {
+         return 0;
+     }
+@@ -339,21 +352,24 @@ int ssl_engine_disable(conn_rec *c)
+ 
+ int ssl_init_ssl_connection(conn_rec *c)
+ {
+-    SSLSrvConfigRec *sc = mySrvConfig(c->base_server);
++    SSLSrvConfigRec *sc;
+     SSL *ssl;
+     SSLConnRec *sslconn = myConnConfig(c);
+     char *vhost_md5;
+     modssl_ctx_t *mctx;
++    server_rec *server;
+ 
++    if (!sslconn) {
++        sslconn = ssl_init_connection_ctx(c);
++    }
++    server = sslconn->server;
++    sc = mySrvConfig(server);
++
+     /*
+      * Seed the Pseudo Random Number Generator (PRNG)
+      */
+-    ssl_rand_seed(c->base_server, c->pool, SSL_RSCTX_CONNECT, "");
++    ssl_rand_seed(server, c->pool, SSL_RSCTX_CONNECT, "");
+ 
+-    if (!sslconn) {
+-        sslconn = ssl_init_connection_ctx(c);
+-    }
+-
+     mctx = sslconn->is_proxy ? sc->proxy : sc->server;
+ 
+     /*
+@@ -365,7 +381,7 @@ int ssl_init_ssl_connection(conn_rec *c)
+         ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c,
+                       "Unable to create a new SSL connection from the SSL "
+                       "context");
+-        ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, c->base_server);
++        ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, server);
+ 
+         c->aborted = 1;
+ 
+@@ -380,7 +396,7 @@ int ssl_init_ssl_connection(conn_rec *c)
+     {
+         ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c,
+                       "Unable to set session id context to `%s'", vhost_md5);
+-        ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, c->base_server);
++        ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, server);
+ 
+         c->aborted = 1;
+ 
+@@ -429,9 +445,15 @@ static apr_port_t ssl_hook_default_port(const requ
+ 
+ static int ssl_hook_pre_connection(conn_rec *c, void *csd)
+ {
+-    SSLSrvConfigRec *sc = mySrvConfig(c->base_server);
++    SSLSrvConfigRec *sc;
+     SSLConnRec *sslconn = myConnConfig(c);
+ 
++    if (sslconn) {
++        sc = mySrvConfig(sslconn->server);
++    }
++    else {
++        sc = mySrvConfig(c->base_server);
++    }
+     /*
+      * Immediately stop processing if SSL is disabled for this connection
+      */
+Index: httpd-2.2.11/modules/ssl/ssl_toolkit_compat.h
+===================================================================
+--- httpd-2.2.11/modules/ssl/ssl_toolkit_compat.h	(revision 768863)
++++ httpd-2.2.11/modules/ssl/ssl_toolkit_compat.h	(working copy)
 @@ -264,6 +264,12 @@ typedef void (*modssl_popfree_fn)(char *data);
  #define SSL_SESS_CACHE_NO_INTERNAL  SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
@@ -544,2 +969,60 @@
  
  /** @} */
+Index: httpd-2.2.11/docs/manual/mod/mod_ssl.html.en
+===================================================================
+--- httpd-2.2.11/docs/manual/mod/mod_ssl.html.en	(revision 768863)
++++ httpd-2.2.11/docs/manual/mod/mod_ssl.html.en	(working copy)
+@@ -75,6 +75,7 @@ to provide the cryptography engine.</p>
+ <li><img alt="" src="../images/down.gif" /> <a href="#sslrequiressl">SSLRequireSSL</a></li>
+ <li><img alt="" src="../images/down.gif" /> <a href="#sslsessioncache">SSLSessionCache</a></li>
+ <li><img alt="" src="../images/down.gif" /> <a href="#sslsessioncachetimeout">SSLSessionCacheTimeout</a></li>
++<li><img alt="" src="../images/down.gif" /> <a href="#sslstrictsnivhostcheck">SSLStrictSNIVHostCheck</a></li>
+ <li><img alt="" src="../images/down.gif" /> <a href="#sslusername">SSLUserName</a></li>
+ <li><img alt="" src="../images/down.gif" /> <a href="#sslverifyclient">SSLVerifyClient</a></li>
+ <li><img alt="" src="../images/down.gif" /> <a href="#sslverifydepth">SSLVerifyDepth</a></li>
+@@ -1613,6 +1614,37 @@ SSLSessionCacheTimeout 600
+ 
+ </div>
+ <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
++<div class="directive-section"><h2><a name="SSLStrictSNIVHostCheck" id="SSLStrictSNIVHostCheck">SSLStrictSNIVHostCheck</a> <a name="sslstrictsnivhostcheck" id="sslstrictsnivhostcheck">Directive</a></h2>
++<table class="directive">
++<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Whether to allow non SNI clients to access a name based virtual
++host.
++</td></tr>
++<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>SSLStrictSNIVHostCheck on|off</code></td></tr>
++<tr><th><a href="directive-dict.html#Default">Default:</a></th><td><code>SSLStrictSNIVHostCheck off</code></td></tr>
++<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host</td></tr>
++<tr><th><a href="directive-dict.html#Status">Status:</a></th><td>Extension</td></tr>
++<tr><th><a href="directive-dict.html#Module">Module:</a></th><td>mod_ssl</td></tr>
++</table>
++<p>
++This directive sets whether a non SNI client is allowed to access a name based
++virtual host. If set to <code>on</code> in the non default name based virtual
++host, non SNI clients are not allowed to access this particular virtual host.
++If set to <code>on</code> in the default name based virtual host, non SNI
++clients are not allowed to access any name based virtual host belonging to
++this IP / port combination.
++</p>
++
++<div class="warning"><p>
++This option is only available if httpd was compiled against an SNI capable
++version of OpenSSL.
++</p></div>
++
++<div class="example"><h3>Example</h3><p><code>
++SSLStrictSNIVHostCheck on
++</code></p></div>
++
++</div>
++<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
+ <div class="directive-section"><h2><a name="SSLUserName" id="SSLUserName">SSLUserName</a> <a name="sslusername" id="sslusername">Directive</a></h2>
+ <table class="directive">
+ <tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Variable name to determine user name</td></tr>
+@@ -1717,6 +1749,6 @@ SSLVerifyDepth 10
+ <div class="bottomlang">
+ <p><span>Available Languages: </span><a href="../en/mod/mod_ssl.html" title="English">&nbsp;en&nbsp;</a></p>
+ </div><div id="footer">
+-<p class="apache">Copyright 2008 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
++<p class="apache">Copyright 2009 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
+ <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="../faq/">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div>
+ </body></html>
