Author: markt Date: Thu Feb 7 11:00:57 2013 New Revision: 1443405 URL: http://svn.apache.org/viewvc?rev=1443405&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/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java tomcat/trunk/test/org/apache/catalina/authenticator/TestDigestAuthenticator.java Modified: tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java?rev=1443405&r1=1443404&r2=1443405&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java (original) +++ tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java Thu Feb 7 11:00:57 2013 @@ -92,6 +92,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. */ @@ -325,6 +333,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/trunk/test/org/apache/catalina/authenticator/TestDigestAuthenticator.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/authenticator/TestDigestAuthenticator.java?rev=1443405&r1=1443404&r2=1443405&view=diff ============================================================================== --- tomcat/trunk/test/org/apache/catalina/authenticator/TestDigestAuthenticator.java (original) +++ tomcat/trunk/test/org/apache/catalina/authenticator/TestDigestAuthenticator.java Thu Feb 7 11:00:57 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, @@ -362,4 +387,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"; + } + } } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org