From 695d6f1f7764c79f9ab21c0b93048fe2e710ca5b Mon Sep 17 00:00:00 2001 From: Harold Teramoto Date: Tue, 11 Mar 2014 22:07:02 -0400 Subject: [PATCH] Fix NTLM Proxy authentication issues. Issue 1) Http request's user credential is used for proxy credential. For most use cases, user will have proxy credential stored in the keychain. Look for credential in keychain first, then use the http request credential. Issue 2) From wireshark network traces, calling startRequest twice does not actually send the NTLM proxy auth challenge response. The third startRequest will send the auth challenge response and get past the proxy authentication. --- Classes/ASIHTTPRequest.m | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/Classes/ASIHTTPRequest.m b/Classes/ASIHTTPRequest.m index ece66b8a..7282d568 100644 --- a/Classes/ASIHTTPRequest.m +++ b/Classes/ASIHTTPRequest.m @@ -2476,14 +2476,6 @@ - (NSMutableDictionary *)findProxyCredentials user = [self proxyUsername]; pass = [self proxyPassword]; } - - // When we connect to a website using NTLM via a proxy, we will use the main credentials - if ((!user || !pass) && [self proxyAuthenticationScheme] == (NSString *)kCFHTTPAuthenticationSchemeNTLM) { - user = [self username]; - pass = [self password]; - } - - // Ok, that didn't work, let's try the keychain // For authenticating proxies, we'll look in the keychain regardless of the value of useKeychainPersistence @@ -2496,6 +2488,13 @@ - (NSMutableDictionary *)findProxyCredentials } + // If proxy credential is still not available and when we connect to a website using NTLM via a proxy, + // we will use the main credentials + if ((!user || !pass) && [self proxyAuthenticationScheme] == (NSString *)kCFHTTPAuthenticationSchemeNTLM) { + user = [self username]; + pass = [self password]; + } + // Handle NTLM, which requires a domain to be set too if (CFHTTPAuthenticationRequiresAccountDomain(proxyAuthentication)) { @@ -2843,12 +2842,15 @@ - (void)attemptToApplyProxyCredentialsAndResume if (proxyCredentials) { + // From wireshark logs, proxy auth challenge is not responded by calling startRequest twice. + // Needed a third call to get the auth challenge response sent. + // We use startRequest rather than starting all over again in load request because NTLM requires we reuse the request - if ((([self proxyAuthenticationScheme] != (NSString *)kCFHTTPAuthenticationSchemeNTLM) || [self proxyAuthenticationRetryCount] < 2) && [self applyProxyCredentials:proxyCredentials]) { + if ((([self proxyAuthenticationScheme] != (NSString *)kCFHTTPAuthenticationSchemeNTLM) || [self proxyAuthenticationRetryCount] < 3) && [self applyProxyCredentials:proxyCredentials]) { [self startRequest]; // We've failed NTLM authentication twice, we should assume our credentials are wrong - } else if ([self proxyAuthenticationScheme] == (NSString *)kCFHTTPAuthenticationSchemeNTLM && [self proxyAuthenticationRetryCount] == 2) { + } else if ([self proxyAuthenticationScheme] == (NSString *)kCFHTTPAuthenticationSchemeNTLM && [self proxyAuthenticationRetryCount] == 3) { [self failWithError:ASIAuthenticationError]; // Something went wrong, we'll have to give up