From: Stefan Fritsch Date: Sat, 5 May 2012 08:44:19 +0000 (+0000) Subject: Merge r1328325, r1328326: X-Git-Tag: 2.4.3~475 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c176f92e001fe480bf4db341e98f0b2c635684aa;p=apache Merge r1328325, r1328326: 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 Reviewed by: sf, jorton, trawick git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1334346 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 00c98e519a..5b5bca6501 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,10 @@ Changes with Apache 2.4.3 + *) 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] + *) core: Fix segfault in logging if r->useragent_addr or c->client_addr is unset. [Stefan Fritsch] diff --git a/STATUS b/STATUS index d37c5a35c8..6dbcc7e854 100644 --- a/STATUS +++ b/STATUS @@ -88,12 +88,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - * mod_ssl: Send speaking-http-on-https-port error response with http 1.0, - not 0.9. Remove potentially wrong link. PR 50823 - trunk patches: http://svn.apache.org/viewvc?rev=1328325&view=rev - http://svn.apache.org/viewvc?rev=1328326&view=rev - 2.4 patch: Trunk patch works - +1: sf, jorton, trawick 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 2ffe21f419..510e16060d 100644 --- a/modules/ssl/ssl_engine_io.c +++ b/modules/ssl/ssl_engine_io.c @@ -813,12 +813,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, \ @@ -848,6 +848,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 MODSSL_ERROR_HTTP_ON_HTTPS: @@ -857,11 +858,12 @@ static apr_status_t ssl_io_filter_error(ap_filter_t *f, "trying to send HTML error page"); ssl_log_ssl_error(SSLLOG_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; case MODSSL_ERROR_BAD_GATEWAY: @@ -877,9 +879,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; } @@ -1282,6 +1285,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 35b2a854a9..e514a74bdf 100644 --- a/modules/ssl/ssl_engine_kernel.c +++ b/modules/ssl/ssl_engine_kernel.c @@ -140,37 +140,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_for_url(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 1b5d0428ce..f393ecfad4 100644 --- a/modules/ssl/ssl_private.h +++ b/modules/ssl/ssl_private.h @@ -454,7 +454,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