Author: markt
Date: Thu Feb  7 11:03:34 2013
New Revision: 1443407

URL: http://svn.apache.org/viewvc?rev=1443407&view=rev
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=54521
Ensure concurrent requests that require DIGEST auth receive unique nonces.

Modified:
    tomcat/tc7.0.x/trunk/   (props changed)
    
tomcat/tc7.0.x/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java
    
tomcat/tc7.0.x/trunk/test/org/apache/catalina/authenticator/TestDigestAuthenticator.java
    tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml

Propchange: tomcat/tc7.0.x/trunk/
------------------------------------------------------------------------------
  Merged /tomcat/trunk:r1443405

Modified: 
tomcat/tc7.0.x/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java?rev=1443407&r1=1443406&r2=1443407&view=diff
==============================================================================
--- 
tomcat/tc7.0.x/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java
 (original)
+++ 
tomcat/tc7.0.x/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java
 Thu Feb  7 11:03:34 2013
@@ -114,6 +114,14 @@ public class DigestAuthenticator extends
 
 
     /**
+     * The last timestamp used to generate a nonce. Each nonce should get a
+     * unique timestamp.
+     */
+    protected long lastTimestamp = 0;
+    protected final Object lastTimestampLock = new Object();
+
+
+    /**
      * Maximum number of server nonces to keep in the cache. If not specified,
      * the default value of 1000 is used.
      */
@@ -399,6 +407,13 @@ public class DigestAuthenticator extends
 
         long currentTime = System.currentTimeMillis();
 
+        synchronized (lastTimestampLock) {
+            if (currentTime > lastTimestamp) {
+                lastTimestamp = currentTime;
+            } else {
+                currentTime = ++lastTimestamp;
+            }
+        }
 
         String ipTimeKey =
             request.getRemoteAddr() + ":" + currentTime + ":" + getKey();

Modified: 
tomcat/tc7.0.x/trunk/test/org/apache/catalina/authenticator/TestDigestAuthenticator.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/test/org/apache/catalina/authenticator/TestDigestAuthenticator.java?rev=1443407&r1=1443406&r2=1443407&view=diff
==============================================================================
--- 
tomcat/tc7.0.x/trunk/test/org/apache/catalina/authenticator/TestDigestAuthenticator.java
 (original)
+++ 
tomcat/tc7.0.x/trunk/test/org/apache/catalina/authenticator/TestDigestAuthenticator.java
 Thu Feb  7 11:03:34 2013
@@ -18,15 +18,21 @@ package org.apache.catalina.authenticato
 
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
+import org.junit.Assert;
 import org.junit.Test;
 
 import org.apache.catalina.Context;
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.core.TesterContext;
 import org.apache.catalina.deploy.LoginConfig;
 import org.apache.catalina.deploy.SecurityCollection;
 import org.apache.catalina.deploy.SecurityConstraint;
@@ -53,6 +59,25 @@ public class TestDigestAuthenticator ext
     private static String NC2 = "00000002";
     private static String QOP = "auth";
 
+
+    @Test
+    public void bug54521() throws LifecycleException {
+        DigestAuthenticator digestAuthenticator = new DigestAuthenticator();
+        digestAuthenticator.setContainer(new TesterContext());
+        digestAuthenticator.start();
+        Request request = new TesterRequest();
+        final int count = 1000;
+
+        Set<String> nonces = new HashSet<>();
+
+        for (int i = 0; i < count; i++) {
+            nonces.add(digestAuthenticator.generateNonce(request));
+        }
+
+        Assert.assertEquals(count,  nonces.size());
+    }
+
+
     @Test
     public void testAllValid() throws Exception {
         doTest(USER, PWD, CONTEXT_PATH + URI, false, true, REALM, true, true,
@@ -363,4 +388,13 @@ public class TestDigestAuthenticator ext
         return MD5Encoder.encode(
                 ConcurrentMessageDigest.digestMD5(input.getBytes()));
     }
+
+
+    private static class TesterRequest extends Request {
+
+        @Override
+        public String getRemoteAddr() {
+            return "127.0.0.1";
+        }
+    }
 }

Modified: tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml?rev=1443407&r1=1443406&r2=1443407&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Thu Feb  7 11:03:34 2013
@@ -56,9 +56,15 @@
 <section name="Tomcat 7.0.37 (markt)">
   <subsection name="Catalina">
     <changelog>
-      <bug>54534</bug>: Ensure that, if a call to
-      <code>StandardWrapper#isSingleThreadModel()</code> triggers the loading 
of
-      a Servlet, the correct class loader is used. (markt)
+      <fix>
+        <bug>54521</bug>: Ensure that concurrent requests that require a DIGEST
+        authentication challenge receive different nonce values. (markt)
+      </fix>
+      <fix>
+        <bug>54534</bug>: Ensure that, if a call to
+        <code>StandardWrapper#isSingleThreadModel()</code> triggers the loading
+        of a Servlet, the correct class loader is used. (markt)
+      </fix>
     </changelog>
   </subsection>
 </section>



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to