diff options
-rw-r--r-- | CHANGES | 4 | ||||
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | Makefile.in | 1 | ||||
-rw-r--r-- | Makefile.win | 1 | ||||
-rw-r--r-- | NWGNUmakefile | 1 | ||||
-rw-r--r-- | include/ap_mmn.h | 3 | ||||
-rw-r--r-- | modules/ssl/mod_ssl.c | 11 | ||||
-rw-r--r-- | modules/ssl/mod_ssl.h | 21 | ||||
-rw-r--r-- | modules/ssl/mod_ssl_openssl.h | 72 | ||||
-rw-r--r-- | modules/ssl/ssl_engine_init.c | 25 | ||||
-rw-r--r-- | modules/ssl/ssl_engine_io.c | 15 |
11 files changed, 154 insertions, 2 deletions
@@ -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] diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ab783562b..d93f9a070d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/Makefile.in b/Makefile.in index 0779d7c735..0f8cf8d51b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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: diff --git a/Makefile.win b/Makefile.win index c1f93cf3eb..e81c03dbab 100644 --- a/Makefile.win +++ b/Makefile.win @@ -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 diff --git a/NWGNUmakefile b/NWGNUmakefile index 1a5e91e72c..e6c53dd053 100644 --- a/NWGNUmakefile +++ b/NWGNUmakefile @@ -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/) diff --git a/include/ap_mmn.h b/include/ap_mmn.h index e2ea31a168..7d9eacd90d 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -450,6 +450,7 @@ * 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" */ @@ -457,7 +458,7 @@ #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 diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c index 13a7833da2..330d1d0905 100644 --- a/modules/ssl/mod_ssl.c +++ b/modules/ssl/mod_ssl.c @@ -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" @@ -37,6 +38,10 @@ 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); diff --git a/modules/ssl/mod_ssl.h b/modules/ssl/mod_ssl.h index ca820103e1..829fd1504a 100644 --- a/modules/ssl/mod_ssl.h +++ b/modules/ssl/mod_ssl.h @@ -29,6 +29,27 @@ #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 index 0000000000..ecca33c15c --- /dev/null +++ b/modules/ssl/mod_ssl_openssl.h @@ -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__ */ +/** @} */ diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c index cbc4a7433d..bb57f48677 100644 --- a/modules/ssl/ssl_engine_init.c +++ b/modules/ssl/ssl_engine_init.c @@ -27,8 +27,14 @@ 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'' diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c index e766f09660..26a901f856 100644 --- a/modules/ssl/ssl_engine_io.c +++ b/modules/ssl/ssl_engine_io.c @@ -29,8 +29,13 @@ -- 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"); |