From 44b3ddc560c490c60600998fa2bf59b142d08e05 Mon Sep 17 00:00:00 2001 From: Joe Orton Date: Tue, 12 Mar 2019 09:24:26 +0000 Subject: [PATCH] Merge r1853190 from trunk: Fix a race condition. Authentication with valid credentials could be refused in case of concurrent accesses from different users. PR: 63124 Submitted by: Simon Kappel Reviewed by: jailletc36, icing, jorton git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1855298 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 4 ++++ modules/aaa/mod_auth_digest.c | 26 ++++++++++++-------------- 2 files changed, 16 insertions(+), 14 deletions(-) #diff --git a/CHANGES b/CHANGES #index 08fc740db30..e79251389d5 100644 #--- a/CHANGES #+++ b/CHANGES #@@ -1,6 +1,10 @@ # -*- coding: utf-8 -*- # Changes with Apache 2.4.39 # #+ *) mod_auth_digest: Fix a race condition. Authentication with valid #+ credentials could be refused in case of concurrent accesses from #+ different users. PR 63124. [Simon Kappel ] #+ # *) mod_proxy_wstunnel: Fix websocket proxy over UDS. # PR 62932 # diff --git a/modules/aaa/mod_auth_digest.c b/modules/aaa/mod_auth_digest.c index a67f06986f2..b76094114dd 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; @@ -1304,7 +1304,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; @@ -1356,7 +1356,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; @@ -1483,25 +1483,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); @@ -1514,7 +1513,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') { @@ -1759,7 +1757,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) @@ -1789,7 +1787,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); @@ -1819,7 +1817,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; @@ -1903,7 +1901,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);