You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by co...@apache.org on 2016/02/22 16:32:40 UTC
svn commit: r1731662 - in /httpd/httpd/trunk: CHANGES
modules/aaa/mod_auth_digest.c
Author: covener
Date: Mon Feb 22 15:32:40 2016
New Revision: 1731662
URL: http://svn.apache.org/viewvc?rev=1731662&view=rev
Log:
PR59039 Digest not working with ap_expr based AuthName
Stop caching the configured realm during config processing and always
call ap_auth_name(r) to determine (=evaluate potential expression)
the configured realm
Modified:
httpd/httpd/trunk/CHANGES
httpd/httpd/trunk/modules/aaa/mod_auth_digest.c
Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1731662&r1=1731661&r2=1731662&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Mon Feb 22 15:32:40 2016
@@ -1,6 +1,9 @@
-*- coding: utf-8 -*-
Changes with Apache 2.5.0
+ *) mod_auth_digest: Fix compatibility with expression-based Authname. PR59039.
+ [Eric Covener]
+
*) mpm: Add a complete_connection hook that confirms whether an MPM is allowed
to leave the WRITE_COMPLETION phase. Move filter code out of the MPMs.
[Graham Leggett]
Modified: httpd/httpd/trunk/modules/aaa/mod_auth_digest.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/aaa/mod_auth_digest.c?rev=1731662&r1=1731661&r2=1731662&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/aaa/mod_auth_digest.c (original)
+++ httpd/httpd/trunk/modules/aaa/mod_auth_digest.c Mon Feb 22 15:32:40 2016
@@ -85,7 +85,6 @@
typedef struct digest_config_struct {
const char *dir_name;
authn_provider_list *providers;
- const char *realm;
apr_array_header_t *qop_list;
apr_sha1_ctx_t nonce_ctx;
apr_time_t nonce_lifetime;
@@ -451,6 +450,11 @@ static void *create_digest_dir_config(ap
return conf;
}
+
+/*
+ * The realm is no longer precomputed because it may be an expression, which
+ * makes this hooking of AuthName quite weird.
+ */
static const char *set_realm(cmd_parms *cmd, void *config, const char *realm)
{
digest_config_rec *conf = (digest_config_rec *) config;
@@ -465,21 +469,13 @@ static const char *set_realm(cmd_parms *
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
- * let the core get at it too, which is why we decline at the end -
- * this relies on the fact that http_core is last in the list.
- */
- conf->realm = realm;
-
/* we precompute the part of the nonce hash that is constant (well,
* the host:port would be too, but that varies for .htaccess files
* and directives outside a virtual host section)
*/
apr_sha1_init(&conf->nonce_ctx);
apr_sha1_update_binary(&conf->nonce_ctx, secret, SECRET_LEN);
- apr_sha1_update_binary(&conf->nonce_ctx, (const unsigned char *) realm,
- strlen(realm));
+
return DECLINE_CMD;
}
@@ -1041,7 +1037,8 @@ static int parse_hdr_and_update_nc(reque
*/
static void gen_nonce_hash(char *hash, const char *timestr, const char *opaque,
const server_rec *server,
- const digest_config_rec *conf)
+ const digest_config_rec *conf,
+ const char *realm)
{
unsigned char sha1[APR_SHA1_DIGESTSIZE];
apr_sha1_ctx_t ctx;
@@ -1053,6 +1050,9 @@ static void gen_nonce_hash(char *hash, c
apr_sha1_update_binary(&ctx, (const unsigned char *) &server->port,
sizeof(server->port));
*/
+
+ apr_sha1_update_binary(&ctx, (const unsigned char *) realm, strlen(realm));
+
apr_sha1_update_binary(&ctx, (const unsigned char *) timestr, strlen(timestr));
if (opaque) {
apr_sha1_update_binary(&ctx, (const unsigned char *) opaque,
@@ -1068,7 +1068,8 @@ static void gen_nonce_hash(char *hash, c
*/
static const char *gen_nonce(apr_pool_t *p, apr_time_t now, const char *opaque,
const server_rec *server,
- const digest_config_rec *conf)
+ const digest_config_rec *conf,
+ const char *realm)
{
char *nonce = apr_palloc(p, NONCE_LEN+1);
time_rec t;
@@ -1087,7 +1088,7 @@ static const char *gen_nonce(apr_pool_t
t.time = 42;
}
apr_base64_encode_binary(nonce, t.arr, sizeof(t.arr));
- gen_nonce_hash(nonce+NONCE_TIME_LEN, nonce, opaque, server, conf);
+ gen_nonce_hash(nonce+NONCE_TIME_LEN, nonce, opaque, server, conf, realm);
return nonce;
}
@@ -1197,7 +1198,7 @@ static void note_digest_auth_failure(req
/* Setup nonce */
- nonce = gen_nonce(r->pool, r->request_time, opaque, r->server, conf);
+ nonce = gen_nonce(r->pool, r->request_time, opaque, r->server, conf, ap_auth_name(r));
if (resp->client && conf->nonce_lifetime == 0) {
memcpy(resp->client->last_nonce, nonce, NONCE_LEN+1);
}
@@ -1303,7 +1304,7 @@ static authn_status get_hash(request_rec
/* We expect the password to be md5 hash of user:realm:password */
- auth_result = provider->get_realm_hash(r, user, conf->realm,
+ auth_result = provider->get_realm_hash(r, user, ap_auth_name(r),
&password);
apr_table_unset(r->notes, AUTHN_PROVIDER_NAME_NOTE);
@@ -1399,7 +1400,7 @@ static int check_nonce(request_rec *r, d
tmp = resp->nonce[NONCE_TIME_LEN];
resp->nonce[NONCE_TIME_LEN] = '\0';
apr_base64_decode_binary(nonce_time.arr, resp->nonce);
- gen_nonce_hash(hash, resp->nonce, resp->opaque, r->server, conf);
+ gen_nonce_hash(hash, resp->nonce, resp->opaque, r->server, conf, ap_auth_name(r));
resp->nonce[NONCE_TIME_LEN] = tmp;
resp->nonce_time = nonce_time.time;
@@ -1546,6 +1547,7 @@ static int authenticate_digest_user(requ
const char *t;
int res;
authn_status return_code;
+ const char *realm;
/* do we require Digest auth for this URI? */
@@ -1573,6 +1575,7 @@ static int authenticate_digest_user(requ
&auth_digest_module);
resp->needed_auth = 1;
+ realm = ap_auth_name(r);
/* get our conf */
@@ -1673,8 +1676,10 @@ static int authenticate_digest_user(requ
note_digest_auth_failure(r, conf, resp, 0);
return HTTP_UNAUTHORIZED;
}
+
+
- if (!conf->realm) {
+ if (!realm) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02533)
"realm mismatch - got `%s' but no realm specified",
resp->realm);
@@ -1682,10 +1687,10 @@ static int authenticate_digest_user(requ
return HTTP_UNAUTHORIZED;
}
- if (!resp->realm || strcmp(resp->realm, conf->realm)) {
+ if (!resp->realm || strcmp(resp->realm, realm)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01788)
"realm mismatch - got `%s' but expected `%s'",
- resp->realm, conf->realm);
+ resp->realm, realm);
note_digest_auth_failure(r, conf, resp, 0);
return HTTP_UNAUTHORIZED;
}
@@ -1704,7 +1709,7 @@ static int authenticate_digest_user(requ
if (return_code == AUTH_USER_NOT_FOUND) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01790)
"user `%s' in realm `%s' not found: %s",
- r->user, conf->realm, r->uri);
+ r->user, realm, r->uri);
note_digest_auth_failure(r, conf, resp, 0);
return HTTP_UNAUTHORIZED;
}
@@ -1715,7 +1720,7 @@ static int authenticate_digest_user(requ
/* authentication denied in the provider before attempting a match */
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01791)
"user `%s' in realm `%s' denied by provider: %s",
- r->user, conf->realm, r->uri);
+ r->user, realm, r->uri);
note_digest_auth_failure(r, conf, resp, 0);
return HTTP_UNAUTHORIZED;
}
@@ -1818,7 +1823,7 @@ static int add_auth_info(request_rec *r)
if ((r->request_time - resp->nonce_time) > (conf->nonce_lifetime-NEXTNONCE_DELTA)) {
nextnonce = apr_pstrcat(r->pool, ", nextnonce=\"",
gen_nonce(r->pool, r->request_time,
- resp->opaque, r->server, conf),
+ resp->opaque, r->server, conf, ap_auth_name(r)),
"\"", NULL);
if (resp->client)
resp->client->nonce_count = 0;
@@ -1826,7 +1831,7 @@ static int add_auth_info(request_rec *r)
}
else if (conf->nonce_lifetime == 0 && resp->client) {
const char *nonce = gen_nonce(r->pool, 0, resp->opaque, r->server,
- conf);
+ conf, ap_auth_name(r));
nextnonce = apr_pstrcat(r->pool, ", nextnonce=\"", nonce, "\"", NULL);
memcpy(resp->client->last_nonce, nonce, NONCE_LEN+1);
}