This is an automated email from the ASF dual-hosted git repository.

markt-asf pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/10.1.x by this push:
     new 4a79a3e505 Require qop for DIGEST.
4a79a3e505 is described below

commit 4a79a3e5057a59108503973d0094b463fa639076
Author: Mark Thomas <[email protected]>
AuthorDate: Wed Jun 24 09:27:23 2026 +0100

    Require qop for DIGEST.
    
    It was only optional to support minimal RFC 2069 (1997) implementations.
---
 .../authenticator/DigestAuthenticator.java         | 58 ++++++++++------------
 .../authenticator/TestDigestAuthenticator.java     |  4 +-
 webapps/docs/changelog.xml                         |  4 ++
 3 files changed, 32 insertions(+), 34 deletions(-)

diff --git a/java/org/apache/catalina/authenticator/DigestAuthenticator.java 
b/java/org/apache/catalina/authenticator/DigestAuthenticator.java
index 561db5c3ab..af179d477e 100644
--- a/java/org/apache/catalina/authenticator/DigestAuthenticator.java
+++ b/java/org/apache/catalina/authenticator/DigestAuthenticator.java
@@ -670,7 +670,8 @@ public class DigestAuthenticator extends AuthenticatorBase {
          * @return {@code true} if validation succeeded
          */
         public boolean validate(Request request, List<AuthDigest> algorithms) {
-            if ((userName == null) || (realmName == null) || (nonce == null) 
|| (uri == null) || (response == null)) {
+            if ((userName == null) || (realmName == null) || (nonce == null) 
|| (uri == null) || (response == null) ||
+                    qop == null) {
                 return false;
             }
 
@@ -743,44 +744,37 @@ public class DigestAuthenticator extends 
AuthenticatorBase {
             }
 
             // Validate qop
-            if (qop != null && !QOP.equals(qop)) {
+            if (!QOP.equals(qop)) {
                 return false;
             }
 
             // Validate cnonce and nc
-            // Check if presence of nc and Cnonce is consistent with presence 
of qop
-            if (qop == null) {
-                if (cnonce != null || nc != null) {
-                    return false;
-                }
+            if (cnonce == null || nc == null) {
+                return false;
+            }
+            // RFC 2617 says nc must be 8 digits long. Older Android clients
+            // use 6. 2.3.5 < fixed Android version <= 4.0.3
+            if (nc.length() < 6 || nc.length() > 8) {
+                return false;
+            }
+            long count;
+            try {
+                count = Long.parseLong(nc, 16);
+            } catch (NumberFormatException nfe) {
+                return false;
+            }
+            NonceInfo info;
+            synchronized (nonces) {
+                info = nonces.get(nonce);
+            }
+            if (info == null) {
+                // Nonce is valid but not in cache. It must have dropped out
+                // of the cache - force a re-authentication
+                nonceStale = true;
             } else {
-                if (cnonce == null || nc == null) {
-                    return false;
-                }
-                // RFC 2617 says nc must be 8 digits long. Older Android 
clients
-                // use 6. 2.3.5 < fixed Android version <= 4.0.3
-                if (nc.length() < 6 || nc.length() > 8) {
+                if (!info.nonceCountValid(count)) {
                     return false;
                 }
-                long count;
-                try {
-                    count = Long.parseLong(nc, 16);
-                } catch (NumberFormatException nfe) {
-                    return false;
-                }
-                NonceInfo info;
-                synchronized (nonces) {
-                    info = nonces.get(nonce);
-                }
-                if (info == null) {
-                    // Nonce is valid but not in cache. It must have dropped 
out
-                    // of the cache - force a re-authentication
-                    nonceStale = true;
-                } else {
-                    if (!info.nonceCountValid(count)) {
-                        return false;
-                    }
-                }
             }
 
             // Validate algorithm is one of the algorithms configured for the 
authenticator
diff --git 
a/test/org/apache/catalina/authenticator/TestDigestAuthenticator.java 
b/test/org/apache/catalina/authenticator/TestDigestAuthenticator.java
index 5ac2654793..72f9bf5039 100644
--- a/test/org/apache/catalina/authenticator/TestDigestAuthenticator.java
+++ b/test/org/apache/catalina/authenticator/TestDigestAuthenticator.java
@@ -85,8 +85,8 @@ public class TestDigestAuthenticator extends TomcatBaseTest {
     }
 
     @Test
-    public void testValidNoQop() throws Exception {
-        doTest(USER, PWD, CONTEXT_PATH + URI, false, true, REALM, true, true, 
null, null, null, null, true, true);
+    public void testInvalidNoQop() throws Exception {
+        doTest(USER, PWD, CONTEXT_PATH + URI, false, true, REALM, true, true, 
null, null, null, null, false, false);
     }
 
     @Test
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index bfb5559b8e..4d7a46ba17 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -129,6 +129,10 @@
         Restore ability to extend many element classes from
         <code>AbstractAccessLogValve</code>. (remm)
       </fix>
+      <fix>
+        Align DIGEST authentication with RFC 7616 and require clients to 
provide
+        a valid <code>qop</code> parameter. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Coyote">


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to