From 3e68148a4dda31d35d12878407cf1d04451e4d3d Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Fri, 1 Aug 2014 12:15:18 +0200 Subject: Network: Fix NTLM (SSPI) with HTTP and HTTPS proxies This commit should fix proxy authentication when NTLM is used. NTLM differs from normal HTTP(S) authentication by having 2 roundtrips instead of 1, some parts of our code however were not prepared for that. I've tested this patch with Microsoft Forefront, both with normal NTLM and with NTLM SSPI (in Windows domain). I removed an optimization added in 3c3ea9a8, I could not see that behavior anymore. That commit was the wrong fix in my opinion. [ChangeLog][QtNetwork] Fix NTLM (SSPI) Proxy Authentication (HTTP/HTTPS) Task-number: QTBUG-30829 Task-number: QTBUG-35101 Change-Id: Idcc9c0dbf388b011d49f2806e9a6dd55ebc35cec Reviewed-by: Richard J. Moore Reviewed-by: Thiago Macieira Reviewed-by: Peter Hartmann --- src/network/socket/qhttpsocketengine.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/network/socket/qhttpsocketengine.cpp') diff --git a/src/network/socket/qhttpsocketengine.cpp b/src/network/socket/qhttpsocketengine.cpp index 0a25815752d..9f3c29e207b 100644 --- a/src/network/socket/qhttpsocketengine.cpp +++ b/src/network/socket/qhttpsocketengine.cpp @@ -594,16 +594,18 @@ void QHttpSocketEngine::slotSocketReadNotification() priv = QAuthenticatorPrivate::getPrivate(d->authenticator); priv->hasFailed = false; } else if (statusCode == 407) { - if (d->credentialsSent) { + if (d->authenticator.isNull()) + d->authenticator.detach(); + priv = QAuthenticatorPrivate::getPrivate(d->authenticator); + + if (d->credentialsSent && priv->phase != QAuthenticatorPrivate::Phase2) { + // Remember that (e.g.) NTLM is two-phase, so only reset when the authentication is not currently in progress. //407 response again means the provided username/password were invalid. d->authenticator = QAuthenticator(); //this is needed otherwise parseHttpResponse won't set the state, and then signal isn't emitted. d->authenticator.detach(); priv = QAuthenticatorPrivate::getPrivate(d->authenticator); priv->hasFailed = true; } - else if (d->authenticator.isNull()) - d->authenticator.detach(); - priv = QAuthenticatorPrivate::getPrivate(d->authenticator); priv->parseHttpResponse(d->reply->header(), true); -- cgit v1.2.3