source: server/common/patches/httpd-2.2.x-sni.patch @ 1115

Last change on this file since 1115 was 1115, checked in by mitchb, 13 years ago
In this week's episode of "As the Server Name Indicates..." (Scripts's favorite night-time soap opera) Update SNI to 4/27/2009 sni.velox.ch patch under consideration for inclusion in upstream Apache 2.2.12
File size: 41.1 KB
RevLine 
[1115]1http://sni.velox.ch/httpd-2.2.11-sni.20090427.patch - server name indication
2support for mod_ssl / Apache 2.2.11 (RFC 4366, section 3.1)
[683]3
[1115]4Last updated 2009-04-27, by Kaspar Brand.
5Provided AS IS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND.
[683]6
[1115]7Based on a patch from the EdelKey project (http://www.edelweb.fr/EdelKey/files/),
8includes further improvements by Ruediger Pluem (from httpd trunk).
[683]9
[1102]10Needs openssl-SNAP-20060330 / OpenSSL 0.9.8f or later
11to work properly (ftp://ftp.openssl.org/snapshot/). OpenSSL versions
12prior to 0.9.8j must be configured explicitly for TLS extension support
13at compile time ("./config enable-tlsext").
14
[1115]15Index: httpd-2.2.11/modules/ssl/ssl_private.h
[683]16===================================================================
[1115]17--- httpd-2.2.11/modules/ssl/ssl_private.h      (revision 768863)
18+++ httpd-2.2.11/modules/ssl/ssl_private.h      (working copy)
[683]19@@ -35,6 +35,7 @@
20 #include "http_connection.h"
21 #include "http_request.h"
22 #include "http_protocol.h"
23+#include "http_vhost.h"
24 #include "util_script.h"
25 #include "util_filter.h"
26 #include "util_ebcdic.h"
[1115]27@@ -129,6 +130,9 @@ ap_set_module_config(c->conn_config, &ssl_module,
28 #define mySrvConfig(srv) (SSLSrvConfigRec *)ap_get_module_config(srv->module_config,  &ssl_module)
29 #define myDirConfig(req) (SSLDirConfigRec *)ap_get_module_config(req->per_dir_config, &ssl_module)
30 #define myModConfig(srv) (mySrvConfig((srv)))->mc
31+#define mySrvFromConn(c) (myConnConfig(c))->server
32+#define mySrvConfigFromConn(c) mySrvConfig(mySrvFromConn(c))
33+#define myModConfigFromConn(c) myModConfig(mySrvFromConn(c))
34 
35 #define myCtxVarSet(mc,num,val)  mc->rCtx.pV##num = val
36 #define myCtxVarGet(mc,num,type) (type)(mc->rCtx.pV##num)
37@@ -347,6 +351,7 @@ typedef struct {
38     int is_proxy;
39     int disabled;
40     int non_ssl_request;
41+    server_rec *server;
42 } SSLConnRec;
43 
44 typedef struct {
45@@ -449,6 +454,9 @@ struct SSLSrvConfigRec {
46     BOOL             cipher_server_pref;
47     modssl_ctx_t    *server;
48     modssl_ctx_t    *proxy;
49+#ifndef OPENSSL_NO_TLSEXT
50+    ssl_enabled_t    strict_sni_vhost_check;
51+#endif
52 };
53 
54 /**
55@@ -513,6 +521,9 @@ const char  *ssl_cmd_SSLOptions(cmd_parms *, void
56 const char  *ssl_cmd_SSLRequireSSL(cmd_parms *, void *);
57 const char  *ssl_cmd_SSLRequire(cmd_parms *, void *, const char *);
58 const char  *ssl_cmd_SSLUserName(cmd_parms *, void *, const char *);
59+#ifndef OPENSSL_NO_TLSEXT
60+const char  *ssl_cmd_SSLStrictSNIVHostCheck(cmd_parms *cmd, void *dcfg, int flag);
61+#endif
62 
63 const char  *ssl_cmd_SSLProxyEngine(cmd_parms *cmd, void *dcfg, int flag);
64 const char  *ssl_cmd_SSLProxyProtocol(cmd_parms *, void *, const char *);
65@@ -555,6 +566,9 @@ int          ssl_callback_NewSessionCacheEntry(SSL
[683]66 SSL_SESSION *ssl_callback_GetSessionCacheEntry(SSL *, unsigned char *, int, int *);
67 void         ssl_callback_DelSessionCacheEntry(SSL_CTX *, SSL_SESSION *);
68 void         ssl_callback_LogTracingState(MODSSL_INFO_CB_ARG_TYPE, int, int);
69+#ifndef OPENSSL_NO_TLSEXT
70+int          ssl_callback_ServerNameIndication(SSL *, int *, modssl_ctx_t *);
71+#endif
72 
73 /**  Session Cache Support  */
74 void         ssl_scache_init(server_rec *, apr_pool_t *);
[1115]75Index: httpd-2.2.11/modules/ssl/ssl_engine_init.c
[683]76===================================================================
[1115]77--- httpd-2.2.11/modules/ssl/ssl_engine_init.c  (revision 768863)
78+++ httpd-2.2.11/modules/ssl/ssl_engine_init.c  (working copy)
[1102]79@@ -358,6 +358,33 @@ static void ssl_init_server_check(server_rec *s,
[683]80     }
81 }
82 
83+#ifndef OPENSSL_NO_TLSEXT
84+static void ssl_init_ctx_tls_extensions(server_rec *s,
85+                                        apr_pool_t *p,
86+                                        apr_pool_t *ptemp,
87+                                        modssl_ctx_t *mctx)
88+{
89+    /*
90+     * Configure TLS extensions support
91+     */
92+    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
93+                 "Configuring TLS extension handling");
94+
95+    /*
96+     * Server name indication (SNI)
97+     */
98+    if (!SSL_CTX_set_tlsext_servername_callback(mctx->ssl_ctx,
99+                          ssl_callback_ServerNameIndication) ||
100+        !SSL_CTX_set_tlsext_servername_arg(mctx->ssl_ctx, mctx)) {
101+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
102+                     "Unable to initialize TLS servername extension "
103+                     "callback (incompatible OpenSSL version?)");
104+        ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
105+        ssl_die();
106+    }
107+}
108+#endif
109+
110 static void ssl_init_ctx_protocol(server_rec *s,
111                                   apr_pool_t *p,
112                                   apr_pool_t *ptemp,
[1102]113@@ -690,6 +717,9 @@ static void ssl_init_ctx(server_rec *s,
[683]114     if (mctx->pks) {
115         /* XXX: proxy support? */
116         ssl_init_ctx_cert_chain(s, p, ptemp, mctx);
117+#ifndef OPENSSL_NO_TLSEXT
118+        ssl_init_ctx_tls_extensions(s, p, ptemp, mctx);
119+#endif
120     }
121 }
122 
[1102]123@@ -1039,9 +1069,19 @@ void ssl_init_CheckServers(server_rec *base_server
[816]124         klen = strlen(key);
125 
[683]126         if ((ps = (server_rec *)apr_hash_get(table, key, klen))) {
[816]127-            ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
128+            ap_log_error(APLOG_MARK,
129+#ifdef OPENSSL_NO_TLSEXT
130+                         APLOG_WARNING,
131+#else
132+                         APLOG_DEBUG,
133+#endif
134+                         0,
[683]135                          base_server,
136+#ifdef OPENSSL_NO_TLSEXT
137                          "Init: SSL server IP/port conflict: "
138+#else
139+                         "Init: SSL server IP/port overlap: "
140+#endif
141                          "%s (%s:%d) vs. %s (%s:%d)",
142                          ssl_util_vhostid(p, s),
143                          (s->defn_name ? s->defn_name : "unknown"),
[1102]144@@ -1058,8 +1098,14 @@ void ssl_init_CheckServers(server_rec *base_server
[683]145 
146     if (conflict) {
147         ap_log_error(APLOG_MARK, APLOG_WARNING, 0, base_server,
148+#ifdef OPENSSL_NO_TLSEXT
149                      "Init: You should not use name-based "
150                      "virtual hosts in conjunction with SSL!!");
151+#else
152+                     "Init: Name-based SSL virtual hosts only "
153+                     "work for clients with TLS server name indication "
154+                     "support (RFC 4366)");
155+#endif
156     }
157 }
158 
[1115]159Index: httpd-2.2.11/modules/ssl/ssl_engine_config.c
[683]160===================================================================
[1115]161--- httpd-2.2.11/modules/ssl/ssl_engine_config.c        (revision 768863)
162+++ httpd-2.2.11/modules/ssl/ssl_engine_config.c        (working copy)
163@@ -169,6 +169,9 @@ static SSLSrvConfigRec *ssl_config_server_new(apr_
164     sc->vhost_id_len           = 0;     /* set during module init */
165     sc->session_cache_timeout  = UNSET;
166     sc->cipher_server_pref     = UNSET;
167+#ifndef OPENSSL_NO_TLSEXT
168+    sc->strict_sni_vhost_check = SSL_ENABLED_UNSET;
169+#endif
170 
171     modssl_ctx_init_proxy(sc, p);
172 
173@@ -257,6 +260,9 @@ void *ssl_config_server_merge(apr_pool_t *p, void
174     cfgMergeBool(proxy_enabled);
175     cfgMergeInt(session_cache_timeout);
176     cfgMergeBool(cipher_server_pref);
177+#ifndef OPENSSL_NO_TLSEXT
178+    cfgMerge(strict_sni_vhost_check, SSL_ENABLED_UNSET);
179+#endif
180 
181     modssl_ctx_cfg_merge_proxy(base->proxy, add->proxy, mrg->proxy);
182 
183@@ -1411,6 +1417,17 @@ const char *ssl_cmd_SSLUserName(cmd_parms *cmd, vo
184     return NULL;
185 }
186 
187+#ifndef OPENSSL_NO_TLSEXT
188+const char  *ssl_cmd_SSLStrictSNIVHostCheck(cmd_parms *cmd, void *dcfg, int flag)
189+{
190+    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
191+
192+    sc->strict_sni_vhost_check = flag ? SSL_ENABLED_TRUE : SSL_ENABLED_FALSE;
193+
194+    return NULL;
195+}
196+#endif
197+
198 void ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s)
199 {
200     if (!ap_exists_config_define("DUMP_CERTS")) {
201Index: httpd-2.2.11/modules/ssl/ssl_engine_io.c
202===================================================================
203--- httpd-2.2.11/modules/ssl/ssl_engine_io.c    (revision 768863)
204+++ httpd-2.2.11/modules/ssl/ssl_engine_io.c    (working copy)
205@@ -695,7 +695,7 @@ static apr_status_t ssl_io_input_read(bio_filter_i
206                  */
207                 ap_log_cerror(APLOG_MARK, APLOG_INFO, inctx->rc, c,
208                               "SSL library error %d reading data", ssl_err);
209-                ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, c->base_server);
210+                ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, mySrvFromConn(c));
211 
212             }
213             if (inctx->rc == APR_SUCCESS) {
214@@ -799,7 +799,7 @@ static apr_status_t ssl_filter_write(ap_filter_t *
215              */
216             ap_log_cerror(APLOG_MARK, APLOG_INFO, outctx->rc, c,
217                           "SSL library error %d writing data", ssl_err);
218-            ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, c->base_server);
219+            ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, mySrvFromConn(c));
220         }
221         if (outctx->rc == APR_SUCCESS) {
222             outctx->rc = APR_EGENERAL;
223@@ -861,7 +861,7 @@ static apr_status_t ssl_io_filter_error(ap_filter_
224             ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, f->c,
225                          "SSL handshake failed: HTTP spoken on HTTPS port; "
226                          "trying to send HTML error page");
227-            ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, f->c->base_server);
228+            ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, sslconn->server);
229 
230             sslconn->non_ssl_request = 1;
231             ssl_io_filter_disable(sslconn, f);
232@@ -971,11 +971,11 @@ static apr_status_t ssl_filter_io_shutdown(ssl_fil
233     SSL_smart_shutdown(ssl);
234 
235     /* and finally log the fact that we've closed the connection */
236-    if (c->base_server->loglevel >= APLOG_INFO) {
237+    if (mySrvFromConn(c)->loglevel >= APLOG_INFO) {
238         ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c,
239                       "Connection closed to child %ld with %s shutdown "
240                       "(server %s)",
241-                      c->id, type, ssl_util_vhostid(c->pool, c->base_server));
242+                      c->id, type, ssl_util_vhostid(c->pool, mySrvFromConn(c)));
243     }
244 
245     /* deallocate the SSL connection */
246@@ -1021,21 +1021,23 @@ static int ssl_io_filter_connect(ssl_filter_ctx_t
247 {
248     conn_rec *c         = (conn_rec *)SSL_get_app_data(filter_ctx->pssl);
249     SSLConnRec *sslconn = myConnConfig(c);
250-    SSLSrvConfigRec *sc = mySrvConfig(c->base_server);
251+    SSLSrvConfigRec *sc;
252     X509 *cert;
253     int n;
254     int ssl_err;
255     long verify_result;
256+    server_rec *server;
257 
258     if (SSL_is_init_finished(filter_ctx->pssl)) {
259         return APR_SUCCESS;
260     }
261 
262+    server = mySrvFromConn(c);
263     if (sslconn->is_proxy) {
264         if ((n = SSL_connect(filter_ctx->pssl)) <= 0) {
265             ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c,
266                           "SSL Proxy connect failed");
267-            ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, c->base_server);
268+            ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, server);
269             /* ensure that the SSL structures etc are freed, etc: */
270             ssl_filter_io_shutdown(filter_ctx, c, 1);
271             return HTTP_BAD_GATEWAY;
272@@ -1092,8 +1094,8 @@ static int ssl_io_filter_connect(ssl_filter_ctx_t
273             ap_log_cerror(APLOG_MARK, APLOG_INFO, rc, c,
274                           "SSL library error %d in handshake "
275                           "(server %s)", ssl_err,
276-                          ssl_util_vhostid(c->pool, c->base_server));
277-            ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, c->base_server);
278+                          ssl_util_vhostid(c->pool, server));
279+            ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, server);
280 
281         }
282         if (inctx->rc == APR_SUCCESS) {
283@@ -1102,6 +1104,7 @@ static int ssl_io_filter_connect(ssl_filter_ctx_t
284 
285         return ssl_filter_io_shutdown(filter_ctx, c, 1);
286     }
287+    sc = mySrvConfig(sslconn->server);
288 
289     /*
290      * Check for failed client authentication
291@@ -1127,7 +1130,7 @@ static int ssl_io_filter_connect(ssl_filter_ctx_t
292                           "accepting certificate based on "
293                           "\"SSLVerifyClient optional_no_ca\" "
294                           "configuration");
295-            ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, c->base_server);
296+            ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, server);
297         }
298         else {
299             const char *error = sslconn->verify_error ?
300@@ -1137,7 +1140,7 @@ static int ssl_io_filter_connect(ssl_filter_ctx_t
301             ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c,
302                          "SSL client authentication failed: %s",
303                          error ? error : "unknown");
304-            ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, c->base_server);
305+            ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, server);
306 
307             return ssl_filter_io_shutdown(filter_ctx, c, 1);
308         }
309@@ -1809,7 +1812,7 @@ long ssl_io_data_cb(BIO *bio, int cmd,
310         return rc;
311     if ((c = (conn_rec *)SSL_get_app_data(ssl)) == NULL)
312         return rc;
313-    s = c->base_server;
314+    s = mySrvFromConn(c);
315 
316     if (   cmd == (BIO_CB_WRITE|BIO_CB_RETURN)
317         || cmd == (BIO_CB_READ |BIO_CB_RETURN) ) {
318Index: httpd-2.2.11/modules/ssl/ssl_engine_vars.c
319===================================================================
320--- httpd-2.2.11/modules/ssl/ssl_engine_vars.c  (revision 768863)
321+++ httpd-2.2.11/modules/ssl/ssl_engine_vars.c  (working copy)
[1102]322@@ -320,6 +320,12 @@ static char *ssl_var_lookup_ssl(apr_pool_t *p, con
[683]323     else if (ssl != NULL && strcEQ(var, "COMPRESS_METHOD")) {
324         result = ssl_var_lookup_ssl_compress_meth(ssl);
325     }
326+#ifndef OPENSSL_NO_TLSEXT
327+    else if (ssl != NULL && strcEQ(var, "TLS_SNI")) {
328+        result = apr_pstrdup(p, SSL_get_servername(ssl,
329+                                                   TLSEXT_NAMETYPE_host_name));
330+    }
331+#endif
332     return result;
333 }
334 
[1115]335@@ -589,7 +595,7 @@ static char *ssl_var_lookup_ssl_cert_verify(apr_po
336     vrc   = SSL_get_verify_result(ssl);
337     xs    = SSL_get_peer_certificate(ssl);
338 
339-    if (vrc == X509_V_OK && verr == NULL && vinfo == NULL && xs == NULL)
340+    if (vrc == X509_V_OK && verr == NULL && xs == NULL)
341         /* no client verification done at all */
342         result = "NONE";
343     else if (vrc == X509_V_OK && verr == NULL && vinfo == NULL && xs != NULL)
344Index: httpd-2.2.11/modules/ssl/ssl_engine_kernel.c
[683]345===================================================================
[1115]346--- httpd-2.2.11/modules/ssl/ssl_engine_kernel.c        (revision 768863)
347+++ httpd-2.2.11/modules/ssl/ssl_engine_kernel.c        (working copy)
[683]348@@ -31,6 +31,9 @@
349 #include "ssl_private.h"
350 
351 static void ssl_configure_env(request_rec *r, SSLConnRec *sslconn);
352+#ifndef OPENSSL_NO_TLSEXT
353+static int ssl_find_vhost(void *servername, conn_rec *c, server_rec *s);
354+#endif
355 
356 /*
357  *  Post Read Request Handler
[816]358@@ -39,6 +42,9 @@ int ssl_hook_ReadReq(request_rec *r)
[683]359 {
360     SSLConnRec *sslconn = myConnConfig(r->connection);
361     SSL *ssl;
362+#ifndef OPENSSL_NO_TLSEXT
363+    const char *servername;
364+#endif
365 
366     if (!sslconn) {
367         return DECLINED;
[1115]368@@ -87,6 +93,51 @@ int ssl_hook_ReadReq(request_rec *r)
[683]369     if (!ssl) {
370         return DECLINED;
371     }
372+#ifndef OPENSSL_NO_TLSEXT
[1102]373+    if ((servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) {
374+        char *host, *scope_id;
375+        apr_port_t port;
376+        apr_status_t rv;
377+
378+        /*
379+         * The SNI extension supplied a hostname. So don't accept requests
380+         * with either no hostname or a different hostname.
381+         */
382+        if (!r->hostname) {
383+            ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
384+                        "Hostname %s provided via SNI, but no hostname"
385+                        " provided in HTTP request", servername);
386+            return HTTP_BAD_REQUEST;
387+        }
388+        rv = apr_parse_addr_port(&host, &scope_id, &port, r->hostname, r->pool);
389+        if (rv != APR_SUCCESS || scope_id) {
390+            return HTTP_BAD_REQUEST;
391+        }
392+        if (strcmp(host, servername)) {
393+            ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
394+                        "Hostname %s provided via SNI and hostname %s provided"
395+                        " via HTTP are different", servername, host);
396+            return HTTP_BAD_REQUEST;
397+        }
[683]398+    }
[1115]399+    else if ((((mySrvConfig(r->server))->strict_sni_vhost_check
400+                == SSL_ENABLED_TRUE)
401+             || (mySrvConfig(sslconn->server))->strict_sni_vhost_check
402+                == SSL_ENABLED_TRUE)
403+             && r->connection->vhost_lookup_data) {
404+        /*
405+         * We are using a name based configuration here, but no hostname was
406+         * provided via SNI. Don't allow that if are requested to do strict
407+         * checking. Check whether this strict checking was setup either in the
408+         * server config we used for handshaking or in our current server.
409+         * This should avoid insecure configuration by accident.
410+         */
411+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
412+                     "No hostname was provided via SNI for a name based"
413+                     " virtual host");
414+        return HTTP_FORBIDDEN;
415+    }
[683]416+#endif
417     SSL_set_app_data2(ssl, r);
418 
419     /*
[1115]420@@ -155,10 +206,11 @@ static void ssl_configure_env(request_rec *r, SSLC
421  */
422 int ssl_hook_Access(request_rec *r)
423 {
424-    SSLDirConfigRec *dc = myDirConfig(r);
425-    SSLSrvConfigRec *sc = mySrvConfig(r->server);
426-    SSLConnRec *sslconn = myConnConfig(r->connection);
427-    SSL *ssl            = sslconn ? sslconn->ssl : NULL;
428+    SSLDirConfigRec *dc         = myDirConfig(r);
429+    SSLSrvConfigRec *sc         = mySrvConfig(r->server);
430+    SSLConnRec *sslconn         = myConnConfig(r->connection);
431+    SSL *ssl                    = sslconn ? sslconn->ssl : NULL;
432+    server_rec *handshakeserver = sslconn ? sslconn->server : NULL;
433     SSL_CTX *ctx = NULL;
434     apr_array_header_t *requires;
435     ssl_require_t *ssl_requires;
436@@ -252,7 +304,7 @@ int ssl_hook_Access(request_rec *r)
[816]437      *   has to enable this via ``SSLOptions +OptRenegotiate''. So we do no
438      *   implicit optimizations.
439      */
440-    if (dc->szCipherSuite) {
[1115]441+    if (dc->szCipherSuite || (r->server != handshakeserver)) {
[816]442         /* remember old state */
443 
444         if (dc->nOptions & SSL_OPT_OPTRENEGOTIATE) {
[1115]445@@ -267,7 +319,10 @@ int ssl_hook_Access(request_rec *r)
[816]446         }
447 
448         /* configure new state */
449-        if (!modssl_set_cipher_list(ssl, dc->szCipherSuite)) {
[1102]450+        if ((dc->szCipherSuite || sc->server->auth.cipher_suite) &&
451+            !modssl_set_cipher_list(ssl, dc->szCipherSuite ?
452+                                         dc->szCipherSuite :
453+                                         sc->server->auth.cipher_suite)) {
[816]454             ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
455                          r->server,
456                          "Unable to reconfigure (per-directory) "
[1115]457@@ -334,8 +389,13 @@ int ssl_hook_Access(request_rec *r)
[816]458             sk_SSL_CIPHER_free(cipher_list_old);
459         }
460 
461-        /* tracing */
462         if (renegotiate) {
463+#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
464+            if (sc->cipher_server_pref == TRUE) {
465+                SSL_set_options(ssl, SSL_OP_CIPHER_SERVER_PREFERENCE);
466+            }
467+#endif
468+            /* tracing */
469             ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
470                          "Reconfigured cipher suite will force renegotiation");
471         }
[1115]472@@ -348,24 +408,22 @@ int ssl_hook_Access(request_rec *r)
473      * function and not by OpenSSL internally (and our function is aware of
474      * both the per-server and per-directory contexts). So we cannot ask
475      * OpenSSL about the currently verify depth. Instead we remember it in our
476-     * ap_ctx attached to the SSL* of OpenSSL.  We've to force the
477+     * SSLConnRec attached to the SSL* of OpenSSL.  We've to force the
478      * renegotiation if the reconfigured/new verify depth is less than the
[816]479      * currently active/remembered verify depth (because this means more
480      * restriction on the certificate chain).
481      */
482-    if (dc->nVerifyDepth != UNSET) {
[1102]483-        /* XXX: doesnt look like sslconn->verify_depth is actually used */
484-        if (!(n = sslconn->verify_depth)) {
485-            sslconn->verify_depth = n = sc->server->auth.verify_depth;
486-        }
487-
488-        /* determine whether a renegotiation has to be forced */
489-        if (dc->nVerifyDepth < n) {
490-            renegotiate = TRUE;
491-            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
492-                         "Reduced client verification depth will force "
493-                         "renegotiation");
494-        }
[1115]495+    n = sslconn->verify_depth ?
496+        sslconn->verify_depth :
497+        (mySrvConfig(handshakeserver))->server->auth.verify_depth;
498+    /* determine the new depth */
[1102]499+    sslconn->verify_depth = (dc->nVerifyDepth != UNSET) ?
500+                            dc->nVerifyDepth : sc->server->auth.verify_depth;
[1115]501+    if (sslconn->verify_depth < n) {
[1102]502+        renegotiate = TRUE;
503+        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
504+                     "Reduced client verification depth will force "
505+                     "renegotiation");
506     }
[816]507 
[1102]508     /*
[1115]509@@ -382,18 +440,22 @@ int ssl_hook_Access(request_rec *r)
[816]510      * verification but at least skip the I/O-intensive renegotation
511      * handshake.
512      */
513-    if (dc->nVerifyClient != SSL_CVERIFY_UNSET) {
514+    if ((dc->nVerifyClient != SSL_CVERIFY_UNSET) ||
515+        (sc->server->auth.verify_mode != SSL_CVERIFY_UNSET)) {
516         /* remember old state */
517         verify_old = SSL_get_verify_mode(ssl);
518         /* configure new state */
519         verify = SSL_VERIFY_NONE;
520 
521-        if (dc->nVerifyClient == SSL_CVERIFY_REQUIRE) {
522+        if ((dc->nVerifyClient == SSL_CVERIFY_REQUIRE) ||
523+            (sc->server->auth.verify_mode == SSL_CVERIFY_REQUIRE)) {
524             verify |= SSL_VERIFY_PEER_STRICT;
525         }
526 
527         if ((dc->nVerifyClient == SSL_CVERIFY_OPTIONAL) ||
528-            (dc->nVerifyClient == SSL_CVERIFY_OPTIONAL_NO_CA))
529+            (dc->nVerifyClient == SSL_CVERIFY_OPTIONAL_NO_CA) ||
530+            (sc->server->auth.verify_mode == SSL_CVERIFY_OPTIONAL) ||
531+            (sc->server->auth.verify_mode == SSL_CVERIFY_OPTIONAL_NO_CA))
532         {
533             verify |= SSL_VERIFY_PEER;
534         }
[1115]535@@ -430,6 +492,45 @@ int ssl_hook_Access(request_rec *r)
536                              renegotiate_quick ? "quick " : "");
537              }
538         }
539+        /* If we're handling a request for a vhost other than the default one,
540+         * then we need to make sure that client authentication is properly
541+         * enforced. For clients supplying an SNI extension, the peer
542+         * certificate verification has happened in the handshake already
543+         * (and r->server == handshakeserver). For non-SNI requests,
544+         * an additional check is needed here. If client authentication
545+         * is configured as mandatory, then we can only proceed if the
546+         * CA list doesn't have to be changed (OpenSSL doesn't provide
547+         * an option to change the list for an existing session).
548+         */
549+        if ((r->server != handshakeserver)
550+            && renegotiate
551+            && ((verify & SSL_VERIFY_PEER) ||
552+                (verify & SSL_VERIFY_FAIL_IF_NO_PEER_CERT))) {
553+            SSLSrvConfigRec *hssc = mySrvConfig(handshakeserver);
554+
[816]555+#define MODSSL_CFG_CA_NE(f, sc1, sc2) \
[1115]556+            (sc1->server->auth.f && \
557+             (!sc2->server->auth.f || \
558+              strNE(sc1->server->auth.f, sc2->server->auth.f)))
[816]559+
[1115]560+            if (MODSSL_CFG_CA_NE(ca_cert_file, sc, hssc) ||
561+                MODSSL_CFG_CA_NE(ca_cert_path, sc, hssc)) {
562+                if (verify & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
563+                    ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
564+                         "Non-default virtual host with SSLVerify set to "
565+                         "'require' and VirtualHost-specific CA certificate "
566+                         "list is only available to clients with TLS server "
567+                         "name indication (SNI) support");
568+                    modssl_set_verify(ssl, verify_old, NULL);
569+                    return HTTP_FORBIDDEN;
570+                } else
571+                    /* let it pass, possibly with an "incorrect" peer cert,
572+                     * so make sure the SSL_CLIENT_VERIFY environment variable
573+                     * will indicate partial success only, later on.
574+                     */
575+                    sslconn->verify_info = "GENEROUS";
576+            }
[816]577+        }
[1115]578     }
[816]579 
[1115]580     /*
581@@ -666,8 +767,10 @@ int ssl_hook_Access(request_rec *r)
[816]582         /*
583          * Finally check for acceptable renegotiation results
584          */
585-        if (dc->nVerifyClient != SSL_CVERIFY_NONE) {
586-            BOOL do_verify = (dc->nVerifyClient == SSL_CVERIFY_REQUIRE);
587+        if ((dc->nVerifyClient != SSL_CVERIFY_NONE) ||
588+            (sc->server->auth.verify_mode != SSL_CVERIFY_NONE)) {
589+            BOOL do_verify = ((dc->nVerifyClient == SSL_CVERIFY_REQUIRE) ||
590+                              (sc->server->auth.verify_mode == SSL_CVERIFY_REQUIRE));
591 
592             if (do_verify && (SSL_get_verify_result(ssl) != X509_V_OK)) {
593                 ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
[1115]594@@ -997,6 +1100,9 @@ int ssl_hook_Fixup(request_rec *r)
[683]595     SSLDirConfigRec *dc = myDirConfig(r);
596     apr_table_t *env = r->subprocess_env;
597     char *var, *val = "";
598+#ifndef OPENSSL_NO_TLSEXT
599+    const char *servername;
600+#endif
601     STACK_OF(X509) *peer_certs;
602     SSL *ssl;
603     int i;
[1115]604@@ -1018,6 +1124,13 @@ int ssl_hook_Fixup(request_rec *r)
[683]605     /* the always present HTTPS (=HTTP over SSL) flag! */
606     apr_table_setn(env, "HTTPS", "on");
607 
608+#ifndef OPENSSL_NO_TLSEXT
609+    /* add content of SNI TLS extension (if supplied with ClientHello) */
610+    if ((servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) {
611+        apr_table_set(env, "SSL_TLS_SNI", servername);
612+    }
613+#endif
614+
615     /* standard SSL environment variables */
616     if (dc->nOptions & SSL_OPT_STDENVVARS) {
617         for (i = 0; ssl_hook_Fixup_vars[i]; i++) {
[1115]618@@ -1105,7 +1218,7 @@ int ssl_hook_Fixup(request_rec *r)
619 RSA *ssl_callback_TmpRSA(SSL *ssl, int export, int keylen)
620 {
621     conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
622-    SSLModConfigRec *mc = myModConfig(c->base_server);
623+    SSLModConfigRec *mc = myModConfigFromConn(c);
624     int idx;
625 
626     ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
627@@ -1137,7 +1250,7 @@ RSA *ssl_callback_TmpRSA(SSL *ssl, int export, int
628 DH *ssl_callback_TmpDH(SSL *ssl, int export, int keylen)
629 {
630     conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
631-    SSLModConfigRec *mc = myModConfig(c->base_server);
632+    SSLModConfigRec *mc = myModConfigFromConn(c);
633     int idx;
634 
635     ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
636@@ -1166,8 +1279,8 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX
[816]637     SSL *ssl = X509_STORE_CTX_get_ex_data(ctx,
638                                           SSL_get_ex_data_X509_STORE_CTX_idx());
639     conn_rec *conn      = (conn_rec *)SSL_get_app_data(ssl);
640-    server_rec *s       = conn->base_server;
641     request_rec *r      = (request_rec *)SSL_get_app_data2(ssl);
[1115]642+    server_rec *s       = r ? r->server : mySrvFromConn(conn);
[816]643 
644     SSLSrvConfigRec *sc = mySrvConfig(s);
645     SSLDirConfigRec *dc = r ? myDirConfig(r) : NULL;
[1115]646@@ -1290,7 +1403,10 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX
[816]647 
648 int ssl_callback_SSLVerify_CRL(int ok, X509_STORE_CTX *ctx, conn_rec *c)
649 {
650-    server_rec *s       = c->base_server;
651+    SSL *ssl = X509_STORE_CTX_get_ex_data(ctx,
652+                                          SSL_get_ex_data_X509_STORE_CTX_idx());
653+    request_rec *r      = (request_rec *)SSL_get_app_data2(ssl);
[1115]654+    server_rec *s       = r ? r->server : mySrvFromConn(c);
[816]655     SSLSrvConfigRec *sc = mySrvConfig(s);
656     SSLConnRec *sslconn = myConnConfig(c);
657     modssl_ctx_t *mctx  = myCtxConfig(sslconn, sc);
[1115]658@@ -1515,7 +1631,7 @@ static void modssl_proxy_info_log(server_rec *s,
659 int ssl_callback_proxy_cert(SSL *ssl, MODSSL_CLIENT_CERT_CB_ARG_TYPE **x509, EVP_PKEY **pkey)
660 {
661     conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
662-    server_rec *s = c->base_server;
663+    server_rec *s = mySrvFromConn(c);
664     SSLSrvConfigRec *sc = mySrvConfig(s);
665     X509_NAME *ca_name, *issuer;
666     X509_INFO *info;
667@@ -1613,7 +1729,7 @@ int ssl_callback_NewSessionCacheEntry(SSL *ssl, SS
668 {
669     /* Get Apache context back through OpenSSL context */
670     conn_rec *conn      = (conn_rec *)SSL_get_app_data(ssl);
671-    server_rec *s       = conn->base_server;
672+    server_rec *s       = mySrvFromConn(conn);
673     SSLSrvConfigRec *sc = mySrvConfig(s);
674     long timeout        = sc->session_cache_timeout;
675     BOOL rc;
676@@ -1661,7 +1777,7 @@ SSL_SESSION *ssl_callback_GetSessionCacheEntry(SSL
677 {
678     /* Get Apache context back through OpenSSL context */
679     conn_rec *conn = (conn_rec *)SSL_get_app_data(ssl);
680-    server_rec *s  = conn->base_server;
681+    server_rec *s  = mySrvFromConn(conn);
682     SSL_SESSION *session;
683 
684     /*
685@@ -1739,7 +1855,7 @@ void ssl_callback_LogTracingState(MODSSL_INFO_CB_A
686         return;
[683]687     }
[1115]688 
689-    s = c->base_server;
690+    s = mySrvFromConn(c);
691     if (!(sc = mySrvConfig(s))) {
692         return;
693     }
694@@ -1810,3 +1926,138 @@ void ssl_callback_LogTracingState(MODSSL_INFO_CB_A
695     }
[683]696 }
697 
698+#ifndef OPENSSL_NO_TLSEXT
699+/*
700+ * This callback function is executed when OpenSSL encounters an extended
701+ * client hello with a server name indication extension ("SNI", cf. RFC 4366).
702+ */
703+int ssl_callback_ServerNameIndication(SSL *ssl, int *al, modssl_ctx_t *mctx)
704+{
705+    const char *servername =
706+                SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
707+
708+    if (servername) {
709+        conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
710+        if (c) {
711+            if (ap_vhost_iterate_given_conn(c, ssl_find_vhost,
712+                                            (void *)servername)) {
713+                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
714+                              "SSL virtual host for servername %s found",
715+                              servername);
716+                return SSL_TLSEXT_ERR_OK;
717+            }
718+            else {
719+                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
720+                              "No matching SSL virtual host for servername "
721+                              "%s found (using default/first virtual host)",
722+                              servername);
723+                return SSL_TLSEXT_ERR_ALERT_WARNING;
724+            }
725+        }
726+    }
727+
728+    return SSL_TLSEXT_ERR_NOACK;
729+}
730+
731+/*
732+ * Find a (name-based) SSL virtual host where either the ServerName
733+ * or one of the ServerAliases matches the supplied name (to be used
734+ * with ap_vhost_iterate_given_conn())
735+ */
736+static int ssl_find_vhost(void *servername, conn_rec *c, server_rec *s)
737+{
738+    SSLSrvConfigRec *sc;
739+    SSL *ssl;
740+    BOOL found = FALSE;
741+    apr_array_header_t *names;
742+    int i;
[1115]743+    SSLConnRec *sslcon;
[683]744+
745+    /* check ServerName */
746+    if (!strcasecmp(servername, s->server_hostname)) {
747+        found = TRUE;
748+    }
749+
750+    /*
751+     * if not matched yet, check ServerAlias entries
752+     * (adapted from vhost.c:matches_aliases())
753+     */
754+    if (!found) {
755+        names = s->names;
756+        if (names) {
757+            char **name = (char **)names->elts;
758+            for (i = 0; i < names->nelts; ++i) {
759+                if (!name[i])
760+                    continue;
761+                if (!strcasecmp(servername, name[i])) {
762+                    found = TRUE;
763+                    break;
764+                }
765+            }
766+        }
767+    }
768+
769+    /* if still no match, check ServerAlias entries with wildcards */
770+    if (!found) {
771+        names = s->wild_names;
772+        if (names) {
773+            char **name = (char **)names->elts;
774+            for (i = 0; i < names->nelts; ++i) {
775+                if (!name[i])
776+                    continue;
777+                if (!ap_strcasecmp_match(servername, name[i])) {
778+                    found = TRUE;
779+                    break;
780+                }
781+            }
782+        }
783+    }
784+
785+    /* set SSL_CTX (if matched) */
[1115]786+    sslcon = myConnConfig(c);
787+    if (found && (ssl = sslcon->ssl) &&
[683]788+        (sc = mySrvConfig(s))) {
789+        SSL_set_SSL_CTX(ssl, sc->server->ssl_ctx);
790+        /*
791+         * SSL_set_SSL_CTX() only deals with the server cert,
792+         * so we need to duplicate a few additional settings
793+         * from the ctx by hand
794+         */
795+        SSL_set_options(ssl, SSL_CTX_get_options(ssl->ctx));
796+        if ((SSL_get_verify_mode(ssl) == SSL_VERIFY_NONE) ||
797+            (SSL_num_renegotiations(ssl) == 0)) {
798+           /*
799+            * Only initialize the verification settings from the ctx
800+            * if they are not yet set, or if we're called when a new
801+            * SSL connection is set up (num_renegotiations == 0).
802+            * Otherwise, we would possibly reset a per-directory
803+            * configuration which was put into effect by ssl_hook_Access.
804+            */
805+            SSL_set_verify(ssl, SSL_CTX_get_verify_mode(ssl->ctx),
806+                           SSL_CTX_get_verify_callback(ssl->ctx));
807+        }
808+
809+        /*
[1115]810+         * Save the found server into our SSLConnRec for later
811+         * retrieval
[683]812+         */
[1115]813+        sslcon->server = s;
[816]814+
815+        /*
816+         * There is one special filter callback, which is set
817+         * very early depending on the base_server's log level.
818+         * If this is not the first vhost we're now selecting
819+         * (and the first vhost doesn't use APLOG_DEBUG), then
820+         * we need to set that callback here.
821+         */
[1115]822+        if (s->loglevel >= APLOG_DEBUG) {
[683]823+            BIO_set_callback(SSL_get_rbio(ssl), ssl_io_data_cb);
824+            BIO_set_callback_arg(SSL_get_rbio(ssl), (void *)ssl);
825+        }
826+
827+        return 1;
828+    }
829+
830+    return 0;
831+}
832+#endif
[1115]833Index: httpd-2.2.11/modules/ssl/mod_ssl.c
[683]834===================================================================
[1115]835--- httpd-2.2.11/modules/ssl/mod_ssl.c  (revision 768863)
836+++ httpd-2.2.11/modules/ssl/mod_ssl.c  (working copy)
837@@ -145,6 +145,10 @@ static const command_rec ssl_config_cmds[] = {
838                 "Use the server's cipher ordering preference")
839     SSL_CMD_ALL(UserName, TAKE1,
840                 "Set user name to SSL variable value")
841+#ifndef OPENSSL_NO_TLSEXT
842+    SSL_CMD_SRV(StrictSNIVHostCheck, FLAG,
843+                "Strict SNI virtual host checking")
844+#endif
845 
846     /*
847      * Proxy configuration for remote SSL connections
848@@ -295,6 +299,8 @@ static SSLConnRec *ssl_init_connection_ctx(conn_re
849 
850     sslconn = apr_pcalloc(c->pool, sizeof(*sslconn));
851 
852+    sslconn->server = c->base_server;
853+
854     myConnConfigSet(c, sslconn);
855 
856     return sslconn;
857@@ -302,9 +308,10 @@ static SSLConnRec *ssl_init_connection_ctx(conn_re
858 
859 int ssl_proxy_enable(conn_rec *c)
860 {
861-    SSLSrvConfigRec *sc = mySrvConfig(c->base_server);
862+    SSLSrvConfigRec *sc;
863 
864     SSLConnRec *sslconn = ssl_init_connection_ctx(c);
865+    sc = mySrvConfig(sslconn->server);
866 
867     if (!sc->proxy_enabled) {
868         ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c,
869@@ -322,10 +329,16 @@ int ssl_proxy_enable(conn_rec *c)
870 
871 int ssl_engine_disable(conn_rec *c)
872 {
873-    SSLSrvConfigRec *sc = mySrvConfig(c->base_server);
874+    SSLSrvConfigRec *sc;
875 
876-    SSLConnRec *sslconn;
877+    SSLConnRec *sslconn = myConnConfig(c);
878 
879+    if (sslconn) {
880+        sc = mySrvConfig(sslconn->server);
881+    }
882+    else {
883+        sc = mySrvConfig(c->base_server);
884+    }
885     if (sc->enabled == SSL_ENABLED_FALSE) {
886         return 0;
887     }
888@@ -339,21 +352,24 @@ int ssl_engine_disable(conn_rec *c)
889 
890 int ssl_init_ssl_connection(conn_rec *c)
891 {
892-    SSLSrvConfigRec *sc = mySrvConfig(c->base_server);
893+    SSLSrvConfigRec *sc;
894     SSL *ssl;
895     SSLConnRec *sslconn = myConnConfig(c);
896     char *vhost_md5;
897     modssl_ctx_t *mctx;
898+    server_rec *server;
899 
900+    if (!sslconn) {
901+        sslconn = ssl_init_connection_ctx(c);
902+    }
903+    server = sslconn->server;
904+    sc = mySrvConfig(server);
905+
906     /*
907      * Seed the Pseudo Random Number Generator (PRNG)
908      */
909-    ssl_rand_seed(c->base_server, c->pool, SSL_RSCTX_CONNECT, "");
910+    ssl_rand_seed(server, c->pool, SSL_RSCTX_CONNECT, "");
911 
912-    if (!sslconn) {
913-        sslconn = ssl_init_connection_ctx(c);
914-    }
915-
916     mctx = sslconn->is_proxy ? sc->proxy : sc->server;
917 
918     /*
919@@ -365,7 +381,7 @@ int ssl_init_ssl_connection(conn_rec *c)
920         ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c,
921                       "Unable to create a new SSL connection from the SSL "
922                       "context");
923-        ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, c->base_server);
924+        ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, server);
925 
926         c->aborted = 1;
927 
928@@ -380,7 +396,7 @@ int ssl_init_ssl_connection(conn_rec *c)
929     {
930         ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c,
931                       "Unable to set session id context to `%s'", vhost_md5);
932-        ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, c->base_server);
933+        ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, server);
934 
935         c->aborted = 1;
936 
937@@ -429,9 +445,15 @@ static apr_port_t ssl_hook_default_port(const requ
938 
939 static int ssl_hook_pre_connection(conn_rec *c, void *csd)
940 {
941-    SSLSrvConfigRec *sc = mySrvConfig(c->base_server);
942+    SSLSrvConfigRec *sc;
943     SSLConnRec *sslconn = myConnConfig(c);
944 
945+    if (sslconn) {
946+        sc = mySrvConfig(sslconn->server);
947+    }
948+    else {
949+        sc = mySrvConfig(c->base_server);
950+    }
951     /*
952      * Immediately stop processing if SSL is disabled for this connection
953      */
954Index: httpd-2.2.11/modules/ssl/ssl_toolkit_compat.h
955===================================================================
956--- httpd-2.2.11/modules/ssl/ssl_toolkit_compat.h       (revision 768863)
957+++ httpd-2.2.11/modules/ssl/ssl_toolkit_compat.h       (working copy)
[1102]958@@ -264,6 +264,12 @@ typedef void (*modssl_popfree_fn)(char *data);
[683]959 #define SSL_SESS_CACHE_NO_INTERNAL  SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
960 #endif
961 
962+#ifndef OPENSSL_NO_TLSEXT
963+#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
964+#define OPENSSL_NO_TLSEXT
965+#endif
966+#endif
967+
968 #endif /* SSL_TOOLKIT_COMPAT_H */
969 
970 /** @} */
[1115]971Index: httpd-2.2.11/docs/manual/mod/mod_ssl.html.en
972===================================================================
973--- httpd-2.2.11/docs/manual/mod/mod_ssl.html.en        (revision 768863)
974+++ httpd-2.2.11/docs/manual/mod/mod_ssl.html.en        (working copy)
975@@ -75,6 +75,7 @@ to provide the cryptography engine.</p>
976 <li><img alt="" src="../images/down.gif" /> <a href="#sslrequiressl">SSLRequireSSL</a></li>
977 <li><img alt="" src="../images/down.gif" /> <a href="#sslsessioncache">SSLSessionCache</a></li>
978 <li><img alt="" src="../images/down.gif" /> <a href="#sslsessioncachetimeout">SSLSessionCacheTimeout</a></li>
979+<li><img alt="" src="../images/down.gif" /> <a href="#sslstrictsnivhostcheck">SSLStrictSNIVHostCheck</a></li>
980 <li><img alt="" src="../images/down.gif" /> <a href="#sslusername">SSLUserName</a></li>
981 <li><img alt="" src="../images/down.gif" /> <a href="#sslverifyclient">SSLVerifyClient</a></li>
982 <li><img alt="" src="../images/down.gif" /> <a href="#sslverifydepth">SSLVerifyDepth</a></li>
983@@ -1613,6 +1614,37 @@ SSLSessionCacheTimeout 600
984 
985 </div>
986 <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
987+<div class="directive-section"><h2><a name="SSLStrictSNIVHostCheck" id="SSLStrictSNIVHostCheck">SSLStrictSNIVHostCheck</a> <a name="sslstrictsnivhostcheck" id="sslstrictsnivhostcheck">Directive</a></h2>
988+<table class="directive">
989+<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Whether to allow non SNI clients to access a name based virtual
990+host.
991+</td></tr>
992+<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>SSLStrictSNIVHostCheck on|off</code></td></tr>
993+<tr><th><a href="directive-dict.html#Default">Default:</a></th><td><code>SSLStrictSNIVHostCheck off</code></td></tr>
994+<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host</td></tr>
995+<tr><th><a href="directive-dict.html#Status">Status:</a></th><td>Extension</td></tr>
996+<tr><th><a href="directive-dict.html#Module">Module:</a></th><td>mod_ssl</td></tr>
997+</table>
998+<p>
999+This directive sets whether a non SNI client is allowed to access a name based
1000+virtual host. If set to <code>on</code> in the non default name based virtual
1001+host, non SNI clients are not allowed to access this particular virtual host.
1002+If set to <code>on</code> in the default name based virtual host, non SNI
1003+clients are not allowed to access any name based virtual host belonging to
1004+this IP / port combination.
1005+</p>
1006+
1007+<div class="warning"><p>
1008+This option is only available if httpd was compiled against an SNI capable
1009+version of OpenSSL.
1010+</p></div>
1011+
1012+<div class="example"><h3>Example</h3><p><code>
1013+SSLStrictSNIVHostCheck on
1014+</code></p></div>
1015+
1016+</div>
1017+<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
1018 <div class="directive-section"><h2><a name="SSLUserName" id="SSLUserName">SSLUserName</a> <a name="sslusername" id="sslusername">Directive</a></h2>
1019 <table class="directive">
1020 <tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Variable name to determine user name</td></tr>
1021@@ -1717,6 +1749,6 @@ SSLVerifyDepth 10
1022 <div class="bottomlang">
1023 <p><span>Available Languages: </span><a href="../en/mod/mod_ssl.html" title="English">&nbsp;en&nbsp;</a></p>
1024 </div><div id="footer">
1025-<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>
1026+<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>
1027 <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>
1028 </body></html>
Note: See TracBrowser for help on using the repository browser.