]> granicus.if.org Git - apache/blobdiff - modules/ssl/mod_ssl.c
Extend SSLOCSPEnable with mode 'leaf' that only checks the leaf of a certificate...
[apache] / modules / ssl / mod_ssl.c
index 99f0c13391a82764b2dc93b8287138311c2534d6..7d2d9380ad472eec37d00e7429a097ec172a4ae5 100644 (file)
@@ -91,7 +91,7 @@ static const command_rec ssl_config_cmds[] = {
     /*
      * Per-server context configuration directives
      */
-    SSL_CMD_SRV(Engine, TAKE1,
+    SSL_CMD_SRV(Engine, RAW_ARGS,
                 "SSL switch for the protocol engine "
                 "('on', 'off')")
     SSL_CMD_SRV(FIPS, FLAG,
@@ -247,8 +247,8 @@ static const command_rec ssl_config_cmds[] = {
                 "request body if a per-location SSL renegotiation is required due to "
                 "changed access control requirements")
 
-    SSL_CMD_SRV(OCSPEnable, FLAG,
-               "Enable use of OCSP to verify certificate revocation ('on', 'off')")
+    SSL_CMD_SRV(OCSPEnable, RAW_ARGS,
+               "Enable use of OCSP to verify certificate revocation mode ('on', 'leaf', 'off')")
     SSL_CMD_SRV(OCSPDefaultResponder, TAKE1,
                "URL of the default OCSP Responder")
     SSL_CMD_SRV(OCSPOverrideResponder, FLAG,
@@ -265,7 +265,7 @@ static const command_rec ssl_config_cmds[] = {
                 "Proxy URL to use for OCSP requests")
 
 /* Define OCSP Responder Certificate Verification Directive */
-    SSL_CMD_SRV(OCSPNoverify, FLAG,
+    SSL_CMD_SRV(OCSPNoVerify, FLAG,
                 "Do not verify OCSP Responder certificate ('on', 'off')")
 /* Define OCSP Responder File Configuration Directive */
     SSL_CMD_SRV(OCSPResponderCertificateFile, TAKE1,
@@ -312,6 +312,15 @@ static const command_rec ssl_config_cmds[] = {
     AP_INIT_RAW_ARGS("SSLLogLevel", ap_set_deprecated, NULL, OR_ALL,
       "SSLLogLevel directive is no longer supported - use LogLevel."),
 
+    AP_INIT_TAKE1("<SSLPolicyDefine", ssl_cmd_SSLPolicyDefine, NULL, RSRC_CONF, 
+                "Define a set of SSL* configurations under a new name. Such a policy may "
+                "be used in any location where the SSL* directives are viable. The policy "
+                "may contain both SSL* and SSLProxy* specific settings. Which one is applied "
+                "depends on the use."),
+    AP_INIT_TAKE1("SSLPolicy", ssl_cmd_SSLPolicyApply, NULL, RSRC_CONF, 
+                "Apply the SSL* (not the SSLProxy*) settings from the policy with the given name."),
+    AP_INIT_TAKE1("SSLProxyPolicy", ssl_cmd_SSLProxyPolicyApply, NULL, RSRC_CONF|PROXY_CONF, 
+                "Use the SSLProxy* settings from the policy with the given name."),
     AP_END_CMD
 };
 
@@ -348,11 +357,13 @@ static apr_status_t ssl_cleanup_pre_config(void *data)
     ENGINE_cleanup();
 #endif
 #if OPENSSL_VERSION_NUMBER >= 0x1000200fL
+#ifndef OPENSSL_NO_COMP
     SSL_COMP_free_compression_methods();
+#endif
 #endif
 
     /* Usually needed per thread, but this parent process is single-threaded */
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#if MODSSL_USE_OPENSSL_PRE_1_1_API
 #if OPENSSL_VERSION_NUMBER >= 0x1000000fL
     ERR_remove_thread_state(NULL);
 #else
@@ -396,15 +407,15 @@ static int ssl_hook_pre_config(apr_pool_t *pconf,
     /* Some OpenSSL internals are allocated per-thread, make sure they
      * are associated to the/our same thread-id until cleaned up.
      */
-#if APR_HAS_THREADS && OPENSSL_VERSION_NUMBER < 0x10100000L
+#if APR_HAS_THREADS && MODSSL_USE_OPENSSL_PRE_1_1_API
     ssl_util_thread_id_setup(pconf);
 #endif
 
     /* We must register the library in full, to ensure our configuration
      * code can successfully test the SSL environment.
      */
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
-    CRYPTO_malloc_init();
+#if MODSSL_USE_OPENSSL_PRE_1_1_API
+    (void)CRYPTO_malloc_init();
 #else
     OPENSSL_malloc_init();
 #endif
@@ -479,6 +490,75 @@ static SSLConnRec *ssl_init_connection_ctx(conn_rec *c,
     return sslconn;
 }
 
+static int ssl_server_addr_matches(server_addr_rec *sar, apr_sockaddr_t *sa)
+{
+    /* Determine if the list of server_addr_rec's matches the given socket address.
+     * IP Address/port may be wilcard/0 for a match to occur. */
+    while (sar) {
+        if (apr_sockaddr_is_wildcard(sar->host_addr)
+            || apr_sockaddr_equal(sar->host_addr, sa)) {
+            if (sar->host_addr->port == sa->port 
+                || sar->host_addr->port == 0
+                || sa->port == 0) {
+                return 1;
+            }
+        }
+        sar = sar->next;
+    }
+    return 0;
+}
+
+int ssl_server_addr_overlap(server_addr_rec *sar1, server_addr_rec *sar2)
+{
+    if (sar1) {
+        while (sar2) {
+            if (ssl_server_addr_matches(sar1, sar2->host_addr)) {
+                return 1;
+            }
+            sar2 = sar2->next;
+        }
+    }
+    return 0;
+}
+
+static ssl_enabled_t ssl_srv_enabled_on(server_rec *s, apr_sockaddr_t *sa)
+{
+    SSLSrvConfigRec *sc = mySrvConfig(s);
+    if (sc->enabled == SSL_ENABLED_TRUE && sc->enabled_on) {
+        if (!ssl_server_addr_matches(sc->enabled_on, sa)) {
+            return SSL_ENABLED_FALSE;
+        }
+    }
+    return sc->enabled;
+}
+
+static ssl_enabled_t ssl_conn_enabled(conn_rec *c)
+{
+    if (c->master) {
+        return ssl_conn_enabled(c->master);
+    }
+    else {
+        SSLConnRec *sslconn = myConnConfig(c);
+        if (sslconn) {
+            if (sslconn->disabled) {
+                return SSL_ENABLED_FALSE;
+            }
+            if (sslconn->is_proxy) {
+                if (!sslconn->dc->proxy_enabled) {
+                    return SSL_ENABLED_FALSE;
+                }
+            }
+            else {
+                return ssl_srv_enabled_on(sslconn->server, c->local_addr);
+            }
+        }
+        else {
+            return ssl_srv_enabled_on(c->base_server, c->local_addr);
+        }
+    }
+    return SSL_ENABLED_TRUE;
+}
+
 static int ssl_engine_status(conn_rec *c, SSLConnRec *sslconn)
 {
     if (c->master) {
@@ -493,17 +573,13 @@ static int ssl_engine_status(conn_rec *c, SSLConnRec *sslconn)
                 return DECLINED;
             }
         }
-        else {
-            if (mySrvConfig(sslconn->server)->enabled != SSL_ENABLED_TRUE) {
-                return DECLINED;
-            }
-        }
-    }
-    else {
-        if (mySrvConfig(c->base_server)->enabled != SSL_ENABLED_TRUE) {
+        else if (ssl_srv_enabled_on(sslconn->server, c->local_addr) != SSL_ENABLED_TRUE) {
             return DECLINED;
         }
     }
+    else if (ssl_srv_enabled_on(c->base_server, c->local_addr) != SSL_ENABLED_TRUE) {
+        return DECLINED;
+    }
     return OK;
 }
 
@@ -621,26 +697,29 @@ int ssl_init_ssl_connection(conn_rec *c, request_rec *r)
     return APR_SUCCESS;
 }
 
+/* FIXME: if we ever want to server http: requests over TLS, this 
+ * needs to change. We probably need the scheme in request_rec and
+ * return that iff it is set. */
 static const char *ssl_hook_http_scheme(const request_rec *r)
 {
-    SSLSrvConfigRec *sc = mySrvConfig(r->server);
-
-    if (sc->enabled == SSL_ENABLED_FALSE || sc->enabled == SSL_ENABLED_OPTIONAL) {
-        return NULL;
+    switch (ssl_conn_enabled(r->connection)) {
+        case SSL_ENABLED_FALSE:
+        case SSL_ENABLED_OPTIONAL:
+            return NULL;
+        default:
+            return "https";
     }
-
-    return "https";
 }
 
 static apr_port_t ssl_hook_default_port(const request_rec *r)
 {
-    SSLSrvConfigRec *sc = mySrvConfig(r->server);
-
-    if (sc->enabled == SSL_ENABLED_FALSE || sc->enabled == SSL_ENABLED_OPTIONAL) {
-        return 0;
+    switch (ssl_conn_enabled(r->connection)) {
+        case SSL_ENABLED_FALSE:
+        case SSL_ENABLED_OPTIONAL:
+            return 0;
+        default:
+            return 443;
     }
-
-    return 443;
 }
 
 static int ssl_hook_pre_connection(conn_rec *c, void *csd)
@@ -759,4 +838,7 @@ module AP_MODULE_DECLARE_DATA ssl_module = {
     ssl_config_server_merge,    /* merge  per-server config structures */
     ssl_config_cmds,            /* table of configuration directives   */
     ssl_register_hooks          /* register hooks */
+#if defined(AP_MODULE_HAS_FLAGS)
+   ,AP_MODULE_FLAG_ALWAYS_MERGE /* flags */
+#endif
 };