]> granicus.if.org Git - apache/commitdiff
Fix a race condition.
authorChristophe Jaillet <jailletc36@apache.org>
Fri, 8 Feb 2019 06:14:47 +0000 (06:14 +0000)
committerChristophe Jaillet <jailletc36@apache.org>
Fri, 8 Feb 2019 06:14:47 +0000 (06:14 +0000)
Authentication with valid credentials could be refused in case of concurrent accesses from different users.

PR 63124 [Simon Kappel <simon.kappel axis.com>]

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1853190 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
modules/aaa/mod_auth_digest.c

diff --git a/CHANGES b/CHANGES
index 80b3102ea8b5838cbb4f486066d7f2ef033df565..b686be6be94191d995cf1b54f394d8ceff55ea92 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,8 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.1
+  *) 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 <simon.kappel axis.com>]
 
   *) mod_ssl: Don't unset FIPS mode on restart unless it's forced by
      configuration (SSLFIPS on) and not active by default in OpenSSL.
index 7179f1dc9701016fb386991fc9b8b4635d143c94..1209784278012fe85498ea960e8ab935b64b5d71 100644 (file)
@@ -91,7 +91,6 @@ typedef struct digest_config_struct {
     int          check_nc;
     const char  *algorithm;
     char        *uri_list;
-    const char  *ha1;
 } digest_config_rec;
 
 
@@ -152,6 +151,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;
 
@@ -1305,7 +1305,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;
@@ -1357,7 +1357,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;
@@ -1484,25 +1484,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);
@@ -1515,7 +1514,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') {
@@ -1738,7 +1736,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)
@@ -1771,7 +1769,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);
@@ -1801,7 +1799,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;
@@ -1885,7 +1883,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);