]> granicus.if.org Git - apache/commitdiff
Allow mod_ssl to send back an error message if an HTTP request is sent
authorRyan Bloom <rbb@apache.org>
Mon, 27 Aug 2001 06:00:51 +0000 (06:00 +0000)
committerRyan Bloom <rbb@apache.org>
Mon, 27 Aug 2001 06:00:51 +0000 (06:00 +0000)
over an HTTPS connection.  This also adds an ap_remove_input_filter
function, which should be used to remove the SSL input filter in this
case, as soon as this code is stressed a bit more.

For right now, we are sending the same message that we used to send in
mod_ssl for Apache 1.3.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@90724 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
include/util_filter.h
modules/ssl/mod_ssl.c
modules/ssl/ssl_engine_io.c
server/util_filter.c

diff --git a/CHANGES b/CHANGES
index 55f29a7d2becb88ee05507aa874250d13a6269d3..428d74ece59097c3d13f54d172c3ceca68f1f22c 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,8 @@
 Changes with Apache 2.0.25-dev
 
+  *) Add a function ap_remove_input_filter.  This is to match
+     up with ap_remove_output_filter.  [Ryan Bloom]
+
   *) Clean up location_walk, so that this step performs a minimum
      amount of redundant effort (it must be run twice, but it will no
      longer reparse all <Location > blocks when the request uri
index 54c2a67e3b570d6294f2f355dd881558aa6188e3..7ba39b49153bfe1e73b06ddf085afe4080c9aaba 100644 (file)
@@ -350,6 +350,14 @@ AP_DECLARE(ap_filter_t *) ap_add_input_filter(const char *name, void *ctx,
 AP_DECLARE(ap_filter_t *) ap_add_output_filter(const char *name, void *ctx, 
                                               request_rec *r, conn_rec *c);
 
+/**
+ * Remove an input filter from either the request or connection stack
+ * it is associated with.
+ * @param f The filter to remove
+ */
+
+AP_DECLARE(void) ap_remove_input_filter(ap_filter_t *f);
+
 /**
  * Remove an output filter from either the request or connection stack
  * it is associated with.
index 033c5af35a0365db5f87e78d99cb8c76748d4412..470127ab94de442c8ffc3cee39e8132806fd3b49 100644 (file)
@@ -73,6 +73,8 @@
         AP_INIT_##args("SSL"#name, ssl_cmd_SSL##name, NULL, OR_##type, desc),
 #define AP_END_CMD { NULL }
 
+#define HTTP_ON_HTTPS_PORT "GET /mod_ssl:error:HTTP-request HTTP/1.0\r\n"
+
 static const command_rec ssl_config_cmds[] = {
 
     /*
@@ -375,35 +377,35 @@ int ssl_hook_process_connection(SSLFilterRec *pRec)
                  * Apache processing.
                  *
                  */
-
-#if 0 /* XXX */
-                /*
-                 * Still need to be ported to Apache 2.0 style
-                 */
-                char ca[2];
-                int rv;
-
+                apr_bucket *e;
+                const char *str;
+                apr_size_t len;
                 /* log the situation */
                 ssl_log(c->base_server, SSL_LOG_ERROR|SSL_ADD_SSLERR,
                         "SSL handshake failed: HTTP spoken on HTTPS port; "
                         "trying to send HTML error page");
-                /* first: skip the remaining bytes of the request line */
-                do {
-                    do {
-                        rv = read(fb->fd, ca, 1);
-                    } while (rv == -1 && errno == EINTR);
-                } while (rv > 0 && ca[0] != '\012' /*LF*/);
-
-                /* second: fake the request line */
-                fb->inbase = ap_palloc(fb->pool, fb->bufsiz);
-                ap_cpystrn((char *)fb->inbase, "GET /mod_ssl:error:HTTP-request HTTP/1.0\r\n",
-                           fb->bufsiz);
-                fb->inptr = fb->inbase;
-                fb->incnt = strlen((char *)fb->inptr);
-#else
-                ssl_log(c->base_server, SSL_LOG_ERROR|SSL_ADD_SSLERR,
-                        "SSL handshake failed: HTTP spoken on HTTPS port");
-#endif
+
+                /* fake the request line */
+                e = apr_bucket_immortal_create(HTTP_ON_HTTPS_PORT, 
+                                               strlen(HTTP_ON_HTTPS_PORT));
+                APR_BRIGADE_INSERT_HEAD(pRec->pbbPendingInput, e);
+
+                APR_BRIGADE_FOREACH(e, pRec->pbbInput) {
+                    apr_bucket_read(e, &str, &len, APR_BLOCK_READ);
+                    if (len) {
+                        APR_BUCKET_REMOVE(e);
+                        APR_BRIGADE_INSERT_TAIL(pRec->pbbPendingInput, e);
+                        if ((strcmp(str, "\r\n") == 0) ||
+                            (ap_strstr_c(str, "\r\n\r\n"))) {
+                            break;
+                        }
+                    }
+                }
+                e = APR_BRIGADE_LAST(pRec->pbbInput);
+                APR_BUCKET_REMOVE(e);
+
+                ap_remove_output_filter(pRec->pOutputFilter);
+                return HTTP_BAD_REQUEST;
             }
             else if (ssl_util_getmodconfig_ssl(pRec->pssl, "ssl::handshake::timeout")
                == (void *)TRUE) {
@@ -536,6 +538,7 @@ static void ssl_register_hooks(apr_pool_t *p)
     ap_hook_fixups        (ssl_hook_Fixup,         NULL,NULL, APR_HOOK_MIDDLE);
     ap_hook_access_checker(ssl_hook_Access,        NULL,NULL, APR_HOOK_MIDDLE);
     ap_hook_auth_checker  (ssl_hook_Auth,          NULL,NULL, APR_HOOK_MIDDLE);
+    ap_hook_post_read_request(ssl_hook_ReadReq,    NULL,NULL, APR_HOOK_MIDDLE);
 
     ssl_var_register();
 }
index 79dc55e8a50da397f6a7d6622683114d83a50829..564e9a783ba33ced46d0e9a8a2762a49b3715e17 100644 (file)
@@ -283,6 +283,9 @@ static apr_status_t churn(SSLFilterRec *pRec,
             /* if this is the case, ssl connection has been shutdown
              * and pRec->pssl has been freed
              */
+            if (ret == HTTP_BAD_REQUEST) {
+                return APR_SUCCESS;
+            }
             return ret;
         }
 
index b8e6dfa0e96750af9d8b08c3bbab1542bc476553..1281686abc1fe4f56b7964933f5b8c6eb95525ab 100644 (file)
@@ -176,13 +176,12 @@ AP_DECLARE(ap_filter_t *) ap_add_output_filter(const char *name, void *ctx,
                          r ? &r->output_filters : NULL, &c->output_filters);
 }
 
-AP_DECLARE(void) ap_remove_output_filter(ap_filter_t *f)
+static void remove_any_filter(ap_filter_t *f, ap_filter_t **r_filt, 
+                                   ap_filter_t **c_filt)
 {
-    ap_filter_t *curr;
-
-    curr = f->r ? f->r->output_filters : f->c->output_filters;
+    ap_filter_t **curr = r_filt ? r_filt : c_filt;
 
-    if (curr == f) {
+    if ((*curr) == f) {
         if (f->r) {
             f->r->output_filters = f->r->output_filters->next;
         }
@@ -192,13 +191,23 @@ AP_DECLARE(void) ap_remove_output_filter(ap_filter_t *f)
         return;
     }
 
-    while (curr->next != f) {
-        curr = curr->next;
-        if (curr == NULL) {
-            return;
-        }
+    while ((*curr) && (*curr)->next != f) {
+        (*curr) = (*curr)->next;
     }
-    curr->next = f->next;
+    if ((*curr) == NULL) {
+        return;
+    }
+    (*curr)->next = f->next;
+}
+
+AP_DECLARE(void) ap_remove_input_filter(ap_filter_t *f)
+{
+    return remove_any_filter(f, f->r ? &f->r->input_filters : NULL, &f->c->input_filters);
+}
+
+AP_DECLARE(void) ap_remove_output_filter(ap_filter_t *f)
+{
+    return remove_any_filter(f, f->r ? &f->r->output_filters : NULL, &f->c->output_filters);
 }
 
 /*