]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
* Add SSLStrictSNIVHostCheck to allow / disallow non SNI clients to connect to
authorRuediger Pluem <rpluem@apache.org>
Sat, 25 Apr 2009 20:15:49 +0000 (20:15 +0000)
committerRuediger Pluem <rpluem@apache.org>
Sat, 25 Apr 2009 20:15:49 +0000 (20:15 +0000)
  name based virtual hosts.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@768596 13f79535-47bb-0310-9956-ffa450edef68

docs/manual/mod/mod_ssl.xml
modules/ssl/mod_ssl.c
modules/ssl/ssl_engine_config.c
modules/ssl/ssl_engine_kernel.c
modules/ssl/ssl_private.h

index fe09b7bdfd9a38330c6c8001a2c86f6633421278..dfaea3b865e7827e1524583408f2cb0b0bafb084 100644 (file)
@@ -1353,6 +1353,37 @@ SSLRenegBufferSize 262144
 </usage>
 </directivesynopsis>
 
+<directivesynopsis>
+<name>SSLStrictSNIVHostCheck</name>
+<description>Whether to allow non SNI clients to access a name based virtual
+host.
+</description>
+<syntax>SSLStrictSNIVHostCheck on|off</syntax>
+<default>SSLStrictSNIVHostCheck off</default>
+<contextlist><context>server config</context>
+<context>virtual host</context></contextlist>
+
+<usage>
+<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>
+
+<note type="warning"><p>
+This option is only available if httpd was compiled against an SNI capable
+version of OpenSSL.
+</p></note>
+
+<example><title>Example</title>
+SSLStrictSNIVHostCheck on
+</example>
+</usage>
+</directivesynopsis>
+
 <directivesynopsis>
 <name>SSLProxyMachineCertificatePath</name>
 <description>Directory of PEM-encoded client certificates and keys to be used by the proxy</description>
index 98dfd4d545055b67218ef8d885cb3c5b06514126..fb5ded244f6366e6971486b6206438d3c2a6e9b7 100644 (file)
@@ -129,6 +129,10 @@ static const command_rec ssl_config_cmds[] = {
     SSL_CMD_SRV(LogLevelDebugDump, TAKE1,
                 "Include I/O Dump when LogLevel is set to Debug "
                 "([ None (default) | IO (not bytes) | Bytes ])")
+#ifndef OPENSSL_NO_TLSEXT
+    SSL_CMD_SRV(StrictSNIVHostCheck, FLAG,
+                "Strict SNI virtual host checking")
+#endif
 
     /*
      * Proxy configuration for remote SSL connections
index 41118c5da9a79222da1775dcd7ddba6b335275a4..70bbf758cf0ecd6c65742023da086dda83d67415 100644 (file)
@@ -175,6 +175,9 @@ static SSLSrvConfigRec *ssl_config_server_new(apr_pool_t *p)
     sc->ssl_log_level          = SSL_LOG_UNSET;
     sc->proxy_ssl_check_peer_expire = SSL_ENABLED_UNSET;
     sc->proxy_ssl_check_peer_cn     = SSL_ENABLED_UNSET;
+#ifndef OPENSSL_NO_TLSEXT
+    sc->strict_sni_vhost_check = SSL_ENABLED_UNSET;
+#endif
 
     modssl_ctx_init_proxy(sc, p);
 
@@ -270,6 +273,9 @@ void *ssl_config_server_merge(apr_pool_t *p, void *basev, void *addv)
     cfgMerge(ssl_log_level, SSL_LOG_UNSET);
     cfgMerge(proxy_ssl_check_peer_expire, SSL_ENABLED_UNSET);
     cfgMerge(proxy_ssl_check_peer_cn, SSL_ENABLED_UNSET);
+#ifndef OPENSSL_NO_TLSEXT
+    cfgMerge(strict_sni_vhost_check, SSL_ENABLED_UNSET);
+#endif
 
     modssl_ctx_cfg_merge_proxy(base->proxy, add->proxy, mrg->proxy);
 
@@ -1440,6 +1446,17 @@ const char *ssl_cmd_SSLProxyCheckPeerCN(cmd_parms *cmd, void *dcfg, int flag)
     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 e2ab5ff93638edb41372ede8d61e5ca6daf39d4d..b12850034e3695548a9687995b2758f82ccab42a 100644 (file)
@@ -186,10 +186,16 @@ int ssl_hook_ReadReq(request_rec *r)
             return HTTP_BAD_REQUEST;
         }
     }
-    else if (r->connection->vhost_lookup_data) {
+    else if (((sc->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.
+         * provided via SNI. Don't allow that if are requested to do strict
+         * checking. Check wether 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"
index f9f82b82d12095d04ef20bc488fe3ab4637df30b..840230a3fce3d03295dac5ba66339ef12dda0a48 100644 (file)
@@ -479,6 +479,9 @@ struct SSLSrvConfigRec {
     ssl_log_level_e  ssl_log_level;
     ssl_enabled_t    proxy_ssl_check_peer_expire;
     ssl_enabled_t    proxy_ssl_check_peer_cn;
+#ifndef OPENSSL_NO_TLSEXT
+    ssl_enabled_t    strict_sni_vhost_check;
+#endif
 };
 
 /**
@@ -544,6 +547,9 @@ const char  *ssl_cmd_SSLRequire(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLUserName(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLLogLevelDebugDump(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLRenegBufferSize(cmd_parms *cmd, void *dcfg, const char *arg);
+#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 *);