From 1cf84e7fd21a98a75b851b03467acf43c27d4504 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Fri, 4 Sep 2020 20:35:25 +0200 Subject: [PATCH] QAuthenticator: Don't reset phase on every set* call In QAuthenticator "detach()" does not do what you expect. First off it doesn't detach at all, and secondly it will reset the phase that the authentication is in. This last part is intended, but it has one issue: if setUser/setPassword is called with the same arguments every time we ask for credentials then we never reach a fail-state since it thinks we will have a new chance to authenticate. Pick-to: 5.15 Change-Id: I02e2e42242220f3fced3572323e6492429cf173e Reviewed-by: Qt CI Bot Reviewed-by: Timur Pocheptsov --- src/network/kernel/qauthenticator.cpp | 41 ++++++++++++++++++++------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp index 45c8217701..87fc2d847a 100644 --- a/src/network/kernel/qauthenticator.cpp +++ b/src/network/kernel/qauthenticator.cpp @@ -249,9 +249,11 @@ QString QAuthenticator::user() const */ void QAuthenticator::setUser(const QString &user) { - detach(); - d->user = user; - d->updateCredentials(); + if (!d || d->user != user) { + detach(); + d->user = user; + d->updateCredentials(); + } } /*! @@ -269,8 +271,10 @@ QString QAuthenticator::password() const */ void QAuthenticator::setPassword(const QString &password) { - detach(); - d->password = password; + if (!d || d->password != password) { + detach(); + d->password = password; + } } /*! @@ -300,8 +304,10 @@ QString QAuthenticator::realm() const */ void QAuthenticator::setRealm(const QString &realm) { - detach(); - d->realm = realm; + if (!d || d->realm != realm) { + detach(); + d->realm = realm; + } } /*! @@ -341,8 +347,10 @@ QVariantHash QAuthenticator::options() const */ void QAuthenticator::setOption(const QString &opt, const QVariant &value) { - detach(); - d->options.insert(opt, value); + if (option(opt) != value) { + detach(); + d->options.insert(opt, value); + } } @@ -453,9 +461,20 @@ void QAuthenticatorPrivate::parseHttpResponse(const QList options = parseDigestAuthenticationChallenge(challenge); + // Sets phase to Start if this updates our realm and sets the two locations where we store + // realm + auto privSetRealm = [this](QString newRealm) { + if (newRealm != realm) { + if (phase == Done) + phase = Start; + realm = newRealm; + this->options[QLatin1String("realm")] = realm; + } + }; + switch(method) { case Basic: - this->options[QLatin1String("realm")] = realm = QString::fromLatin1(options.value("realm")); + privSetRealm(QString::fromLatin1(options.value("realm"))); if (user.isEmpty() && password.isEmpty()) phase = Done; break; @@ -464,7 +483,7 @@ void QAuthenticatorPrivate::parseHttpResponse(const QListoptions[QLatin1String("realm")] = realm = QString::fromLatin1(options.value("realm")); + privSetRealm(QString::fromLatin1(options.value("realm"))); if (options.value("stale").compare("true", Qt::CaseInsensitive) == 0) { phase = Start; nonceCount = 0;