summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn O. Pearce <spearce@spearce.org>2010-12-13 10:09:14 -0800
committerShawn O. Pearce <spearce@spearce.org>2010-12-13 10:11:03 -0800
commit2bc13104a8ec2c31dc5198cf77d2cf261b8a44b8 (patch)
treea896cabf39ac7501222ab3762eeda08647a9246e
parentc6ca443b61372d73a7f1438c995713bad39b5277 (diff)
downloadjgit-2bc13104a8ec2c31dc5198cf77d2cf261b8a44b8.tar.gz
jgit-2bc13104a8ec2c31dc5198cf77d2cf261b8a44b8.zip
Fix HTTP digest authentication
JGit's internal implementation of the HTTP digest authentication method wasn't conforming to RFC 2617 (HTTP Authentication: Basic and Digest Access Authentication), resulting in authentication failures when connecting to a digest protected site. The code now more accurately matches section 3.2.2 (The Authorization Request Header) from the standards document. Change-Id: If41b5c2cbdd59ddd6b2dea143f325e42cd58c395 Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpAuthMethod.java68
1 files changed, 52 insertions, 16 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpAuthMethod.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpAuthMethod.java
index 926661667e..d9673f74e8 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpAuthMethod.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpAuthMethod.java
@@ -49,10 +49,12 @@ import static org.eclipse.jgit.util.HttpSupport.HDR_WWW_AUTHENTICATE;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
+import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Collections;
import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Random;
@@ -216,35 +218,50 @@ abstract class HttpAuthMethod {
@SuppressWarnings("boxing")
@Override
void configureRequest(final HttpURLConnection conn) throws IOException {
- final Map<String, String> p = new HashMap<String, String>(params);
- p.put("username", user);
+ final Map<String, String> r = new LinkedHashMap<String, String>();
- final String realm = p.get("realm");
- final String nonce = p.get("nonce");
- final String uri = p.get("uri");
- final String qop = p.get("qop");
+ final String realm = params.get("realm");
+ final String nonce = params.get("nonce");
+ final String cnonce = params.get("cnonce");
+ final String uri = uri(conn.getURL());
+ final String qop = params.get("qop");
final String method = conn.getRequestMethod();
final String A1 = user + ":" + realm + ":" + pass;
final String A2 = method + ":" + uri;
- final String expect;
+ r.put("username", user);
+ r.put("realm", realm);
+ r.put("nonce", nonce);
+ r.put("uri", uri);
+
+ final String response, nc;
if ("auth".equals(qop)) {
- final String c = p.get("cnonce");
- final String nc = String.format("%08x", ++requestCount);
- p.put("nc", nc);
- expect = KD(H(A1), nonce + ":" + nc + ":" + c + ":" + qop + ":"
+ nc = String.format("%08x", ++requestCount);
+ response = KD(H(A1), nonce + ":" + nc + ":" + cnonce + ":"
+ + qop
+ + ":"
+ H(A2));
} else {
- expect = KD(H(A1), nonce + ":" + H(A2));
+ nc = null;
+ response = KD(H(A1), nonce + ":" + H(A2));
}
- p.put("response", expect);
+ r.put("response", response);
+ if (params.containsKey("algorithm"))
+ r.put("algorithm", "MD5");
+ if (cnonce != null && qop != null)
+ r.put("cnonce", cnonce);
+ if (params.containsKey("opaque"))
+ r.put("opaque", params.get("opaque"));
+ if (qop != null)
+ r.put("qop", qop);
+ if (nc != null)
+ r.put("nc", nc);
StringBuilder v = new StringBuilder();
- for (Map.Entry<String, String> e : p.entrySet()) {
- if (v.length() > 0) {
+ for (Map.Entry<String, String> e : r.entrySet()) {
+ if (v.length() > 0)
v.append(", ");
- }
v.append(e.getKey());
v.append('=');
v.append('"');
@@ -254,6 +271,25 @@ abstract class HttpAuthMethod {
conn.setRequestProperty(HDR_AUTHORIZATION, NAME + " " + v);
}
+ private static String uri(URL u) {
+ StringBuilder r = new StringBuilder();
+ r.append(u.getProtocol());
+ r.append("://");
+ r.append(u.getHost());
+ if (0 < u.getPort()) {
+ if (u.getPort() == 80 && "http".equals(u.getProtocol()))
+ /* nothing */;
+ else if (u.getPort() == 443 && "https".equals(u.getProtocol()))
+ /* nothing */;
+ else
+ r.append(':').append(u.getPort());
+ }
+ r.append(u.getPath());
+ if (u.getQuery() != null)
+ r.append('?').append(u.getQuery());
+ return r.toString();
+ }
+
private static String H(String data) {
try {
MessageDigest md = newMD5();