summaryrefslogtreecommitdiffstats
path: root/nss_engine_kernel.c
diff options
context:
space:
mode:
authorrcritten <>2006-08-09 20:11:45 +0000
committerrcritten <>2006-08-09 20:11:45 +0000
commita2c56687f17bdefe258c63b17264d80be2cbd44c (patch)
tree21a4cc83b8f4aeae50778f598faea587d585e91c /nss_engine_kernel.c
parentecf3a7e8c544b351ed3923ff01806759e7abbb75 (diff)
downloadmod_nss-a2c56687f17bdefe258c63b17264d80be2cbd44c.tar.gz
mod_nss-a2c56687f17bdefe258c63b17264d80be2cbd44c.tar.xz
mod_nss-a2c56687f17bdefe258c63b17264d80be2cbd44c.zip
Merge in changes from http://svn.apache.org/viewvc?view=rev&revision=290965
Implement a (bounded) buffer of request body data to provide a limited but safe fix for the mod_nss renegotiation-vs-requests-with-bodies bug: * mod_nss.h (nss_io_buffer_fill): Add prototype. * nss_engine_io.c (nss_io_buffer_fill, nss_io_filter_buffer): New functions. * nss_engine_kernel.c (nss_hook_Access): If a renegotiation is needed, and the request has a non-zero content-length, or a t-e header (and 100-continue was not requested), call nss_io_buffer_fill to set aside the request body data if possible, then proceed with the negotiation. PR: 12355
Diffstat (limited to 'nss_engine_kernel.c')
-rw-r--r--nss_engine_kernel.c90
1 files changed, 26 insertions, 64 deletions
diff --git a/nss_engine_kernel.c b/nss_engine_kernel.c
index baa8c49..6a73007 100644
--- a/nss_engine_kernel.c
+++ b/nss_engine_kernel.c
@@ -312,73 +312,35 @@ int nss_hook_Access(request_rec *r)
}
}
- /*
- * SSL renegotiations in conjunction with HTTP
- * requests using the POST method are not supported.
- *
- * Background:
- *
- * 1. When the client sends a HTTP/HTTPS request, Apache's core code
- * reads only the request line ("METHOD /path HTTP/x.y") and the
- * attached MIME headers ("Foo: bar") up to the terminating line ("CR
- * LF"). An attached request body (for instance the data of a POST
- * method) is _NOT_ read. Instead it is read by mod_cgi's content
- * handler and directly passed to the CGI script.
- *
- * 2. mod_ssl supports per-directory re-configuration of SSL parameters.
- * This is implemented by performing an SSL renegotiation of the
- * re-configured parameters after the request is read, but before the
- * response is sent. In more detail: the renegotiation happens after the
- * request line and MIME headers were read, but _before_ the attached
- * request body is read. The reason simply is that in the HTTP protocol
- * usually there is no acknowledgment step between the headers and the
- * body (there is the 100-continue feature and the chunking facility
- * only), so Apache has no API hook for this step.
- *
- * 3. the problem now occurs when the client sends a POST request for
- * URL /foo via HTTPS the server and the server has SSL parameters
- * re-configured on a per-URL basis for /foo. Then mod_ssl has to
- * perform an SSL renegotiation after the request was read and before
- * the response is sent. But the problem is the pending POST body data
- * in the receive buffer of SSL (which Apache still has not read - it's
- * pending until mod_cgi sucks it in). When mod_ssl now tries to perform
- * the renegotiation the pending data leads to an I/O error.
- *
- * Solution Idea:
- *
- * There are only two solutions: Either to simply state that POST
- * requests to URLs with SSL re-configurations are not allowed, or to
- * renegotiate really after the _complete_ request (i.e. including
- * the POST body) was read. Obviously the latter would be preferred,
- * but it cannot be done easily inside Apache, because as already
- * mentioned, there is no API step between the body reading and the body
- * processing. And even when we mod_ssl would hook directly into the
- * loop of mod_cgi, we wouldn't solve the problem for other handlers, of
- * course. So the only general solution is to suck in the pending data
- * of the request body from the OpenSSL BIO into the Apache BUFF. Then
- * the renegotiation can be done and after this step Apache can proceed
- * processing the request as before.
- *
- * Solution Implementation:
- *
- * We cannot simply suck in the data via an SSL_read-based loop because of
- * HTTP chunking. Instead we _have_ to use the Apache API for this step which
- * is aware of HTTP chunking. So the trick is to suck in the pending request
- * data via the Apache API (which uses Apache's BUFF code and in the
- * background mod_ssl's I/O glue code) and re-inject it later into the Apache
- * BUFF code again. This way the data flows twice through the Apache BUFF, of
- * course. But this way the solution doesn't depend on any Apache specifics
- * and is fully transparent to Apache modules.
+ /* If a renegotiation is now required for this location, and the
+ * request includes a message body (and the client has not
+ * requested a "100 Continue" response), then the client will be
+ * streaming the request body over the wire already. In that
+ * case, it is not possible to stop and perform a new SSL
+ * handshake immediately; once the SSL library moves to the
+ * "accept" state, it will reject the SSL packets which the client
+ * is sending for the request body.
*
- * !! BUT ALL THIS IS STILL NOT RE-IMPLEMENTED FOR APACHE 2.0 !!
+ * To allow authentication to complete in this auth hook, the
+ * solution used here is to fill a (bounded) buffer with the
+ * request body, and then to reinject that request body later.
*/
- if (renegotiate && !renegotiate_quick && (r->method_number == M_POST)) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
- "SSL Re-negotiation in conjunction "
- "with POST method not supported!"
- "hint: try NSSOptions +OptRenegotiate");
+ if (renegotiate && !renegotiate_quick
+ && (apr_table_get(r->headers_in, "transfer-encoding")
+ || (apr_table_get(r->headers_in, "content-length")
+ && strcmp(apr_table_get(r->headers_in, "content-length"), "0")))
+ && !r->expecting_100) {
+ int rv;
- return HTTP_METHOD_NOT_ALLOWED;
+ /* Fill the I/O buffer with the request body if possible. */
+ rv = nss_io_buffer_fill(r);
+
+ if (rv) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ "could not buffer message body to allow "
+ "SSL renegotiation to proceed");
+ return rv;
+ }
}
/*