|
|
@@ -69,8 +69,39 @@ import org.eclipse.jgit.util.Base64; |
|
|
|
* may need to maintain per-connection state information. |
|
|
|
*/ |
|
|
|
abstract class HttpAuthMethod { |
|
|
|
/** No authentication is configured. */ |
|
|
|
static final HttpAuthMethod NONE = new None(); |
|
|
|
/** |
|
|
|
* Enum listing the http authentication method types supported by jgit. They |
|
|
|
* are sorted by priority order!!! |
|
|
|
*/ |
|
|
|
public enum Type { |
|
|
|
NONE { |
|
|
|
@Override |
|
|
|
public HttpAuthMethod method(String hdr) { |
|
|
|
return None.INSTANCE; |
|
|
|
} |
|
|
|
}, |
|
|
|
BASIC { |
|
|
|
@Override |
|
|
|
public HttpAuthMethod method(String hdr) { |
|
|
|
return new Basic(); |
|
|
|
} |
|
|
|
}, |
|
|
|
DIGEST { |
|
|
|
@Override |
|
|
|
public HttpAuthMethod method(String hdr) { |
|
|
|
return new Digest(hdr); |
|
|
|
} |
|
|
|
}; |
|
|
|
/** |
|
|
|
* Creates a HttpAuthMethod instance configured with the provided HTTP |
|
|
|
* WWW-Authenticate header. |
|
|
|
* |
|
|
|
* @param hdr the http header |
|
|
|
* @return a configured HttpAuthMethod instance |
|
|
|
*/ |
|
|
|
public abstract HttpAuthMethod method(String hdr); |
|
|
|
} |
|
|
|
|
|
|
|
static final String EMPTY_STRING = ""; //$NON-NLS-1$ |
|
|
|
static final String SCHEMA_NAME_SEPARATOR = " "; //$NON-NLS-1$ |
|
|
|
|
|
|
@@ -83,7 +114,7 @@ abstract class HttpAuthMethod { |
|
|
|
*/ |
|
|
|
static HttpAuthMethod scanResponse(final HttpConnection conn) { |
|
|
|
final Map<String, List<String>> headers = conn.getHeaderFields(); |
|
|
|
HttpAuthMethod authentication = NONE; |
|
|
|
HttpAuthMethod authentication = Type.NONE.method(EMPTY_STRING); |
|
|
|
|
|
|
|
for (final Entry<String, List<String>> entry : headers.entrySet()) { |
|
|
|
if (HDR_WWW_AUTHENTICATE.equalsIgnoreCase(entry.getKey())) { |
|
|
@@ -93,19 +124,23 @@ abstract class HttpAuthMethod { |
|
|
|
final String[] valuePart = value.split( |
|
|
|
SCHEMA_NAME_SEPARATOR, 2); |
|
|
|
|
|
|
|
if (Digest.NAME.equalsIgnoreCase(valuePart[0])) { |
|
|
|
try { |
|
|
|
Type methodType = Type.valueOf(valuePart[0].toUpperCase()); |
|
|
|
if (authentication.getType().compareTo(methodType) >= 0) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
final String param; |
|
|
|
if (valuePart.length == 1) |
|
|
|
param = EMPTY_STRING; |
|
|
|
else |
|
|
|
param = valuePart[1]; |
|
|
|
|
|
|
|
authentication = new Digest(param); |
|
|
|
break; |
|
|
|
authentication = methodType |
|
|
|
.method(param); |
|
|
|
} catch (IllegalArgumentException e) { |
|
|
|
// This auth method is not supported |
|
|
|
} |
|
|
|
|
|
|
|
if (Basic.NAME.equalsIgnoreCase(valuePart[0])) |
|
|
|
authentication = new Basic(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@@ -116,6 +151,12 @@ abstract class HttpAuthMethod { |
|
|
|
return authentication; |
|
|
|
} |
|
|
|
|
|
|
|
protected final Type type; |
|
|
|
|
|
|
|
protected HttpAuthMethod(Type type) { |
|
|
|
this.type = type; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Update this method with the credentials from the URIish. |
|
|
|
* |
|
|
@@ -170,8 +211,22 @@ abstract class HttpAuthMethod { |
|
|
|
*/ |
|
|
|
abstract void configureRequest(HttpConnection conn) throws IOException; |
|
|
|
|
|
|
|
/** |
|
|
|
* Gives the method type associated to this http auth method |
|
|
|
* |
|
|
|
* @return the method type |
|
|
|
*/ |
|
|
|
public Type getType() { |
|
|
|
return type; |
|
|
|
} |
|
|
|
|
|
|
|
/** Performs no user authentication. */ |
|
|
|
private static class None extends HttpAuthMethod { |
|
|
|
static final None INSTANCE = new None(); |
|
|
|
public None() { |
|
|
|
super(Type.NONE); |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
void authorize(String user, String pass) { |
|
|
|
// Do nothing when no authentication is enabled. |
|
|
@@ -185,12 +240,14 @@ abstract class HttpAuthMethod { |
|
|
|
|
|
|
|
/** Performs HTTP basic authentication (plaintext username/password). */ |
|
|
|
private static class Basic extends HttpAuthMethod { |
|
|
|
static final String NAME = "Basic"; //$NON-NLS-1$ |
|
|
|
|
|
|
|
private String user; |
|
|
|
|
|
|
|
private String pass; |
|
|
|
|
|
|
|
public Basic() { |
|
|
|
super(Type.BASIC); |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
void authorize(final String username, final String password) { |
|
|
|
this.user = username; |
|
|
@@ -201,14 +258,13 @@ abstract class HttpAuthMethod { |
|
|
|
void configureRequest(final HttpConnection conn) throws IOException { |
|
|
|
String ident = user + ":" + pass; //$NON-NLS-1$ |
|
|
|
String enc = Base64.encodeBytes(ident.getBytes("UTF-8")); //$NON-NLS-1$ |
|
|
|
conn.setRequestProperty(HDR_AUTHORIZATION, NAME + " " + enc); //$NON-NLS-1$ |
|
|
|
conn.setRequestProperty(HDR_AUTHORIZATION, type.name() |
|
|
|
+ " " + enc); //$NON-NLS-1$ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** Performs HTTP digest authentication. */ |
|
|
|
private static class Digest extends HttpAuthMethod { |
|
|
|
static final String NAME = "Digest"; //$NON-NLS-1$ |
|
|
|
|
|
|
|
private static final Random PRNG = new Random(); |
|
|
|
|
|
|
|
private final Map<String, String> params; |
|
|
@@ -220,6 +276,7 @@ abstract class HttpAuthMethod { |
|
|
|
private String pass; |
|
|
|
|
|
|
|
Digest(String hdr) { |
|
|
|
super(Type.DIGEST); |
|
|
|
params = parse(hdr); |
|
|
|
|
|
|
|
final String qop = params.get("qop"); //$NON-NLS-1$ |
|
|
@@ -288,7 +345,8 @@ abstract class HttpAuthMethod { |
|
|
|
v.append(e.getValue()); |
|
|
|
v.append('"'); |
|
|
|
} |
|
|
|
conn.setRequestProperty(HDR_AUTHORIZATION, NAME + " " + v); //$NON-NLS-1$ |
|
|
|
conn.setRequestProperty(HDR_AUTHORIZATION, type.name() |
|
|
|
+ " " + v); //$NON-NLS-1$ |
|
|
|
} |
|
|
|
|
|
|
|
private static String uri(URL u) { |