summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '2.0/patches/08_all_mod_ssl-ssl-client-cert-post.patch')
-rw-r--r--2.0/patches/08_all_mod_ssl-ssl-client-cert-post.patch332
1 files changed, 0 insertions, 332 deletions
diff --git a/2.0/patches/08_all_mod_ssl-ssl-client-cert-post.patch b/2.0/patches/08_all_mod_ssl-ssl-client-cert-post.patch
deleted file mode 100644
index 8833481..0000000
--- a/2.0/patches/08_all_mod_ssl-ssl-client-cert-post.patch
+++ /dev/null
@@ -1,332 +0,0 @@
----
- modules/ssl/mod_ssl.h | 4
- modules/ssl/ssl_engine_io.c | 185 ++++++++++++++++++++++++++++++++++++++++
- modules/ssl/ssl_engine_kernel.c | 96 ++++++--------------
- 3 files changed, 218 insertions(+), 67 deletions(-)
-
---- a/modules/ssl/mod_ssl.h
-+++ b/modules/ssl/mod_ssl.h
-@@ -682,6 +682,10 @@ void ssl_io_filter_init(conn_rec
- void ssl_io_filter_register(apr_pool_t *);
- long ssl_io_data_cb(BIO *, int, MODSSL_BIO_CB_ARG_TYPE *, int, long, long);
-
-+/* ssl_io_buffer_fill fills the setaside buffering of the HTTP request
-+ * to allow an SSL renegotiation to take place. */
-+int ssl_io_buffer_fill(request_rec *r);
-+
- /* PRNG */
- int ssl_rand_seed(server_rec *, apr_pool_t *, ssl_rsctx_t, char *);
-
---- a/modules/ssl/ssl_engine_io.c
-+++ b/modules/ssl/ssl_engine_io.c
-@@ -880,6 +880,7 @@ static apr_status_t ssl_io_filter_error(
- }
-
- static const char ssl_io_filter[] = "SSL/TLS Filter";
-+static const char ssl_io_buffer[] = "SSL/TLS Buffer";
-
- /*
- * Close the SSL part of the socket connection
-@@ -1373,6 +1374,187 @@ static apr_status_t ssl_io_filter_output
- return status;
- }
-
-+/* 128K maximum buffer size by default. */
-+#ifndef SSL_MAX_IO_BUFFER
-+#define SSL_MAX_IO_BUFFER (128 * 1024)
-+#endif
-+
-+struct modssl_buffer_ctx {
-+ apr_bucket_brigade *bb;
-+ apr_pool_t *pool;
-+};
-+
-+int ssl_io_buffer_fill(request_rec *r)
-+{
-+ conn_rec *c = r->connection;
-+ struct modssl_buffer_ctx *ctx;
-+ apr_bucket_brigade *tempb;
-+ apr_off_t total = 0; /* total length buffered */
-+ int eos = 0; /* non-zero once EOS is seen */
-+
-+ /* Create the context which will be passed to the input filter;
-+ * containing a setaside pool and a brigade which constrain the
-+ * lifetime of the buffered data. */
-+ ctx = apr_palloc(r->pool, sizeof *ctx);
-+ apr_pool_create(&ctx->pool, r->pool);
-+ ctx->bb = apr_brigade_create(ctx->pool, c->bucket_alloc);
-+
-+ /* ... and a temporary brigade. */
-+ tempb = apr_brigade_create(r->pool, c->bucket_alloc);
-+
-+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "filling buffer");
-+
-+ do {
-+ apr_status_t rv;
-+ apr_bucket *e, *next;
-+
-+ /* The request body is read from the protocol-level input
-+ * filters; the buffering filter will reinject it from that
-+ * level, allowing content/resource filters to run later, if
-+ * necessary. */
-+
-+ rv = ap_get_brigade(r->proto_input_filters, tempb, AP_MODE_READBYTES,
-+ APR_BLOCK_READ, 8192);
-+ if (rv) {
-+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
-+ "could not read request body for SSL buffer");
-+ return HTTP_INTERNAL_SERVER_ERROR;
-+ }
-+
-+ /* Iterate through the returned brigade: setaside each bucket
-+ * into the context's pool and move it into the brigade. */
-+ for (e = APR_BRIGADE_FIRST(tempb);
-+ e != APR_BRIGADE_SENTINEL(tempb) && !eos; e = next) {
-+ const char *data;
-+ apr_size_t len;
-+
-+ next = APR_BUCKET_NEXT(e);
-+
-+ if (APR_BUCKET_IS_EOS(e)) {
-+ eos = 1;
-+ } else if (!APR_BUCKET_IS_METADATA(e)) {
-+ rv = apr_bucket_read(e, &data, &len, APR_BLOCK_READ);
-+ if (rv != APR_SUCCESS) {
-+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
-+ "could not read bucket for SSL buffer");
-+ return HTTP_INTERNAL_SERVER_ERROR;
-+ }
-+ total += len;
-+ }
-+
-+ rv = apr_bucket_setaside(e, ctx->pool);
-+ if (rv != APR_SUCCESS) {
-+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
-+ "could not setaside bucket for SSL buffer");
-+ return HTTP_INTERNAL_SERVER_ERROR;
-+ }
-+
-+ APR_BUCKET_REMOVE(e);
-+ APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
-+ }
-+
-+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
-+ "total of %" APR_OFF_T_FMT " bytes in buffer, eos=%d",
-+ total, eos);
-+
-+ /* Fail if this exceeds the maximum buffer size. */
-+ if (total > SSL_MAX_IO_BUFFER) {
-+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
-+ "request body exceeds maximum size for SSL buffer");
-+ return HTTP_REQUEST_ENTITY_TOO_LARGE;
-+ }
-+
-+ } while (!eos);
-+
-+ apr_brigade_destroy(tempb);
-+
-+ /* Insert the filter which will supply the buffered data. */
-+ ap_add_input_filter(ssl_io_buffer, ctx, r, c);
-+
-+ return 0;
-+}
-+
-+/* This input filter supplies the buffered request body to the caller
-+ * from the brigade stored in f->ctx. */
-+static apr_status_t ssl_io_filter_buffer(ap_filter_t *f,
-+ apr_bucket_brigade *bb,
-+ ap_input_mode_t mode,
-+ apr_read_type_e block,
-+ apr_off_t bytes)
-+{
-+ struct modssl_buffer_ctx *ctx = f->ctx;
-+ apr_status_t rv;
-+
-+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, f->r,
-+ "read from buffered SSL brigade, mode %d, "
-+ "%" APR_OFF_T_FMT " bytes",
-+ mode, bytes);
-+
-+ if (mode != AP_MODE_READBYTES && mode != AP_MODE_GETLINE) {
-+ return APR_ENOTIMPL;
-+ }
-+
-+ if (mode == AP_MODE_READBYTES) {
-+ apr_bucket *e;
-+
-+ /* Partition the buffered brigade. */
-+ rv = apr_brigade_partition(ctx->bb, bytes, &e);
-+ if (rv && rv != APR_INCOMPLETE) {
-+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r,
-+ "could not partition buffered SSL brigade");
-+ ap_remove_input_filter(f);
-+ return rv;
-+ }
-+
-+ /* If the buffered brigade contains less then the requested
-+ * length, just pass it all back. */
-+ if (rv == APR_INCOMPLETE) {
-+ APR_BRIGADE_CONCAT(bb, ctx->bb);
-+ } else {
-+ apr_bucket *d = APR_BRIGADE_FIRST(ctx->bb);
-+
-+ e = APR_BUCKET_PREV(e);
-+
-+ /* Unsplice the partitioned segment and move it into the
-+ * passed-in brigade; no convenient way to do this with
-+ * the APR_BRIGADE_* macros. */
-+ APR_RING_UNSPLICE(d, e, link);
-+ APR_RING_SPLICE_HEAD(&bb->list, d, e, apr_bucket, link);
-+
-+ APR_BRIGADE_CHECK_CONSISTENCY(bb);
-+ APR_BRIGADE_CHECK_CONSISTENCY(ctx->bb);
-+ }
-+ }
-+ else {
-+ /* Split a line into the passed-in brigade. */
-+ rv = apr_brigade_split_line(bb, ctx->bb, mode, bytes);
-+
-+ if (rv) {
-+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r,
-+ "could not split line from buffered SSL brigade");
-+ ap_remove_input_filter(f);
-+ return rv;
-+ }
-+ }
-+
-+ if (APR_BRIGADE_EMPTY(ctx->bb)) {
-+ apr_bucket *e = APR_BRIGADE_LAST(bb);
-+
-+ /* Ensure that the brigade is terminated by an EOS if the
-+ * buffered request body has been entirely consumed. */
-+ if (e == APR_BRIGADE_SENTINEL(bb) || !APR_BUCKET_IS_EOS(e)) {
-+ e = apr_bucket_eos_create(f->c->bucket_alloc);
-+ APR_BRIGADE_INSERT_TAIL(bb, e);
-+ }
-+
-+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, f->r,
-+ "buffered SSL brigade now exhausted; removing filter");
-+ ap_remove_input_filter(f);
-+ }
-+
-+ return APR_SUCCESS;
-+}
-+
- static void ssl_io_input_add_filter(ssl_filter_ctx_t *filter_ctx, conn_rec *c,
- SSL *ssl)
- {
-@@ -1430,6 +1612,9 @@ void ssl_io_filter_register(apr_pool_t *
- {
- ap_register_input_filter (ssl_io_filter, ssl_io_filter_input, NULL, AP_FTYPE_CONNECTION + 5);
- ap_register_output_filter (ssl_io_filter, ssl_io_filter_output, NULL, AP_FTYPE_CONNECTION + 5);
-+
-+ ap_register_input_filter (ssl_io_buffer, ssl_io_filter_buffer, NULL, AP_FTYPE_PROTOCOL - 1);
-+
- return;
- }
-
---- a/modules/ssl/ssl_engine_kernel.c
-+++ b/modules/ssl/ssl_engine_kernel.c
-@@ -483,73 +483,35 @@ int ssl_hook_Access(request_rec *r)
- }
- #endif /* HAVE_SSL_SET_CERT_STORE */
-
-- /*
-- * 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.
-- *
-- * !! BUT ALL THIS IS STILL NOT RE-IMPLEMENTED FOR APACHE 2.0 !!
-- */
-- 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 SSLOptions +OptRenegotiate");
--
-- return HTTP_METHOD_NOT_ALLOWED;
-+ /* 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.
-+ *
-+ * 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
-+ && (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;
-+
-+ /* Fill the I/O buffer with the request body if possible. */
-+ rv = ssl_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;
-+ }
- }
-
- /*