summaryrefslogtreecommitdiffstats
path: root/src/network/kernel/qauthenticator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/kernel/qauthenticator.cpp')
-rw-r--r--src/network/kernel/qauthenticator.cpp75
1 files changed, 50 insertions, 25 deletions
diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp
index e715a88cdf..93b323f0bd 100644
--- a/src/network/kernel/qauthenticator.cpp
+++ b/src/network/kernel/qauthenticator.cpp
@@ -1,12 +1,11 @@
/****************************************************************************
**
-** Copyright (C) 2021 The Qt Company Ltd.
+** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtNetwork module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:COMM$
-**
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
@@ -15,25 +14,26 @@
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
-** $QT_END_LICENSE$
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
-**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
+** $QT_END_LICENSE$
**
****************************************************************************/
@@ -50,6 +50,7 @@
#include <qstring.h>
#include <qdatetime.h>
#include <qrandom.h>
+#include "private/qsystemlibrary_p.h"
#ifdef Q_OS_WIN
#include <qmutex.h>
@@ -423,6 +424,22 @@ void QAuthenticatorPrivate::updateCredentials()
}
}
+static bool verifyDigestMD5(const QByteArray &value)
+{
+ auto opts = QAuthenticatorPrivate::parseDigestAuthenticationChallenge(value);
+ auto it = opts.constFind("algorithm");
+ if (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 = QByteArray::fromRawData(alg.data(), 3);
+ return view.compare("MD5", Qt::CaseInsensitive) == 0;
+ }
+ return true; // assume it's ok if algorithm is not specified
+}
+
void QAuthenticatorPrivate::parseHttpResponse(const QList<QPair<QByteArray, QByteArray> > &values, bool isProxy, const QString &host)
{
#if !QT_CONFIG(gssapi)
@@ -454,8 +471,13 @@ void QAuthenticatorPrivate::parseHttpResponse(const QList<QPair<QByteArray, QByt
method = Ntlm;
headerVal = current.second.mid(5);
} else if (method < DigestMd5 && str.startsWith("digest")) {
+ // Make sure the algorithm is actually MD5 before committing to it:
+ QByteArray fieldValue = current.second.mid(7);
+ if (!verifyDigestMD5(fieldValue))
+ continue;
+
method = DigestMd5;
- headerVal = current.second.mid(7);
+ headerVal = fieldValue;
} else if (method < Negotiate && str.startsWith("negotiate")) {
#if QT_CONFIG(sspi) || QT_CONFIG(gssapi) // if it's not supported then we shouldn't try to use it
#if QT_CONFIG(gssapi)
@@ -599,9 +621,11 @@ QByteArray QAuthenticatorPrivate::calculateResponse(const QByteArray &requestMet
} else {
QByteArray phase3Token;
#if QT_CONFIG(sspi) // SSPI
- phase3Token = qSspiContinue(this, method, host, QByteArray::fromBase64(challenge));
+ if (sspiWindowsHandles)
+ phase3Token = qSspiContinue(this, method, host, QByteArray::fromBase64(challenge));
#elif QT_CONFIG(gssapi) // GSSAPI
- phase3Token = qGssapiContinue(this, QByteArray::fromBase64(challenge));
+ if (gssApiHandles)
+ phase3Token = qGssapiContinue(this, QByteArray::fromBase64(challenge));
#endif
if (!phase3Token.isEmpty()) {
response = phase3Token.toBase64();
@@ -1542,7 +1566,7 @@ static bool q_SSPI_library_load()
// Initialize security interface
if (pSecurityFunctionTable == nullptr) {
- securityDLLHandle = LoadLibrary(L"secur32.dll");
+ securityDLLHandle = QSystemLibrary::load(L"secur32");
if (securityDLLHandle != nullptr) {
INIT_SECURITY_INTERFACE pInitSecurityInterface =
reinterpret_cast<INIT_SECURITY_INTERFACE>(
@@ -1568,7 +1592,8 @@ static QByteArray qSspiStartup(QAuthenticatorPrivate *ctx, QAuthenticatorPrivate
if (!ctx->sspiWindowsHandles)
ctx->sspiWindowsHandles.reset(new QSSPIWindowsHandles);
- memset(&ctx->sspiWindowsHandles->credHandle, 0, sizeof(CredHandle));
+ SecInvalidateHandle(&ctx->sspiWindowsHandles->credHandle);
+ SecInvalidateHandle(&ctx->sspiWindowsHandles->ctxHandle);
SEC_WINNT_AUTH_IDENTITY auth;
auth.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;