From ad100835c46c05d89c150df7e161c6550b0fec97 Mon Sep 17 00:00:00 2001 From: Rainer Jung Date: Fri, 15 Feb 2013 15:50:37 +0000 Subject: [PATCH] When receiving http on https, send the error response with http 1.0 It is important that we send a proper error status, or search engines may index the error message. Remove the link in the speaking-http-on-https error message. With SNI, the link will usually be wrong. So better send no link at all. PR: 50823 Backport of r1328325 and r1328326 from trunk resp. r1334346 from 2.4.x. Submitted by: sf Backported by: rjung Reviewed by: wrowe, rpluem git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@1446642 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 4 ++++ STATUS | 12 ------------ modules/ssl/ssl_engine_io.c | 26 ++++++++++++++++++-------- modules/ssl/ssl_engine_kernel.c | 33 ++++++--------------------------- modules/ssl/ssl_private.h | 6 +++++- 5 files changed, 33 insertions(+), 48 deletions(-) diff --git a/CHANGES b/CHANGES index a7e415d5d32..ca458741358 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,10 @@ -*- coding: utf-8 -*- Changes with Apache 2.2.24 + *) mod_ssl: Send the error message for speaking http to an https port using + HTTP/1.0 instead of HTTP/0.9, and omit the link that may be wrong when + using SNI. PR 50823. [Stefan Fritsch] + *) mod_ssl: log revoked certificates at level INFO instead of DEBUG. PR 52162. [Stefan Fritsch] diff --git a/STATUS b/STATUS index 92889220afc..7e6e412b5fe 100644 --- a/STATUS +++ b/STATUS @@ -94,18 +94,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - * mod_ssl: When receiving http on https, send the error response with http 1.0 - It is important that we send a proper error status, or search engines - may index the error message. - Remove the link in the speaking-http-on-https error message. - With SNI, the link will usually be wrong. So better send no link at all. - PR: 50823 - trunk patch: http://svn.apache.org/viewvc?view=revision&revision=1328325 and - http://svn.apache.org/viewvc?view=revision&revision=1328326 - 2.4.x patch: http://svn.apache.org/viewvc?view=revision&revision=1334346 - 2.2.x patch: http://people.apache.org/~rjung/patches/improve-speaking-http-on-https-message-2_2.patch - +1: rjung, wrowe, rpluem - PATCHES PROPOSED TO BACKPORT FROM TRUNK: [ New proposals should be added at the end of the list ] diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c index e2d33909d1e..7bba787e588 100644 --- a/modules/ssl/ssl_engine_io.c +++ b/modules/ssl/ssl_engine_io.c @@ -853,12 +853,12 @@ static apr_status_t ssl_filter_write(ap_filter_t *f, /* Just use a simple request. Any request will work for this, because * we use a flag in the conn_rec->conn_vector now. The fake request just * gets the request back to the Apache core so that a response can be sent. - * - * To avoid calling back for more data from the socket, use an HTTP/0.9 - * request, and tack on an EOS bucket. + * Since we use an HTTP/1.x request, we also have to inject the empty line + * that terminates the headers, or the core will read more data from the + * socket. */ #define HTTP_ON_HTTPS_PORT \ - "GET /" CRLF + "GET / HTTP/1.0" CRLF #define HTTP_ON_HTTPS_PORT_BUCKET(alloc) \ apr_bucket_immortal_create(HTTP_ON_HTTPS_PORT, \ @@ -880,6 +880,7 @@ static apr_status_t ssl_io_filter_error(ap_filter_t *f, { SSLConnRec *sslconn = myConnConfig(f->c); apr_bucket *bucket; + int send_eos = 1; switch (status) { case HTTP_BAD_REQUEST: @@ -889,11 +890,12 @@ static apr_status_t ssl_io_filter_error(ap_filter_t *f, "trying to send HTML error page"); ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, sslconn->server); - sslconn->non_ssl_request = 1; + sslconn->non_ssl_request = NON_SSL_SEND_HDR_SEP; ssl_io_filter_disable(sslconn, f); /* fake the request line */ bucket = HTTP_ON_HTTPS_PORT_BUCKET(f->c->bucket_alloc); + send_eos = 0; break; default: @@ -901,9 +903,10 @@ static apr_status_t ssl_io_filter_error(ap_filter_t *f, } APR_BRIGADE_INSERT_TAIL(bb, bucket); - bucket = apr_bucket_eos_create(f->c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, bucket); - + if (send_eos) { + bucket = apr_bucket_eos_create(f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, bucket); + } return APR_SUCCESS; } @@ -1345,6 +1348,13 @@ static apr_status_t ssl_io_filter_input(ap_filter_t *f, } if (!inctx->ssl) { + SSLConnRec *sslconn = myConnConfig(f->c); + if (sslconn->non_ssl_request == NON_SSL_SEND_HDR_SEP) { + apr_bucket *bucket = apr_bucket_immortal_create(CRLF, 2, f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, bucket); + sslconn->non_ssl_request = NON_SSL_SET_ERROR_MSG; + return APR_SUCCESS; + } return ap_get_brigade(f->next, bb, mode, block, readbytes); } diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c index a7bd6e51b36..efe8c5a7526 100644 --- a/modules/ssl/ssl_engine_kernel.c +++ b/modules/ssl/ssl_engine_kernel.c @@ -73,37 +73,16 @@ int ssl_hook_ReadReq(request_rec *r) return DECLINED; } - if (sslconn->non_ssl_request) { - const char *errmsg; - char *thisurl; - char *thisport = ""; - int port = ap_get_server_port(r); - - if (!ap_is_default_port(port, r)) { - thisport = apr_psprintf(r->pool, ":%u", port); - } - - thisurl = ap_escape_html(r->pool, - apr_psprintf(r->pool, "https://%s%s/", - ap_get_server_name(r), - thisport)); - - errmsg = apr_psprintf(r->pool, - "Reason: You're speaking plain HTTP " - "to an SSL-enabled server port.
\n" - "Instead use the HTTPS scheme to access " - "this URL, please.
\n" - "
Hint: " - "%s
", - thisurl, thisurl); - - apr_table_setn(r->notes, "error-notes", errmsg); + if (sslconn->non_ssl_request == NON_SSL_SET_ERROR_MSG) { + apr_table_setn(r->notes, "error-notes", + "Reason: You're speaking plain HTTP to an SSL-enabled " + "server port.
\n Instead use the HTTPS scheme to " + "access this URL, please.
\n"); /* Now that we have caught this error, forget it. we are done * with using SSL on this request. */ - sslconn->non_ssl_request = 0; - + sslconn->non_ssl_request = NON_SSL_OK; return HTTP_BAD_REQUEST; } diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h index e9700aca30f..9c9c7491eca 100644 --- a/modules/ssl/ssl_private.h +++ b/modules/ssl/ssl_private.h @@ -378,7 +378,11 @@ typedef struct { int verify_depth; int is_proxy; int disabled; - int non_ssl_request; + enum { + NON_SSL_OK = 0, /* is SSL request, or error handling completed */ + NON_SSL_SEND_HDR_SEP, /* Need to send the header separator */ + NON_SSL_SET_ERROR_MSG /* Need to set the error message */ + } non_ssl_request; /* Track the handshake/renegotiation state for the connection so * that all client-initiated renegotiations can be rejected, as a -- 2.47.2