diff options
author | Shane Kearns <shane.kearns@accenture.com> | 2011-12-15 17:32:47 (GMT) |
---|---|---|
committer | Shane Kearns <shane.kearns@accenture.com> | 2012-01-04 17:35:26 (GMT) |
commit | 682555cb0104f90117f0e492999c41362ab7aad9 (patch) | |
tree | 4824ea81d19fbf7223be00e7a0e3d3555fa28bb0 /src/network/access | |
parent | 26f1ca8681db995e82c0f4c0fa9363c842520700 (diff) | |
download | Qt-682555cb0104f90117f0e492999c41362ab7aad9.zip Qt-682555cb0104f90117f0e492999c41362ab7aad9.tar.gz Qt-682555cb0104f90117f0e492999c41362ab7aad9.tar.bz2 |
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>
(cherry-picked from d24aad82896addce88f1ffb4040560e406acf083)
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 5ef4df0..a79b10f 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -375,9 +375,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 } @@ -438,6 +452,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; } } } @@ -449,6 +464,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 b9db7fe..e4f0f12 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 @@ -555,6 +557,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 @@ -562,7 +572,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 f635cc9..31a286b 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 8fc8eb7..689441e 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -61,7 +61,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" @@ -1093,14 +1093,8 @@ void QNetworkAccessManagerPrivate::proxyAuthenticationRequired(QNetworkAccessBac QAuthenticator *authenticator) { 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 != backend->reply->lastProxyAuthentication) { + QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(*authenticator); + if (proxy != backend->reply->lastProxyAuthentication && (!priv || !priv->hasFailed)) { QNetworkAuthenticationCredential cred = authenticationManager->fetchCachedProxyCredentials(proxy); if (!cred.isNull()) { authenticator->setUser(cred.user); |