]> source.dussan.org Git - jgit.git/commitdiff
http transport does not use authentication fallback 28/71028/10
authorChristian Pontesegger <christian.pontesegger@web.de>
Wed, 20 Apr 2016 06:31:18 +0000 (08:31 +0200)
committerMatthias Sohn <matthias.sohn@sap.com>
Mon, 6 Jun 2016 14:45:49 +0000 (16:45 +0200)
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>
org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/HttpAuthTest.java
org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpAuthMethod.java
org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java

index 52330135829dde444c458c246397522a6eb24e4f..3dc022d386bf901709182d96b0d3ed9b15ccb767 100644 (file)
@@ -100,7 +100,7 @@ public class HttpAuthTest {
                } 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
index 998f280014ab28163c34c6db50e00fdbb0e50415..81e6904bff57ee6413b0a7398a576cb3a6cdb8d8 100644 (file)
@@ -51,6 +51,7 @@ import java.io.UnsupportedEncodingException;
 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 @@ abstract class HttpAuthMethod {
         *
         * @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 @@ abstract class HttpAuthMethod {
 
                                                        try {
                                                                Type methodType = Type.valueOf(valuePart[0].toUpperCase());
+
+                                                               if ((ignoreTypes != null)
+                                                                               && (ignoreTypes.contains(methodType))) {
+                                                                       continue;
+                                                               }
+
                                                                if (authentication.getType().compareTo(methodType) >= 0) {
                                                                        continue;
                                                                }
index 414e8790ca534db30e44900f96d383999bca2afc..1166080f2a6739ae54a5208eb40890393e74124c 100644 (file)
@@ -73,6 +73,7 @@ import java.util.Arrays;
 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.ProgressMonitor;
 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 @@ public class TransportHttp extends HttpTransport implements WalkTransport,
                        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 @@ public class TransportHttp extends HttpTransport implements WalkTransport,
                                        // 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 @@ public class TransportHttp extends HttpTransport implements WalkTransport,
                                                        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 @@ public class TransportHttp extends HttpTransport implements WalkTransport,
                                        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);
                }
        }