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