From: Eric Covener Date: Sat, 31 Jan 2009 20:51:37 +0000 (+0000) Subject: Merge r726109, r733465, r733467, r733695 from trunk: X-Git-Tag: 2.2.12~244 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=99cf2dc9d6d333c1c33ac368025bb15b67d3272f;p=thirdparty%2Fapache%2Fhttpd.git Merge r726109, r733465, r733467, r733695 from trunk: mod_ssl: Make the size of the per-dir-reneg request-body buffer configurable, by popular demand: * modules/ssl/ssl_private.h: Define DEFAULT_RENEG_BUFFER_SIZE. (SSLDirConfigRec): Add nRenegBufferSize field. * modules/ssl/ssl_engine_config.c (ssl_cmd_SSLRenegBufferSize): New function. (ssl_config_perdir_create, ssl_config_perdir_merge): Handle nRenegBufferSize. * modules/ssl/ssl_engine_io.c (ssl_io_buffer_fill): Take max buffer size as an argument rather than compile-time constant. * modules/ssl/ssl_engine_kernel.c (ssl_hook_Access): Pass nRenegBufferSize to ssl_io_buffer_fill. * modules/ssl/mod_ssl.c (ssl_config_cmds): Add SSLRenegBufferSize. PR: 39243 * Correctly merge SSLRenegBufferSize directive. PR: 46508 Submitted by: Reviewed by: rpluem, jorton, pgollucci * Add a stub documentation for SSLRenegBufferSize. * docs/manual/mod/mod_ssl.xml: Flesh out SSLRenegBufferSize docs a little - thanks rpluem! git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@739605 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index fb56508aa20..058b267bd0f 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,9 @@ -*- coding: utf-8 -*- Changes with Apache 2.2.12 + + *) mod_ssl: Add SSLRenegBufferSize directive to allow changing the + size of the buffer used for the request-body where necessary + during a per-dir renegotiation. PR 39243. [Joe Orton] *) mod_rewrite: Introduce DiscardPathInfo|DPI flag to stop the troublesome way that per-directory rewrites append the previous notion of PATH_INFO diff --git a/STATUS b/STATUS index 6913a6a68f2..530da8b9014 100644 --- a/STATUS +++ b/STATUS @@ -86,19 +86,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - * mod_ssl: Add SSLRenegBufferSize to configure the amount of memory that will - be used for buffering the request body if a per-location SSL renegotiationi - is required due to changed access control requirements. - PR 39243, 46508 - Trunk version of patch: - http://svn.apache.org/viewvc?rev=726109&view=rev - http://svn.apache.org/viewvc?rev=733465&view=rev - http://svn.apache.org/viewvc?rev=733467&view=rev - http://svn.apache.org/viewvc?rev=733695&view=rev - Backport version for 2.2.x of patch: - Trunk version of patch works - +1: rpluem, jorton, pgollucci - * prefork: release mutex when exiting in single-process mode, add timeout to pollset-poll to avoid hanging during graceful stop/restart with multiple listening sockets diff --git a/docs/manual/mod/mod_ssl.html.en b/docs/manual/mod/mod_ssl.html.en index f7cbfe4cc9b..98f397864bf 100644 --- a/docs/manual/mod/mod_ssl.html.en +++ b/docs/manual/mod/mod_ssl.html.en @@ -71,6 +71,7 @@ to provide the cryptography engine.

  • SSLProxyVerify
  • SSLProxyVerifyDepth
  • SSLRandomSeed
  • +
  • SSLRenegBufferSize
  • SSLRequire
  • SSLRequireSSL
  • SSLSessionCache
  • @@ -1353,6 +1354,36 @@ SSLRandomSeed connect file:/dev/random
    SSLRandomSeed connect file:/dev/urandom 1024

    + +
    top
    +

    SSLRenegBufferSize Directive

    + + + + + + + + +
    Description:Set the size for the SSL renegotiation buffer
    Syntax:SSLRenegBufferSize bytes
    Default:SSLRenegBufferSize 131072
    Context:directory, .htaccess
    Override:AuthConfig
    Status:Extension
    Module:mod_ssl
    + +

    If an SSL renegotiation is required in per-location context, for +example, any use of SSLVerifyClient in a Directory or +Location block, then mod_ssl must buffer any HTTP +request body into memory until the new SSL handshake can be performed. +This directive can be used to set the amount of memory that will be +used for this buffer.

    + +

    +Note that in many configurations, the client sending the request body +will be untrusted so a denial of service attack by consumption of +memory must be considered when changing this configuration setting. +

    + +

    Example

    +SSLRenegBufferSize 262144 +

    +
    top

    SSLRequire Directive

    diff --git a/docs/manual/mod/mod_ssl.xml b/docs/manual/mod/mod_ssl.xml index c903c5f7694..2f4b0531642 100644 --- a/docs/manual/mod/mod_ssl.xml +++ b/docs/manual/mod/mod_ssl.xml @@ -1323,6 +1323,37 @@ SSL_VERSION_INTERFACE SSL_CLIENT_S_DN_OU SSL_SERVER_S_DN_OU + +SSLRenegBufferSize +Set the size for the SSL renegotiation buffer +SSLRenegBufferSize bytes +SSLRenegBufferSize 131072 +directory +.htaccess +AuthConfig + + + +

    If an SSL renegotiation is required in per-location context, for +example, any use of SSLVerifyClient in a Directory or +Location block, then mod_ssl must buffer any HTTP +request body into memory until the new SSL handshake can be performed. +This directive can be used to set the amount of memory that will be +used for this buffer.

    + +

    +Note that in many configurations, the client sending the request body +will be untrusted so a denial of service attack by consumption of +memory must be considered when changing this configuration setting. +

    + +Example +SSLRenegBufferSize 262144 + +
    +
    + SSLProxyMachineCertificatePath Directory of PEM-encoded client certificates and keys to be used by the proxy diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c index ff690167460..f8a88a2adb5 100644 --- a/modules/ssl/mod_ssl.c +++ b/modules/ssl/mod_ssl.c @@ -195,6 +195,10 @@ static const command_rec ssl_config_cmds[] = { SSL_CMD_DIR(Require, AUTHCFG, RAW_ARGS, "Require a boolean expression to evaluate to true for granting access" "(arbitrary complex boolean expression - see manual)") + SSL_CMD_DIR(RenegBufferSize, AUTHCFG, TAKE1, + "Configure the amount of memory that will be used for buffering the " + "request body if a per-location SSL renegotiation is required due to " + "changed access control requirements") /* Deprecated directives. */ AP_INIT_RAW_ARGS("SSLLog", ap_set_deprecated, NULL, OR_ALL, diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c index df6674dd10e..3b22c4a10b6 100644 --- a/modules/ssl/ssl_engine_config.c +++ b/modules/ssl/ssl_engine_config.c @@ -286,6 +286,8 @@ void *ssl_config_perdir_create(apr_pool_t *p, char *dir) dc->szCACertificateFile = NULL; dc->szUserName = NULL; + dc->nRenegBufferSize = UNSET; + return dc; } @@ -323,6 +325,8 @@ void *ssl_config_perdir_merge(apr_pool_t *p, void *basev, void *addv) cfgMergeString(szCACertificateFile); cfgMergeString(szUserName); + cfgMergeInt(nRenegBufferSize); + return mrg; } @@ -1185,6 +1189,19 @@ const char *ssl_cmd_SSLRequire(cmd_parms *cmd, return NULL; } +const char *ssl_cmd_SSLRenegBufferSize(cmd_parms *cmd, void *dcfg, const char *arg) +{ + SSLDirConfigRec *dc = dcfg; + + dc->nRenegBufferSize = atoi(arg); + if (dc->nRenegBufferSize < 0) { + return apr_pstrcat(cmd->pool, "Invalid size for SSLRenegBufferSize: ", + arg, NULL); + } + + return NULL; +} + static const char *ssl_cmd_protocol_parse(cmd_parms *parms, const char *arg, ssl_proto_t *options) diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c index 1264c289e3c..c46e9eec9be 100644 --- a/modules/ssl/ssl_engine_io.c +++ b/modules/ssl/ssl_engine_io.c @@ -1447,17 +1447,12 @@ static apr_status_t ssl_io_filter_output(ap_filter_t *f, 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) +int ssl_io_buffer_fill(request_rec *r, apr_size_t maxlen) { conn_rec *c = r->connection; struct modssl_buffer_ctx *ctx; @@ -1475,7 +1470,8 @@ int ssl_io_buffer_fill(request_rec *r) /* ... and a temporary brigade. */ tempb = apr_brigade_create(r->pool, c->bucket_alloc); - ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, "filling buffer"); + ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, "filling buffer, max size " + "%" APR_SIZE_T_FMT " bytes", maxlen); do { apr_status_t rv; @@ -1531,9 +1527,10 @@ int ssl_io_buffer_fill(request_rec *r) total, eos); /* Fail if this exceeds the maximum buffer size. */ - if (total > SSL_MAX_IO_BUFFER) { + if (total > maxlen) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "request body exceeds maximum size for SSL buffer"); + "request body exceeds maximum size (%" APR_SIZE_T_FMT + ") for SSL buffer", maxlen); return HTTP_REQUEST_ENTITY_TOO_LARGE; } diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c index 0a8e1933bbe..b050f3f84a2 100644 --- a/modules/ssl/ssl_engine_kernel.c +++ b/modules/ssl/ssl_engine_kernel.c @@ -512,9 +512,18 @@ int ssl_hook_Access(request_rec *r) && strcmp(apr_table_get(r->headers_in, "content-length"), "0"))) && !r->expecting_100) { int rv; + apr_size_t rsize; - /* Fill the I/O buffer with the request body if possible. */ - rv = ssl_io_buffer_fill(r); + rsize = dc->nRenegBufferSize == UNSET ? DEFAULT_RENEG_BUFFER_SIZE : + dc->nRenegBufferSize; + if (rsize > 0) { + /* Fill the I/O buffer with the request body if possible. */ + rv = ssl_io_buffer_fill(r, rsize); + } + else { + /* If the reneg buffer size is set to zero, just fail. */ + rv = HTTP_REQUEST_ENTITY_TOO_LARGE; + } if (rv) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h index 64ad36bef4a..2dfa16f6540 100644 --- a/modules/ssl/ssl_private.h +++ b/modules/ssl/ssl_private.h @@ -140,6 +140,11 @@ ap_set_module_config(c->conn_config, &ssl_module, val) #define SSL_SESSION_CACHE_TIMEOUT 300 #endif +/* Default setting for per-dir reneg buffer. */ +#ifndef DEFAULT_RENEG_BUFFER_SIZE +#define DEFAULT_RENEG_BUFFER_SIZE (128 * 1024) +#endif + /** * Support for MM library */ @@ -468,6 +473,7 @@ typedef struct { const char *szCACertificatePath; const char *szCACertificateFile; const char *szUserName; + apr_size_t nRenegBufferSize; } SSLDirConfigRec; /** @@ -513,6 +519,7 @@ const char *ssl_cmd_SSLOptions(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLRequireSSL(cmd_parms *, void *); const char *ssl_cmd_SSLRequire(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLUserName(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLRenegBufferSize(cmd_parms *cmd, void *dcfg, const char *arg); const char *ssl_cmd_SSLProxyEngine(cmd_parms *cmd, void *dcfg, int flag); const char *ssl_cmd_SSLProxyProtocol(cmd_parms *, void *, const char *); @@ -597,7 +604,7 @@ long ssl_io_data_cb(BIO *, int, MODSSL_BIO_CB_ARG_TYPE *, int, long, lon /* 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); +int ssl_io_buffer_fill(request_rec *r, apr_size_t maxlen); /* PRNG */ int ssl_rand_seed(server_rec *, apr_pool_t *, ssl_rsctx_t, char *);