mod_ssl: Add hooks to allow other modules to perform processing at
authorJeff Trawick <trawick@apache.org>
Tue, 15 Apr 2014 15:25:03 +0000 (15:25 +0000)
committerJeff Trawick <trawick@apache.org>
Tue, 15 Apr 2014 15:25:03 +0000 (15:25 +0000)
several stages of initialization and connection handling.  See
mod_ssl_openssl.h.

This is enough to allow implementation of Certificate Transparency
outside of mod_ssl.

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

CHANGES
CMakeLists.txt
Makefile.in
Makefile.win
NWGNUmakefile
include/ap_mmn.h
modules/ssl/mod_ssl.c
modules/ssl/mod_ssl.h
modules/ssl/mod_ssl_openssl.h [new file with mode: 0644]
modules/ssl/ssl_engine_init.c
modules/ssl/ssl_engine_io.c

diff --git a/CHANGES b/CHANGES
index 08072fc3c4027f45f3a57290cf71fe414b272e98..5969ba20a2dff9a0eb8021ebda2faa94cdd5390b 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,10 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.0
 
+  *) mod_ssl: Add hooks to allow other modules to perform processing at
+     several stages of initialization and connection handling.  See
+     mod_ssl_openssl.h.  [Jeff Trawick]
+
   *) mod_proxy_wstunnel: Avoid sending error responses down an upgraded
      websockets connection as it is being close down. [Eric Covener]
   
index 1ab783562b299648275dc65a750a3d73936c423f..d93f9a070d6f40374551ff4e5419161bb1a98bdd 100644 (file)
@@ -409,6 +409,7 @@ SET(mod_session_crypto_requires      APU_HAVE_CRYPTO)
 SET(mod_session_crypto_extra_libs    mod_session)
 SET(mod_session_dbd_extra_libs       mod_session)
 SET(mod_socache_dc_requires          AN_UNIMPLEMENTED_SUPPORT_LIBRARY_REQUIREMENT)
+SET(mod_ssl_extra_defines            SSL_DECLARE_EXPORT)
 SET(mod_ssl_requires                 OPENSSL_FOUND)
 IF(OPENSSL_FOUND)
   SET(mod_ssl_extra_includes           ${OPENSSL_INCLUDE_DIR})
@@ -614,6 +615,7 @@ SET(other_installed_h
   ${CMAKE_CURRENT_SOURCE_DIR}/modules/proxy/mod_proxy.h
   ${CMAKE_CURRENT_SOURCE_DIR}/modules/session/mod_session.h
   ${CMAKE_CURRENT_SOURCE_DIR}/modules/ssl/mod_ssl.h
+  ${CMAKE_CURRENT_SOURCE_DIR}/modules/ssl/mod_ssl_openssl.h
 )
 # When mod_serf is buildable, don't forget to copy modules/proxy/mod_serf.h
 
index 0779d7c735244b9c3358cb32ef293ac05fb69c94..0f8cf8d51bca565518372ea903a17df3dc9265ad 100644 (file)
@@ -213,6 +213,7 @@ INSTALL_HEADERS = \
        $(srcdir)/modules/proxy/mod_serf.h \
         $(srcdir)/modules/session/mod_session.h \
        $(srcdir)/modules/ssl/mod_ssl.h \
+       $(srcdir)/modules/ssl/mod_ssl_openssl.h \
        $(srcdir)/os/$(OS_DIR)/*.h
 
 install-include:
index c1f93cf3eb9066d3008b19d22e9809faaacc8518..e81c03dbabfd5365b9fdd3c7045f8d95ddcb5808 100644 (file)
@@ -1094,6 +1094,7 @@ BEGIN {
                modules\proxy\mod_proxy.h \
                modules\proxy\mod_serf.h \
                modules\ssl\mod_ssl.h \
+               modules\ssl\mod_ssl_openssl.h \
           ) do \
            @copy %f "$(INSTDIR)\include" < .y > nul
        copy srclib\apr\Lib$(SHORT)\apr-1.lib           "$(INSTDIR)\lib" <.y
index 1a5e91e72c54abca5330198ac0ef9202a4d077df..e6c53dd05369de887e74c002abefeeb1863d48f9 100644 (file)
@@ -452,6 +452,7 @@ installdev :: FORCE
        $(call COPY,$(STDMOD)/proxy/mod_serf.h,                        $(INSTALLBASE)/include/)
        $(call COPY,$(STDMOD)/session/mod_session.h,                   $(INSTALLBASE)/include/)
        $(call COPY,$(STDMOD)/ssl/mod_ssl.h,                           $(INSTALLBASE)/include/)
+       $(call COPY,$(STDMOD)/ssl/mod_ssl_openssl.h,                   $(INSTALLBASE)/include/)
        $(call COPY,$(APR)/*.imp,                                      $(INSTALLBASE)/lib/)
        $(call COPY,$(NWOS)/*.imp,                                     $(INSTALLBASE)/lib/)
        $(call COPY,$(NWOS)/*.xdc,                                     $(INSTALLBASE)/lib/)
index e2ea31a1689c8eae135f42cdeddcf2be2ec433b4..7d9eacd90d21fe67f4b6610a609800893d91589b 100644 (file)
  * 20140207.0 (2.5.0-dev)  Support for slaved connections in core.c
  * 20140207.1 (2.5.0-dev)  Add SSL reusable SNI to mod_proxy.h's proxy_conn_rec
  * 20140207.2 (2.5.0-dev)  Add proxy detach_backend hook
+ * 20140207.3 (2.5.0-dev)  Add mod_ssl_openssl.h and OpenSSL-specific hooks
  */
 
 #define MODULE_MAGIC_COOKIE 0x41503235UL /* "AP25" */
 #ifndef MODULE_MAGIC_NUMBER_MAJOR
 #define MODULE_MAGIC_NUMBER_MAJOR 20140207
 #endif
-#define MODULE_MAGIC_NUMBER_MINOR 2                  /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 3                  /* 0...n */
 
 /**
  * Determine if the server's current MODULE_MAGIC_NUMBER is at least a
index 13a7833da285aad00e6f8ba9d72c568c81da85e0..330d1d0905bbff247871026717cef0e4418ab8e6 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "ssl_private.h"
 #include "mod_ssl.h"
+#include "mod_ssl_openssl.h"
 #include "util_md5.h"
 #include "util_mutex.h"
 #include "ap_provider.h"
 int ssl_running_on_valgrind = 0;
 #endif
 
+APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, pre_handshake,
+                                    (conn_rec *c,SSL *ssl),
+                                    (c,ssl), OK, DECLINED);
+
 /*
  *  the table of configuration directives we provide
  */
@@ -468,6 +473,7 @@ int ssl_init_ssl_connection(conn_rec *c, request_rec *r)
     SSL *ssl;
     SSLConnRec *sslconn = myConnConfig(c);
     char *vhost_md5;
+    int rc;
     modssl_ctx_t *mctx;
     server_rec *server;
 
@@ -500,6 +506,11 @@ int ssl_init_ssl_connection(conn_rec *c, request_rec *r)
         return DECLINED; /* XXX */
     }
 
+    rc = ssl_run_pre_handshake(c, ssl);
+    if (rc != OK && rc != DECLINED) {
+        return rc;
+    }
+
     vhost_md5 = ap_md5_binary(c->pool, (unsigned char *)sc->vhost_id,
                               sc->vhost_id_len);
 
index ca820103e1cf9df6fa7f5ab2702f8eb81d32619d..829fd1504a622257277939d9ce09e5818a719abc 100644 (file)
 #include "httpd.h"
 #include "apr_optional.h"
 
+/* Create a set of SSL_DECLARE(type), SSL_DECLARE_NONSTD(type) and
+ * SSL_DECLARE_DATA with appropriate export and import tags for the platform
+ */
+#if !defined(WIN32)
+#define SSL_DECLARE(type)            type
+#define SSL_DECLARE_NONSTD(type)     type
+#define SSL_DECLARE_DATA
+#elif defined(SSL_DECLARE_STATIC)
+#define SSL_DECLARE(type)            type __stdcall
+#define SSL_DECLARE_NONSTD(type)     type
+#define SSL_DECLARE_DATA
+#elif defined(SSL_DECLARE_EXPORT)
+#define SSL_DECLARE(type)            __declspec(dllexport) type __stdcall
+#define SSL_DECLARE_NONSTD(type)     __declspec(dllexport) type
+#define SSL_DECLARE_DATA             __declspec(dllexport)
+#else
+#define SSL_DECLARE(type)            __declspec(dllimport) type __stdcall
+#define SSL_DECLARE_NONSTD(type)     __declspec(dllimport) type
+#define SSL_DECLARE_DATA             __declspec(dllimport)
+#endif
+
 /** The ssl_var_lookup() optional function retrieves SSL environment
  * variables. */
 APR_DECLARE_OPTIONAL_FN(char *, ssl_var_lookup,
diff --git a/modules/ssl/mod_ssl_openssl.h b/modules/ssl/mod_ssl_openssl.h
new file mode 100644 (file)
index 0000000..ecca33c
--- /dev/null
@@ -0,0 +1,72 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file mod_ssl_openssl.h
+ * @brief Interface to OpenSSL-specific APIs provided by mod_ssl
+ *
+ * @defgroup MOD_SSL mod_ssl_openssl
+ * @ingroup  APACHE_MODS
+ * @{
+ */
+
+#ifndef __MOD_SSL_OPENSSL_H__
+#define __MOD_SSL_OPENSSL_H__
+
+#include "mod_ssl.h"
+
+/* OpenSSL headers */
+
+#ifndef SSL_PRIVATE_H
+#include <openssl/opensslv.h>
+#if (OPENSSL_VERSION_NUMBER >= 0x10001000)
+/* must be defined before including ssl.h */
+#define OPENSSL_NO_SSL_INTERN
+#endif
+#include <openssl/ssl.h>
+#endif
+
+/**
+ * init_server hook -- allow SSL_CTX-specific initialization to be performed by
+ * a module for each SSL-enabled server (one at a time)
+ * @param s SSL-enabled [virtual] server
+ * @param p pconf pool
+ * @param is_proxy 1 if this server supports backend connections
+ * over SSL/TLS, 0 if it supports client connections over SSL/TLS
+ * @param ctx OpenSSL SSL Context for the server
+ */
+APR_DECLARE_EXTERNAL_HOOK(ssl, SSL, int, init_server,
+                          (server_rec *s, apr_pool_t *p, int is_proxy, SSL_CTX *ctx))
+
+/**
+ * pre_handshake hook
+ * @param c conn_rec for new connection from client or to backend server
+ * @param ssl OpenSSL SSL Connection for the client or backend server
+ */
+APR_DECLARE_EXTERNAL_HOOK(ssl, SSL, int, pre_handshake,
+                          (conn_rec *c, SSL *ssl))
+
+/**
+ * proxy_post_handshake hook -- allow module to abort after successful
+ * handshake with backend server and subsequent peer checks
+ * @param c conn_rec for connection to backend server
+ * @param ssl OpenSSL SSL Connection for the client or backend server
+ */
+APR_DECLARE_EXTERNAL_HOOK(ssl, SSL, int, proxy_post_handshake,
+                          (conn_rec *c, SSL *ssl))
+
+#endif /* __MOD_SSL_OPENSSL_H__ */
+/** @} */
index cbc4a7433d0e75ca9c25450ccd8e67f50c500a0a..bb57f4867761402061358637e82dd80d95707522 100644 (file)
                                   see Recursive.''
                                         -- Unknown   */
 #include "ssl_private.h"
+#include "mod_ssl.h"
+#include "mod_ssl_openssl.h"
 #include "mpm_common.h"
 
+APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, init_server,
+                                    (server_rec *s,apr_pool_t *p,int is_proxy,SSL_CTX *ctx),
+                                    (s,p,is_proxy,ctx), OK, DECLINED)
+
 /*  _________________________________________________________________
 **
 **  Module Initialization
@@ -248,6 +254,25 @@ apr_status_t ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
         return rv;
     }
 
+    for (s = base_server; s; s = s->next) {
+        sc = mySrvConfig(s);
+
+        if (sc->enabled == SSL_ENABLED_TRUE || sc->enabled == SSL_ENABLED_OPTIONAL) {
+            if ((rv = ssl_run_init_server(s, p, 0, sc->server->ssl_ctx)) != APR_SUCCESS) {
+                ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO()
+                             "Init: server init_server failed");
+                return rv;
+            }
+        }
+        else if (sc->proxy_enabled == SSL_ENABLED_TRUE) {
+            if ((rv = ssl_run_init_server(s, p, 1, sc->proxy->ssl_ctx)) != APR_SUCCESS) {
+                ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO()
+                             "Init: proxy init_server failed");
+                return rv;
+            }
+        }
+    }
+
     /*
      *  Announce mod_ssl and SSL library in HTTP Server field
      *  as ``mod_ssl/X.X.X OpenSSL/X.X.X''
index e766f096602b12b3e1e997efd7c0c1409df8a83e..26a901f85654027efbbe272f5bb39064f5540ae2 100644 (file)
                                             -- Unknown    */
 #include "ssl_private.h"
 #include "mod_ssl.h"
+#include "mod_ssl_openssl.h"
 #include "apr_date.h"
 
+APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, proxy_post_handshake,
+                                    (conn_rec *c,SSL *ssl),
+                                    (c,ssl),OK,DECLINED);
+
 /*  _________________________________________________________________
 **
 **  I/O Hooks
@@ -1119,6 +1124,8 @@ static apr_status_t ssl_io_filter_handshake(ssl_filter_ctx_t *filter_ctx)
         const char *hostname_note = apr_table_get(c->notes,
                                                   "proxy-request-hostname");
         BOOL proxy_ssl_check_peer_ok = TRUE;
+        int post_handshake_rc;
+
         sc = mySrvConfig(server);
 
 #ifdef HAVE_TLSEXT
@@ -1208,11 +1215,17 @@ static apr_status_t ssl_io_filter_handshake(ssl_filter_ctx_t *filter_ctx)
             }
         }
 
+        if (proxy_ssl_check_peer_ok == TRUE) {
+            /* another chance to fail */
+            post_handshake_rc = ssl_run_proxy_post_handshake(c, filter_ctx->pssl);
+        }
+
         if (cert) {
             X509_free(cert);
         }
 
-        if (proxy_ssl_check_peer_ok != TRUE) {
+        if (proxy_ssl_check_peer_ok != TRUE
+            || (post_handshake_rc != OK && post_handshake_rc != DECLINED)) {
             /* ensure that the SSL structures etc are freed, etc: */
             ssl_filter_io_shutdown(filter_ctx, c, 1);
             apr_table_setn(c->notes, "SSL_connect_rv", "err");