summaryrefslogtreecommitdiffstats
path: root/src/network/access
diff options
context:
space:
mode:
authorShane Kearns <shane.kearns@accenture.com>2011-12-15 17:32:47 (GMT)
committerShane Kearns <shane.kearns@accenture.com>2012-01-04 17:35:26 (GMT)
commit682555cb0104f90117f0e492999c41362ab7aad9 (patch)
tree4824ea81d19fbf7223be00e7a0e3d3555fa28bb0 /src/network/access
parent26f1ca8681db995e82c0f4c0fa9363c842520700 (diff)
downloadQt-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.cpp16
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp12
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel_p.h2
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp12
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);