Index: src/java/org/apache/commons/httpclient/auth/DigestScheme.java =================================================================== RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/DigestScheme.java,v retrieving revision 1.6 diff -u -r1.6 DigestScheme.java --- src/java/org/apache/commons/httpclient/auth/DigestScheme.java 13 Aug 2003 19:57:10 -0000 1.6 +++ src/java/org/apache/commons/httpclient/auth/DigestScheme.java 4 Sep 2003 18:54:29 -0000 @@ -220,6 +220,12 @@ String cnonce = (String) params.get("cnonce"); String qop = (String) params.get("qop"); String method = (String) params.get("methodname"); + String algorithm = (String) params.get("algorithm"); + + // If an algorithm is not specified, default to MD5. + if(algorithm == null) { + algorithm="MD5"; + } if (qop != null) { qop = "auth"; @@ -236,16 +242,35 @@ } // Calculating digest according to rfc 2617 + + String a1 = null; + if(algorithm.equals("MD5")) { + // unq(username-value) ":" unq(realm-value) ":" passwd + a1 = uname + ":" + realm + ":" + pwd; + } else if(algorithm.equals("MD5-sess")) { + // H( unq(username-value) ":" unq(realm-value) ":" passwd ) + // ":" unq(nonce-value) + // ":" unq(cnonce-value) + + String tmp=encode(md5Helper.digest(HttpConstants.getBytes( + uname + ":" + realm + ":" + pwd))); + + a1 = tmp + ":" + nonce + ":" + cnonce; + } else { + LOG.warn("Unhandled algorithm " + algorithm + " requested"); + a1 = uname + ":" + realm + ":" + pwd; + } + String md5a1 = encode(md5Helper.digest(HttpConstants.getBytes(a1))); + String serverDigestValue; + String a2 = method + ":" + uri; String md5a2 = encode(md5Helper.digest(HttpConstants.getBytes(a2))); - String digestValue = uname + ":" + realm + ":" + pwd; - String md5a1 - = encode(md5Helper.digest(HttpConstants.getBytes(digestValue))); - String serverDigestValue; if (qop == null) { + LOG.debug("Using null qop method"); serverDigestValue = md5a1 + ":" + nonce + ":" + md5a2; } else { + LOG.debug("Using qop method " + qop); serverDigestValue = md5a1 + ":" + nonce + ":" + nc + ":" + cnonce + ":" + qop + ":" + md5a2; } @@ -283,12 +308,11 @@ String opaque = (String) params.get("opaque"); String response = digest; String qop = (String) params.get("qop"); + String algorithm = (String) params.get("algorithm"); if (qop != null) { qop = "auth"; //we only support auth } - - String algorithm = "MD5"; //we only support MD5 sb.append("username=\"" + uname + "\"") .append(", realm=\"" + realm + "\"") Index: src/test/org/apache/commons/httpclient/TestAuthenticator.java =================================================================== RCS file: /home/cvspublic/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestAuthenticator.java,v retrieving revision 1.28 diff -u -r1.28 TestAuthenticator.java --- src/test/org/apache/commons/httpclient/TestAuthenticator.java 12 Aug 2003 02:35:17 -0000 1.28 +++ src/test/org/apache/commons/httpclient/TestAuthenticator.java 4 Sep 2003 18:54:30 -0000 @@ -378,7 +378,39 @@ checkAuthorization(cred2, method.getName(), method.getRequestHeader("Authorization").getValue()); } } - + + /** + * Test digest authentication using the MD5-sess algorithm. + */ + public void testDigestAuthenticationMD5Sess() throws Exception { + // Example using Digest auth with MD5-sess + + String realm="realm"; + String username="username"; + String password="password"; + String nonce="e273f1776275974f1a120d8b92c5b3cb"; + + String challenge="Digest realm=\"" + realm + "\", " + + nonce + "\"" + nonce + "\", " + + "opaque=\"SomeString\", " + + "stale=false, " + + "algorithm=MD5-sess, " + + "qop=\"auth\""; + + HttpState state = new HttpState(); + UsernamePasswordCredentials cred = + new UsernamePasswordCredentials(username, password); + state.setCredentials(realm, null, cred); + AuthScheme authscheme = new DigestScheme(challenge); + HttpMethod method = + new SimpleHttpMethod(new Header("WWW-Authenticate", challenge)); + assertTrue(HttpAuthenticator.authenticate( + authscheme, method, null, state)); + assertTrue(null != method.getRequestHeader("Authorization")); + checkAuthorization(cred, method.getName(), + method.getRequestHeader("Authorization").getValue()); + } + // --------------------------------- Test Methods for NTLM Authentication public void testNTLMAuthenticationWithNoCreds() {