From owner-freebsd-ports-bugs@FreeBSD.ORG Sat Nov 7 14:00:11 2009 Return-Path: Delivered-To: freebsd-ports-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 837B9106566C for ; Sat, 7 Nov 2009 14:00:11 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 614FC8FC1F for ; Sat, 7 Nov 2009 14:00:11 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.3/8.14.3) with ESMTP id nA7E0BLO071992 for ; Sat, 7 Nov 2009 14:00:11 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.3/8.14.3/Submit) id nA7E0BXn071991; Sat, 7 Nov 2009 14:00:11 GMT (envelope-from gnats) Resent-Date: Sat, 7 Nov 2009 14:00:11 GMT Resent-Message-Id: <200911071400.nA7E0BXn071991@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-ports-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Eygene Ryabinkin Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 5D5BB106566C; Sat, 7 Nov 2009 13:51:59 +0000 (UTC) (envelope-from rea-fbsd@codelabs.ru) Received: from 0.mx.codelabs.ru (0.mx.codelabs.ru [144.206.177.45]) by mx1.freebsd.org (Postfix) with ESMTP id ABC3A8FC13; Sat, 7 Nov 2009 13:51:58 +0000 (UTC) Received: from phoenix.codelabs.ru (ppp83-237-104-175.pppoe.mtu-net.ru [83.237.104.175]) by 0.mx.codelabs.ru with esmtps (TLSv1:CAMELLIA256-SHA:256) id 1N6lht-0009FS-Gi; Sat, 07 Nov 2009 16:51:57 +0300 Message-Id: <20091107135157.41F9CB8035@phoenix.codelabs.ru> Date: Sat, 7 Nov 2009 16:51:57 +0300 (MSK) From: Eygene Ryabinkin To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Cc: apache@FreeBSD.org, miwi@FreeBSD.org Subject: ports/140357: [patch] www/apache22 and www/apache20: fix CVE-2009-3555 X-BeenThere: freebsd-ports-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Eygene Ryabinkin List-Id: Ports bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 07 Nov 2009 14:00:11 -0000 >Number: 140357 >Category: ports >Synopsis: [patch] www/apache22 and www/apache20: fix CVE-2009-3555 >Confidential: no >Severity: critical >Priority: high >Responsible: freebsd-ports-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sat Nov 07 14:00:10 UTC 2009 >Closed-Date: >Last-Modified: >Originator: Eygene Ryabinkin >Release: FreeBSD 8.0-BETA2 amd64 >Organization: Code Labs >Environment: System: FreeBSD 8.0-BETA2 amd64 >Description: See [1]. >How-To-Repeat: [1] http://marc.info/?l=apache-httpd-announce&m=125755783724966&w=2 >Fix: I had applied the upstream fix for the Apache 2.2 and backported it to Apache 2.0. Since OpenSSL port was already upgraded to 0.9.8k that disables renegotiation, the only missing piece is the system OpenSSL, so the patch is applied only when system OpenSSL is used. I had verified this with www/apache22 -- renegotiation turns the connection down and error is logged to the Apache error log. Hadn't yet tested www/apache20 in the real world -- only compilability. --- apache-fix.diff begins here --- >From 7ab29b62ed92d86bc7c593a762f888a0482a0bcc Mon Sep 17 00:00:00 2001 From: Eygene Ryabinkin Date: Sat, 7 Nov 2009 15:29:59 +0300 Signed-off-by: Eygene Ryabinkin --- www/apache20/Makefile | 3 +- www/apache20/files/fix-cve-2009-3555 | 279 +++++++++++++++++++++++++++++++ www/apache22/Makefile | 5 + www/apache22/files/fix-cve-2009-3555 | 303 ++++++++++++++++++++++++++++++++++ 4 files changed, 589 insertions(+), 1 deletions(-) create mode 100644 www/apache20/files/fix-cve-2009-3555 create mode 100644 www/apache22/files/fix-cve-2009-3555 diff --git a/www/apache20/Makefile b/www/apache20/Makefile index 14a06c5..23011bd 100644 --- a/www/apache20/Makefile +++ b/www/apache20/Makefile @@ -9,7 +9,7 @@ PORTNAME= apache PORTVERSION= 2.0.63 -PORTREVISION= 3 +PORTREVISION= 4 CATEGORIES= www MASTER_SITES= ${MASTER_SITE_APACHE_HTTPD} \ ${MASTER_SITE_LOCAL:S/$/:powerlogo/} @@ -37,6 +37,7 @@ CONFLICTS= apache+mod_ssl-1.* apache+mod_ssl+ipv6-1.* apache+mod_ssl+modsnmp-1.* # patch files EXTRA_PATCHES+= ${FILESDIR}/build-fix-openssl_beta +EXTRA_PATCHES+= ${FILESDIR}/fix-cve-2009-3555 .if defined(WITH_EXPERIMENTAL_PATCHES) IGNORE= : Please define WITH_KQUEUE_SUPPORT instead diff --git a/www/apache20/files/fix-cve-2009-3555 b/www/apache20/files/fix-cve-2009-3555 new file mode 100644 index 0000000..c6a7265 --- /dev/null +++ b/www/apache20/files/fix-cve-2009-3555 @@ -0,0 +1,279 @@ +Modified patch from http://www.apache.org/dist/httpd/patches/apply_to_2.2.14/CVE-2009-3555-2.2.patch + +--- modules/ssl/mod_ssl.h.orig 2009-11-07 14:55:25.000000000 +0300 ++++ modules/ssl/mod_ssl.h 2009-11-07 14:56:40.000000000 +0300 +@@ -389,6 +389,19 @@ + int is_proxy; + int disabled; + int non_ssl_request; ++ ++ /* Track the handshake/renegotiation state for the connection so ++ * that all client-initiated renegotiations can be rejected, as a ++ * partial fix for CVE-2009-3555. */ ++ enum { ++ RENEG_INIT = 0, /* Before initial handshake */ ++ RENEG_REJECT, /* After initial handshake; any client-initiated ++ * renegotiation should be rejected */ ++ RENEG_ALLOW, /* A server-initated renegotiation is taking ++ * place (as dictated by configuration) */ ++ RENEG_ABORT /* Renegotiation initiated by client, abort the ++ * connection */ ++ } reneg_state; + } SSLConnRec; + + typedef struct { +@@ -585,7 +598,7 @@ + int ssl_callback_NewSessionCacheEntry(SSL *, SSL_SESSION *); + SSL_SESSION *ssl_callback_GetSessionCacheEntry(SSL *, unsigned char *, int, int *); + void ssl_callback_DelSessionCacheEntry(SSL_CTX *, SSL_SESSION *); +-void ssl_callback_LogTracingState(MODSSL_INFO_CB_ARG_TYPE, int, int); ++void ssl_callback_Info(MODSSL_INFO_CB_ARG_TYPE, int, int); + + /* Session Cache Support */ + void ssl_scache_init(server_rec *, apr_pool_t *); +--- modules/ssl/ssl_engine_init.c.orig 2009-11-07 14:57:31.000000000 +0300 ++++ modules/ssl/ssl_engine_init.c 2009-11-07 14:58:00.000000000 +0300 +@@ -464,10 +464,7 @@ + SSL_CTX_set_tmp_rsa_callback(ctx, ssl_callback_TmpRSA); + SSL_CTX_set_tmp_dh_callback(ctx, ssl_callback_TmpDH); + +- if (s->loglevel >= APLOG_DEBUG) { +- /* this callback only logs if LogLevel >= info */ +- SSL_CTX_set_info_callback(ctx, ssl_callback_LogTracingState); +- } ++ SSL_CTX_set_info_callback(ctx, ssl_callback_Info); + } + + static void ssl_init_ctx_verify(server_rec *s, +--- modules/ssl/ssl_engine_io.c.orig 2009-11-07 14:58:35.000000000 +0300 ++++ modules/ssl/ssl_engine_io.c 2009-11-07 15:01:05.000000000 +0300 +@@ -102,6 +102,7 @@ + ap_filter_t *pInputFilter; + ap_filter_t *pOutputFilter; + int nobuffer; /* non-zero to prevent buffering */ ++ SSLConnRec *config; + } ssl_filter_ctx_t; + + typedef struct { +@@ -193,6 +194,12 @@ + { + bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)(bio->ptr); + ++ /* Abort early if the client has initiated a renegotiation. */ ++ if (outctx->filter_ctx->config->reneg_state == RENEG_ABORT) { ++ outctx->rc = APR_ECONNABORTED; ++ return -1; ++ } ++ + /* when handshaking we'll have a small number of bytes. + * max size SSL will pass us here is about 16k. + * (16413 bytes to be exact) +@@ -465,6 +472,12 @@ + if (!in) + return 0; + ++ /* Abort early if the client has initiated a renegotiation. */ ++ if (inctx->filter_ctx->config->reneg_state == RENEG_ABORT) { ++ inctx->rc = APR_ECONNABORTED; ++ return -1; ++ } ++ + /* XXX: flush here only required for SSLv2; + * OpenSSL calls BIO_flush() at the appropriate times for + * the other protocols. +@@ -1585,6 +1598,8 @@ + + filter_ctx = apr_palloc(c->pool, sizeof(ssl_filter_ctx_t)); + ++ filter_ctx->config = myConnConfig(c); ++ + filter_ctx->nobuffer = 0; + filter_ctx->pOutputFilter = ap_add_output_filter(ssl_io_filter, + filter_ctx, NULL, c); +--- modules/ssl/ssl_engine_kernel.c.orig 2009-11-07 15:01:41.000000000 +0300 ++++ modules/ssl/ssl_engine_kernel.c 2009-11-07 15:09:49.000000000 +0300 +@@ -611,6 +611,10 @@ + (unsigned char *)&id, + sizeof(id)); + ++ /* Toggle the renegotiation state to allow the new ++ * handshake to proceed. */ ++ sslconn->reneg_state = RENEG_ALLOW; ++ + SSL_renegotiate(ssl); + SSL_do_handshake(ssl); + +@@ -628,6 +632,8 @@ + SSL_set_state(ssl, SSL_ST_ACCEPT); + SSL_do_handshake(ssl); + ++ sslconn->reneg_state = RENEG_REJECT; ++ + if (SSL_get_state(ssl) != SSL_ST_OK) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "Re-negotiation handshake failed: " +@@ -1700,76 +1706,56 @@ + return; + } + +-/* +- * This callback function is executed while OpenSSL processes the +- * SSL handshake and does SSL record layer stuff. We use it to +- * trace OpenSSL's processing in out SSL logfile. +- */ +-void ssl_callback_LogTracingState(MODSSL_INFO_CB_ARG_TYPE ssl, int where, int rc) +-{ +- conn_rec *c; +- server_rec *s; +- SSLSrvConfigRec *sc; ++/* Dump debugginfo trace to the log file. */ ++static void log_tracing_state(MODSSL_INFO_CB_ARG_TYPE ssl, conn_rec *c, ++ server_rec *s, int where, int rc) + ++{ + /* +- * find corresponding server ++ * create the various trace messages + */ +- if (!(c = (conn_rec *)SSL_get_app_data((SSL *)ssl))) { +- return; ++ if (where & SSL_CB_HANDSHAKE_START) { ++ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, ++ "%s: Handshake: start", SSL_LIBRARY_NAME); + } +- +- s = c->base_server; +- if (!(sc = mySrvConfig(s))) { +- return; ++ else if (where & SSL_CB_HANDSHAKE_DONE) { ++ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, ++ "%s: Handshake: done", SSL_LIBRARY_NAME); + } +- +- /* +- * create the various trace messages +- */ +- if (s->loglevel >= APLOG_DEBUG) { +- if (where & SSL_CB_HANDSHAKE_START) { +- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, +- "%s: Handshake: start", SSL_LIBRARY_NAME); +- } +- else if (where & SSL_CB_HANDSHAKE_DONE) { +- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, +- "%s: Handshake: done", SSL_LIBRARY_NAME); +- } +- else if (where & SSL_CB_LOOP) { +- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, +- "%s: Loop: %s", +- SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); +- } +- else if (where & SSL_CB_READ) { ++ else if (where & SSL_CB_LOOP) { ++ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, ++ "%s: Loop: %s", ++ SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); ++ } ++ else if (where & SSL_CB_READ) { ++ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, ++ "%s: Read: %s", ++ SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); ++ } ++ else if (where & SSL_CB_WRITE) { ++ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, ++ "%s: Write: %s", ++ SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); ++ } ++ else if (where & SSL_CB_ALERT) { ++ char *str = (where & SSL_CB_READ) ? "read" : "write"; ++ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, ++ "%s: Alert: %s:%s:%s", ++ SSL_LIBRARY_NAME, str, ++ SSL_alert_type_string_long(rc), ++ SSL_alert_desc_string_long(rc)); ++ } ++ else if (where & SSL_CB_EXIT) { ++ if (rc == 0) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, +- "%s: Read: %s", ++ "%s: Exit: failed in %s", + SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); + } +- else if (where & SSL_CB_WRITE) { ++ else if (rc < 0) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, +- "%s: Write: %s", ++ "%s: Exit: error in %s", + SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); + } +- else if (where & SSL_CB_ALERT) { +- char *str = (where & SSL_CB_READ) ? "read" : "write"; +- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, +- "%s: Alert: %s:%s:%s", +- SSL_LIBRARY_NAME, str, +- SSL_alert_type_string_long(rc), +- SSL_alert_desc_string_long(rc)); +- } +- else if (where & SSL_CB_EXIT) { +- if (rc == 0) { +- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, +- "%s: Exit: failed in %s", +- SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); +- } +- else if (rc < 0) { +- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, +- "%s: Exit: error in %s", +- SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); +- } +- } + } + + /* +@@ -1789,3 +1775,48 @@ + } + } + ++/* ++ * This callback function is executed while OpenSSL processes the SSL ++ * handshake and does SSL record layer stuff. It's used to trap ++ * client-initiated renegotiations, and for dumping everything to the ++ * log. ++ */ ++void ssl_callback_Info(MODSSL_INFO_CB_ARG_TYPE ssl, int where, int rc) ++{ ++ conn_rec *c; ++ server_rec *s; ++ SSLConnRec *scr; ++ ++ /* Retrieve the conn_rec and the associated SSLConnRec. */ ++ if ((c = (conn_rec *)SSL_get_app_data((SSL *)ssl)) == NULL) { ++ return; ++ } ++ ++ if ((scr = myConnConfig(c)) == NULL) { ++ return; ++ } ++ ++ /* If the reneg state is to reject renegotiations, check the SSL ++ * state machine and move to ABORT if a Client Hello is being ++ * read. */ ++ if ((where & SSL_CB_ACCEPT_LOOP) && scr->reneg_state == RENEG_REJECT) { ++ int state = SSL_get_state(ssl); ++ ++ if (state == SSL3_ST_SR_CLNT_HELLO_A ++ || state == SSL23_ST_SR_CLNT_HELLO_A) { ++ scr->reneg_state = RENEG_ABORT; ++ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, ++ "rejecting client initiated renegotiation"); ++ } ++ } ++ /* If the first handshake is complete, change state to reject any ++ * subsequent client-initated renegotiation. */ ++ else if ((where & SSL_CB_HANDSHAKE_DONE) && scr->reneg_state == RENEG_INIT) { ++ scr->reneg_state = RENEG_REJECT; ++ } ++ ++ s = mySrvFromConn(c); ++ if (s && s->loglevel >= APLOG_DEBUG) { ++ log_tracing_state(ssl, c, s, where, rc); ++ } ++} diff --git a/www/apache22/Makefile b/www/apache22/Makefile index 4eb1f0c..cb9bcd4 100644 --- a/www/apache22/Makefile +++ b/www/apache22/Makefile @@ -9,6 +9,7 @@ PORTNAME= apache PORTVERSION= 2.2.13 +PORTREVISION= 1 CATEGORIES= www MASTER_SITES= ${MASTER_SITE_APACHE_HTTPD} DISTNAME= httpd-${PORTVERSION} @@ -121,6 +122,10 @@ WITH_LDAP= yes CFLAGS+= -I${OPENSSLINC} LDFLAGS+= -L${OPENSSLLIB} +.if defined(WITH_OPENSSL_BASE) +EXTRA_PATCHES+= ${FILESDIR}/fix-cve-2009-3555 +.endif + .endif .if defined(WITH_APR_FROM_PORTS) diff --git a/www/apache22/files/fix-cve-2009-3555 b/www/apache22/files/fix-cve-2009-3555 new file mode 100644 index 0000000..f2253e6 --- /dev/null +++ b/www/apache22/files/fix-cve-2009-3555 @@ -0,0 +1,303 @@ + + SECURITY: CVE-2009-3555 (cve.mitre.org) + + A partial fix for the TLS renegotiation prefix injection attack by + rejecting any client-initiated renegotiations. Any configuration + which requires renegotiation for per-directory/location access + control is still vulnerable, unless using OpenSSL >= 0.9.8l. + [Joe Orton, Ruediger Pluem] + +Obtained-From: http://www.apache.org/dist/httpd/patches/apply_to_2.2.14/CVE-2009-3555-2.2.patch +Notes: should be discarded when OpenSSL will be upgraded to 0.9.8l. + +Index: modules/ssl/ssl_private.h +=================================================================== +--- modules/ssl/ssl_private.h (revision 833621) ++++ modules/ssl/ssl_private.h (revision 833622) +@@ -356,6 +356,20 @@ + int is_proxy; + int disabled; + int non_ssl_request; ++ ++ /* Track the handshake/renegotiation state for the connection so ++ * that all client-initiated renegotiations can be rejected, as a ++ * partial fix for CVE-2009-3555. */ ++ enum { ++ RENEG_INIT = 0, /* Before initial handshake */ ++ RENEG_REJECT, /* After initial handshake; any client-initiated ++ * renegotiation should be rejected */ ++ RENEG_ALLOW, /* A server-initated renegotiation is taking ++ * place (as dictated by configuration) */ ++ RENEG_ABORT /* Renegotiation initiated by client, abort the ++ * connection */ ++ } reneg_state; ++ + server_rec *server; + } SSLConnRec; + +@@ -574,7 +588,7 @@ + int ssl_callback_NewSessionCacheEntry(SSL *, SSL_SESSION *); + SSL_SESSION *ssl_callback_GetSessionCacheEntry(SSL *, unsigned char *, int, int *); + void ssl_callback_DelSessionCacheEntry(SSL_CTX *, SSL_SESSION *); +-void ssl_callback_LogTracingState(MODSSL_INFO_CB_ARG_TYPE, int, int); ++void ssl_callback_Info(MODSSL_INFO_CB_ARG_TYPE, int, int); + #ifndef OPENSSL_NO_TLSEXT + int ssl_callback_ServerNameIndication(SSL *, int *, modssl_ctx_t *); + #endif +Index: modules/ssl/ssl_engine_init.c +=================================================================== +--- modules/ssl/ssl_engine_init.c (revision 833621) ++++ modules/ssl/ssl_engine_init.c (revision 833622) +@@ -501,10 +501,7 @@ + SSL_CTX_set_tmp_rsa_callback(ctx, ssl_callback_TmpRSA); + SSL_CTX_set_tmp_dh_callback(ctx, ssl_callback_TmpDH); + +- if (s->loglevel >= APLOG_DEBUG) { +- /* this callback only logs if LogLevel >= info */ +- SSL_CTX_set_info_callback(ctx, ssl_callback_LogTracingState); +- } ++ SSL_CTX_set_info_callback(ctx, ssl_callback_Info); + } + + static void ssl_init_ctx_verify(server_rec *s, +Index: modules/ssl/ssl_engine_io.c +=================================================================== +--- modules/ssl/ssl_engine_io.c (revision 833621) ++++ modules/ssl/ssl_engine_io.c (revision 833622) +@@ -103,6 +103,7 @@ + ap_filter_t *pInputFilter; + ap_filter_t *pOutputFilter; + int nobuffer; /* non-zero to prevent buffering */ ++ SSLConnRec *config; + } ssl_filter_ctx_t; + + typedef struct { +@@ -193,7 +194,13 @@ + static int bio_filter_out_write(BIO *bio, const char *in, int inl) + { + bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)(bio->ptr); +- ++ ++ /* Abort early if the client has initiated a renegotiation. */ ++ if (outctx->filter_ctx->config->reneg_state == RENEG_ABORT) { ++ outctx->rc = APR_ECONNABORTED; ++ return -1; ++ } ++ + /* when handshaking we'll have a small number of bytes. + * max size SSL will pass us here is about 16k. + * (16413 bytes to be exact) +@@ -466,6 +473,12 @@ + if (!in) + return 0; + ++ /* Abort early if the client has initiated a renegotiation. */ ++ if (inctx->filter_ctx->config->reneg_state == RENEG_ABORT) { ++ inctx->rc = APR_ECONNABORTED; ++ return -1; ++ } ++ + /* XXX: flush here only required for SSLv2; + * OpenSSL calls BIO_flush() at the appropriate times for + * the other protocols. +@@ -1724,6 +1737,8 @@ + + filter_ctx = apr_palloc(c->pool, sizeof(ssl_filter_ctx_t)); + ++ filter_ctx->config = myConnConfig(c); ++ + filter_ctx->nobuffer = 0; + filter_ctx->pOutputFilter = ap_add_output_filter(ssl_io_filter, + filter_ctx, NULL, c); +Index: modules/ssl/ssl_engine_kernel.c +=================================================================== +--- modules/ssl/ssl_engine_kernel.c (revision 833621) ++++ modules/ssl/ssl_engine_kernel.c (revision 833622) +@@ -729,6 +729,10 @@ + (unsigned char *)&id, + sizeof(id)); + ++ /* Toggle the renegotiation state to allow the new ++ * handshake to proceed. */ ++ sslconn->reneg_state = RENEG_ALLOW; ++ + SSL_renegotiate(ssl); + SSL_do_handshake(ssl); + +@@ -750,6 +754,8 @@ + SSL_set_state(ssl, SSL_ST_ACCEPT); + SSL_do_handshake(ssl); + ++ sslconn->reneg_state = RENEG_REJECT; ++ + if (SSL_get_state(ssl) != SSL_ST_OK) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Re-negotiation handshake failed: " +@@ -1844,76 +1850,55 @@ + return; + } + +-/* +- * This callback function is executed while OpenSSL processes the +- * SSL handshake and does SSL record layer stuff. We use it to +- * trace OpenSSL's processing in out SSL logfile. +- */ +-void ssl_callback_LogTracingState(MODSSL_INFO_CB_ARG_TYPE ssl, int where, int rc) ++/* Dump debugginfo trace to the log file. */ ++static void log_tracing_state(MODSSL_INFO_CB_ARG_TYPE ssl, conn_rec *c, ++ server_rec *s, int where, int rc) + { +- conn_rec *c; +- server_rec *s; +- SSLSrvConfigRec *sc; +- + /* +- * find corresponding server ++ * create the various trace messages + */ +- if (!(c = (conn_rec *)SSL_get_app_data((SSL *)ssl))) { +- return; ++ if (where & SSL_CB_HANDSHAKE_START) { ++ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, ++ "%s: Handshake: start", SSL_LIBRARY_NAME); + } +- +- s = mySrvFromConn(c); +- if (!(sc = mySrvConfig(s))) { +- return; ++ else if (where & SSL_CB_HANDSHAKE_DONE) { ++ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, ++ "%s: Handshake: done", SSL_LIBRARY_NAME); + } +- +- /* +- * create the various trace messages +- */ +- if (s->loglevel >= APLOG_DEBUG) { +- if (where & SSL_CB_HANDSHAKE_START) { ++ else if (where & SSL_CB_LOOP) { ++ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, ++ "%s: Loop: %s", ++ SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); ++ } ++ else if (where & SSL_CB_READ) { ++ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, ++ "%s: Read: %s", ++ SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); ++ } ++ else if (where & SSL_CB_WRITE) { ++ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, ++ "%s: Write: %s", ++ SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); ++ } ++ else if (where & SSL_CB_ALERT) { ++ char *str = (where & SSL_CB_READ) ? "read" : "write"; ++ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, ++ "%s: Alert: %s:%s:%s", ++ SSL_LIBRARY_NAME, str, ++ SSL_alert_type_string_long(rc), ++ SSL_alert_desc_string_long(rc)); ++ } ++ else if (where & SSL_CB_EXIT) { ++ if (rc == 0) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, +- "%s: Handshake: start", SSL_LIBRARY_NAME); +- } +- else if (where & SSL_CB_HANDSHAKE_DONE) { +- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, +- "%s: Handshake: done", SSL_LIBRARY_NAME); +- } +- else if (where & SSL_CB_LOOP) { +- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, +- "%s: Loop: %s", ++ "%s: Exit: failed in %s", + SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); + } +- else if (where & SSL_CB_READ) { ++ else if (rc < 0) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, +- "%s: Read: %s", ++ "%s: Exit: error in %s", + SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); + } +- else if (where & SSL_CB_WRITE) { +- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, +- "%s: Write: %s", +- SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); +- } +- else if (where & SSL_CB_ALERT) { +- char *str = (where & SSL_CB_READ) ? "read" : "write"; +- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, +- "%s: Alert: %s:%s:%s", +- SSL_LIBRARY_NAME, str, +- SSL_alert_type_string_long(rc), +- SSL_alert_desc_string_long(rc)); +- } +- else if (where & SSL_CB_EXIT) { +- if (rc == 0) { +- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, +- "%s: Exit: failed in %s", +- SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); +- } +- else if (rc < 0) { +- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, +- "%s: Exit: error in %s", +- SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); +- } +- } + } + + /* +@@ -1933,6 +1918,52 @@ + } + } + ++/* ++ * This callback function is executed while OpenSSL processes the SSL ++ * handshake and does SSL record layer stuff. It's used to trap ++ * client-initiated renegotiations, and for dumping everything to the ++ * log. ++ */ ++void ssl_callback_Info(MODSSL_INFO_CB_ARG_TYPE ssl, int where, int rc) ++{ ++ conn_rec *c; ++ server_rec *s; ++ SSLConnRec *scr; ++ ++ /* Retrieve the conn_rec and the associated SSLConnRec. */ ++ if ((c = (conn_rec *)SSL_get_app_data((SSL *)ssl)) == NULL) { ++ return; ++ } ++ ++ if ((scr = myConnConfig(c)) == NULL) { ++ return; ++ } ++ ++ /* If the reneg state is to reject renegotiations, check the SSL ++ * state machine and move to ABORT if a Client Hello is being ++ * read. */ ++ if ((where & SSL_CB_ACCEPT_LOOP) && scr->reneg_state == RENEG_REJECT) { ++ int state = SSL_get_state(ssl); ++ ++ if (state == SSL3_ST_SR_CLNT_HELLO_A ++ || state == SSL23_ST_SR_CLNT_HELLO_A) { ++ scr->reneg_state = RENEG_ABORT; ++ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, ++ "rejecting client initiated renegotiation"); ++ } ++ } ++ /* If the first handshake is complete, change state to reject any ++ * subsequent client-initated renegotiation. */ ++ else if ((where & SSL_CB_HANDSHAKE_DONE) && scr->reneg_state == RENEG_INIT) { ++ scr->reneg_state = RENEG_REJECT; ++ } ++ ++ s = mySrvFromConn(c); ++ if (s && s->loglevel >= APLOG_DEBUG) { ++ log_tracing_state(ssl, c, s, where, rc); ++ } ++} ++ + #ifndef OPENSSL_NO_TLSEXT + /* + * This callback function is executed when OpenSSL encounters an extended -- 1.6.3.1 --- apache-fix.diff ends here --- VuXML entry will follow, probably today. >Release-Note: >Audit-Trail: >Unformatted: