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 <thomas.wolf@paranor.ch>
This commit is contained in:
Thomas Wolf 2017-11-15 23:23:27 +01:00 committed by Matthias Sohn
parent df3a7c32a4
commit 7f2ef4b6ba
1 changed files with 22 additions and 7 deletions

View File

@ -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;
}
}
}