- mod_ssl: add SSLKEYLOGFILE support (#1982656)

Resolves: rhbz#1982656
This commit is contained in:
Joe Orton 2021-07-15 12:41:39 +01:00
parent daf3bf9ef7
commit e6d49b6319
4 changed files with 152 additions and 158 deletions

View File

@ -1,118 +0,0 @@
diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c
index 12617b2..0fe7464 100644
--- a/modules/ssl/mod_ssl.c
+++ b/modules/ssl/mod_ssl.c
@@ -459,6 +459,10 @@ static int ssl_hook_pre_config(apr_pool_t *pconf,
return OK;
}
+static APR_OPTIONAL_FN_TYPE(ssl_engine_disable) *othermod_engine_disable;
+static APR_OPTIONAL_FN_TYPE(ssl_engine_set) *othermod_engine_set;
+
+
static SSLConnRec *ssl_init_connection_ctx(conn_rec *c,
ap_conf_vector_t *per_dir_config,
int new_proxy)
@@ -466,6 +470,10 @@ static SSLConnRec *ssl_init_connection_ctx(conn_rec *c,
SSLConnRec *sslconn = myConnConfig(c);
int need_setup = 0;
+ if (othermod_engine_disable) {
+ othermod_engine_disable(c);
+ }
+
/* mod_proxy's (r->)per_dir_config has the lifetime of the request, thus
* it uses ssl_engine_set() to reset sslconn->dc when reusing SSL backend
* connections, so we must fall through here. But in the case where we are
@@ -544,6 +552,10 @@ static int ssl_engine_set(conn_rec *c,
{
SSLConnRec *sslconn;
int status;
+
+ if (othermod_engine_set) {
+ return othermod_engine_set(c, per_dir_config, proxy, enable);
+ }
if (proxy) {
sslconn = ssl_init_connection_ctx(c, per_dir_config, 1);
@@ -572,12 +584,18 @@ static int ssl_engine_set(conn_rec *c,
static int ssl_proxy_enable(conn_rec *c)
{
- return ssl_engine_set(c, NULL, 1, 1);
+ if (othermod_engine_set)
+ return othermod_engine_set(c, NULL, 1, 1);
+ else
+ return ssl_engine_set(c, NULL, 1, 1);
}
static int ssl_engine_disable(conn_rec *c)
{
- return ssl_engine_set(c, NULL, 0, 0);
+ if (othermod_engine_set)
+ return othermod_engine_set(c, NULL, 0, 0);
+ else
+ return ssl_engine_set(c, NULL, 0, 0);
}
int ssl_init_ssl_connection(conn_rec *c, request_rec *r)
@@ -753,6 +771,9 @@ static void ssl_register_hooks(apr_pool_t *p)
APR_HOOK_MIDDLE);
ssl_var_register(p);
+
+ othermod_engine_disable = APR_RETRIEVE_OPTIONAL_FN(ssl_engine_disable);
+ othermod_engine_set = APR_RETRIEVE_OPTIONAL_FN(ssl_engine_set);
APR_REGISTER_OPTIONAL_FN(ssl_proxy_enable);
APR_REGISTER_OPTIONAL_FN(ssl_engine_disable);
diff --git a/modules/ssl/ssl_engine_vars.c b/modules/ssl/ssl_engine_vars.c
index 5724f18..81c56ba 100644
--- a/modules/ssl/ssl_engine_vars.c
+++ b/modules/ssl/ssl_engine_vars.c
@@ -54,6 +54,8 @@ static char *ssl_var_lookup_ssl_cipher(apr_pool_t *p, SSLConnRec *sslconn, char
static void ssl_var_lookup_ssl_cipher_bits(SSL *ssl, int *usekeysize, int *algkeysize);
static char *ssl_var_lookup_ssl_version(apr_pool_t *p, char *var);
static char *ssl_var_lookup_ssl_compress_meth(SSL *ssl);
+static APR_OPTIONAL_FN_TYPE(ssl_is_https) *othermod_is_https;
+static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *othermod_var_lookup;
static SSLConnRec *ssl_get_effective_config(conn_rec *c)
{
@@ -68,7 +70,9 @@ static SSLConnRec *ssl_get_effective_config(conn_rec *c)
static int ssl_is_https(conn_rec *c)
{
SSLConnRec *sslconn = ssl_get_effective_config(c);
- return sslconn && sslconn->ssl;
+
+ return (sslconn && sslconn->ssl)
+ || (othermod_is_https && othermod_is_https(c));
}
static const char var_interface[] = "mod_ssl/" AP_SERVER_BASEREVISION;
@@ -137,6 +141,9 @@ void ssl_var_register(apr_pool_t *p)
{
char *cp, *cp2;
+ othermod_is_https = APR_RETRIEVE_OPTIONAL_FN(ssl_is_https);
+ othermod_var_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup);
+
APR_REGISTER_OPTIONAL_FN(ssl_is_https);
APR_REGISTER_OPTIONAL_FN(ssl_var_lookup);
APR_REGISTER_OPTIONAL_FN(ssl_ext_list);
@@ -271,6 +278,15 @@ char *ssl_var_lookup(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r,
*/
if (result == NULL && c != NULL) {
SSLConnRec *sslconn = ssl_get_effective_config(c);
+
+ if (strlen(var) > 4 && strcEQn(var, "SSL_", 4)
+ && (!sslconn || !sslconn->ssl) && othermod_var_lookup) {
+ /* For an SSL_* variable, if mod_ssl is not enabled for
+ * this connection and another SSL module is present, pass
+ * through to that module. */
+ return othermod_var_lookup(p, s, c, r, var);
+ }
+
if (strlen(var) > 4 && strcEQn(var, "SSL_", 4)
&& sslconn && sslconn->ssl)
result = ssl_var_lookup_ssl(p, sslconn, r, var+4);

117
httpd-2.4.48-r1869842.patch Normal file
View File

@ -0,0 +1,117 @@
# ./pullrev.sh 1869842
http://svn.apache.org/viewvc?view=revision&revision=1869842
--- httpd-2.4.48/modules/ssl/ssl_engine_config.c.r1869842
+++ httpd-2.4.48/modules/ssl/ssl_engine_config.c
@@ -75,6 +75,10 @@
mc->stapling_refresh_mutex = NULL;
#endif
+#ifdef HAVE_OPENSSL_KEYLOG
+ mc->keylog_file = NULL;
+#endif
+
apr_pool_userdata_set(mc, SSL_MOD_CONFIG_KEY,
apr_pool_cleanup_null,
pool);
--- httpd-2.4.48/modules/ssl/ssl_engine_init.c.r1869842
+++ httpd-2.4.48/modules/ssl/ssl_engine_init.c
@@ -445,6 +445,28 @@
init_bio_methods();
#endif
+#ifdef HAVE_OPENSSL_KEYLOG
+ {
+ const char *logfn = getenv("SSLKEYLOGFILE");
+
+ if (logfn) {
+ rv = apr_file_open(&mc->keylog_file, logfn,
+ APR_FOPEN_CREATE|APR_FOPEN_WRITE|APR_FOPEN_APPEND|APR_FOPEN_LARGEFILE,
+ APR_FPROT_UREAD|APR_FPROT_UWRITE,
+ mc->pPool);
+ if (rv) {
+ ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, s, APLOGNO(10226)
+ "Could not open log file '%s' configured via SSLKEYLOGFILE",
+ logfn);
+ return rv;
+ }
+
+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, APLOGNO(10227)
+ "Init: Logging SSL private key material to %s", logfn);
+ }
+ }
+#endif
+
return OK;
}
@@ -806,6 +828,12 @@
* https://github.com/openssl/openssl/issues/7178 */
SSL_CTX_clear_mode(ctx, SSL_MODE_AUTO_RETRY);
#endif
+
+#ifdef HAVE_OPENSSL_KEYLOG
+ if (mctx->sc->mc->keylog_file) {
+ SSL_CTX_set_keylog_callback(ctx, modssl_callback_keylog);
+ }
+#endif
return APR_SUCCESS;
}
--- httpd-2.4.48/modules/ssl/ssl_engine_kernel.c.r1869842
+++ httpd-2.4.48/modules/ssl/ssl_engine_kernel.c
@@ -2822,3 +2822,17 @@
}
#endif /* HAVE_SRP */
+
+
+#ifdef HAVE_OPENSSL_KEYLOG
+/* Callback used with SSL_CTX_set_keylog_callback. */
+void modssl_callback_keylog(const SSL *ssl, const char *line)
+{
+ conn_rec *conn = SSL_get_app_data(ssl);
+ SSLSrvConfigRec *sc = mySrvConfig(conn->base_server);
+
+ if (sc && sc->mc->keylog_file) {
+ apr_file_printf(sc->mc->keylog_file, "%s\n", line);
+ }
+}
+#endif
--- httpd-2.4.48/modules/ssl/ssl_private.h.r1869842
+++ httpd-2.4.48/modules/ssl/ssl_private.h
@@ -252,6 +252,10 @@
#endif
#endif
+#if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
+#define HAVE_OPENSSL_KEYLOG
+#endif
+
/* mod_ssl headers */
#include "ssl_util_ssl.h"
@@ -620,6 +624,11 @@
apr_global_mutex_t *stapling_cache_mutex;
apr_global_mutex_t *stapling_refresh_mutex;
#endif
+
+#ifdef HAVE_OPENSSL_KEYLOG
+ /* Used for logging if SSLKEYLOGFILE is set at startup. */
+ apr_file_t *keylog_file;
+#endif
} SSLModConfigRec;
/** Structure representing configured filenames for certs and keys for
@@ -979,6 +988,11 @@
int ssl_callback_SRPServerParams(SSL *, int *, void *);
#endif
+#ifdef HAVE_OPENSSL_KEYLOG
+/* Callback used with SSL_CTX_set_keylog_callback. */
+void modssl_callback_keylog(const SSL *ssl, const char *line);
+#endif
+
/** I/O */
void ssl_io_filter_init(conn_rec *, request_rec *r, SSL *);
void ssl_io_filter_register(apr_pool_t *);

View File

@ -1,10 +1,10 @@
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
index 699bdcd..15f68f9 100644
--- a/modules/ssl/ssl_engine_init.c
+++ b/modules/ssl/ssl_engine_init.c
@@ -842,6 +842,13 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s,
* https://github.com/openssl/openssl/issues/7178 */
SSL_CTX_clear_mode(ctx, SSL_MODE_AUTO_RETRY);
--- httpd-2.4.48/modules/ssl/ssl_engine_init.c.r1877397
+++ httpd-2.4.48/modules/ssl/ssl_engine_init.c
@@ -870,6 +870,13 @@
SSL_CTX_set_keylog_callback(ctx, modssl_callback_keylog);
}
#endif
+
+#ifdef SSL_OP_NO_RENEGOTIATION
@ -16,7 +16,7 @@ index 699bdcd..15f68f9 100644
return APR_SUCCESS;
}
@@ -863,6 +870,14 @@ static void ssl_init_ctx_session_cache(server_rec *s,
@@ -891,6 +898,14 @@
}
}
@ -31,7 +31,7 @@ index 699bdcd..15f68f9 100644
static void ssl_init_ctx_callbacks(server_rec *s,
apr_pool_t *p,
apr_pool_t *ptemp,
@@ -872,7 +887,13 @@ static void ssl_init_ctx_callbacks(server_rec *s,
@@ -900,7 +915,13 @@
SSL_CTX_set_tmp_dh_callback(ctx, ssl_callback_TmpDH);
@ -46,11 +46,9 @@ index 699bdcd..15f68f9 100644
#ifdef HAVE_TLS_ALPN
SSL_CTX_set_alpn_select_cb(ctx, ssl_callback_alpn_select, NULL);
diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c
index 1a0791a..5c1ad5d 100644
--- a/modules/ssl/ssl_engine_io.c
+++ b/modules/ssl/ssl_engine_io.c
@@ -205,11 +205,13 @@ static int bio_filter_out_write(BIO *bio, const char *in, int inl)
--- httpd-2.4.48/modules/ssl/ssl_engine_io.c.r1877397
+++ httpd-2.4.48/modules/ssl/ssl_engine_io.c
@@ -205,11 +205,13 @@
BIO_clear_retry_flags(bio);
@ -64,7 +62,7 @@ index 1a0791a..5c1ad5d 100644
ap_log_cerror(APLOG_MARK, APLOG_TRACE6, 0, outctx->c,
"bio_filter_out_write: %i bytes", inl);
@@ -462,11 +464,13 @@ static int bio_filter_in_read(BIO *bio, char *in, int inlen)
@@ -462,11 +464,13 @@
BIO_clear_retry_flags(bio);
@ -78,11 +76,9 @@ index 1a0791a..5c1ad5d 100644
if (!inctx->bb) {
inctx->rc = APR_EOF;
diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c
index f2d49ad..a38f03d 100644
--- a/modules/ssl/ssl_engine_kernel.c
+++ b/modules/ssl/ssl_engine_kernel.c
@@ -992,7 +992,7 @@ static int ssl_hook_Access_classic(request_rec *r, SSLSrvConfigRec *sc, SSLDirCo
--- httpd-2.4.48/modules/ssl/ssl_engine_kernel.c.r1877397
+++ httpd-2.4.48/modules/ssl/ssl_engine_kernel.c
@@ -992,7 +992,7 @@
/* Toggle the renegotiation state to allow the new
* handshake to proceed. */
@ -91,7 +87,7 @@ index f2d49ad..a38f03d 100644
SSL_renegotiate(ssl);
SSL_do_handshake(ssl);
@@ -1019,7 +1019,7 @@ static int ssl_hook_Access_classic(request_rec *r, SSLSrvConfigRec *sc, SSLDirCo
@@ -1019,7 +1019,7 @@
*/
SSL_peek(ssl, peekbuf, 0);
@ -100,7 +96,7 @@ index f2d49ad..a38f03d 100644
if (!SSL_is_init_finished(ssl)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02261)
@@ -1078,7 +1078,7 @@ static int ssl_hook_Access_modern(request_rec *r, SSLSrvConfigRec *sc, SSLDirCon
@@ -1078,7 +1078,7 @@
(sc->server->auth.verify_mode != SSL_CVERIFY_UNSET)) {
int vmode_inplace, vmode_needed;
int change_vmode = FALSE;
@ -109,7 +105,7 @@ index f2d49ad..a38f03d 100644
vmode_inplace = SSL_get_verify_mode(ssl);
vmode_needed = SSL_VERIFY_NONE;
@@ -1180,8 +1180,6 @@ static int ssl_hook_Access_modern(request_rec *r, SSLSrvConfigRec *sc, SSLDirCon
@@ -1180,8 +1180,6 @@
return HTTP_FORBIDDEN;
}
@ -118,7 +114,7 @@ index f2d49ad..a38f03d 100644
modssl_set_app_data2(ssl, r);
SSL_do_handshake(ssl);
@@ -1191,7 +1189,6 @@ static int ssl_hook_Access_modern(request_rec *r, SSLSrvConfigRec *sc, SSLDirCon
@@ -1191,7 +1189,6 @@
*/
SSL_peek(ssl, peekbuf, 0);
@ -126,7 +122,7 @@ index f2d49ad..a38f03d 100644
modssl_set_app_data2(ssl, NULL);
/*
@@ -2261,8 +2258,8 @@ static void log_tracing_state(const SSL *ssl, conn_rec *c,
@@ -2261,8 +2258,8 @@
/*
* This callback function is executed while OpenSSL processes the SSL
* handshake and does SSL record layer stuff. It's used to trap
@ -137,7 +133,7 @@ index f2d49ad..a38f03d 100644
*/
void ssl_callback_Info(const SSL *ssl, int where, int rc)
{
@@ -2274,14 +2271,12 @@ void ssl_callback_Info(const SSL *ssl, int where, int rc)
@@ -2274,14 +2271,12 @@
return;
}
@ -158,7 +154,7 @@ index f2d49ad..a38f03d 100644
{
SSLConnRec *sslconn;
@@ -2306,6 +2301,7 @@ void ssl_callback_Info(const SSL *ssl, int where, int rc)
@@ -2306,6 +2301,7 @@
sslconn->reneg_state = RENEG_REJECT;
}
}
@ -166,11 +162,9 @@ index f2d49ad..a38f03d 100644
s = mySrvFromConn(c);
if (s && APLOGdebug(s)) {
diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h
index 71d658c..f9654af 100644
--- a/modules/ssl/ssl_private.h
+++ b/modules/ssl/ssl_private.h
@@ -509,6 +509,16 @@ typedef struct {
--- httpd-2.4.48/modules/ssl/ssl_private.h.r1877397
+++ httpd-2.4.48/modules/ssl/ssl_private.h
@@ -513,6 +513,16 @@
apr_time_t source_mtime;
} ssl_asn1_t;
@ -187,7 +181,7 @@ index 71d658c..f9654af 100644
/**
* Define the mod_ssl per-module configuration structure
* (i.e. the global configuration for each httpd process)
@@ -541,18 +551,13 @@ typedef struct {
@@ -545,18 +555,13 @@
NON_SSL_SET_ERROR_MSG /* Need to set the error message */
} non_ssl_request;
@ -213,7 +207,7 @@ index 71d658c..f9654af 100644
server_rec *server;
SSLDirConfigRec *dc;
@@ -1145,6 +1150,9 @@ int ssl_is_challenge(conn_rec *c, const char *servername,
@@ -1159,6 +1164,9 @@
* the configured ENGINE. */
int modssl_is_engine_id(const char *name);
@ -223,11 +217,9 @@ index 71d658c..f9654af 100644
#endif /* SSL_PRIVATE_H */
/** @} */
diff --git a/modules/ssl/ssl_util_ssl.c b/modules/ssl/ssl_util_ssl.c
index 38079a9..dafb833 100644
--- a/modules/ssl/ssl_util_ssl.c
+++ b/modules/ssl/ssl_util_ssl.c
@@ -589,3 +589,19 @@ cleanup:
--- httpd-2.4.48/modules/ssl/ssl_util_ssl.c.r1877397
+++ httpd-2.4.48/modules/ssl/ssl_util_ssl.c
@@ -589,3 +589,19 @@
}
return rv;
}

View File

@ -13,7 +13,7 @@
Summary: Apache HTTP Server
Name: httpd
Version: 2.4.48
Release: 11%{?dist}
Release: 12%{?dist}
URL: https://httpd.apache.org/
Source0: https://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2
Source1: https://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2.asc
@ -76,7 +76,7 @@ Patch25: httpd-2.4.43-selinux.patch
Patch26: httpd-2.4.43-gettid.patch
Patch27: httpd-2.4.43-icons.patch
Patch30: httpd-2.4.43-cachehardmax.patch
Patch31: httpd-2.4.43-sslmultiproxy.patch
Patch32: httpd-2.4.48-r1869842.patch
Patch34: httpd-2.4.43-socket-activation.patch
Patch38: httpd-2.4.43-sslciphdefault.patch
Patch39: httpd-2.4.43-sslprotdefault.patch
@ -241,7 +241,7 @@ written in the Lua programming language.
%patch26 -p1 -b .gettid
%patch27 -p1 -b .icons
%patch30 -p1 -b .cachehardmax
#patch31 -p1 -b .sslmultiproxy
%patch32 -p1 -b .r1869842
%patch34 -p1 -b .socketactivation
%patch38 -p1 -b .sslciphdefault
%patch39 -p1 -b .sslprotdefault
@ -802,6 +802,9 @@ exit $rv
%{_rpmconfigdir}/macros.d/macros.httpd
%changelog
* Thu Jul 15 2021 Joe Orton <jorton@redhat.com> - 2.4.48-12
- mod_ssl: add SSLKEYLOGFILE support (#1982656)
* Mon Jul 12 2021 Joe Orton <jorton@redhat.com> - 2.4.48-11
- mod_cgid: fix doubled script timeout (#1977234)