diff options
author | Shane Kearns <shane.kearns@accenture.com> | 2011-12-15 17:32:47 +0000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-12-22 15:56:00 +0100 |
commit | d24aad82896addce88f1ffb4040560e406acf083 (patch) | |
tree | 705b5b9c2cf86b2cb7bb03aa6a497483cf1121f3 /src/network/access | |
parent | 2cc78885b0b7d08f965998d156945a077e56c1d8 (diff) |
Don't fetch credentials from cache following a failed proxy authentication
Add variable to QAuthenticatorPrivate for tracking failure
Track authentication success/failure in http proxy socket engine
Track authentication success/failure in http connection channel
Task-number: QTBUG-22875
Change-Id: Id5d39e839428271ad687e9da12fbbdea9c478f4f
Reviewed-by: Peter Hartmann <peter.hartmann@nokia.com>
Diffstat (limited to 'src/network/access')
-rw-r--r-- | src/network/access/qhttpnetworkconnection.cpp | 16 | ||||
-rw-r--r-- | src/network/access/qhttpnetworkconnectionchannel.cpp | 12 | ||||
-rw-r--r-- | src/network/access/qhttpnetworkconnectionchannel_p.h | 2 | ||||
-rw-r--r-- | src/network/access/qnetworkaccessmanager.cpp | 12 |
4 files changed, 32 insertions, 10 deletions
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index d9738b6255..4a8d672c56 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -428,9 +428,23 @@ bool QHttpNetworkConnectionPrivate::handleAuthenticateChallenge(QAbstractSocket if (priv->phase == QAuthenticatorPrivate::Done) { pauseConnection(); if (!isProxy) { + if (channels[i].authenticationCredentialsSent) { + auth->detach(); + priv = QAuthenticatorPrivate::getPrivate(*auth); + priv->hasFailed = true; + priv->phase = QAuthenticatorPrivate::Done; + channels[i].authenticationCredentialsSent = false; + } emit reply->authenticationRequired(reply->request(), auth); #ifndef QT_NO_NETWORKPROXY } else { + if (channels[i].proxyCredentialsSent) { + auth->detach(); + priv = QAuthenticatorPrivate::getPrivate(*auth); + priv->hasFailed = true; + priv->phase = QAuthenticatorPrivate::Done; + channels[i].proxyCredentialsSent = false; + } emit reply->proxyAuthenticationRequired(networkProxy, auth); #endif } @@ -491,6 +505,7 @@ void QHttpNetworkConnectionPrivate::createAuthorization(QAbstractSocket *socket, if (priv && priv->method != QAuthenticatorPrivate::None) { QByteArray response = priv->calculateResponse(request.d->methodName(), request.d->uri(false)); request.setHeaderField("Authorization", response); + channels[i].authenticationCredentialsSent = true; } } } @@ -502,6 +517,7 @@ void QHttpNetworkConnectionPrivate::createAuthorization(QAbstractSocket *socket, if (priv && priv->method != QAuthenticatorPrivate::None) { QByteArray response = priv->calculateResponse(request.d->methodName(), request.d->uri(false)); request.setHeaderField("Proxy-Authorization", response); + channels[i].proxyCredentialsSent = true; } } } diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index ab178be582..02c1cacd9d 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -73,6 +73,8 @@ QHttpNetworkConnectionChannel::QHttpNetworkConnectionChannel() , lastStatus(0) , pendingEncrypt(false) , reconnectAttempts(2) + , authenticationCredentialsSent(false) + , proxyCredentialsSent(false) , authMethod(QAuthenticatorPrivate::None) , proxyAuthMethod(QAuthenticatorPrivate::None) #ifndef QT_NO_OPENSSL @@ -549,6 +551,14 @@ bool QHttpNetworkConnectionChannel::ensureConnection() // reset state pipeliningSupported = PipeliningSupportUnknown; + authenticationCredentialsSent = false; + proxyCredentialsSent = false; + authenticator.detach(); + QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(authenticator); + priv->hasFailed = false; + proxyAuthenticator.detach(); + priv = QAuthenticatorPrivate::getPrivate(proxyAuthenticator); + priv->hasFailed = false; // This workaround is needed since we use QAuthenticator for NTLM authentication. The "phase == Done" // is the usual criteria for emitting authentication signals. The "phase" is set to "Done" when the @@ -556,7 +566,7 @@ bool QHttpNetworkConnectionChannel::ensureConnection() // check the "phase" for generating the Authorization header. NTLM authentication is a two stage // process & needs the "phase". To make sure the QAuthenticator uses the current username/password // the phase is reset to Start. - QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(authenticator); + priv = QAuthenticatorPrivate::getPrivate(authenticator); if (priv && priv->phase == QAuthenticatorPrivate::Done) priv->phase = QAuthenticatorPrivate::Start; priv = QAuthenticatorPrivate::getPrivate(proxyAuthenticator); diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h index 7a4dd07db1..b93d002de6 100644 --- a/src/network/access/qhttpnetworkconnectionchannel_p.h +++ b/src/network/access/qhttpnetworkconnectionchannel_p.h @@ -113,6 +113,8 @@ public: QAuthenticatorPrivate::Method proxyAuthMethod; QAuthenticator authenticator; QAuthenticator proxyAuthenticator; + bool authenticationCredentialsSent; + bool proxyCredentialsSent; #ifndef QT_NO_OPENSSL bool ignoreAllSslErrors; QList<QSslError> ignoreSslErrorsList; diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 3978bd6c85..2146749ea5 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -60,7 +60,7 @@ #include "QtCore/qbuffer.h" #include "QtCore/qurl.h" #include "QtCore/qvector.h" -#include "QtNetwork/qauthenticator.h" +#include "QtNetwork/private/qauthenticator_p.h" #include "QtNetwork/qsslconfiguration.h" #include "QtNetwork/qnetworkconfigmanager.h" #include "QtNetwork/qhttpmultipart.h" @@ -1115,14 +1115,8 @@ void QNetworkAccessManagerPrivate::proxyAuthenticationRequired(const QNetworkPro QNetworkProxy *lastProxyAuthentication) { Q_Q(QNetworkAccessManager); - // ### FIXME Tracking of successful authentications - // This code is a bit broken right now for SOCKS authentication - // first request: proxyAuthenticationRequired gets emitted, credentials gets saved - // second request: (proxy != backend->reply->lastProxyAuthentication) does not evaluate to true, - // proxyAuthenticationRequired gets emitted again - // possible solution: some tracking inside the authenticator - // or a new function proxyAuthenticationSucceeded(true|false) - if (proxy != *lastProxyAuthentication) { + QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(*authenticator); + if (proxy != *lastProxyAuthentication && (!priv || !priv->hasFailed)) { QNetworkAuthenticationCredential cred = authenticationManager->fetchCachedProxyCredentials(proxy); if (!cred.isNull()) { authenticator->setUser(cred.user); |