#if 0 /* XXX */
-/* _________________________________________________________________
-**
-** I/O Request Body Sucking and Re-Injection
-** _________________________________________________________________
-*/
-
-#ifndef SSL_CONSERVATIVE
-
-/*
- * 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.
- */
-
-struct ssl_io_suck_st {
- BOOL active;
- char *bufptr;
- int buflen;
- char *pendptr;
- int pendlen;
-};
-
-/* prepare request_rec structure for input sucking */
-static void ssl_io_suck_start(request_rec *r)
-{
- struct ssl_io_suck_st *ss;
-
- ss = ap_ctx_get(r->ctx, "ssl::io::suck");
- if (ss == NULL) {
- ss = ap_palloc(r->pool, sizeof(struct ssl_io_suck_st));
- ap_ctx_set(r->ctx, "ssl::io::suck", ss);
- ss->buflen = 8192;
- ss->bufptr = ap_palloc(r->pool, ss->buflen);
- }
- ss->pendptr = ss->bufptr;
- ss->pendlen = 0;
- ss->active = FALSE;
- return;
-}
-
-/* record a sucked input chunk */
-static void ssl_io_suck_record(request_rec *r, char *buf, int len)
-{
- struct ssl_io_suck_st *ss;
-
- if ((ss = ap_ctx_get(r->ctx, "ssl::io::suck")) == NULL)
- return;
- if (((ss->bufptr + ss->buflen) - (ss->pendptr + ss->pendlen)) < len) {
- /* "expand" buffer: actually we cannot really expand the buffer
- here, because Apache's pool system doesn't support expanding chunks
- of memory. Instead we have to either reuse processed data or
- allocate a new chunk of memory in advance if we really need more
- memory. */
- int newlen;
- char *newptr;
-
- if (( (ss->pendptr - ss->bufptr)
- + ((ss->bufptr + ss->buflen) - (ss->pendptr + ss->pendlen)) ) >= len) {
- /* make memory available by reusing already processed data */
- memmove(ss->bufptr, ss->pendptr, ss->pendlen);
- ss->pendptr = ss->bufptr;
- }
- else {
- /* too bad, we have to allocate a new larger buffer */
- newlen = (ss->buflen * 2) + len;
- newptr = ap_palloc(r->pool, newlen);
- ss->bufptr = newptr;
- ss->buflen = newlen;
- memcpy(ss->bufptr, ss->pendptr, ss->pendlen);
- ss->pendptr = ss->bufptr;
- }
- }
- memcpy(ss->pendptr+ss->pendlen, buf, len);
- ss->pendlen += len;
- return;
-}
-
-/* finish request_rec after input sucking */
-static void ssl_io_suck_end(request_rec *r)
-{
- struct ssl_io_suck_st *ss;
-
- if ((ss = ap_ctx_get(r->ctx, "ssl::io::suck")) == NULL)
- return;
- ss->active = TRUE;
- r->read_body = REQUEST_NO_BODY;
- r->read_length = 0;
- r->read_chunked = 0;
- r->remaining = 0;
- ap_bsetflag(r->connection->client, B_CHUNK, 0);
- return;
-}
-
-void ssl_io_suck(request_rec *r, SSL *ssl)
-{
- int rc;
- int len;
- char *buf;
- int buflen;
- char c;
- int sucked;
-
- if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK)) == OK) {
- if (ap_should_client_block(r)) {
-
- /* read client request block through Apache API */
- buflen = HUGE_STRING_LEN;
- buf = ap_palloc(r->pool, buflen);
- ap_hard_timeout("SSL I/O request body pre-sucking", r);
- sucked = 0;
- ssl_io_suck_start(r);
- while ((len = ap_get_client_block(r, buf, buflen)) > 0) {
- ssl_io_suck_record(r, buf, len);
- sucked += len;
- }
- ssl_io_suck_end(r);
- ap_kill_timeout(r);
-
- /* suck trailing data (usually CR LF) which
- is still in the Apache BUFF layer */
- while (ap_bpeekc(r->connection->client) != EOF) {
- c = ap_bgetc(r->connection->client);
- ssl_io_suck_record(r, &c, 1);
- sucked++;
- }
-
- ssl_log(r->server, SSL_LOG_TRACE,
- "I/O: sucked %d bytes of input data from SSL/TLS I/O layer "
- "for delayed injection into Apache I/O layer", sucked);
- }
- }
- return;
-}
-
-/* the SSL_read replacement routine which knows about the suck buffer */
-static int ssl_io_suck_read(SSL *ssl, char *buf, int len)
-{
- ap_ctx *actx;
- struct ssl_io_suck_st *ss;
- request_rec *r = NULL;
- int rv;
-
- actx = (ap_ctx *)SSL_get_app_data2(ssl);
- if (actx != NULL)
- r = (request_rec *)ap_ctx_get(actx, "ssl::request_rec");
-
- rv = -1;
- if (r != NULL) {
- ss = ap_ctx_get(r->ctx, "ssl::io::suck");
- if (ss != NULL) {
- if (ss->active && ss->pendlen > 0) {
- /* ok, there is pre-sucked data */
- len = (ss->pendlen > len ? len : ss->pendlen);
- memcpy(buf, ss->pendptr, len);
- ss->pendptr += len;
- ss->pendlen -= len;
- ssl_log(r->server, SSL_LOG_TRACE,
- "I/O: injecting %d bytes of pre-sucked data "
- "into Apache I/O layer", len);
- rv = len;
- }
- }
- }
- if (rv == -1)
- rv = SSL_read(ssl, buf, len);
- return rv;
-}
-
-/* override SSL_read in the following code... */
-#define SSL_read ssl_io_suck_read
-
-#endif /* !SSL_CONSERVATIVE */
-
/* _________________________________________________________________
**
** I/O Hooks
}
#endif /* SSL_EXPERIMENTAL_PERDIRCA */
-#ifdef SSL_CONSERVATIVE
/*
- * SSL renegotiations in conjunction with HTTP
- * requests using the POST method are not supported.
+ * 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 && r->method_number == M_POST) {
ssl_log(r->server, SSL_LOG_ERROR,
"SSL Re-negotiation in conjunction with POST method not supported!");
- ssl_log(r->server, SSL_LOG_INFO,
- "You have to compile without -DSSL_CONSERVATIVE to enabled support for this.");
return METHOD_NOT_ALLOWED;
}
-#endif /* SSL_CONSERVATIVE */
/*
* now do the renegotiation if anything was actually reconfigured
SSL_set_session_id_context(ssl, (unsigned char *)&(r->main), sizeof(r->main));
else
SSL_set_session_id_context(ssl, (unsigned char *)&r, sizeof(r));
-#ifndef SSL_CONSERVATIVE
- ssl_io_suck(r, ssl);
-#endif
SSL_renegotiate(ssl);
SSL_do_handshake(ssl);
if (SSL_get_state(ssl) != SSL_ST_OK) {