httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From do...@apache.org
Subject cvs commit: httpd-2.0/modules/ssl mod_ssl.c ssl_engine_io.c ssl_engine_kernel.c
Date Thu, 16 Aug 2001 03:58:16 GMT
dougm       01/08/15 20:58:16

  Modified:    modules/http http_protocol.c
               modules/ssl mod_ssl.c ssl_engine_io.c ssl_engine_kernel.c
  Log:
  enable ssl Translate, UserCheck, Access and Auth hooks
  
  add support for renegotiation during the Access hook
  this requires hooking into the read and write SSL BIOs in order to
  flush data to the client and read from the filter chain
  
  this also requires that the ssl filters become "aware" that
  renegotitation is in progress so that the BIOs are left alone for
  SSL_renegotiate/SSL_do_handshake in ssl_hook_Access to deal with
  
  Revision  Changes    Path
  1.354     +3 -1      httpd-2.0/modules/http/http_protocol.c
  
  Index: http_protocol.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/http/http_protocol.c,v
  retrieving revision 1.353
  retrieving revision 1.354
  diff -u -r1.353 -r1.354
  --- http_protocol.c	2001/08/11 04:04:13	1.353
  +++ http_protocol.c	2001/08/16 03:58:16	1.354
  @@ -690,7 +690,9 @@
               ctx->b = apr_brigade_split(b, e);
           }
           else {
  -            ctx->b = NULL;
  +            if (!APR_BRIGADE_EMPTY(ctx->b)) {
  +                ctx->b = NULL; /*XXX*/
  +            }
           }
           apr_brigade_length(b, 1, &total);
           *readbytes -= total;
  
  
  
  1.13      +2 -3      httpd-2.0/modules/ssl/mod_ssl.c
  
  Index: mod_ssl.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/ssl/mod_ssl.c,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- mod_ssl.c	2001/07/31 03:40:47	1.12
  +++ mod_ssl.c	2001/08/16 03:58:16	1.13
  @@ -488,20 +488,19 @@
       ap_hook_default_port  (ssl_hook_default_port,  NULL,NULL, APR_HOOK_MIDDLE);
       ap_hook_handler       (ssl_hook_Handler,       NULL,NULL, APR_HOOK_MIDDLE);
       ap_hook_pre_config    (ssl_hook_pre_config,    NULL,NULL, APR_HOOK_MIDDLE);
  -    ap_hook_fixups        (ssl_hook_Fixup,         NULL,NULL, APR_HOOK_MIDDLE);
  -
   #if 0 /* XXX - Work in progress */
       ap_hook_child_init    (ssl_init_Child,         NULL,NULL, APR_HOOK_MIDDLE);
       ap_hook_process_connection (ssl_hook_process_connection, 
                                                      NULL,NULL, APR_HOOK_MIDDLE);
       ap_hook_post_read_request  (ssl_hook_post_read_request, 
                                                      NULL,NULL, APR_HOOK_MIDDLE);
  +#endif
       ap_hook_translate_name(ssl_hook_Translate,     NULL,NULL, APR_HOOK_MIDDLE);
       ap_hook_check_user_id (ssl_hook_UserCheck,     NULL,NULL, APR_HOOK_MIDDLE);
       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);
  -
  +#if 0 /* XXX - Work in progress */
       ap_hook_open_logs     (ssl_hook_open_logs,     NULL,NULL, APR_HOOK_MIDDLE);
       ap_hook_quick_handler (ssl_hook_quick_handler, NULL,NULL, APR_HOOK_MIDDLE);
       ap_hook_log_transaction(ssl_hook_fixer_upper,  NULL,NULL, APR_HOOK_MIDDLE);
  
  
  
  1.17      +48 -17    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.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- ssl_engine_io.c	2001/08/14 17:03:03	1.16
  +++ ssl_engine_io.c	2001/08/16 03:58:16	1.17
  @@ -220,6 +220,9 @@
       return APR_SUCCESS;
   }
   
  +#define bio_is_renegotiating(bio) \
  +(((int)BIO_get_callback_arg(bio)) == SSL_ST_RENEGOTIATE)
  +
   static apr_status_t churn (SSLFilterRec *pRec,
           apr_read_type_e eReadType, apr_off_t *readbytes)
   {
  @@ -282,13 +285,22 @@
           
           assert(n >= 0 && (apr_size_t)n == len);
   
  +        if (bio_is_renegotiating(pRec->pbioRead)) {
  +            /* we're doing renegotiation in the access phase */
  +            if (len >= *readbytes) {
  +                /* trick ap_http_filter into leaving us alone */
  +                *readbytes = 0;
  +                break; /* SSL_renegotiate will take it from here */
  +            }
  +        }
  +
           if ((ret = ssl_hook_process_connection(pRec)) != APR_SUCCESS) {
               /* if this is the case, ssl connection has been shutdown
                * and pRec->pssl has been freed
                */
               return ret;
           }
  -        
  +
           /* pass along all of the current BIO */
           while ((n = ssl_io_hook_read(pRec->pssl,
                                        (unsigned char *)buf, sizeof(buf))) > 0)
  @@ -334,23 +346,35 @@
                       APLOG_MARK,APLOG_ERR,ret,NULL, "Error in churn_output");
   		return ret;
               }
  -
  -            if ((ret = ssl_hook_CloseConnection (pRec)) != APR_SUCCESS)
  -                ap_log_error(APLOG_MARK,APLOG_ERR,ret,NULL,
  -                    "Error in ssl_hook_CloseConnection");
   	    break;
   	}
   
  -	if(APR_BUCKET_IS_FLUSH(pbktIn)) {
  -	    continue;
  -	}
  +	if (!APR_BUCKET_IS_FLUSH(pbktIn)) {
  +            /* read filter */
  +            apr_bucket_read(pbktIn,&data,&len,APR_BLOCK_READ);
  +
  +            /* write SSL */
  +            n = ssl_io_hook_write(pRec->pssl, (unsigned char *)data, len);
  +
  +            if (n != len) {
  +                conn_rec *c = (conn_rec *)SSL_get_app_data(pRec->pssl);
  +                char *reason = "reason unknown";
  +
  +                /* XXX: probably a better way to determine this */
  +                if (SSL_total_renegotiations(pRec->pssl)) {
  +                    reason = "likely due to failed renegotiation";
  +                }
  +
  +                ssl_log(c->base_server, SSL_LOG_ERROR,
  +                        "failed to write %d of %d bytes (%s)",
  +                        n > 0 ? len - n : len, len, reason);
   
  -	/* read filter */
  -	apr_bucket_read(pbktIn,&data,&len,APR_BLOCK_READ);
  -
  -	/* write SSL */
  -        n = ssl_io_hook_write(pRec->pssl, (unsigned char *)data, len);
  -        assert (n == len);
  +                return APR_EINVAL;
  +            }
  +        }
  +        /* else fallthrough to flush the current wbio
  +         * likely triggered by renegotiation in ssl_hook_Access
  +         */
   
   	/* churn the state machine */
   	ret=churn_output(pRec);
  @@ -388,8 +412,15 @@
   
   apr_status_t ssl_io_filter_cleanup (void *data)
   {
  -    SSL *ssl = (SSL *)data;
  -    return APR_SUCCESS;
  +    apr_status_t ret;
  +    SSLFilterRec *pRec = (SSLFilterRec *)data;
  +
  +    if ((ret = ssl_hook_CloseConnection(pRec)) != APR_SUCCESS) {
  +        ap_log_error(APLOG_MARK, APLOG_ERR, ret, NULL,
  +                     "Error in ssl_hook_CloseConnection");
  +    }
  +
  +    return ret;
   }
   
   void ssl_io_filter_init(conn_rec *c, SSL *ssl)
  @@ -406,7 +437,7 @@
       SSL_set_bio(ssl, filter->pbioRead, filter->pbioWrite);
       filter->pssl            = ssl;
   
  -    apr_pool_cleanup_register(c->pool, (void*)ssl,
  +    apr_pool_cleanup_register(c->pool, (void*)filter,
                                 ssl_io_filter_cleanup, apr_pool_cleanup_null);
   
       return;
  
  
  
  1.14      +85 -0     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.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- ssl_engine_kernel.c	2001/07/31 03:40:47	1.13
  +++ ssl_engine_kernel.c	2001/08/16 03:58:16	1.14
  @@ -573,6 +573,84 @@
       return HTTP_BAD_REQUEST;
   }
   
  +typedef long bio_hook_t (BIO *, int, const char *, int, long, long);
  +
  +static void bio_hook_set(BIO *b, bio_hook_t *hook, void *data)
  +{
  +    while (b) {
  +        BIO_set_callback(b, hook);
  +        BIO_set_callback_arg(b, data);
  +        b = BIO_next(b);
  +    }
  +}
  +
  +/* XXX: save/restore current callbacks if any? */
  +#define ssl_bio_hooks_set(ssl, hook, data) \
  +    bio_hook_set(SSL_get_wbio(ssl), hook, data); \
  +    bio_hook_set(SSL_get_rbio(ssl), hook, data)
  +
  +#define ssl_bio_renegotiate_hook_set(ssl, data) \
  +ssl_bio_hooks_set(ssl, ssl_renegotiate_hook, data)
  +
  +#define ssl_bio_hooks_unset(ssl) \
  +ssl_bio_hooks_set(ssl, NULL, NULL)
  +
  +#define bio_mem_length(b) ((BUF_MEM *)b->ptr)->length
  +
  +/* if we need to renegotiate in the access phase
  + * data needs to be pushed to / pulled from the filter chain
  + * otherwise, a BIO_write just sits in memory and theres nothing
  + * to BIO_read
  + */
  +
  +static long ssl_renegotiate_hook(BIO *bio, int cmd, const char *argp,
  +                                 int argi, long argl, long rc)
  +{
  +    request_rec *r = (request_rec *)BIO_get_callback_arg(bio);
  +    SSL *ssl;
  +
  +    int is_failed_read = (cmd == (BIO_CB_READ|BIO_CB_RETURN) && (rc == -1));
  +    int is_flush       = ((cmd == BIO_CB_CTRL) && (argi == BIO_CTRL_FLUSH));
  +
  +    if (is_flush || is_failed_read) {
  +        ssl = (SSL *)apr_table_get(r->connection->notes, "ssl");
  +        /* disable this callback to prevent recursion
  +         * and leave a "note" so the input filter leaves the rbio
  +         * as-as
  +         */
  +        ssl_bio_hooks_set(ssl, NULL, (void*)SSL_ST_RENEGOTIATE);
  +    }
  +    else {
  +        return rc;
  +    }
  +
  +    if (is_flush) {
  +        /* flush what was written into wbio to the client */
  +        ssl_log(r->server, SSL_LOG_DEBUG,
  +                "flushing %d bytes to the client",
  +                bio_mem_length(bio));
  +        ap_rflush(r);
  +    }
  +    else {
  +        /* force read from the client socket */
  +        apr_bucket_brigade *bb = apr_brigade_create(r->connection->pool);
  +        apr_off_t bytes = argi;
  +        ap_get_brigade(r->input_filters, bb,
  +                       AP_MODE_BLOCKING, &bytes);
  +
  +        rc = BIO_read(bio, (void *)argp, argi);
  +
  +        ssl_log(r->server, SSL_LOG_DEBUG,
  +                "retry read: wanted %d, got %d, %d remain\n",
  +                argi, rc, bio_mem_length(bio));
  +    }
  +
  +    /* reset this bio hook for further read/writes */
  +    ssl_bio_renegotiate_hook_set(ssl, r);
  +
  +    return rc;
  +}
  +
   /*
    *  Access Handler
    */
  @@ -982,15 +1060,22 @@
                   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));
  +            /* will need to push to / pull from filters to renegotiate */
  +            ssl_bio_renegotiate_hook_set(ssl, r);
               SSL_renegotiate(ssl);
               SSL_do_handshake(ssl);
  +
               if (SSL_get_state(ssl) != SSL_ST_OK) {
                   ssl_log(r->server, SSL_LOG_ERROR, "Re-negotiation request failed");
  +                ssl_bio_hooks_unset(ssl);
                   return HTTP_FORBIDDEN;
               }
               ssl_log(r->server, SSL_LOG_INFO, "Awaiting re-negotiation handshake");
               SSL_set_state(ssl, SSL_ST_ACCEPT);
               SSL_do_handshake(ssl);
  +
  +            ssl_bio_hooks_unset(ssl);
  +
               if (SSL_get_state(ssl) != SSL_ST_OK) {
                   ssl_log(r->server, SSL_LOG_ERROR,
                           "Re-negotiation handshake failed: Not accepted by client!?");
  
  
  

Mime
View raw message