diff --git a/httpclient/src/main/java/org/apache/http/impl/auth/NTLMScheme.java b/httpclient/src/main/java/org/apache/http/impl/auth/NTLMScheme.java index 6913e0e75..88bd9faf6 100644 --- a/httpclient/src/main/java/org/apache/http/impl/auth/NTLMScheme.java +++ b/httpclient/src/main/java/org/apache/http/impl/auth/NTLMScheme.java @@ -109,6 +109,7 @@ public class NTLMScheme extends AuthSchemeBase { } else { if (this.state.compareTo(State.MSG_TYPE1_GENERATED) < 0) { this.state = State.FAILED; + throw new MalformedChallengeException("Out of sequence NTLM response message"); } else if (this.state == State.MSG_TYPE1_GENERATED) { this.state = State.MSG_TYPE2_RECEVIED; } @@ -127,7 +128,9 @@ public class NTLMScheme extends AuthSchemeBase { + credentials.getClass().getName()); } String response = null; - if (this.state == State.CHALLENGE_RECEIVED || this.state == State.FAILED) { + if (this.state == State.FAILED) { + throw new AuthenticationException("NTLM authentication failed"); + } else if (this.state == State.CHALLENGE_RECEIVED) { response = this.engine.generateType1Msg( ntcredentials.getDomain(), ntcredentials.getWorkstation()); diff --git a/httpclient/src/test/java/org/apache/http/impl/client/integration/TestClientAuthenticationFakeNTLM.java b/httpclient/src/test/java/org/apache/http/impl/client/integration/TestClientAuthenticationFakeNTLM.java index 351489813..09e7e8ac3 100644 --- a/httpclient/src/test/java/org/apache/http/impl/client/integration/TestClientAuthenticationFakeNTLM.java +++ b/httpclient/src/test/java/org/apache/http/impl/client/integration/TestClientAuthenticationFakeNTLM.java @@ -178,6 +178,12 @@ public class TestClientAuthenticationFakeNTLM extends IntegrationTestBase { static class NtlmType2MessageOnlyResponseHandler implements HttpRequestHandler { + private final String authenticateHeaderValue; + + public NtlmType2MessageOnlyResponseHandler(final String type2Message) { + this.authenticateHeaderValue = "NTLM " + type2Message; + } + public void handle( final HttpRequest request, final HttpResponse response, @@ -187,15 +193,41 @@ public class TestClientAuthenticationFakeNTLM extends IntegrationTestBase { HttpStatus.SC_UNAUTHORIZED, "Authentication Required")); response.setHeader("Connection", "Keep-Alive"); - response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "NTLM TlRMTVNTUAACAA" + - "AADAAMADgAAAAzggLiASNFZ4mrze8AAAAAAAAAAAAAAAAAAAAABgBwFwAAAA9T" + - "AGUAcgB2AGUAcgA="); + response.setHeader(HttpHeaders.WWW_AUTHENTICATE, authenticateHeaderValue); } } @Test public void testNTLMType2MessageOnlyAuthenticationFailure() throws Exception { - this.localServer.register("*", new NtlmType2MessageOnlyResponseHandler()); + this.localServer.register("*", new NtlmType2MessageOnlyResponseHandler("TlRMTVNTUAACAA" + + "AADAAMADgAAAAzggLiASNFZ4mrze8AAAAAAAAAAAAAAAAAAAAABgBwFwAAAA9T" + + "AGUAcgB2AGUAcgA=")); + this.localServer.start(); + + final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider(); + credsProvider.setCredentials(AuthScope.ANY, + new NTCredentials("test", "test", null, null)); + + this.httpclient = HttpClients.custom() + .setDefaultCredentialsProvider(credsProvider) + .build(); + + final HttpContext context = HttpClientContext.create(); + + final HttpHost targethost = getServerHttp(); + final HttpGet httpget = new HttpGet("/"); + + final HttpResponse response = this.httpclient.execute(targethost, httpget, context); + EntityUtils.consume(response.getEntity()); + Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, + response.getStatusLine().getStatusCode()); + } + + @Test + public void testNTLMType2NonUnicodeMessageOnlyAuthenticationFailure() throws Exception { + this.localServer.register("*", new NtlmType2MessageOnlyResponseHandler("TlRMTVNTUAACAA" + + "AABgAGADgAAAAyggLiASNFZ4mrze8AAAAAAAAAAAAAAAAAAAAABgBwFwAAAA9T" + + "ZXJ2ZXI=")); this.localServer.start(); final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();