diff options
author | Mårten Nordheim <marten.nordheim@qt.io> | 2020-09-04 20:35:25 +0200 |
---|---|---|
committer | Mårten Nordheim <marten.nordheim@qt.io> | 2020-09-11 11:30:57 +0200 |
commit | 1cf84e7fd21a98a75b851b03467acf43c27d4504 (patch) | |
tree | 59e1c6883cc17b4b566d8a7010935cf706aa59e9 /src/network/kernel | |
parent | 5a47939d5c07a968f27562a3ebc800fcc2b225bc (diff) |
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 <qt_ci_bot@qt-project.org>
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Diffstat (limited to 'src/network/kernel')
-rw-r--r-- | src/network/kernel/qauthenticator.cpp | 41 |
1 files 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<QPair<QByteArray, QByt challenge = headerVal.trimmed(); QHash<QByteArray, QByteArray> 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 QList<QPair<QByteArray, QByt // work is done in calculateResponse() break; case DigestMd5: { - this->options[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; |