Skip to content

Commit 4321163

Browse files
committed
Fix NPE in preemptive digest auth, see AsyncHttpClient#1355
1 parent 3e6e6e1 commit 4321163

File tree

5 files changed

+37
-19
lines changed

5 files changed

+37
-19
lines changed

client/src/main/java/org/asynchttpclient/Realm.java

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ protected MessageDigest initialValue() {
218218
}
219219
}
220220
};
221-
221+
222222
private static MessageDigest getMessageDigest() {
223223
MessageDigest md = DIGEST_TL.get();
224224
md.reset();
@@ -457,21 +457,24 @@ private void appendDataBase(StringBuilder sb) {
457457
}
458458

459459
private void newResponse(MessageDigest md) {
460-
// BEWARE: compute first as it uses the cached StringBuilder
461-
String digestUri = AuthenticatorUtils.computeRealmURI(uri, useAbsoluteURI, omitQuery);
460+
// when using preemptive auth, the request uri is missing
461+
if (uri != null) {
462+
// BEWARE: compute first as it uses the cached StringBuilder
463+
String digestUri = AuthenticatorUtils.computeRealmURI(uri, useAbsoluteURI, omitQuery);
462464

463-
StringBuilder sb = StringBuilderPool.DEFAULT.stringBuilder();
465+
StringBuilder sb = StringBuilderPool.DEFAULT.stringBuilder();
464466

465-
// WARNING: DON'T MOVE, BUFFER IS RECYCLED!!!!
466-
byte[] secretDigest = secretDigest(sb, md);
467-
byte[] dataDigest = dataDigest(sb, digestUri, md);
467+
// WARNING: DON'T MOVE, BUFFER IS RECYCLED!!!!
468+
byte[] secretDigest = secretDigest(sb, md);
469+
byte[] dataDigest = dataDigest(sb, digestUri, md);
468470

469-
appendBase16(sb, secretDigest);
470-
appendDataBase(sb);
471-
appendBase16(sb, dataDigest);
471+
appendBase16(sb, secretDigest);
472+
appendDataBase(sb);
473+
appendBase16(sb, dataDigest);
472474

473-
byte[] responseDigest = md5FromRecycledStringBuilder(sb, md);
474-
response = toHexString(responseDigest);
475+
byte[] responseDigest = md5FromRecycledStringBuilder(sb, md);
476+
response = toHexString(responseDigest);
477+
}
475478
}
476479

477480
/**

client/src/main/java/org/asynchttpclient/netty/request/NettyRequestFactory.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,10 +210,10 @@ public NettyRequest newNettyRequest(Request request, boolean forceConnect, Proxy
210210
headers.set(HOST, hostHeader(request, uri));
211211

212212
// don't override authorization but append
213-
addAuthorizationHeader(headers, perRequestAuthorizationHeader(realm));
213+
addAuthorizationHeader(headers, perRequestAuthorizationHeader(request, realm));
214214
// only set proxy auth on request over plain HTTP, or when performing CONNECT
215215
if (!uri.isSecured() || connect) {
216-
setProxyAuthorizationHeader(headers, perRequestProxyAuthorizationHeader(proxyRealm));
216+
setProxyAuthorizationHeader(headers, perRequestProxyAuthorizationHeader(request, proxyRealm));
217217
}
218218

219219
// Add default accept headers

client/src/main/java/org/asynchttpclient/util/AuthenticatorUtils.java

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import static io.netty.handler.codec.http.HttpHeaderNames.PROXY_AUTHORIZATION;
1616
import static java.nio.charset.StandardCharsets.ISO_8859_1;
17+
import static org.asynchttpclient.Dsl.realm;
1718
import static org.asynchttpclient.util.HttpUtils.getNonEmptyPath;
1819
import static org.asynchttpclient.util.MiscUtils.isNonEmpty;
1920

@@ -123,7 +124,7 @@ public static String perConnectionProxyAuthorizationHeader(Request request, Real
123124
return proxyAuthorization;
124125
}
125126

126-
public static String perRequestProxyAuthorizationHeader(Realm proxyRealm) {
127+
public static String perRequestProxyAuthorizationHeader(Request request, Realm proxyRealm) {
127128

128129
String proxyAuthorization = null;
129130
if (proxyRealm != null && proxyRealm.isUsePreemptiveAuth()) {
@@ -133,8 +134,14 @@ public static String perRequestProxyAuthorizationHeader(Realm proxyRealm) {
133134
proxyAuthorization = computeBasicAuthentication(proxyRealm);
134135
break;
135136
case DIGEST:
136-
if (isNonEmpty(proxyRealm.getNonce()))
137+
if (isNonEmpty(proxyRealm.getNonce())) {
138+
// update realm with request information
139+
proxyRealm = realm(proxyRealm)//
140+
.setUri(request.getUri())//
141+
.setMethodName(request.getMethod())//
142+
.build();
137143
proxyAuthorization = computeDigestAuthentication(proxyRealm);
144+
}
138145
break;
139146
case NTLM:
140147
case KERBEROS:
@@ -183,7 +190,7 @@ else if (request.getVirtualHost() != null)
183190
return authorizationHeader;
184191
}
185192

186-
public static String perRequestAuthorizationHeader(Realm realm) {
193+
public static String perRequestAuthorizationHeader(Request request, Realm realm) {
187194

188195
String authorizationHeader = null;
189196

@@ -194,8 +201,14 @@ public static String perRequestAuthorizationHeader(Realm realm) {
194201
authorizationHeader = computeBasicAuthentication(realm);
195202
break;
196203
case DIGEST:
197-
if (isNonEmpty(realm.getNonce()))
204+
if (isNonEmpty(realm.getNonce())) {
205+
// update realm with request information
206+
realm = realm(realm)//
207+
.setUri(request.getUri())//
208+
.setMethodName(request.getMethod())//
209+
.build();
198210
authorizationHeader = computeDigestAuthentication(realm);
211+
}
199212
break;
200213
case NTLM:
201214
case KERBEROS:

client/src/test/java/org/asynchttpclient/AuthTimeoutTest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,9 @@ protected Future<Response> execute(AsyncHttpClient client, boolean basic, boolea
165165
realm = digestAuthRealm(USER, ADMIN);
166166
url = getTargetUrl2();
167167
if (preemptive) {
168+
realm.setRealmName("MyRealm");
169+
realm.setAlgorithm("MD5");
170+
realm.setQop("auth");
168171
realm.setNonce("fFDVc60re9zt8fFDvht0tNrYuvqrcchN");
169172
}
170173
}

client/src/test/java/org/asynchttpclient/DigestAuthTest.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ public void setUpGlobal() throws Exception {
4848

4949
private static class SimpleHandler extends AbstractHandler {
5050
public void handle(String s, Request r, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
51-
5251
response.addHeader("X-Auth", request.getHeader("Authorization"));
5352
response.setStatus(200);
5453
response.getOutputStream().flush();

0 commit comments

Comments
 (0)