Skip to content

Commit 333de99

Browse files
committed
Merge pull request AsyncHttpClient#97 from taer/master
Support for old style digest auth
2 parents ca59da0 + 5255aaf commit 333de99

File tree

3 files changed

+96
-2
lines changed

3 files changed

+96
-2
lines changed

src/main/java/com/ning/http/client/Realm.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -524,12 +524,23 @@ private void newResponse() throws UnsupportedEncodingException {
524524
byte[] ha1 = md.digest();
525525

526526
md.reset();
527+
528+
//HA2 if qop is auth-int is methodName:url:md5(entityBody)
527529
md.update(new StringBuilder(methodName)
528530
.append(':')
529531
.append(uri).toString().getBytes("ISO-8859-1"));
530532
byte[] ha2 = md.digest();
531533

532-
md.update(new StringBuilder(toBase16(ha1))
534+
if(qop==null || qop.equals("")) {
535+
md.update(new StringBuilder(toBase16(ha1))
536+
.append(':')
537+
.append(nonce)
538+
.append(':')
539+
.append(toBase16(ha2)).toString().getBytes("ISO-8859-1"));
540+
541+
} else {
542+
//qop ="auth" or "auth-int"
543+
md.update(new StringBuilder(toBase16(ha1))
533544
.append(':')
534545
.append(nonce)
535546
.append(':')
@@ -540,6 +551,8 @@ private void newResponse() throws UnsupportedEncodingException {
540551
.append(qop)
541552
.append(':')
542553
.append(toBase16(ha2)).toString().getBytes("ISO-8859-1"));
554+
}
555+
543556
byte[] digest = md.digest();
544557

545558
response = toHexString(digest);

src/main/java/com/ning/http/client/providers/netty/NettyAsyncHttpProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2141,7 +2141,7 @@ public void handle(final ChannelHandlerContext ctx, final MessageEvent e) throws
21412141
}
21422142

21432143
final Realm nr = new Realm.RealmBuilder().clone(newRealm)
2144-
.setUri(request.getUrl()).build();
2144+
.setUri(URI.create(request.getUrl()).getPath()).build();
21452145

21462146
log.debug("Sending authentication to {}", request.getUrl());
21472147
AsyncCallable ac = new AsyncCallable(future) {

src/test/java/com/ning/http/client/RealmTest.java

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
import com.ning.http.client.Realm.AuthScheme;
1616
import com.ning.http.client.Realm.RealmBuilder;
1717
import org.testng.Assert;
18+
import java.math.BigInteger;
19+
import java.security.MessageDigest;
20+
import java.security.NoSuchAlgorithmException;
1821
import org.testng.annotations.Test;
1922

2023
public class RealmTest {
@@ -36,4 +39,82 @@ public void testClone() {
3639
Assert.assertEquals( clone.getAlgorithm(), orig.getAlgorithm() );
3740
Assert.assertEquals( clone.getAuthScheme(), orig.getAuthScheme() );
3841
}
42+
@Test(groups = "fast")
43+
public void testOldDigestEmptyString() {
44+
String qop="";
45+
testOldDigest(qop);
46+
}
47+
@Test(groups = "fast")
48+
public void testOldDigestNull() {
49+
String qop=null;
50+
testOldDigest(qop);
51+
}
52+
53+
private void testOldDigest(String qop){
54+
String user="user";
55+
String pass="pass";
56+
String realm="realm";
57+
String nonce="nonce";
58+
String method="GET";
59+
String uri="/foo";
60+
RealmBuilder builder = new RealmBuilder();
61+
builder.setPrincipal( user ).setPassword( pass );
62+
builder.setNonce( nonce );
63+
builder.setUri( uri );
64+
builder.setMethodName(method);
65+
builder.setRealmName( realm );
66+
builder.setQop(qop);
67+
builder.setScheme( AuthScheme.DIGEST );
68+
Realm orig = builder.build();
69+
70+
String ha1=getMd5(user +":" + realm +":"+pass);
71+
String ha2=getMd5(method +":"+ uri);
72+
String expectedResponse=getMd5(ha1 +":" + nonce +":" + ha2);
73+
74+
Assert.assertEquals(expectedResponse,orig.getResponse());
75+
}
76+
77+
@Test(groups = "fast")
78+
public void testStrongDigest() {
79+
String user="user";
80+
String pass="pass";
81+
String realm="realm";
82+
String nonce="nonce";
83+
String method="GET";
84+
String uri="/foo";
85+
String qop="auth";
86+
RealmBuilder builder = new RealmBuilder();
87+
builder.setPrincipal( user ).setPassword( pass );
88+
builder.setNonce( nonce );
89+
builder.setUri( uri );
90+
builder.setMethodName(method);
91+
builder.setRealmName( realm );
92+
builder.setQop(qop);
93+
builder.setScheme( AuthScheme.DIGEST );
94+
Realm orig = builder.build();
95+
96+
String nc = orig.getNc();
97+
String cnonce = orig.getCnonce();
98+
String ha1=getMd5(user +":" + realm +":"+pass);
99+
String ha2=getMd5(method +":"+ uri);
100+
String expectedResponse=getMd5(ha1 +":" + nonce +":" + nc + ":" + cnonce +":" + qop + ":" + ha2);
101+
102+
Assert.assertEquals(expectedResponse,orig.getResponse());
103+
}
104+
105+
private String getMd5(String what){
106+
try {
107+
MessageDigest md = MessageDigest.getInstance("MD5");
108+
md.update(what.getBytes("ISO-8859-1"));
109+
byte[] hash = md.digest();
110+
BigInteger bi = new BigInteger(1, hash);
111+
String result = bi.toString(16);
112+
if (result.length() % 2 != 0) {
113+
return "0" + result;
114+
}
115+
return result;
116+
} catch (Exception e) {
117+
throw new RuntimeException(e);
118+
}
119+
}
39120
}

0 commit comments

Comments
 (0)