>From 36b9bf3fc85feb936bce888499aec3c7f7124352 Mon Sep 17 00:00:00 2001
From: Jonh Wendell <jonh.wendell@gmail.com>
Date: Mon, 20 Apr 2015 10:51:22 -0300
Subject: [PATCH] Fix the error message when accessing a SSL port via HTTP

This is the backported (from 2.4) fix for the upstream bug:
https://bz.apache.org/bugzilla/show_bug.cgi?id=50823
---
 debian/patches/http_on_https_port.patch |  135 +++++++++++++++++++++++++++++++
 debian/patches/series                   |    1 +
 2 files changed, 136 insertions(+)
 create mode 100644 debian/patches/http_on_https_port.patch

diff --git a/debian/patches/http_on_https_port.patch b/debian/patches/http_on_https_port.patch
new file mode 100644
index 0000000..bf583ba
--- /dev/null
+++ b/debian/patches/http_on_https_port.patch
@@ -0,0 +1,135 @@
+Index: apache2-2.2.22/modules/ssl/ssl_engine_io.c
+===================================================================
+--- apache2-2.2.22.orig/modules/ssl/ssl_engine_io.c	2011-02-11 10:30:21.000000000 -0200
++++ apache2-2.2.22/modules/ssl/ssl_engine_io.c	2015-04-20 10:12:20.365864180 -0300
+@@ -853,12 +853,12 @@
+ /* 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 @@
+ {
+     SSLConnRec *sslconn = myConnConfig(f->c);
+     apr_bucket *bucket;
++    int send_eos = 1;
+ 
+     switch (status) {
+       case HTTP_BAD_REQUEST:
+@@ -889,11 +890,12 @@
+                          "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 @@
+     }
+ 
+     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 @@
+     }
+ 
+     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);
+     }
+ 
+Index: apache2-2.2.22/modules/ssl/ssl_engine_kernel.c
+===================================================================
+--- apache2-2.2.22.orig/modules/ssl/ssl_engine_kernel.c	2015-04-20 09:31:46.000000000 -0300
++++ apache2-2.2.22/modules/ssl/ssl_engine_kernel.c	2015-04-20 10:19:46.317870597 -0300
+@@ -73,36 +73,16 @@
+         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.<br />\n"
+-                              "Instead use the HTTPS scheme to access "
+-                              "this URL, please.<br />\n"
+-                              "<blockquote>Hint: "
+-                              "<a href=\"%s\"><b>%s</b></a></blockquote>",
+-                              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.<br />\n Instead use the HTTPS scheme to "
++                       "access this URL, please.<br />\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;
+Index: apache2-2.2.22/modules/ssl/ssl_private.h
+===================================================================
+--- apache2-2.2.22.orig/modules/ssl/ssl_private.h	2015-04-20 09:31:46.000000000 -0300
++++ apache2-2.2.22/modules/ssl/ssl_private.h	2015-04-20 10:10:59.449869970 -0300
+@@ -388,7 +388,11 @@
+     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
diff --git a/debian/patches/series b/debian/patches/series
index 807c605..d663d03 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -48,3 +48,4 @@ CVE-2014-0118_mod_deflate-DoS.patch
 CVE-2013-5704_trailers.patch
 SNI_case_insensitve.diff
 mod_ssl_SSL_CLIENT_S_DN_UID.diff
+http_on_https_port.patch
-- 
1.7.10.4

