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) {
fail("Couldn't instantiate AuthHeadersResponse: " + e.toString());
}
HttpAuthMethod authMethod = HttpAuthMethod.scanResponse(response);
HttpAuthMethod authMethod = HttpAuthMethod.scanResponse(response, null);
if (!expectedAuthMethod.equals(getAuthMethodName(authMethod))) {
fail("Wrong authentication method: expected " + expectedAuthMethod

View File

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

View File

@ -73,6 +73,7 @@
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
@ -95,6 +96,7 @@
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.SymbolicRef;
import org.eclipse.jgit.transport.HttpAuthMethod.Type;
import org.eclipse.jgit.transport.http.HttpConnection;
import org.eclipse.jgit.util.HttpSupport;
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);
}
try {
int authAttempts = 1;
for (;;) {
int authAttempts = 1;
Collection<Type> ignoreTypes = null;
for (;;) {
try {
final HttpConnection conn = httpOpen(u);
if (useSmartHttp) {
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
if (authMethod.getType() == HttpAuthMethod.Type.NONE
&& conn.getHeaderField(HDR_WWW_AUTHENTICATE) != null)
authMethod = HttpAuthMethod.scanResponse(conn);
authMethod = HttpAuthMethod.scanResponse(conn, ignoreTypes);
return conn;
case HttpConnection.HTTP_NOT_FOUND:
@ -475,7 +479,7 @@ private HttpConnection connect(final String service)
MessageFormat.format(JGitText.get().uriNotFound, u));
case HttpConnection.HTTP_UNAUTHORIZED:
authMethod = HttpAuthMethod.scanResponse(conn);
authMethod = HttpAuthMethod.scanResponse(conn, ignoreTypes);
if (authMethod.getType() == HttpAuthMethod.Type.NONE)
throw new TransportException(uri, MessageFormat.format(
JGitText.get().authenticationNotSupported, uri));
@ -501,13 +505,27 @@ private HttpConnection connect(final String service)
String err = status + " " + conn.getResponseMessage(); //$NON-NLS-1$
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);
}
}