http transport does not use authentication fallback

Git servers supporting HTTP transport can send multiple WWW-Authenticate
challenges [1] for different authentication schemes the server supports.
If authentication fails now retry all authentication types proposed by
the server.

[1] https://tools.ietf.org/html/rfc2617#page-3

Bug: 492057
Change-Id: I01d438a5896f9b1008bd6b751ad9c7cbf780af1a
Signed-off-by: Christian Pontesegger <christian.pontesegger@web.de>
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
This commit is contained in:
Christian Pontesegger 2016-04-20 08:31:18 +02:00 committed by Matthias Sohn
parent 534fcb1479
commit ac3d3af632
3 changed files with 41 additions and 13 deletions

View File

@ -100,7 +100,7 @@ private static void checkResponse(String[] headers,
} catch (IOException e) { } catch (IOException e) {
fail("Couldn't instantiate AuthHeadersResponse: " + e.toString()); fail("Couldn't instantiate AuthHeadersResponse: " + e.toString());
} }
HttpAuthMethod authMethod = HttpAuthMethod.scanResponse(response); HttpAuthMethod authMethod = HttpAuthMethod.scanResponse(response, null);
if (!expectedAuthMethod.equals(getAuthMethodName(authMethod))) { if (!expectedAuthMethod.equals(getAuthMethodName(authMethod))) {
fail("Wrong authentication method: expected " + expectedAuthMethod fail("Wrong authentication method: expected " + expectedAuthMethod

View File

@ -51,6 +51,7 @@
import java.net.URL; import java.net.URL;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
@ -149,9 +150,12 @@ public String getSchemeName() {
* *
* @param conn * @param conn
* the connection that failed. * the connection that failed.
* @param ignoreTypes
* authentication types to be ignored.
* @return new authentication method to try. * @return new authentication method to try.
*/ */
static HttpAuthMethod scanResponse(final HttpConnection conn) { static HttpAuthMethod scanResponse(final HttpConnection conn,
Collection<Type> ignoreTypes) {
final Map<String, List<String>> headers = conn.getHeaderFields(); final Map<String, List<String>> headers = conn.getHeaderFields();
HttpAuthMethod authentication = Type.NONE.method(EMPTY_STRING); HttpAuthMethod authentication = Type.NONE.method(EMPTY_STRING);
@ -165,6 +169,12 @@ static HttpAuthMethod scanResponse(final HttpConnection conn) {
try { try {
Type methodType = Type.valueOf(valuePart[0].toUpperCase()); Type methodType = Type.valueOf(valuePart[0].toUpperCase());
if ((ignoreTypes != null)
&& (ignoreTypes.contains(methodType))) {
continue;
}
if (authentication.getType().compareTo(methodType) >= 0) { if (authentication.getType().compareTo(methodType) >= 0) {
continue; continue;
} }

View File

@ -73,6 +73,7 @@
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.HashSet;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -95,6 +96,7 @@
import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.SymbolicRef; import org.eclipse.jgit.lib.SymbolicRef;
import org.eclipse.jgit.transport.HttpAuthMethod.Type;
import org.eclipse.jgit.transport.http.HttpConnection; import org.eclipse.jgit.transport.http.HttpConnection;
import org.eclipse.jgit.util.HttpSupport; import org.eclipse.jgit.util.HttpSupport;
import org.eclipse.jgit.util.IO; import org.eclipse.jgit.util.IO;
@ -448,9 +450,11 @@ private HttpConnection connect(final String service)
throw new NotSupportedException(MessageFormat.format(JGitText.get().invalidURL, uri), e); throw new NotSupportedException(MessageFormat.format(JGitText.get().invalidURL, uri), e);
} }
try {
int authAttempts = 1; int authAttempts = 1;
for (;;) { Collection<Type> ignoreTypes = null;
for (;;) {
try {
final HttpConnection conn = httpOpen(u); final HttpConnection conn = httpOpen(u);
if (useSmartHttp) { if (useSmartHttp) {
String exp = "application/x-" + service + "-advertisement"; //$NON-NLS-1$ //$NON-NLS-2$ String exp = "application/x-" + service + "-advertisement"; //$NON-NLS-1$ //$NON-NLS-2$
@ -467,7 +471,7 @@ private HttpConnection connect(final String service)
// explicit authentication would be required // explicit authentication would be required
if (authMethod.getType() == HttpAuthMethod.Type.NONE if (authMethod.getType() == HttpAuthMethod.Type.NONE
&& conn.getHeaderField(HDR_WWW_AUTHENTICATE) != null) && conn.getHeaderField(HDR_WWW_AUTHENTICATE) != null)
authMethod = HttpAuthMethod.scanResponse(conn); authMethod = HttpAuthMethod.scanResponse(conn, ignoreTypes);
return conn; return conn;
case HttpConnection.HTTP_NOT_FOUND: case HttpConnection.HTTP_NOT_FOUND:
@ -475,7 +479,7 @@ private HttpConnection connect(final String service)
MessageFormat.format(JGitText.get().uriNotFound, u)); MessageFormat.format(JGitText.get().uriNotFound, u));
case HttpConnection.HTTP_UNAUTHORIZED: case HttpConnection.HTTP_UNAUTHORIZED:
authMethod = HttpAuthMethod.scanResponse(conn); authMethod = HttpAuthMethod.scanResponse(conn, ignoreTypes);
if (authMethod.getType() == HttpAuthMethod.Type.NONE) if (authMethod.getType() == HttpAuthMethod.Type.NONE)
throw new TransportException(uri, MessageFormat.format( throw new TransportException(uri, MessageFormat.format(
JGitText.get().authenticationNotSupported, uri)); JGitText.get().authenticationNotSupported, uri));
@ -501,13 +505,27 @@ private HttpConnection connect(final String service)
String err = status + " " + conn.getResponseMessage(); //$NON-NLS-1$ String err = status + " " + conn.getResponseMessage(); //$NON-NLS-1$
throw new TransportException(uri, err); throw new TransportException(uri, err);
} }
} catch (NotSupportedException e) {
throw e;
} catch (TransportException e) {
throw e;
} catch (IOException e) {
if (authMethod.getType() != HttpAuthMethod.Type.NONE) {
if (ignoreTypes == null) {
ignoreTypes = new HashSet<Type>();
}
ignoreTypes.add(authMethod.getType());
// reset auth method & attempts for next authentication type
authMethod = HttpAuthMethod.Type.NONE.method(null);
authAttempts = 1;
continue;
}
throw new TransportException(uri, MessageFormat.format(JGitText.get().cannotOpenService, service), e);
} }
} catch (NotSupportedException e) {
throw e;
} catch (TransportException e) {
throw e;
} catch (IOException e) {
throw new TransportException(uri, MessageFormat.format(JGitText.get().cannotOpenService, service), e);
} }
} }