diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp index f7e8a205a1e..ba61f661155 100644 --- a/src/network/kernel/qauthenticator.cpp +++ b/src/network/kernel/qauthenticator.cpp @@ -443,6 +443,21 @@ bool QAuthenticatorPrivate::isMethodSupported(QByteArrayView method) return std::any_of(methods, methods + std::size(methods), isSupported); } +static bool verifyDigestMD5(QByteArrayView value) +{ + auto opts = QAuthenticatorPrivate::parseDigestAuthenticationChallenge(value.toByteArray()); + if (auto it = opts.constFind("algorithm"); it != opts.cend()) { + QByteArray alg = it.value(); + if (alg.size() < 3) + return false; + // Just compare the first 3 characters, that way we match other subvariants as well, such as + // "MD5-sess" + auto view = QByteArrayView(alg).first(3); + return view.compare("MD5", Qt::CaseInsensitive) == 0; + } + return true; // assume it's ok if algorithm is not specified +} + void QAuthenticatorPrivate::parseHttpResponse(const QList > &values, bool isProxy, const QString &host) { #if !QT_CONFIG(gssapi) @@ -474,6 +489,10 @@ void QAuthenticatorPrivate::parseHttpResponse(const QListcalculateResponse("GET", "/", "").startsWith("NTLM ")); } +// We don't (currently) support SHA256. So, when presented with the option of MD5 or SHA256, +// we should always pick MD5. +void tst_QAuthenticator::sha256AndMd5Digest() +{ + QByteArray md5 = "Digest realm=\"\", nonce=\"\", algorithm=MD5, qop=\"auth\""; + QByteArray sha256 = "Digest realm=\"\", nonce=\"\", algorithm=SHA-256, qop=\"auth\""; + + QAuthenticator auth; + auth.setUser("unimportant"); + auth.setPassword("unimportant"); + + QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(auth); + QVERIFY(priv->isMethodSupported("digest")); // sanity check + + QCOMPARE(priv->phase, QAuthenticatorPrivate::Start); + QList> headers; + // Put sha256 first, so that its parsed first... + headers.emplace_back("WWW-Authenticate", sha256); + headers.emplace_back("WWW-Authenticate", md5); + priv->parseHttpResponse(headers, false, QString()); + + QByteArray response = priv->calculateResponse("GET", "/index", {}); + QCOMPARE(priv->phase, QAuthenticatorPrivate::Done); + + QVERIFY(!response.isEmpty()); + QVERIFY(!response.contains("algorithm=SHA-256")); + QVERIFY(response.contains("algorithm=MD5")); +} + void tst_QAuthenticator::equalityOperators() { QAuthenticator s1, s2;