webbuilder_pel7ppc64lebuilder0
5 years ago
13 changed files with 1513 additions and 6 deletions
@ -0,0 +1,399 @@
@@ -0,0 +1,399 @@
|
||||
diff --git a/modules/aaa/mod_auth_digest.c b/modules/aaa/mod_auth_digest.c |
||||
index cbb4434..b50bcf9 100644 |
||||
--- a/modules/aaa/mod_auth_digest.c |
||||
+++ b/modules/aaa/mod_auth_digest.c |
||||
@@ -26,20 +26,13 @@ |
||||
* reports to the Apache bug-database, or send them directly to me |
||||
* at ronald@innovation.ch. |
||||
* |
||||
- * Requires either /dev/random (or equivalent) or the truerand library, |
||||
- * available for instance from |
||||
- * ftp://research.att.com/dist/mab/librand.shar |
||||
- * |
||||
* Open Issues: |
||||
* - qop=auth-int (when streams and trailer support available) |
||||
* - nonce-format configurability |
||||
* - Proxy-Authorization-Info header is set by this module, but is |
||||
* currently ignored by mod_proxy (needs patch to mod_proxy) |
||||
- * - generating the secret takes a while (~ 8 seconds) if using the |
||||
- * truerand library |
||||
* - The source of the secret should be run-time directive (with server |
||||
- * scope: RSRC_CONF). However, that could be tricky when trying to |
||||
- * choose truerand vs. file... |
||||
+ * scope: RSRC_CONF) |
||||
* - shared-mem not completely tested yet. Seems to work ok for me, |
||||
* but... (definitely won't work on Windoze) |
||||
* - Sharing a realm among multiple servers has following problems: |
||||
@@ -52,6 +45,8 @@ |
||||
* captures a packet sent to one server and sends it to another |
||||
* one. Should we add "AuthDigestNcCheck Strict"? |
||||
* - expired nonces give amaya fits. |
||||
+ * - MD5-sess and auth-int are not yet implemented. An incomplete |
||||
+ * implementation has been removed and can be retrieved from svn history. |
||||
*/ |
||||
|
||||
#include "apr_sha1.h" |
||||
@@ -94,7 +89,6 @@ typedef struct digest_config_struct { |
||||
apr_array_header_t *qop_list; |
||||
apr_sha1_ctx_t nonce_ctx; |
||||
apr_time_t nonce_lifetime; |
||||
- const char *nonce_format; |
||||
int check_nc; |
||||
const char *algorithm; |
||||
char *uri_list; |
||||
@@ -112,7 +106,8 @@ typedef struct digest_config_struct { |
||||
#define NONCE_HASH_LEN (2*APR_SHA1_DIGESTSIZE) |
||||
#define NONCE_LEN (int )(NONCE_TIME_LEN + NONCE_HASH_LEN) |
||||
|
||||
-#define SECRET_LEN 20 |
||||
+#define SECRET_LEN 20 |
||||
+#define RETAINED_DATA_ID "mod_auth_digest" |
||||
|
||||
|
||||
/* client list definitions */ |
||||
@@ -121,7 +116,6 @@ typedef struct hash_entry { |
||||
unsigned long key; /* the key for this entry */ |
||||
struct hash_entry *next; /* next entry in the bucket */ |
||||
unsigned long nonce_count; /* for nonce-count checking */ |
||||
- char ha1[2*APR_MD5_DIGESTSIZE+1]; /* for algorithm=MD5-sess */ |
||||
char last_nonce[NONCE_LEN+1]; /* for one-time nonce's */ |
||||
} client_entry; |
||||
|
||||
@@ -170,7 +164,7 @@ typedef union time_union { |
||||
unsigned char arr[sizeof(apr_time_t)]; |
||||
} time_rec; |
||||
|
||||
-static unsigned char secret[SECRET_LEN]; |
||||
+static unsigned char *secret; |
||||
|
||||
/* client-list, opaque, and one-time-nonce stuff */ |
||||
|
||||
@@ -228,35 +222,11 @@ static apr_status_t cleanup_tables(void *not_used) |
||||
return APR_SUCCESS; |
||||
} |
||||
|
||||
-static apr_status_t initialize_secret(server_rec *s) |
||||
-{ |
||||
- apr_status_t status; |
||||
- |
||||
- ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, APLOGNO(01757) |
||||
- "generating secret for digest authentication ..."); |
||||
- |
||||
-#if APR_HAS_RANDOM |
||||
- status = apr_generate_random_bytes(secret, sizeof(secret)); |
||||
-#else |
||||
-#error APR random number support is missing; you probably need to install the truerand library. |
||||
-#endif |
||||
- |
||||
- if (status != APR_SUCCESS) { |
||||
- ap_log_error(APLOG_MARK, APLOG_CRIT, status, s, APLOGNO(01758) |
||||
- "error generating secret"); |
||||
- return status; |
||||
- } |
||||
- |
||||
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01759) "done"); |
||||
- |
||||
- return APR_SUCCESS; |
||||
-} |
||||
- |
||||
static void log_error_and_cleanup(char *msg, apr_status_t sts, server_rec *s) |
||||
{ |
||||
ap_log_error(APLOG_MARK, APLOG_ERR, sts, s, APLOGNO(01760) |
||||
- "%s - all nonce-count checking, one-time nonces, and " |
||||
- "MD5-sess algorithm disabled", msg); |
||||
+ "%s - all nonce-count checking and one-time nonces" |
||||
+ "disabled", msg); |
||||
|
||||
cleanup_tables(NULL); |
||||
} |
||||
@@ -377,16 +347,32 @@ static int initialize_tables(server_rec *s, apr_pool_t *ctx) |
||||
static int pre_init(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp) |
||||
{ |
||||
apr_status_t rv; |
||||
+ void *retained; |
||||
|
||||
rv = ap_mutex_register(pconf, client_mutex_type, NULL, APR_LOCK_DEFAULT, 0); |
||||
- if (rv == APR_SUCCESS) { |
||||
- rv = ap_mutex_register(pconf, opaque_mutex_type, NULL, APR_LOCK_DEFAULT, |
||||
- 0); |
||||
- } |
||||
- if (rv != APR_SUCCESS) { |
||||
- return rv; |
||||
- } |
||||
+ if (rv != APR_SUCCESS) |
||||
+ return !OK; |
||||
+ rv = ap_mutex_register(pconf, opaque_mutex_type, NULL, APR_LOCK_DEFAULT, 0); |
||||
+ if (rv != APR_SUCCESS) |
||||
+ return !OK; |
||||
|
||||
+ retained = ap_retained_data_get(RETAINED_DATA_ID); |
||||
+ if (retained == NULL) { |
||||
+ retained = ap_retained_data_create(RETAINED_DATA_ID, SECRET_LEN); |
||||
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, APLOGNO(01757) |
||||
+ "generating secret for digest authentication"); |
||||
+#if APR_HAS_RANDOM |
||||
+ rv = apr_generate_random_bytes(retained, SECRET_LEN); |
||||
+#else |
||||
+#error APR random number support is missing |
||||
+#endif |
||||
+ if (rv != APR_SUCCESS) { |
||||
+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, APLOGNO(01758) |
||||
+ "error generating secret"); |
||||
+ return !OK; |
||||
+ } |
||||
+ } |
||||
+ secret = retained; |
||||
return OK; |
||||
} |
||||
|
||||
@@ -399,10 +385,6 @@ static int initialize_module(apr_pool_t *p, apr_pool_t *plog, |
||||
if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG) |
||||
return OK; |
||||
|
||||
- if (initialize_secret(s) != APR_SUCCESS) { |
||||
- return !OK; |
||||
- } |
||||
- |
||||
#if APR_HAS_SHARED_MEMORY |
||||
/* Note: this stuff is currently fixed for the lifetime of the server, |
||||
* i.e. even across restarts. This means that A) any shmem-size |
||||
@@ -483,6 +465,16 @@ static void *create_digest_dir_config(apr_pool_t *p, char *dir) |
||||
static const char *set_realm(cmd_parms *cmd, void *config, const char *realm) |
||||
{ |
||||
digest_config_rec *conf = (digest_config_rec *) config; |
||||
+#ifdef AP_DEBUG |
||||
+ int i; |
||||
+ |
||||
+ /* check that we got random numbers */ |
||||
+ for (i = 0; i < SECRET_LEN; i++) { |
||||
+ if (secret[i] != 0) |
||||
+ break; |
||||
+ } |
||||
+ ap_assert(i < SECRET_LEN); |
||||
+#endif |
||||
|
||||
/* The core already handles the realm, but it's just too convenient to |
||||
* grab it ourselves too and cache some setups. However, we need to |
||||
@@ -496,7 +488,7 @@ static const char *set_realm(cmd_parms *cmd, void *config, const char *realm) |
||||
* and directives outside a virtual host section) |
||||
*/ |
||||
apr_sha1_init(&conf->nonce_ctx); |
||||
- apr_sha1_update_binary(&conf->nonce_ctx, secret, sizeof(secret)); |
||||
+ apr_sha1_update_binary(&conf->nonce_ctx, secret, SECRET_LEN); |
||||
apr_sha1_update_binary(&conf->nonce_ctx, (const unsigned char *) realm, |
||||
strlen(realm)); |
||||
|
||||
@@ -590,8 +582,7 @@ static const char *set_nonce_lifetime(cmd_parms *cmd, void *config, |
||||
static const char *set_nonce_format(cmd_parms *cmd, void *config, |
||||
const char *fmt) |
||||
{ |
||||
- ((digest_config_rec *) config)->nonce_format = fmt; |
||||
- return "AuthDigestNonceFormat is not implemented (yet)"; |
||||
+ return "AuthDigestNonceFormat is not implemented"; |
||||
} |
||||
|
||||
static const char *set_nc_check(cmd_parms *cmd, void *config, int flag) |
||||
@@ -612,7 +603,7 @@ static const char *set_algorithm(cmd_parms *cmd, void *config, const char *alg) |
||||
{ |
||||
if (!strcasecmp(alg, "MD5-sess")) { |
||||
return "AuthDigestAlgorithm: ERROR: algorithm `MD5-sess' " |
||||
- "is not fully implemented"; |
||||
+ "is not implemented"; |
||||
} |
||||
else if (strcasecmp(alg, "MD5")) { |
||||
return apr_pstrcat(cmd->pool, "Invalid algorithm in AuthDigestAlgorithm: ", alg, NULL); |
||||
@@ -1138,7 +1129,7 @@ static const char *gen_nonce(apr_pool_t *p, apr_time_t now, const char *opaque, |
||||
static client_entry *gen_client(const request_rec *r) |
||||
{ |
||||
unsigned long op; |
||||
- client_entry new_entry = { 0, NULL, 0, "", "" }, *entry; |
||||
+ client_entry new_entry = { 0, NULL, 0, "" }, *entry; |
||||
|
||||
if (!opaque_cntr) { |
||||
return NULL; |
||||
@@ -1158,92 +1149,6 @@ static client_entry *gen_client(const request_rec *r) |
||||
} |
||||
|
||||
|
||||
-/* |
||||
- * MD5-sess code. |
||||
- * |
||||
- * If you want to use algorithm=MD5-sess you must write get_userpw_hash() |
||||
- * yourself (see below). The dummy provided here just uses the hash from |
||||
- * the auth-file, i.e. it is only useful for testing client implementations |
||||
- * of MD5-sess . |
||||
- */ |
||||
- |
||||
-/* |
||||
- * get_userpw_hash() will be called each time a new session needs to be |
||||
- * generated and is expected to return the equivalent of |
||||
- * |
||||
- * h_urp = ap_md5(r->pool, |
||||
- * apr_pstrcat(r->pool, username, ":", ap_auth_name(r), ":", passwd)) |
||||
- * ap_md5(r->pool, |
||||
- * (unsigned char *) apr_pstrcat(r->pool, h_urp, ":", resp->nonce, ":", |
||||
- * resp->cnonce, NULL)); |
||||
- * |
||||
- * or put differently, it must return |
||||
- * |
||||
- * MD5(MD5(username ":" realm ":" password) ":" nonce ":" cnonce) |
||||
- * |
||||
- * If something goes wrong, the failure must be logged and NULL returned. |
||||
- * |
||||
- * You must implement this yourself, which will probably consist of code |
||||
- * contacting the password server with the necessary information (typically |
||||
- * the username, realm, nonce, and cnonce) and receiving the hash from it. |
||||
- * |
||||
- * TBD: This function should probably be in a separate source file so that |
||||
- * people need not modify mod_auth_digest.c each time they install a new |
||||
- * version of apache. |
||||
- */ |
||||
-static const char *get_userpw_hash(const request_rec *r, |
||||
- const digest_header_rec *resp, |
||||
- const digest_config_rec *conf) |
||||
-{ |
||||
- return ap_md5(r->pool, |
||||
- (unsigned char *) apr_pstrcat(r->pool, conf->ha1, ":", resp->nonce, |
||||
- ":", resp->cnonce, NULL)); |
||||
-} |
||||
- |
||||
- |
||||
-/* Retrieve current session H(A1). If there is none and "generate" is |
||||
- * true then a new session for MD5-sess is generated and stored in the |
||||
- * client struct; if generate is false, or a new session could not be |
||||
- * generated then NULL is returned (in case of failure to generate the |
||||
- * failure reason will have been logged already). |
||||
- */ |
||||
-static const char *get_session_HA1(const request_rec *r, |
||||
- digest_header_rec *resp, |
||||
- const digest_config_rec *conf, |
||||
- int generate) |
||||
-{ |
||||
- const char *ha1 = NULL; |
||||
- |
||||
- /* return the current sessions if there is one */ |
||||
- if (resp->opaque && resp->client && resp->client->ha1[0]) { |
||||
- return resp->client->ha1; |
||||
- } |
||||
- else if (!generate) { |
||||
- return NULL; |
||||
- } |
||||
- |
||||
- /* generate a new session */ |
||||
- if (!resp->client) { |
||||
- resp->client = gen_client(r); |
||||
- } |
||||
- if (resp->client) { |
||||
- ha1 = get_userpw_hash(r, resp, conf); |
||||
- if (ha1) { |
||||
- memcpy(resp->client->ha1, ha1, sizeof(resp->client->ha1)); |
||||
- } |
||||
- } |
||||
- |
||||
- return ha1; |
||||
-} |
||||
- |
||||
- |
||||
-static void clear_session(const digest_header_rec *resp) |
||||
-{ |
||||
- if (resp->client) { |
||||
- resp->client->ha1[0] = '\0'; |
||||
- } |
||||
-} |
||||
- |
||||
/* |
||||
* Authorization challenge generation code (for WWW-Authenticate) |
||||
*/ |
||||
@@ -1282,8 +1187,7 @@ static void note_digest_auth_failure(request_rec *r, |
||||
|
||||
if (resp->opaque == NULL) { |
||||
/* new client */ |
||||
- if ((conf->check_nc || conf->nonce_lifetime == 0 |
||||
- || !strcasecmp(conf->algorithm, "MD5-sess")) |
||||
+ if ((conf->check_nc || conf->nonce_lifetime == 0) |
||||
&& (resp->client = gen_client(r)) != NULL) { |
||||
opaque = ltox(r->pool, resp->client->key); |
||||
} |
||||
@@ -1323,15 +1227,6 @@ static void note_digest_auth_failure(request_rec *r, |
||||
memcpy(resp->client->last_nonce, nonce, NONCE_LEN+1); |
||||
} |
||||
|
||||
- /* Setup MD5-sess stuff. Note that we just clear out the session |
||||
- * info here, since we can't generate a new session until the request |
||||
- * from the client comes in with the cnonce. |
||||
- */ |
||||
- |
||||
- if (!strcasecmp(conf->algorithm, "MD5-sess")) { |
||||
- clear_session(resp); |
||||
- } |
||||
- |
||||
/* setup domain attribute. We want to send this attribute wherever |
||||
* possible so that the client won't send the Authorization header |
||||
* unnecessarily (it's usually > 200 bytes!). |
||||
@@ -1597,24 +1492,9 @@ static const char *new_digest(const request_rec *r, |
||||
{ |
||||
const char *ha1, *ha2, *a2; |
||||
|
||||
- if (resp->algorithm && !strcasecmp(resp->algorithm, "MD5-sess")) { |
||||
- ha1 = get_session_HA1(r, resp, conf, 1); |
||||
- if (!ha1) { |
||||
- return NULL; |
||||
- } |
||||
- } |
||||
- else { |
||||
- ha1 = conf->ha1; |
||||
- } |
||||
+ ha1 = conf->ha1; |
||||
|
||||
- if (resp->message_qop && !strcasecmp(resp->message_qop, "auth-int")) { |
||||
- a2 = apr_pstrcat(r->pool, resp->method, ":", resp->uri, ":", |
||||
- ap_md5(r->pool, (const unsigned char*) ""), NULL); |
||||
- /* TBD */ |
||||
- } |
||||
- else { |
||||
- a2 = apr_pstrcat(r->pool, resp->method, ":", resp->uri, NULL); |
||||
- } |
||||
+ a2 = apr_pstrcat(r->pool, resp->method, ":", resp->uri, NULL); |
||||
ha2 = ap_md5(r->pool, (const unsigned char *)a2); |
||||
|
||||
return ap_md5(r->pool, |
||||
@@ -1854,8 +1734,7 @@ static int authenticate_digest_user(request_rec *r) |
||||
} |
||||
|
||||
if (resp->algorithm != NULL |
||||
- && strcasecmp(resp->algorithm, "MD5") |
||||
- && strcasecmp(resp->algorithm, "MD5-sess")) { |
||||
+ && strcasecmp(resp->algorithm, "MD5")) { |
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01789) |
||||
"unknown algorithm `%s' received: %s", |
||||
resp->algorithm, r->uri); |
||||
@@ -2007,27 +1886,9 @@ static int add_auth_info(request_rec *r) |
||||
|
||||
/* calculate rspauth attribute |
||||
*/ |
||||
- if (resp->algorithm && !strcasecmp(resp->algorithm, "MD5-sess")) { |
||||
- ha1 = get_session_HA1(r, resp, conf, 0); |
||||
- if (!ha1) { |
||||
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01795) |
||||
- "internal error: couldn't find session " |
||||
- "info for user %s", resp->username); |
||||
- return !OK; |
||||
- } |
||||
- } |
||||
- else { |
||||
- ha1 = conf->ha1; |
||||
- } |
||||
+ ha1 = conf->ha1; |
||||
|
||||
- if (resp->message_qop && !strcasecmp(resp->message_qop, "auth-int")) { |
||||
- a2 = apr_pstrcat(r->pool, ":", resp->uri, ":", |
||||
- ap_md5(r->pool,(const unsigned char *) ""), NULL); |
||||
- /* TBD */ |
||||
- } |
||||
- else { |
||||
- a2 = apr_pstrcat(r->pool, ":", resp->uri, NULL); |
||||
- } |
||||
+ a2 = apr_pstrcat(r->pool, ":", resp->uri, NULL); |
||||
ha2 = ap_md5(r->pool, (const unsigned char *)a2); |
||||
|
||||
resp_dig = ap_md5(r->pool, |
@ -0,0 +1,113 @@
@@ -0,0 +1,113 @@
|
||||
diff --git a/modules/aaa/mod_auth_digest.c b/modules/aaa/mod_auth_digest.c |
||||
index b50bcf9..5bfec82 100644 |
||||
--- a/modules/aaa/mod_auth_digest.c |
||||
+++ b/modules/aaa/mod_auth_digest.c |
||||
@@ -92,7 +92,6 @@ typedef struct digest_config_struct { |
||||
int check_nc; |
||||
const char *algorithm; |
||||
char *uri_list; |
||||
- const char *ha1; |
||||
} digest_config_rec; |
||||
|
||||
|
||||
@@ -153,6 +152,7 @@ typedef struct digest_header_struct { |
||||
apr_time_t nonce_time; |
||||
enum hdr_sts auth_hdr_sts; |
||||
int needed_auth; |
||||
+ const char *ha1; |
||||
client_entry *client; |
||||
} digest_header_rec; |
||||
|
||||
@@ -1295,7 +1295,7 @@ static int hook_note_digest_auth_failure(request_rec *r, const char *auth_type) |
||||
*/ |
||||
|
||||
static authn_status get_hash(request_rec *r, const char *user, |
||||
- digest_config_rec *conf) |
||||
+ digest_config_rec *conf, const char **rethash) |
||||
{ |
||||
authn_status auth_result; |
||||
char *password; |
||||
@@ -1347,7 +1347,7 @@ static authn_status get_hash(request_rec *r, const char *user, |
||||
} while (current_provider); |
||||
|
||||
if (auth_result == AUTH_USER_FOUND) { |
||||
- conf->ha1 = password; |
||||
+ *rethash = password; |
||||
} |
||||
|
||||
return auth_result; |
||||
@@ -1474,25 +1474,24 @@ static int check_nonce(request_rec *r, digest_header_rec *resp, |
||||
|
||||
/* RFC-2069 */ |
||||
static const char *old_digest(const request_rec *r, |
||||
- const digest_header_rec *resp, const char *ha1) |
||||
+ const digest_header_rec *resp) |
||||
{ |
||||
const char *ha2; |
||||
|
||||
ha2 = ap_md5(r->pool, (unsigned char *)apr_pstrcat(r->pool, resp->method, ":", |
||||
resp->uri, NULL)); |
||||
return ap_md5(r->pool, |
||||
- (unsigned char *)apr_pstrcat(r->pool, ha1, ":", resp->nonce, |
||||
- ":", ha2, NULL)); |
||||
+ (unsigned char *)apr_pstrcat(r->pool, resp->ha1, ":", |
||||
+ resp->nonce, ":", ha2, NULL)); |
||||
} |
||||
|
||||
/* RFC-2617 */ |
||||
static const char *new_digest(const request_rec *r, |
||||
- digest_header_rec *resp, |
||||
- const digest_config_rec *conf) |
||||
+ digest_header_rec *resp) |
||||
{ |
||||
const char *ha1, *ha2, *a2; |
||||
|
||||
- ha1 = conf->ha1; |
||||
+ ha1 = resp->ha1; |
||||
|
||||
a2 = apr_pstrcat(r->pool, resp->method, ":", resp->uri, NULL); |
||||
ha2 = ap_md5(r->pool, (const unsigned char *)a2); |
||||
@@ -1505,7 +1504,6 @@ static const char *new_digest(const request_rec *r, |
||||
NULL)); |
||||
} |
||||
|
||||
- |
||||
static void copy_uri_components(apr_uri_t *dst, |
||||
apr_uri_t *src, request_rec *r) { |
||||
if (src->scheme && src->scheme[0] != '\0') { |
||||
@@ -1742,7 +1740,7 @@ static int authenticate_digest_user(request_rec *r) |
||||
return HTTP_UNAUTHORIZED; |
||||
} |
||||
|
||||
- return_code = get_hash(r, r->user, conf); |
||||
+ return_code = get_hash(r, r->user, conf, &resp->ha1); |
||||
|
||||
if (return_code == AUTH_USER_NOT_FOUND) { |
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01790) |
||||
@@ -1772,7 +1770,7 @@ static int authenticate_digest_user(request_rec *r) |
||||
|
||||
if (resp->message_qop == NULL) { |
||||
/* old (rfc-2069) style digest */ |
||||
- if (strcmp(resp->digest, old_digest(r, resp, conf->ha1))) { |
||||
+ if (strcmp(resp->digest, old_digest(r, resp))) { |
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01792) |
||||
"user %s: password mismatch: %s", r->user, |
||||
r->uri); |
||||
@@ -1802,7 +1800,7 @@ static int authenticate_digest_user(request_rec *r) |
||||
return HTTP_UNAUTHORIZED; |
||||
} |
||||
|
||||
- exp_digest = new_digest(r, resp, conf); |
||||
+ exp_digest = new_digest(r, resp); |
||||
if (!exp_digest) { |
||||
/* we failed to allocate a client struct */ |
||||
return HTTP_INTERNAL_SERVER_ERROR; |
||||
@@ -1886,7 +1884,7 @@ static int add_auth_info(request_rec *r) |
||||
|
||||
/* calculate rspauth attribute |
||||
*/ |
||||
- ha1 = conf->ha1; |
||||
+ ha1 = resp->ha1; |
||||
|
||||
a2 = apr_pstrcat(r->pool, ":", resp->uri, NULL); |
||||
ha2 = ap_md5(r->pool, (const unsigned char *)a2); |
@ -0,0 +1,244 @@
@@ -0,0 +1,244 @@
|
||||
diff --git a/docs/manual/mod/core.html.en b/docs/manual/mod/core.html.en |
||||
index 86d9bee..e08034b 100644 |
||||
--- a/docs/manual/mod/core.html.en |
||||
+++ b/docs/manual/mod/core.html.en |
||||
@@ -90,6 +90,7 @@ available</td></tr> |
||||
<li><img alt="" src="../images/down.gif" /> <a href="#maxrangeoverlaps">MaxRangeOverlaps</a></li> |
||||
<li><img alt="" src="../images/down.gif" /> <a href="#maxrangereversals">MaxRangeReversals</a></li> |
||||
<li><img alt="" src="../images/down.gif" /> <a href="#maxranges">MaxRanges</a></li> |
||||
+<li><img alt="" src="../images/down.gif" /> <a href="#mergeslashes">MergeSlashes</a></li> |
||||
<li><img alt="" src="../images/down.gif" /> <a href="#mutex">Mutex</a></li> |
||||
<li><img alt="" src="../images/down.gif" /> <a href="#namevirtualhost">NameVirtualHost</a></li> |
||||
<li><img alt="" src="../images/down.gif" /> <a href="#options">Options</a></li> |
||||
@@ -3170,6 +3171,30 @@ resource </td></tr> |
||||
|
||||
</div> |
||||
<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> |
||||
+<div class="directive-section"><h2><a name="MergeSlashes" id="MergeSlashes">MergeSlashes</a> <a name="mergeslashes" id="mergeslashes">Directive</a></h2> |
||||
+<table class="directive"> |
||||
+<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Controls whether the server merges consecutive slashes in URLs. </td></tr> |
||||
+<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>MergeSlashes ON | OFF</code></td></tr> |
||||
+<tr><th><a href="directive-dict.html#Default">Default:</a></th><td><code>MergeSlashes ON</code></td></tr> |
||||
+<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host</td></tr> |
||||
+<tr><th><a href="directive-dict.html#Status">Status:</a></th><td>Core</td></tr> |
||||
+<tr><th><a href="directive-dict.html#Module">Module:</a></th><td>core</td></tr> |
||||
+<tr><th><a href="directive-dict.html#Compatibility">Compatibility:</a></th><td>Available in Apache HTTP Server 2.4.6 in Red Hat Enterprise Linux 7</td></tr> |
||||
+</table> |
||||
+ <p>By default, the server merges (or collapses) multiple consecutive slash |
||||
+ ('/') characters in the path component of the request URL.</p> |
||||
+ |
||||
+ <p>When mapping URL's to the filesystem, these multiple slashes are not |
||||
+ significant. However, URL's handled other ways, such as by CGI or proxy, |
||||
+ might prefer to retain the significance of multiple consecutive slashes. |
||||
+ In these cases <code class="directive">MergeSlashes</code> can be set to |
||||
+ <em>OFF</em> to retain the multiple consecutive slashes. In these |
||||
+ configurations, regular expressions used in the configuration file that match |
||||
+ the path component of the URL (<code class="directive">LocationMatch</code>, |
||||
+ <code class="directive">RewriteRule</code>, ...) need to take into account multiple |
||||
+ consecutive slashes.</p> |
||||
+</div> |
||||
+<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> |
||||
<div class="directive-section"><h2><a name="Mutex" id="Mutex">Mutex</a> <a name="mutex" id="mutex">Directive</a></h2> |
||||
<table class="directive"> |
||||
<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Configures mutex mechanism and lock file directory for all |
||||
diff --git a/include/http_core.h b/include/http_core.h |
||||
index c05d06e..76bf5a4 100644 |
||||
--- a/include/http_core.h |
||||
+++ b/include/http_core.h |
||||
@@ -465,6 +465,17 @@ typedef unsigned long etag_components_t; |
||||
/* This is the default value used */ |
||||
#define ETAG_BACKWARD (ETAG_MTIME | ETAG_SIZE) |
||||
|
||||
+/* Generic ON/OFF/UNSET for unsigned int foo :2 */ |
||||
+#define AP_CORE_CONFIG_OFF (0) |
||||
+#define AP_CORE_CONFIG_ON (1) |
||||
+#define AP_CORE_CONFIG_UNSET (2) |
||||
+ |
||||
+/* Generic merge of flag */ |
||||
+#define AP_CORE_MERGE_FLAG(field, to, base, over) to->field = \ |
||||
+ over->field != AP_CORE_CONFIG_UNSET \ |
||||
+ ? over->field \ |
||||
+ : base->field |
||||
+ |
||||
/** |
||||
* @brief Server Signature Enumeration |
||||
*/ |
||||
@@ -682,7 +693,7 @@ typedef struct { |
||||
#define AP_HTTP_METHODS_LENIENT 1 |
||||
#define AP_HTTP_METHODS_REGISTERED 2 |
||||
char http_methods; |
||||
- |
||||
+ unsigned int merge_slashes; |
||||
} core_server_config; |
||||
|
||||
/* for AddOutputFiltersByType in core.c */ |
||||
diff --git a/include/httpd.h b/include/httpd.h |
||||
index 176ef5e..a552358 100644 |
||||
--- a/include/httpd.h |
||||
+++ b/include/httpd.h |
||||
@@ -1622,11 +1622,21 @@ AP_DECLARE(int) ap_unescape_url_keep2f(char *url, int decode_slashes); |
||||
AP_DECLARE(int) ap_unescape_urlencoded(char *query); |
||||
|
||||
/** |
||||
- * Convert all double slashes to single slashes |
||||
- * @param name The string to convert |
||||
+ * Convert all double slashes to single slashes, except where significant |
||||
+ * to the filesystem on the current platform. |
||||
+ * @param name The string to convert, assumed to be a filesystem path |
||||
*/ |
||||
AP_DECLARE(void) ap_no2slash(char *name); |
||||
|
||||
+/** |
||||
+ * Convert all double slashes to single slashes, except where significant |
||||
+ * to the filesystem on the current platform. |
||||
+ * @param name The string to convert |
||||
+ * @param is_fs_path if set to 0, the significance of any double-slashes is |
||||
+ * ignored. |
||||
+ */ |
||||
+AP_DECLARE(void) ap_no2slash_ex(char *name, int is_fs_path); |
||||
+ |
||||
/** |
||||
* Remove all ./ and xx/../ substrings from a file name. Also remove |
||||
* any leading ../ or /../ substrings. |
||||
diff --git a/server/core.c b/server/core.c |
||||
index 0e69f8c..67efd7e 100644 |
||||
--- a/server/core.c |
||||
+++ b/server/core.c |
||||
@@ -476,6 +476,7 @@ static void *create_core_server_config(apr_pool_t *a, server_rec *s) |
||||
*/ |
||||
|
||||
conf->trace_enable = AP_TRACE_UNSET; |
||||
+ conf->merge_slashes = AP_CORE_CONFIG_UNSET; |
||||
|
||||
return (void *)conf; |
||||
} |
||||
@@ -536,6 +537,8 @@ static void *merge_core_server_configs(apr_pool_t *p, void *basev, void *virtv) |
||||
? virt->merge_trailers |
||||
: base->merge_trailers; |
||||
|
||||
+ AP_CORE_MERGE_FLAG(merge_slashes, conf, base, virt); |
||||
+ |
||||
return conf; |
||||
} |
||||
|
||||
@@ -1673,6 +1676,13 @@ static const char *set_override(cmd_parms *cmd, void *d_, const char *l) |
||||
return NULL; |
||||
} |
||||
|
||||
+static const char *set_core_server_flag(cmd_parms *cmd, void *s_, int flag) |
||||
+{ |
||||
+ core_server_config *conf = |
||||
+ ap_get_core_module_config(cmd->server->module_config); |
||||
+ return ap_set_flag_slot(cmd, conf, flag); |
||||
+} |
||||
+ |
||||
static const char *set_override_list(cmd_parms *cmd, void *d_, int argc, char *const argv[]) |
||||
{ |
||||
core_dir_config *d = d_; |
||||
@@ -4216,6 +4226,10 @@ AP_INIT_ITERATE("HttpProtocolOptions", set_http_protocol_options, NULL, RSRC_CON |
||||
, |
||||
AP_INIT_ITERATE("RegisterHttpMethod", set_http_method, NULL, RSRC_CONF, |
||||
"Registers non-standard HTTP methods"), |
||||
+AP_INIT_FLAG("MergeSlashes", set_core_server_flag, |
||||
+ (void *)APR_OFFSETOF(core_server_config, merge_slashes), |
||||
+ RSRC_CONF, |
||||
+ "Controls whether consecutive slashes in the URI path are merged"), |
||||
{ NULL } |
||||
}; |
||||
|
||||
diff --git a/server/request.c b/server/request.c |
||||
index 4eef097..cba3891 100644 |
||||
--- a/server/request.c |
||||
+++ b/server/request.c |
||||
@@ -167,6 +167,8 @@ AP_DECLARE(int) ap_process_request_internal(request_rec *r) |
||||
int file_req = (r->main && r->filename); |
||||
int access_status; |
||||
core_dir_config *d; |
||||
+ core_server_config *sconf = |
||||
+ ap_get_core_module_config(r->server->module_config); |
||||
|
||||
/* Ignore embedded %2F's in path for proxy requests */ |
||||
if (!r->proxyreq && r->parsed_uri.path) { |
||||
@@ -191,6 +193,12 @@ AP_DECLARE(int) ap_process_request_internal(request_rec *r) |
||||
} |
||||
|
||||
ap_getparents(r->uri); /* OK --- shrinking transformations... */ |
||||
+ if (sconf->merge_slashes != AP_CORE_CONFIG_OFF) { |
||||
+ ap_no2slash(r->uri); |
||||
+ if (r->parsed_uri.path) { |
||||
+ ap_no2slash(r->parsed_uri.path); |
||||
+ } |
||||
+ } |
||||
|
||||
/* All file subrequests are a huge pain... they cannot bubble through the |
||||
* next several steps. Only file subrequests are allowed an empty uri, |
||||
@@ -1383,20 +1391,7 @@ AP_DECLARE(int) ap_location_walk(request_rec *r) |
||||
|
||||
cache = prep_walk_cache(AP_NOTE_LOCATION_WALK, r); |
||||
cached = (cache->cached != NULL); |
||||
- |
||||
- /* Location and LocationMatch differ on their behaviour w.r.t. multiple |
||||
- * slashes. Location matches multiple slashes with a single slash, |
||||
- * LocationMatch doesn't. An exception, for backwards brokenness is |
||||
- * absoluteURIs... in which case neither match multiple slashes. |
||||
- */ |
||||
- if (r->uri[0] != '/') { |
||||
- entry_uri = r->uri; |
||||
- } |
||||
- else { |
||||
- char *uri = apr_pstrdup(r->pool, r->uri); |
||||
- ap_no2slash(uri); |
||||
- entry_uri = uri; |
||||
- } |
||||
+ entry_uri = r->uri; |
||||
|
||||
/* If we have an cache->cached location that matches r->uri, |
||||
* and the vhost's list of locations hasn't changed, we can skip |
||||
@@ -1449,7 +1444,7 @@ AP_DECLARE(int) ap_location_walk(request_rec *r) |
||||
* terminated (or at the end of the string) to match. |
||||
*/ |
||||
if (entry_core->r |
||||
- ? ap_regexec(entry_core->r, r->uri, 0, NULL, 0) |
||||
+ ? ap_regexec(entry_core->r, entry_uri, 0, NULL, 0) |
||||
: (entry_core->d_is_fnmatch |
||||
? apr_fnmatch(entry_core->d, cache->cached, APR_FNM_PATHNAME) |
||||
: (strncmp(entry_core->d, cache->cached, len) |
||||
diff --git a/server/util.c b/server/util.c |
||||
index f9e3b51..4eac462 100644 |
||||
--- a/server/util.c |
||||
+++ b/server/util.c |
||||
@@ -561,16 +561,20 @@ AP_DECLARE(void) ap_getparents(char *name) |
||||
name[l] = '\0'; |
||||
} |
||||
} |
||||
- |
||||
-AP_DECLARE(void) ap_no2slash(char *name) |
||||
+AP_DECLARE(void) ap_no2slash_ex(char *name, int is_fs_path) |
||||
{ |
||||
+ |
||||
char *d, *s; |
||||
|
||||
+ if (!*name) { |
||||
+ return; |
||||
+ } |
||||
+ |
||||
s = d = name; |
||||
|
||||
#ifdef HAVE_UNC_PATHS |
||||
/* Check for UNC names. Leave leading two slashes. */ |
||||
- if (s[0] == '/' && s[1] == '/') |
||||
+ if (is_fs_path && s[0] == '/' && s[1] == '/') |
||||
*d++ = *s++; |
||||
#endif |
||||
|
||||
@@ -587,6 +591,10 @@ AP_DECLARE(void) ap_no2slash(char *name) |
||||
*d = '\0'; |
||||
} |
||||
|
||||
+AP_DECLARE(void) ap_no2slash(char *name) |
||||
+{ |
||||
+ ap_no2slash_ex(name, 1); |
||||
+} |
||||
|
||||
/* |
||||
* copy at most n leading directories of s into d |
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c |
||||
index e672e4a..8be833a 100644 |
||||
--- a/modules/proxy/proxy_util.c |
||||
+++ b/modules/proxy/proxy_util.c |
||||
@@ -3557,6 +3557,8 @@ static proxy_schemes_t pschemes[] = |
||||
{"fcgi", 8000}, |
||||
{"ajp", AJP13_DEF_PORT}, |
||||
{"scgi", 4000}, |
||||
+ {"ws", 80}, |
||||
+ {"wss", 443}, |
||||
{ NULL, 0xFFFF } /* unknown port */ |
||||
}; |
||||
|
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
--- a/modules/ldap/util_ldap_cache.c 2013/08/19 11:41:29 1515371 |
||||
+++ b/modules/ldap/util_ldap_cache.c 2013/08/19 11:45:19 1515372 |
||||
@@ -52,7 +52,7 @@ |
||||
|
||||
if (node) { |
||||
if (!(node->url = util_ald_strdup(cache, n->url))) { |
||||
- util_ald_free(cache, node->url); |
||||
+ util_ald_free(cache, node); |
||||
return NULL; |
||||
} |
||||
node->search_cache = n->search_cache; |
@ -0,0 +1,265 @@
@@ -0,0 +1,265 @@
|
||||
diff --git a/docs/manual/expr.html.en b/docs/manual/expr.html.en |
||||
index 5c3ae45..8bd941a 100644 |
||||
--- a/docs/manual/expr.html.en |
||||
+++ b/docs/manual/expr.html.en |
||||
@@ -46,7 +46,7 @@ |
||||
<li><img alt="" src="./images/down.gif" /> <a href="#other">Other</a></li> |
||||
<li><img alt="" src="./images/down.gif" /> <a href="#sslrequire">Comparison with SSLRequire</a></li> |
||||
<li><img alt="" src="./images/down.gif" /> <a href="#compatibility">Version History</a></li> |
||||
-</ul><h3>See also</h3><ul class="seealso"><li><code class="directive"><a href="./mod/core.html#if"><If></a></code></li><li><code class="directive"><a href="./mod/core.html#elseif"><ElseIf></a></code></li><li><code class="directive"><a href="./mod/core.html#else"><Else></a></code></li><li><code class="directive"><a href="./mod/mod_auth_basic.html#authbasicfake">AuthBasicFake</a></code></li><li><code class="directive"><a href="./mod/mod_auth_form.html#authformloginrequiredlocation">AuthFormLoginRequiredLocation</a></code></li><li><code class="directive"><a href="./mod/mod_auth_form.html#authformloginsuccesslocation">AuthFormLoginSuccessLocation</a></code></li><li><code class="directive"><a href="./mod/mod_auth_form.html#authformlogoutlocation">AuthFormLogoutLocation</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewritecond">RewriteCond</a></code></li><li><code class="directive"><a href="./mod/mod_setenvif.html#setenvifexpr">SetEnvIfExpr</a></code></li><li><code class="directive"><a href="./mod/mod_headers.html#header">Header</a></code></li><li><code class="directive"><a href="./mod/mod_headers.html#requestheader">RequestHeader</a></code></li><li><code class="directive"><a href="./mod/mod_filter.html#filterprovider">FilterProvider</a></code></li><li><a href="mod/mod_authz_core.html#reqexpr">Require expr</a></li><li><code class="directive"><a href="./mod/mod_ssl.html#sslrequire">SSLRequire</a></code></li><li><code class="directive"><a href="./mod/mod_log_debug.html#logmessage">LogMessage</a></code></li><li><code class="module"><a href="./mod/mod_include.html">mod_include</a></code></li></ul><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div> |
||||
+</ul><h3>See also</h3><ul class="seealso"><li><code class="directive"><a href="./mod/core.html#if"><If></a></code></li><li><code class="directive"><a href="./mod/core.html#elseif"><ElseIf></a></code></li><li><code class="directive"><a href="./mod/core.html#else"><Else></a></code></li><li><code class="directive"><a href="./mod/mod_auth_basic.html#authbasicfake">AuthBasicFake</a></code></li><li><code class="directive"><a href="./mod/mod_auth_form.html#authformloginrequiredlocation">AuthFormLoginRequiredLocation</a></code></li><li><code class="directive"><a href="./mod/mod_auth_form.html#authformloginsuccesslocation">AuthFormLoginSuccessLocation</a></code></li><li><code class="directive"><a href="./mod/mod_auth_form.html#authformlogoutlocation">AuthFormLogoutLocation</a></code></li><li><code class="directive"><a href="./mod/mod_rewrite.html#rewritecond">RewriteCond</a></code></li><li><code class="directive"><a href="./mod/mod_setenvif.html#setenvifexpr">SetEnvIfExpr</a></code></li><li><code class="directive"><a href="./mod/mod_headers.html#header">Header</a></code></li><li><code class="directive"><a href="./mod/mod_headers.html#requestheader">RequestHeader</a></code></li><li><code class="directive"><a href="./mod/mod_filter.html#filterprovider">FilterProvider</a></code></li><li><a href="mod/mod_authz_core.html#reqexpr">Require expr</a></li><li><code class="directive"><a href="mod/mod_authnz_ldap.html#requser">Require ldap-user</a></code></li><li><code class="directive"><a href="mod/mod_authnz_ldap.html#reqgroup">Require ldap-group</a></code></li><li><code class="directive"><a href="mod/mod_authnz_ldap.html#reqdn">Require ldap-dn</a></code></li><li><code class="directive"><a href="mod/mod_authnz_ldap.html#reqattribute">Require ldap-attribute</a></code></li><li><code class="directive"><a href="mod/mod_authnz_ldap.html#reqfilter">Require ldap-filter</a></code></li><li><code class="directive"><a href="./mod/mod_ssl.html#sslrequire">SSLRequire</a></code></li><li><code class="directive"><a href="./mod/mod_log_debug.html#logmessage">LogMessage</a></code></li><li><code class="module"><a href="./mod/mod_include.html">mod_include</a></code></li></ul><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div> |
||||
<div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div> |
||||
<div class="section"> |
||||
<h2><a name="grammar" id="grammar">Grammar in Backus-Naur Form notation</a></h2> |
||||
diff --git a/docs/manual/mod/mod_authnz_ldap.html.en b/docs/manual/mod/mod_authnz_ldap.html.en |
||||
index 7199052..c86dc8a 100644 |
||||
--- a/docs/manual/mod/mod_authnz_ldap.html.en |
||||
+++ b/docs/manual/mod/mod_authnz_ldap.html.en |
||||
@@ -350,6 +350,9 @@ for HTTP Basic authentication.</td></tr> |
||||
<code>ldap-filter</code>. Other authorization types may also be |
||||
used but may require that additional authorization modules be loaded.</p> |
||||
|
||||
+ <p>Since v2.5.0, <a href="../expr.html">expressions</a> are supported |
||||
+ within the LDAP require directives.</p> |
||||
+ |
||||
<h3><a name="requser" id="requser">Require ldap-user</a></h3> |
||||
|
||||
<p>The <code>Require ldap-user</code> directive specifies what |
||||
@@ -576,6 +579,16 @@ Require ldap-group cn=Administrators, o=Example |
||||
</li> |
||||
|
||||
<li> |
||||
+ Grant access to anybody in the group whose name matches the |
||||
+ hostname of the virtual host. In this example an |
||||
+ <a href="../expr.html">expression</a> is used to build the filter. |
||||
+<highlight language="config"> |
||||
+AuthLDAPURL ldap://ldap.example.com/o=Example?uid |
||||
+Require ldap-group cn=%{SERVER_NAME}, o=Example |
||||
+</highlight> |
||||
+ </li> |
||||
+ |
||||
+ <li> |
||||
The next example assumes that everyone at Example who |
||||
carries an alphanumeric pager will have an LDAP attribute |
||||
of <code>qpagePagerID</code>. The example will grant access |
||||
diff --git a/modules/aaa/mod_authnz_ldap.c b/modules/aaa/mod_authnz_ldap.c |
||||
index 2c25dbc..063debe 100644 |
||||
--- a/modules/aaa/mod_authnz_ldap.c |
||||
+++ b/modules/aaa/mod_authnz_ldap.c |
||||
@@ -607,6 +607,10 @@ static authz_status ldapuser_check_authorization(request_rec *r, |
||||
|
||||
util_ldap_connection_t *ldc = NULL; |
||||
|
||||
+ const char *err = NULL; |
||||
+ const ap_expr_info_t *expr = parsed_require_args; |
||||
+ const char *require; |
||||
+ |
||||
const char *t; |
||||
char *w; |
||||
|
||||
@@ -680,11 +684,19 @@ static authz_status ldapuser_check_authorization(request_rec *r, |
||||
return AUTHZ_DENIED; |
||||
} |
||||
|
||||
+ require = ap_expr_str_exec(r, expr, &err); |
||||
+ if (err) { |
||||
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02585) |
||||
+ "auth_ldap authorize: require user: Can't evaluate expression: %s", |
||||
+ err); |
||||
+ return AUTHZ_DENIED; |
||||
+ } |
||||
+ |
||||
/* |
||||
* First do a whole-line compare, in case it's something like |
||||
* require user Babs Jensen |
||||
*/ |
||||
- result = util_ldap_cache_compare(r, ldc, sec->url, req->dn, sec->attribute, require_args); |
||||
+ result = util_ldap_cache_compare(r, ldc, sec->url, req->dn, sec->attribute, require); |
||||
switch(result) { |
||||
case LDAP_COMPARE_TRUE: { |
||||
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01703) |
||||
@@ -704,7 +716,7 @@ static authz_status ldapuser_check_authorization(request_rec *r, |
||||
/* |
||||
* Now break apart the line and compare each word on it |
||||
*/ |
||||
- t = require_args; |
||||
+ t = require; |
||||
while ((w = ap_getword_conf(r->pool, &t)) && w[0]) { |
||||
result = util_ldap_cache_compare(r, ldc, sec->url, req->dn, sec->attribute, w); |
||||
switch(result) { |
||||
@@ -744,6 +756,10 @@ static authz_status ldapgroup_check_authorization(request_rec *r, |
||||
|
||||
util_ldap_connection_t *ldc = NULL; |
||||
|
||||
+ const char *err = NULL; |
||||
+ const ap_expr_info_t *expr = parsed_require_args; |
||||
+ const char *require; |
||||
+ |
||||
const char *t; |
||||
|
||||
char filtbuf[FILTER_LENGTH]; |
||||
@@ -863,7 +879,15 @@ static authz_status ldapgroup_check_authorization(request_rec *r, |
||||
} |
||||
} |
||||
|
||||
- t = require_args; |
||||
+ require = ap_expr_str_exec(r, expr, &err); |
||||
+ if (err) { |
||||
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02586) |
||||
+ "auth_ldap authorize: require group: Can't evaluate expression: %s", |
||||
+ err); |
||||
+ return AUTHZ_DENIED; |
||||
+ } |
||||
+ |
||||
+ t = require; |
||||
|
||||
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01713) |
||||
"auth_ldap authorize: require group: testing for group " |
||||
@@ -959,6 +983,10 @@ static authz_status ldapdn_check_authorization(request_rec *r, |
||||
|
||||
util_ldap_connection_t *ldc = NULL; |
||||
|
||||
+ const char *err = NULL; |
||||
+ const ap_expr_info_t *expr = parsed_require_args; |
||||
+ const char *require; |
||||
+ |
||||
const char *t; |
||||
|
||||
char filtbuf[FILTER_LENGTH]; |
||||
@@ -1021,7 +1049,15 @@ static authz_status ldapdn_check_authorization(request_rec *r, |
||||
req->user = r->user; |
||||
} |
||||
|
||||
- t = require_args; |
||||
+ require = ap_expr_str_exec(r, expr, &err); |
||||
+ if (err) { |
||||
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02587) |
||||
+ "auth_ldap authorize: require dn: Can't evaluate expression: %s", |
||||
+ err); |
||||
+ return AUTHZ_DENIED; |
||||
+ } |
||||
+ |
||||
+ t = require; |
||||
|
||||
if (req->dn == NULL || strlen(req->dn) == 0) { |
||||
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01725) |
||||
@@ -1068,6 +1104,10 @@ static authz_status ldapattribute_check_authorization(request_rec *r, |
||||
|
||||
util_ldap_connection_t *ldc = NULL; |
||||
|
||||
+ const char *err = NULL; |
||||
+ const ap_expr_info_t *expr = parsed_require_args; |
||||
+ const char *require; |
||||
+ |
||||
const char *t; |
||||
char *w, *value; |
||||
|
||||
@@ -1138,7 +1178,16 @@ static authz_status ldapattribute_check_authorization(request_rec *r, |
||||
return AUTHZ_DENIED; |
||||
} |
||||
|
||||
- t = require_args; |
||||
+ require = ap_expr_str_exec(r, expr, &err); |
||||
+ if (err) { |
||||
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02588) |
||||
+ "auth_ldap authorize: require ldap-attribute: Can't " |
||||
+ "evaluate expression: %s", err); |
||||
+ return AUTHZ_DENIED; |
||||
+ } |
||||
+ |
||||
+ t = require; |
||||
+ |
||||
while (t[0]) { |
||||
w = ap_getword(r->pool, &t, '='); |
||||
value = ap_getword_conf(r->pool, &t); |
||||
@@ -1183,6 +1232,11 @@ static authz_status ldapfilter_check_authorization(request_rec *r, |
||||
(authn_ldap_config_t *)ap_get_module_config(r->per_dir_config, &authnz_ldap_module); |
||||
|
||||
util_ldap_connection_t *ldc = NULL; |
||||
+ |
||||
+ const char *err = NULL; |
||||
+ const ap_expr_info_t *expr = parsed_require_args; |
||||
+ const char *require; |
||||
+ |
||||
const char *t; |
||||
|
||||
char filtbuf[FILTER_LENGTH]; |
||||
@@ -1252,7 +1306,15 @@ static authz_status ldapfilter_check_authorization(request_rec *r, |
||||
return AUTHZ_DENIED; |
||||
} |
||||
|
||||
- t = require_args; |
||||
+ require = ap_expr_str_exec(r, expr, &err); |
||||
+ if (err) { |
||||
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02589) |
||||
+ "auth_ldap authorize: require ldap-filter: Can't " |
||||
+ "evaluate require expression: %s", err); |
||||
+ return AUTHZ_DENIED; |
||||
+ } |
||||
+ |
||||
+ t = require; |
||||
|
||||
if (t[0]) { |
||||
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01743) |
||||
@@ -1311,6 +1373,25 @@ static authz_status ldapfilter_check_authorization(request_rec *r, |
||||
return AUTHZ_DENIED; |
||||
} |
||||
|
||||
+static const char *ldap_parse_config(cmd_parms *cmd, const char *require_line, |
||||
+ const void **parsed_require_line) |
||||
+{ |
||||
+ const char *expr_err = NULL; |
||||
+ ap_expr_info_t *expr; |
||||
+ |
||||
+ expr = ap_expr_parse_cmd(cmd, require_line, AP_EXPR_FLAG_STRING_RESULT, |
||||
+ &expr_err, NULL); |
||||
+ |
||||
+ if (expr_err) |
||||
+ return apr_pstrcat(cmd->temp_pool, |
||||
+ "Cannot parse expression in require line: ", |
||||
+ expr_err, NULL); |
||||
+ |
||||
+ *parsed_require_line = expr; |
||||
+ |
||||
+ return NULL; |
||||
+} |
||||
+ |
||||
|
||||
/* |
||||
* Use the ldap url parsing routines to break up the ldap url into |
||||
@@ -1769,30 +1850,30 @@ static const authn_provider authn_ldap_provider = |
||||
static const authz_provider authz_ldapuser_provider = |
||||
{ |
||||
&ldapuser_check_authorization, |
||||
- NULL, |
||||
+ &ldap_parse_config, |
||||
}; |
||||
static const authz_provider authz_ldapgroup_provider = |
||||
{ |
||||
&ldapgroup_check_authorization, |
||||
- NULL, |
||||
+ &ldap_parse_config, |
||||
}; |
||||
|
||||
static const authz_provider authz_ldapdn_provider = |
||||
{ |
||||
&ldapdn_check_authorization, |
||||
- NULL, |
||||
+ &ldap_parse_config, |
||||
}; |
||||
|
||||
static const authz_provider authz_ldapattribute_provider = |
||||
{ |
||||
&ldapattribute_check_authorization, |
||||
- NULL, |
||||
+ &ldap_parse_config, |
||||
}; |
||||
|
||||
static const authz_provider authz_ldapfilter_provider = |
||||
{ |
||||
&ldapfilter_check_authorization, |
||||
- NULL, |
||||
+ &ldap_parse_config, |
||||
}; |
||||
|
||||
static void ImportULDAPOptFn(void) |
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
# ./pullrev.sh 1737363 |
||||
http://svn.apache.org/viewvc?view=revision&revision=1737363 |
||||
|
||||
--- httpd-2.4.6/modules/proxy/mod_proxy_express.c |
||||
+++ httpd-2.4.6/modules/proxy/mod_proxy_express.c |
||||
@@ -145,16 +145,14 @@ |
||||
key.dsize = strlen(key.dptr); |
||||
|
||||
rv = apr_dbm_fetch(db, key, &val); |
||||
+ if (rv == APR_SUCCESS) { |
||||
+ backend = apr_pstrmemdup(r->pool, val.dptr, val.dsize); |
||||
+ } |
||||
apr_dbm_close(db); |
||||
- if (rv != APR_SUCCESS) { |
||||
+ if (rv != APR_SUCCESS || !backend) { |
||||
return DECLINED; |
||||
} |
||||
|
||||
- backend = apr_pstrmemdup(r->pool, val.dptr, val.dsize); |
||||
- if (!backend) { |
||||
- return DECLINED; |
||||
- } |
||||
- |
||||
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01004) |
||||
"proxy_express: found %s -> %s", name, backend); |
||||
r->filename = apr_pstrcat(r->pool, "proxy:", backend, r->uri, NULL); |
@ -0,0 +1,25 @@
@@ -0,0 +1,25 @@
|
||||
--- a/modules/ldap/util_ldap.c 2018/02/20 13:00:39 1824871 |
||||
+++ b/modules/ldap/util_ldap.c 2018/02/20 13:02:54 1824872 |
||||
@@ -2858,7 +2858,6 @@ |
||||
st->search_cache_size = base->search_cache_size; |
||||
st->compare_cache_ttl = base->compare_cache_ttl; |
||||
st->compare_cache_size = base->compare_cache_size; |
||||
- st->util_ldap_cache_lock = base->util_ldap_cache_lock; |
||||
|
||||
st->connections = NULL; |
||||
st->ssl_supported = 0; /* not known until post-config and re-merged */ |
||||
@@ -2977,12 +2976,12 @@ |
||||
st_vhost = (util_ldap_state_t *) |
||||
ap_get_module_config(s_vhost->module_config, |
||||
&ldap_module); |
||||
- |
||||
+ st_vhost->util_ldap_cache = st->util_ldap_cache; |
||||
+ st_vhost->util_ldap_cache_lock = st->util_ldap_cache_lock; |
||||
#if APR_HAS_SHARED_MEMORY |
||||
st_vhost->cache_shm = st->cache_shm; |
||||
st_vhost->cache_rmm = st->cache_rmm; |
||||
st_vhost->cache_file = st->cache_file; |
||||
- st_vhost->util_ldap_cache = st->util_ldap_cache; |
||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, result, s, APLOGNO(01316) |
||||
"LDAP merging Shared Cache conf: shm=0x%pp rmm=0x%pp " |
||||
"for VHOST: %s", st->cache_shm, st->cache_rmm, |
@ -0,0 +1,96 @@
@@ -0,0 +1,96 @@
|
||||
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c |
||||
index 57b76c0..814ec4f 100644 |
||||
--- a/modules/ssl/ssl_engine_init.c |
||||
+++ b/modules/ssl/ssl_engine_init.c |
||||
@@ -1522,70 +1522,18 @@ void ssl_init_CheckServers(SSLModConfigRec *mc, server_rec *base_server, apr_poo |
||||
} |
||||
} |
||||
|
||||
-static int ssl_init_FindCAList_X509NameCmp(const X509_NAME * const *a, |
||||
- const X509_NAME * const *b) |
||||
-{ |
||||
- return(X509_NAME_cmp(*a, *b)); |
||||
-} |
||||
- |
||||
-static void ssl_init_PushCAList(STACK_OF(X509_NAME) *ca_list, |
||||
- server_rec *s, apr_pool_t *ptemp, |
||||
- const char *file) |
||||
-{ |
||||
- int n; |
||||
- STACK_OF(X509_NAME) *sk; |
||||
- |
||||
- sk = (STACK_OF(X509_NAME) *) |
||||
- SSL_load_client_CA_file(file); |
||||
- |
||||
- if (!sk) { |
||||
- return; |
||||
- } |
||||
- |
||||
- for (n = 0; n < sk_X509_NAME_num(sk); n++) { |
||||
- X509_NAME *name = sk_X509_NAME_value(sk, n); |
||||
- |
||||
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02209) |
||||
- "CA certificate: %s", |
||||
- SSL_X509_NAME_to_string(ptemp, name, 0)); |
||||
- |
||||
- /* |
||||
- * note that SSL_load_client_CA_file() checks for duplicates, |
||||
- * but since we call it multiple times when reading a directory |
||||
- * we must also check for duplicates ourselves. |
||||
- */ |
||||
- |
||||
- if (sk_X509_NAME_find(ca_list, name) < 0) { |
||||
- /* this will be freed when ca_list is */ |
||||
- sk_X509_NAME_push(ca_list, name); |
||||
- } |
||||
- else { |
||||
- /* need to free this ourselves, else it will leak */ |
||||
- X509_NAME_free(name); |
||||
- } |
||||
- } |
||||
- |
||||
- sk_X509_NAME_free(sk); |
||||
-} |
||||
- |
||||
STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s, |
||||
apr_pool_t *ptemp, |
||||
const char *ca_file, |
||||
const char *ca_path) |
||||
{ |
||||
- STACK_OF(X509_NAME) *ca_list; |
||||
- |
||||
- /* |
||||
- * Start with a empty stack/list where new |
||||
- * entries get added in sorted order. |
||||
- */ |
||||
- ca_list = sk_X509_NAME_new(ssl_init_FindCAList_X509NameCmp); |
||||
+ STACK_OF(X509_NAME) *ca_list = sk_X509_NAME_new_null();; |
||||
|
||||
/* |
||||
* Process CA certificate bundle file |
||||
*/ |
||||
if (ca_file) { |
||||
- ssl_init_PushCAList(ca_list, s, ptemp, ca_file); |
||||
+ SSL_add_file_cert_subjects_to_stack(ca_list, ca_file); |
||||
/* |
||||
* If ca_list is still empty after trying to load ca_file |
||||
* then the file failed to load, and users should hear about that. |
||||
@@ -1619,17 +1567,12 @@ STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s, |
||||
continue; /* don't try to load directories */ |
||||
} |
||||
file = apr_pstrcat(ptemp, ca_path, "/", direntry.name, NULL); |
||||
- ssl_init_PushCAList(ca_list, s, ptemp, file); |
||||
+ SSL_add_file_cert_subjects_to_stack(ca_list, file); |
||||
} |
||||
|
||||
apr_dir_close(dir); |
||||
} |
||||
|
||||
- /* |
||||
- * Cleanup |
||||
- */ |
||||
- (void) sk_X509_NAME_set_cmp_func(ca_list, NULL); |
||||
- |
||||
return ca_list; |
||||
} |
||||
|
@ -0,0 +1,198 @@
@@ -0,0 +1,198 @@
|
||||
diff --git a/docs/manual/mod/mod_ssl.html.en b/docs/manual/mod/mod_ssl.html.en |
||||
index 4580f1c..fb8202e 100644 |
||||
--- a/docs/manual/mod/mod_ssl.html.en |
||||
+++ b/docs/manual/mod/mod_ssl.html.en |
||||
@@ -991,7 +991,8 @@ the certificate being verified.</p> |
||||
<p>This option enables OCSP validation of the client certificate |
||||
chain. If this option is enabled, certificates in the client's |
||||
certificate chain will be validated against an OCSP responder after |
||||
-normal verification (including CRL checks) have taken place.</p> |
||||
+normal verification (including CRL checks) have taken place. In |
||||
+mode 'leaf', only the client certificate itself will be validated.</p> |
||||
|
||||
<p>The OCSP responder used is either extracted from the certificate |
||||
itself, or derived by configuration; see the |
||||
diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c |
||||
index 4a8b661..e637a9d 100644 |
||||
--- a/modules/ssl/mod_ssl.c |
||||
+++ b/modules/ssl/mod_ssl.c |
||||
@@ -227,8 +227,8 @@ static const command_rec ssl_config_cmds[] = { |
||||
"request body if a per-location SSL renegotiation is required due to " |
||||
"changed access control requirements") |
||||
|
||||
- SSL_CMD_SRV(OCSPEnable, FLAG, |
||||
- "Enable use of OCSP to verify certificate revocation ('on', 'off')") |
||||
+ SSL_CMD_SRV(OCSPEnable, RAW_ARGS, |
||||
+ "Enable use of OCSP to verify certificate revocation mode ('on', 'leaf', 'off')") |
||||
SSL_CMD_SRV(OCSPDefaultResponder, TAKE1, |
||||
"URL of the default OCSP Responder") |
||||
SSL_CMD_SRV(OCSPOverrideResponder, FLAG, |
||||
diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c |
||||
index 86a7f0f..714aee9 100644 |
||||
--- a/modules/ssl/ssl_engine_config.c |
||||
+++ b/modules/ssl/ssl_engine_config.c |
||||
@@ -130,7 +130,7 @@ static void modssl_ctx_init(modssl_ctx_t *mctx) |
||||
mctx->auth.verify_depth = UNSET; |
||||
mctx->auth.verify_mode = SSL_CVERIFY_UNSET; |
||||
|
||||
- mctx->ocsp_enabled = FALSE; |
||||
+ mctx->ocsp_mask = UNSET; |
||||
mctx->ocsp_force_default = FALSE; |
||||
mctx->ocsp_responder = NULL; |
||||
mctx->ocsp_resptime_skew = UNSET; |
||||
@@ -264,7 +264,7 @@ static void modssl_ctx_cfg_merge(modssl_ctx_t *base, |
||||
cfgMergeInt(auth.verify_depth); |
||||
cfgMerge(auth.verify_mode, SSL_CVERIFY_UNSET); |
||||
|
||||
- cfgMergeBool(ocsp_enabled); |
||||
+ cfgMergeInt(ocsp_mask); |
||||
cfgMergeBool(ocsp_force_default); |
||||
cfgMerge(ocsp_responder, NULL); |
||||
cfgMergeInt(ocsp_resptime_skew); |
||||
@@ -1575,11 +1575,46 @@ const char *ssl_cmd_SSLUserName(cmd_parms *cmd, void *dcfg, |
||||
return NULL; |
||||
} |
||||
|
||||
-const char *ssl_cmd_SSLOCSPEnable(cmd_parms *cmd, void *dcfg, int flag) |
||||
+static const char *ssl_cmd_ocspcheck_parse(cmd_parms *parms, |
||||
+ const char *arg, |
||||
+ int *mask) |
||||
{ |
||||
- SSLSrvConfigRec *sc = mySrvConfig(cmd->server); |
||||
+ const char *w; |
||||
+ |
||||
+ w = ap_getword_conf(parms->temp_pool, &arg); |
||||
+ if (strcEQ(w, "off")) { |
||||
+ *mask = SSL_OCSPCHECK_NONE; |
||||
+ } |
||||
+ else if (strcEQ(w, "leaf")) { |
||||
+ *mask = SSL_OCSPCHECK_LEAF; |
||||
+ } |
||||
+ else if (strcEQ(w, "on")) { |
||||
+ *mask = SSL_OCSPCHECK_CHAIN; |
||||
+ } |
||||
+ else { |
||||
+ return apr_pstrcat(parms->temp_pool, parms->cmd->name, |
||||
+ ": Invalid argument '", w, "'", |
||||
+ NULL); |
||||
+ } |
||||
+ |
||||
+ while (*arg) { |
||||
+ w = ap_getword_conf(parms->temp_pool, &arg); |
||||
+ if (strcEQ(w, "no_ocsp_for_cert_ok")) { |
||||
+ *mask |= SSL_OCSPCHECK_NO_OCSP_FOR_CERT_OK; |
||||
+ } |
||||
+ else { |
||||
+ return apr_pstrcat(parms->temp_pool, parms->cmd->name, |
||||
+ ": Invalid argument '", w, "'", |
||||
+ NULL); |
||||
+ } |
||||
+ } |
||||
|
||||
- sc->server->ocsp_enabled = flag ? TRUE : FALSE; |
||||
+ return NULL; |
||||
+} |
||||
+ |
||||
+const char *ssl_cmd_SSLOCSPEnable(cmd_parms *cmd, void *dcfg, const char *arg) |
||||
+{ |
||||
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server); |
||||
|
||||
#ifdef OPENSSL_NO_OCSP |
||||
if (flag) { |
||||
@@ -1588,7 +1623,7 @@ const char *ssl_cmd_SSLOCSPEnable(cmd_parms *cmd, void *dcfg, int flag) |
||||
} |
||||
#endif |
||||
|
||||
- return NULL; |
||||
+ return ssl_cmd_ocspcheck_parse(cmd, arg, &sc->server->ocsp_mask); |
||||
} |
||||
|
||||
const char *ssl_cmd_SSLOCSPOverrideResponder(cmd_parms *cmd, void *dcfg, int flag) |
||||
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c |
||||
index 672760c..57b76c0 100644 |
||||
--- a/modules/ssl/ssl_engine_init.c |
||||
+++ b/modules/ssl/ssl_engine_init.c |
||||
@@ -762,6 +762,10 @@ static void ssl_init_ctx_crl(server_rec *s, |
||||
unsigned long crlflags = 0; |
||||
char *cfgp = mctx->pkp ? "SSLProxy" : "SSL"; |
||||
|
||||
+ if (mctx->ocsp_mask == UNSET) { |
||||
+ mctx->ocsp_mask = SSL_OCSPCHECK_NONE; |
||||
+ } |
||||
+ |
||||
/* |
||||
* Configure Certificate Revocation List (CRL) Details |
||||
*/ |
||||
diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c |
||||
index 5ff35f5..9dc236c 100644 |
||||
--- a/modules/ssl/ssl_engine_kernel.c |
||||
+++ b/modules/ssl/ssl_engine_kernel.c |
||||
@@ -1416,7 +1416,8 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX *ctx) |
||||
/* |
||||
* Perform OCSP-based revocation checks |
||||
*/ |
||||
- if (ok && sc->server->ocsp_enabled) { |
||||
+ if (ok && ((sc->server->ocsp_mask & SSL_OCSPCHECK_CHAIN) || |
||||
+ (errdepth == 0 && (sc->server->ocsp_mask & SSL_OCSPCHECK_LEAF)))) { |
||||
/* If there was an optional verification error, it's not |
||||
* possible to perform OCSP validation since the issuer may be |
||||
* missing/untrusted. Fail in that case. */ |
||||
diff --git a/modules/ssl/ssl_engine_ocsp.c b/modules/ssl/ssl_engine_ocsp.c |
||||
index 90da5c2..58d267b 100644 |
||||
--- a/modules/ssl/ssl_engine_ocsp.c |
||||
+++ b/modules/ssl/ssl_engine_ocsp.c |
||||
@@ -136,7 +136,14 @@ static int verify_ocsp_status(X509 *cert, X509_STORE_CTX *ctx, conn_rec *c, |
||||
|
||||
ruri = determine_responder_uri(sc, cert, c, pool); |
||||
if (!ruri) { |
||||
- return V_OCSP_CERTSTATUS_UNKNOWN; |
||||
+ if (sc->server->ocsp_mask & SSL_OCSPCHECK_NO_OCSP_FOR_CERT_OK) { |
||||
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, |
||||
+ "Skipping OCSP check for certificate cos no OCSP URL" |
||||
+ " found and no_ocsp_for_cert_ok is set"); |
||||
+ return V_OCSP_CERTSTATUS_GOOD; |
||||
+ } else { |
||||
+ return V_OCSP_CERTSTATUS_UNKNOWN; |
||||
+ } |
||||
} |
||||
|
||||
request = create_request(ctx, cert, &certID, s, pool); |
||||
diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h |
||||
index b601316..2d505f9 100644 |
||||
--- a/modules/ssl/ssl_private.h |
||||
+++ b/modules/ssl/ssl_private.h |
||||
@@ -379,6 +379,16 @@ typedef enum { |
||||
} ssl_crlcheck_t; |
||||
|
||||
/** |
||||
+ * OCSP checking mask (mode | flags) |
||||
+ */ |
||||
+typedef enum { |
||||
+ SSL_OCSPCHECK_NONE = (0), |
||||
+ SSL_OCSPCHECK_LEAF = (1 << 0), |
||||
+ SSL_OCSPCHECK_CHAIN = (1 << 1), |
||||
+ SSL_OCSPCHECK_NO_OCSP_FOR_CERT_OK = (1 << 2) |
||||
+} ssl_ocspcheck_t; |
||||
+ |
||||
+/** |
||||
* Define the SSL pass phrase dialog types |
||||
*/ |
||||
typedef enum { |
||||
@@ -668,7 +678,7 @@ typedef struct { |
||||
|
||||
modssl_auth_ctx_t auth; |
||||
|
||||
- BOOL ocsp_enabled; /* true if OCSP verification enabled */ |
||||
+ int ocsp_mask; |
||||
BOOL ocsp_force_default; /* true if the default responder URL is |
||||
* used regardless of per-cert URL */ |
||||
const char *ocsp_responder; /* default responder URL */ |
||||
@@ -796,7 +806,7 @@ const char *ssl_cmd_SSLOCSPDefaultResponder(cmd_parms *cmd, void *dcfg, const ch |
||||
const char *ssl_cmd_SSLOCSPResponseTimeSkew(cmd_parms *cmd, void *dcfg, const char *arg); |
||||
const char *ssl_cmd_SSLOCSPResponseMaxAge(cmd_parms *cmd, void *dcfg, const char *arg); |
||||
const char *ssl_cmd_SSLOCSPResponderTimeout(cmd_parms *cmd, void *dcfg, const char *arg); |
||||
-const char *ssl_cmd_SSLOCSPEnable(cmd_parms *cmd, void *dcfg, int flag); |
||||
+const char *ssl_cmd_SSLOCSPEnable(cmd_parms *cmd, void *dcfg, const char *flag); |
||||
|
||||
#ifndef OPENSSL_NO_SRP |
||||
const char *ssl_cmd_SSLSRPVerifierFile(cmd_parms *cmd, void *dcfg, const char *arg); |
@ -0,0 +1,83 @@
@@ -0,0 +1,83 @@
|
||||
diff --git a/modules/http/http_request.c b/modules/http/http_request.c |
||||
index c97dc77..9885de4 100644 |
||||
--- a/modules/http/http_request.c |
||||
+++ b/modules/http/http_request.c |
||||
@@ -227,11 +227,21 @@ AP_DECLARE(void) ap_die(int type, request_rec *r) |
||||
ap_die_r(type, r, r->status); |
||||
} |
||||
|
||||
-static void check_pipeline(conn_rec *c) |
||||
+#define RETRIEVE_BRIGADE_FROM_POOL(bb, key, pool, allocator) do { \ |
||||
+ apr_pool_userdata_get((void **)&bb, key, pool); \ |
||||
+ if (bb == NULL) { \ |
||||
+ bb = apr_brigade_create(pool, allocator); \ |
||||
+ apr_pool_userdata_setn((const void *)bb, key, NULL, pool); \ |
||||
+ } \ |
||||
+ else { \ |
||||
+ apr_brigade_cleanup(bb); \ |
||||
+ } \ |
||||
+} while(0) |
||||
+ |
||||
+static void check_pipeline(conn_rec *c, apr_bucket_brigade *bb) |
||||
{ |
||||
if (c->keepalive != AP_CONN_CLOSE) { |
||||
apr_status_t rv; |
||||
- apr_bucket_brigade *bb = apr_brigade_create(c->pool, c->bucket_alloc); |
||||
|
||||
rv = ap_get_brigade(c->input_filters, bb, AP_MODE_SPECULATIVE, |
||||
APR_NONBLOCK_READ, 1); |
||||
@@ -245,11 +255,10 @@ static void check_pipeline(conn_rec *c) |
||||
else { |
||||
c->data_in_input_filters = 1; |
||||
} |
||||
- apr_brigade_destroy(bb); |
||||
+ apr_brigade_cleanup(bb); |
||||
} |
||||
} |
||||
|
||||
- |
||||
AP_DECLARE(void) ap_process_request_after_handler(request_rec *r) |
||||
{ |
||||
apr_bucket_brigade *bb; |
||||
@@ -260,11 +269,13 @@ AP_DECLARE(void) ap_process_request_after_handler(request_rec *r) |
||||
* this bucket is destroyed, the request will be logged and |
||||
* its pool will be freed |
||||
*/ |
||||
- bb = apr_brigade_create(r->connection->pool, r->connection->bucket_alloc); |
||||
+ RETRIEVE_BRIGADE_FROM_POOL(bb, "ap_process_request_after_handler_brigade", |
||||
+ c->pool, c->bucket_alloc); |
||||
b = ap_bucket_eor_create(r->connection->bucket_alloc, r); |
||||
APR_BRIGADE_INSERT_HEAD(bb, b); |
||||
|
||||
ap_pass_brigade(r->connection->output_filters, bb); |
||||
+ apr_brigade_cleanup(bb); |
||||
|
||||
/* From here onward, it is no longer safe to reference r |
||||
* or r->pool, because r->pool may have been destroyed |
||||
@@ -273,7 +284,7 @@ AP_DECLARE(void) ap_process_request_after_handler(request_rec *r) |
||||
|
||||
if (c->cs) |
||||
c->cs->state = CONN_STATE_WRITE_COMPLETION; |
||||
- check_pipeline(c); |
||||
+ check_pipeline(c, bb); |
||||
AP_PROCESS_REQUEST_RETURN((uintptr_t)r, r->uri, r->status); |
||||
if (ap_extended_status) { |
||||
ap_time_process_request(c->sbh, STOP_PREQUEST); |
||||
@@ -363,7 +374,8 @@ void ap_process_request(request_rec *r) |
||||
ap_process_async_request(r); |
||||
|
||||
if (!c->data_in_input_filters) { |
||||
- bb = apr_brigade_create(c->pool, c->bucket_alloc); |
||||
+ RETRIEVE_BRIGADE_FROM_POOL(bb, "ap_process_request_after_handler_brigade", |
||||
+ c->pool, c->bucket_alloc); |
||||
b = apr_bucket_flush_create(c->bucket_alloc); |
||||
APR_BRIGADE_INSERT_HEAD(bb, b); |
||||
rv = ap_pass_brigade(c->output_filters, bb); |
||||
@@ -380,6 +392,7 @@ void ap_process_request(request_rec *r) |
||||
"Timeout while writing data for URI %s to the" |
||||
" client", r->unparsed_uri); |
||||
} |
||||
+ apr_brigade_cleanup(bb); |
||||
} |
||||
if (ap_extended_status) { |
||||
ap_time_process_request(c->sbh, STOP_PREQUEST); |
Loading…
Reference in new issue