summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRyan Bloom <rbb@apache.org>2001-08-27 08:00:51 +0200
committerRyan Bloom <rbb@apache.org>2001-08-27 08:00:51 +0200
commitbfe91354fbac913aef8d8121bbc8d5065f9aadc4 (patch)
tree60eeddff75b9f297b9e5b2709792a21b066a8528
parent Regroup some of the headers in the win32 module, to make the distinction (diff)
downloadapache2-bfe91354fbac913aef8d8121bbc8d5065f9aadc4.tar.xz
apache2-bfe91354fbac913aef8d8121bbc8d5065f9aadc4.zip
Allow mod_ssl to send back an error message if an HTTP request is sent
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
-rw-r--r--CHANGES3
-rw-r--r--include/util_filter.h8
-rw-r--r--modules/ssl/mod_ssl.c53
-rw-r--r--modules/ssl/ssl_engine_io.c3
-rw-r--r--server/util_filter.c31
5 files changed, 62 insertions, 36 deletions
diff --git a/CHANGES b/CHANGES
index 55f29a7d2b..428d74ece5 100644
--- 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
diff --git a/include/util_filter.h b/include/util_filter.h
index 54c2a67e3b..7ba39b4915 100644
--- a/include/util_filter.h
+++ b/include/util_filter.h
@@ -351,6 +351,14 @@ 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.
* @param f The filter to remove
diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c
index 033c5af35a..470127ab94 100644
--- a/modules/ssl/mod_ssl.c
+++ b/modules/ssl/mod_ssl.c
@@ -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();
}
diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c
index 79dc55e8a5..564e9a783b 100644
--- a/modules/ssl/ssl_engine_io.c
+++ b/modules/ssl/ssl_engine_io.c
@@ -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;
}
diff --git a/server/util_filter.c b/server/util_filter.c
index b8e6dfa0e9..1281686abc 100644
--- a/server/util_filter.c
+++ b/server/util_filter.c
@@ -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);
}
/*