From 7f2ef4b6bac25c0690e0c67617000863ca7364b8 Mon Sep 17 00:00:00 2001 From: Thomas Wolf Date: Wed, 15 Nov 2017 23:23:27 +0100 Subject: [PATCH] TransportHttp: retry on IOException with another mechanism When a 401 occurs on POST and the server advertises Negotiate, we may get an exception from GSSAPI if the client isn't configured at all for Kerberos. Add exception logic similar to the GET case: keep trying other authentication mechanisms if this occurs. Bug: 501167 Change-Id: Ic3a3368378d4b3408a35aec93e78ef425d54b3e4 Signed-off-by: Thomas Wolf --- .../eclipse/jgit/transport/TransportHttp.java | 29 ++++++++++++++----- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java index 7c3f738d9..35bbd10d7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java @@ -1257,13 +1257,7 @@ void sendRequest() throws IOException { } authAttempts = 1; // We only do the Kerberos part of SPNEGO, which - // requires only one attempt. We do *not* to the - // NTLM part of SPNEGO; it's a multi-round - // negotiation and among other problems it would - // be unclear when to stop if no HTTP_OK is - // forthcoming. In theory a malicious server - // could keep sending requests for another NTLM - // round, keeping a client stuck here. + // requires only one round. break; default: // DIGEST or BASIC. Let's be sure we ignore @@ -1305,6 +1299,27 @@ void sendRequest() throws IOException { } catch (SSLHandshakeException e) { handleSslFailure(e); continue; // Re-try + } catch (IOException e) { + if (authenticator == null || authMethod + .getType() != HttpAuthMethod.Type.NONE) { + // Can happen for instance if the server advertises + // Negotiate, but the client isn't configured for + // Kerberos. The first time (authenticator == null) we + // must re-try even if the authMethod was NONE: this may + // occur if the server advertised NTLM on the GET + // and the HttpConnection managed to successfully + // authenticate under the hood with NTLM. We might not + // have picked this up on the GET's 200 response. + if (authMethod.getType() != HttpAuthMethod.Type.NONE) { + ignoreTypes.add(authMethod.getType()); + } + // Start over with the remaining available methods. + authMethod = HttpAuthMethod.Type.NONE.method(null); + authenticator = authMethod; + authAttempts = 1; + continue; + } + throw e; } } }