Commit b67aec5e authored by Rainer Jung's avatar Rainer Jung
Browse files

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
parent d9b0ea8e
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
                                                         -*- 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]

+0 −12
Original line number Diff line number Diff line
@@ -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 ]

+18 −8
Original line number Diff line number Diff line
@@ -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);
    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);
    }

+6 −27
Original line number Diff line number Diff line
@@ -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.<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;
    }
+5 −1
Original line number Diff line number Diff line
@@ -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