httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From r..@apache.org
Subject cvs commit: httpd-2.0/modules/ssl README mod_ssl.h ssl_engine_io.c ssl_engine_kernel.c
Date Sat, 05 May 2001 16:23:02 GMT
rse         01/05/05 09:23:01

  Modified:    modules/ssl README mod_ssl.h ssl_engine_io.c
                        ssl_engine_kernel.c
  Log:
  Axe out SSL_CONSERVATIVE stuff which for Apache 1.3 did I/O data
  pre-sucking on POST requests and I/O re-injection in case of SSL
  renegotiations. This all either cannot be solved any longer or at least
  has to be implemented totally different through I/O layering/filtering.
  
  Revision  Changes    Path
  1.10      +3 -0      httpd-2.0/modules/ssl/README
  
  Index: README
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/ssl/README,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- README	2001/05/05 16:02:33	1.9
  +++ README	2001/05/05 16:22:59	1.10
  @@ -145,6 +145,9 @@
    o The complete EAPI-based SSL_VENDOR stuff was removed.
    o The complete EAPI-based SSL_COMPAT stuff was removed.
    o The <IfDefine> variable MOD_SSL is no longer provided automatically 
  + o The complete SSL_CONSERVATIVE stuff was removed, i.e.,
  +   SSL renegotiations in combination with POST request are not supported
  +   unless the problem is solved again, but this time through layered I/O.
   
    MAJOR CHANGES 
   
  
  
  
  1.8       +0 -3      httpd-2.0/modules/ssl/mod_ssl.h
  
  Index: mod_ssl.h
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/ssl/mod_ssl.h,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- mod_ssl.h	2001/05/05 15:26:06	1.7
  +++ mod_ssl.h	2001/05/05 16:22:59	1.8
  @@ -778,9 +778,6 @@
   void         ssl_io_register(void);
   void         ssl_io_unregister(void);
   long         ssl_io_data_cb(BIO *, int, const char *, int, long, long);
  -#ifndef SSL_CONSERVATIVE
  -void         ssl_io_suck(request_rec *, SSL *);
  -#endif
   
   /*  PRNG  */
   int          ssl_rand_seed(server_rec *, pool *, ssl_rsctx_t, char *);
  
  
  
  1.4       +0 -223    httpd-2.0/modules/ssl/ssl_engine_io.c
  
  Index: ssl_engine_io.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/ssl/ssl_engine_io.c,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ssl_engine_io.c	2001/05/05 10:12:03	1.3
  +++ ssl_engine_io.c	2001/05/05 16:23:00	1.4
  @@ -66,229 +66,6 @@
   
   /*  _________________________________________________________________
   **
  -**  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
   **  _________________________________________________________________
   */
  
  
  
  1.6       +58 -9     httpd-2.0/modules/ssl/ssl_engine_kernel.c
  
  Index: ssl_engine_kernel.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/ssl/ssl_engine_kernel.c,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- ssl_engine_kernel.c	2001/05/05 15:10:58	1.5
  +++ ssl_engine_kernel.c	2001/05/05 16:23:00	1.6
  @@ -857,19 +857,71 @@
       }
   #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
  @@ -922,9 +974,6 @@
                   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) {
  
  
  

Mime
View raw message