OpenCoverage

qauthenticator.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/network/kernel/qauthenticator.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2016 The Qt Company Ltd.-
4** Contact: https://www.qt.io/licensing/-
5**-
6** This file is part of the QtNetwork module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL$-
9** Commercial License Usage-
10** Licensees holding valid commercial Qt licenses may use this file in-
11** accordance with the commercial license agreement provided with the-
12** Software or, alternatively, in accordance with the terms contained in-
13** a written agreement between you and The Qt Company. For licensing terms-
14** and conditions see https://www.qt.io/terms-conditions. For further-
15** information use the contact form at https://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 3 as published by the Free Software-
20** Foundation and appearing in the file LICENSE.LGPL3 included in the-
21** packaging of this file. Please review the following information to-
22** ensure the GNU Lesser General Public License version 3 requirements-
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
24**-
25** GNU General Public License Usage-
26** Alternatively, this file may be used under the terms of the GNU-
27** General Public License version 2.0 or (at your option) the GNU General-
28** Public license version 3 or any later version approved by the KDE Free-
29** Qt Foundation. The licenses are as published by the Free Software-
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
31** included in the packaging of this file. Please review the following-
32** information to ensure the GNU General Public License requirements will-
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
34** https://www.gnu.org/licenses/gpl-3.0.html.-
35**-
36** $QT_END_LICENSE$-
37**-
38****************************************************************************/-
39-
40#include <qauthenticator.h>-
41#include <qauthenticator_p.h>-
42#include <qdebug.h>-
43#include <qhash.h>-
44#include <qbytearray.h>-
45#include <qcryptographichash.h>-
46#include <qiodevice.h>-
47#include <qdatastream.h>-
48#include <qendian.h>-
49#include <qstring.h>-
50#include <qdatetime.h>-
51-
52#ifdef Q_OS_WIN-
53#include <qmutex.h>-
54#include <private/qmutexpool_p.h>-
55#include <rpc.h>-
56#ifndef Q_OS_WINRT-
57#define SECURITY_WIN32 1-
58#include <security.h>-
59#endif-
60#endif-
61-
62QT_BEGIN_NAMESPACE-
63-
64static QByteArray qNtlmPhase1();-
65static QByteArray qNtlmPhase3(QAuthenticatorPrivate *ctx, const QByteArray& phase2data);-
66#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)-
67static QByteArray qNtlmPhase1_SSPI(QAuthenticatorPrivate *ctx);-
68static QByteArray qNtlmPhase3_SSPI(QAuthenticatorPrivate *ctx, const QByteArray& phase2data);-
69#endif-
70-
71/*!-
72 \class QAuthenticator-
73 \brief The QAuthenticator class provides an authentication object.-
74 \since 4.3-
75-
76 \reentrant-
77 \ingroup network-
78 \inmodule QtNetwork-
79-
80 The QAuthenticator class is usually used in the-
81 \l{QNetworkAccessManager::}{authenticationRequired()} and-
82 \l{QNetworkAccessManager::}{proxyAuthenticationRequired()} signals of QNetworkAccessManager and-
83 QAbstractSocket. The class provides a way to pass back the required-
84 authentication information to the socket when accessing services that-
85 require authentication.-
86-
87 QAuthenticator supports the following authentication methods:-
88 \list-
89 \li Basic-
90 \li NTLM version 2-
91 \li Digest-MD5-
92 \endlist-
93-
94 \target qauthenticator-options-
95 \section1 Options-
96-
97 In addition to the username and password required for authentication, a-
98 QAuthenticator object can also contain additional options. The-
99 options() function can be used to query incoming options sent by-
100 the server; the setOption() function can-
101 be used to set outgoing options, to be processed by the authenticator-
102 calculation. The options accepted and provided depend on the authentication-
103 type (see method()).-
104-
105 The following tables list known incoming options as well as accepted-
106 outgoing options. The list of incoming options is not exhaustive, since-
107 servers may include additional information at any time. The list of-
108 outgoing options is exhaustive, however, and no unknown options will be-
109 treated or sent back to the server.-
110-
111 \section2 Basic-
112-
113 \table-
114 \header \li Option \li Direction \li Type \li Description-
115 \row \li \tt{realm} \li Incoming \li QString \li Contains the realm of the authentication, the same as realm()-
116 \endtable-
117-
118 The Basic authentication mechanism supports no outgoing options.-
119-
120 \section2 NTLM version 2-
121-
122 The NTLM authentication mechanism currently supports no incoming or outgoing options.-
123 On Windows, if no \a user has been set, domain\\user credentials will be searched for on the-
124 local system to enable Single-Sign-On functionality.-
125-
126 \section2 Digest-MD5-
127-
128 \table-
129 \header \li Option \li Direction \li Type \li Description-
130 \row \li \tt{realm} \li Incoming \li QString \li Contains the realm of the authentication, the same as realm()-
131 \endtable-
132-
133 The Digest-MD5 authentication mechanism supports no outgoing options.-
134-
135 \sa QSslSocket-
136*/-
137-
138-
139/*!-
140 Constructs an empty authentication object.-
141*/-
142QAuthenticator::QAuthenticator()-
143 : d(0)-
144{-
145}
executed 7351 times by 15 tests: end of block
Executed by:
  • tst_QAbstractNetworkCache
  • tst_QHttpNetworkConnection
  • tst_QNetworkAccessManager_And_QProgressDialog
  • tst_QNetworkDiskCache
  • tst_QNetworkProxyFactory
  • tst_QNetworkReply
  • tst_QXmlInputSource
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsocks5socketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
7351
146-
147/*!-
148 Destructs the object.-
149*/-
150QAuthenticator::~QAuthenticator()-
151{-
152 if (d)
dDescription
TRUEevaluated 2549 times by 16 tests
Evaluated by:
  • tst_QAbstractNetworkCache
  • tst_QHttpNetworkConnection
  • tst_QNetworkAccessManager_And_QProgressDialog
  • tst_QNetworkDiskCache
  • tst_QNetworkProxyFactory
  • tst_QNetworkReply
  • tst_QXmlInputSource
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsocks5socketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
  • tst_spdy - unknown status
FALSEevaluated 4790 times by 13 tests
Evaluated by:
  • tst_QAbstractNetworkCache
  • tst_QHttpNetworkConnection
  • tst_QNetworkAccessManager_And_QProgressDialog
  • tst_QNetworkDiskCache
  • tst_QNetworkProxyFactory
  • tst_QNetworkReply
  • tst_QXmlInputSource
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsocks5socketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qtcpsocket - unknown status
2549-4790
153 delete d;
executed 2549 times by 16 tests: delete d;
Executed by:
  • tst_QAbstractNetworkCache
  • tst_QHttpNetworkConnection
  • tst_QNetworkAccessManager_And_QProgressDialog
  • tst_QNetworkDiskCache
  • tst_QNetworkProxyFactory
  • tst_QNetworkReply
  • tst_QXmlInputSource
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsocks5socketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
  • tst_spdy - unknown status
2549
154}
executed 7339 times by 16 tests: end of block
Executed by:
  • tst_QAbstractNetworkCache
  • tst_QHttpNetworkConnection
  • tst_QNetworkAccessManager_And_QProgressDialog
  • tst_QNetworkDiskCache
  • tst_QNetworkProxyFactory
  • tst_QNetworkReply
  • tst_QXmlInputSource
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsocks5socketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
  • tst_spdy - unknown status
7339
155-
156/*!-
157 Constructs a copy of \a other.-
158*/-
159QAuthenticator::QAuthenticator(const QAuthenticator &other)-
160 : d(0)-
161{-
162 if (other.d)
other.dDescription
TRUEnever evaluated
FALSEnever evaluated
0
163 *this = other;
never executed: *this = other;
0
164}
never executed: end of block
0
165-
166/*!-
167 Assigns the contents of \a other to this authenticator.-
168*/-
169QAuthenticator &QAuthenticator::operator=(const QAuthenticator &other)-
170{-
171 if (d == other.d)
d == other.dDescription
TRUEnever evaluated
FALSEevaluated 43 times by 3 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_qhttpsocketengine - unknown status
0-43
172 return *this;
never executed: return *this;
0
173-
174 // Do not share the d since challange reponse/based changes-
175 // could corrupt the internal store and different network requests-
176 // can utilize different types of proxies.-
177 detach();-
178 if (other.d) {
other.dDescription
TRUEnever evaluated
FALSEevaluated 43 times by 3 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_qhttpsocketengine - unknown status
0-43
179 d->user = other.d->user;-
180 d->userDomain = other.d->userDomain;-
181 d->workstation = other.d->workstation;-
182 d->extractedUser = other.d->extractedUser;-
183 d->password = other.d->password;-
184 d->realm = other.d->realm;-
185 d->method = other.d->method;-
186 d->options = other.d->options;-
187 } else if (d->phase == QAuthenticatorPrivate::Start) {
never executed: end of block
d->phase == QA...Private::StartDescription
TRUEevaluated 43 times by 3 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_qhttpsocketengine - unknown status
FALSEnever evaluated
0-43
188 delete d;-
189 d = 0;-
190 }
executed 43 times by 3 tests: end of block
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_qhttpsocketengine - unknown status
43
191 return *this;
executed 43 times by 3 tests: return *this;
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_qhttpsocketengine - unknown status
43
192}-
193-
194/*!-
195 Returns \c true if this authenticator is identical to \a other; otherwise-
196 returns \c false.-
197*/-
198bool QAuthenticator::operator==(const QAuthenticator &other) const-
199{-
200 if (d == other.d)
d == other.dDescription
TRUEevaluated 4 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
FALSEevaluated 4 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
4
201 return true;
executed 4 times by 1 test: return true;
Executed by:
  • tst_qauthenticator - unknown status
4
202 if (!d || !other.d)
!dDescription
TRUEevaluated 2 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
FALSEevaluated 2 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
!other.dDescription
TRUEevaluated 2 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
FALSEnever evaluated
0-2
203 return false;
executed 4 times by 1 test: return false;
Executed by:
  • tst_qauthenticator - unknown status
4
204 return d->user == other.d->user
never executed: return d->user == other.d->user && d->password == other.d->password && d->realm == other.d->realm && d->method == other.d->method && d->options == other.d->options;
0
205 && d->password == other.d->password
never executed: return d->user == other.d->user && d->password == other.d->password && d->realm == other.d->realm && d->method == other.d->method && d->options == other.d->options;
0
206 && d->realm == other.d->realm
never executed: return d->user == other.d->user && d->password == other.d->password && d->realm == other.d->realm && d->method == other.d->method && d->options == other.d->options;
0
207 && d->method == other.d->method
never executed: return d->user == other.d->user && d->password == other.d->password && d->realm == other.d->realm && d->method == other.d->method && d->options == other.d->options;
0
208 && d->options == other.d->options;
never executed: return d->user == other.d->user && d->password == other.d->password && d->realm == other.d->realm && d->method == other.d->method && d->options == other.d->options;
0
209}-
210-
211/*!-
212 \fn bool QAuthenticator::operator!=(const QAuthenticator &other) const-
213-
214 Returns \c true if this authenticator is different from \a other; otherwise-
215 returns \c false.-
216*/-
217-
218/*!-
219 Returns the user used for authentication.-
220*/-
221QString QAuthenticator::user() const-
222{-
223 return d ? d->user : QString();
executed 4333 times by 8 tests: return d ? d->user : QString();
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qsocks5socketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
4333
224}-
225-
226/*!-
227 Sets the \a user used for authentication.-
228-
229 \sa QNetworkAccessManager::authenticationRequired()-
230*/-
231void QAuthenticator::setUser(const QString &user)-
232{-
233 detach();-
234 d->user = user;-
235 d->updateCredentials();-
236}
executed 1156 times by 10 tests: end of block
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsocks5socketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
1156
237-
238/*!-
239 Returns the password used for authentication.-
240*/-
241QString QAuthenticator::password() const-
242{-
243 return d ? d->password : QString();
executed 3969 times by 8 tests: return d ? d->password : QString();
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qsocks5socketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
3969
244}-
245-
246/*!-
247 Sets the \a password used for authentication.-
248-
249 \sa QNetworkAccessManager::authenticationRequired()-
250*/-
251void QAuthenticator::setPassword(const QString &password)-
252{-
253 detach();-
254 d->password = password;-
255}
executed 1165 times by 10 tests: end of block
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsocks5socketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
1165
256-
257/*!-
258 \internal-
259*/-
260void QAuthenticator::detach()-
261{-
262 if (!d) {
!dDescription
TRUEevaluated 2596 times by 15 tests
Evaluated by:
  • tst_QAbstractNetworkCache
  • tst_QHttpNetworkConnection
  • tst_QNetworkAccessManager_And_QProgressDialog
  • tst_QNetworkDiskCache
  • tst_QNetworkProxyFactory
  • tst_QNetworkReply
  • tst_QXmlInputSource
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsocks5socketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
FALSEevaluated 2156 times by 10 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsocks5socketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
2156-2596
263 d = new QAuthenticatorPrivate;-
264 return;
executed 2596 times by 15 tests: return;
Executed by:
  • tst_QAbstractNetworkCache
  • tst_QHttpNetworkConnection
  • tst_QNetworkAccessManager_And_QProgressDialog
  • tst_QNetworkDiskCache
  • tst_QNetworkProxyFactory
  • tst_QNetworkReply
  • tst_QXmlInputSource
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsocks5socketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
2596
265 }-
266-
267 if (d->phase == QAuthenticatorPrivate::Done)
d->phase == QA...rPrivate::DoneDescription
TRUEevaluated 578 times by 9 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
FALSEevaluated 1578 times by 10 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsocks5socketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
578-1578
268 d->phase = QAuthenticatorPrivate::Start;
executed 578 times by 9 tests: d->phase = QAuthenticatorPrivate::Start;
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
578
269}
executed 2156 times by 10 tests: end of block
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsocks5socketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
2156
270-
271/*!-
272 Returns the realm requiring authentication.-
273*/-
274QString QAuthenticator::realm() const-
275{-
276 return d ? d->realm : QString();
executed 430 times by 3 tests: return d ? d->realm : QString();
Executed by:
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
430
277}-
278-
279/*!-
280 \internal-
281*/-
282void QAuthenticator::setRealm(const QString &realm)-
283{-
284 detach();-
285 d->realm = realm;-
286}
never executed: end of block
0
287-
288/*!-
289 \since 4.7-
290 Returns the value related to option \a opt if it was set by the server.-
291 See the \l{QAuthenticator#qauthenticator-options}{Options section} for-
292 more information on incoming options.-
293 If option \a opt isn't found, an invalid QVariant will be returned.-
294-
295 \sa options(), {QAuthenticator#qauthenticator-options}{QAuthenticator options}-
296*/-
297QVariant QAuthenticator::option(const QString &opt) const-
298{-
299 return d ? d->options.value(opt) : QVariant();
executed 3 times by 1 test: return d ? d->options.value(opt) : QVariant();
Executed by:
  • tst_qauthenticator - unknown status
3
300}-
301-
302/*!-
303 \since 4.7-
304 Returns all incoming options set in this QAuthenticator object by parsing-
305 the server reply. See the \l{QAuthenticator#qauthenticator-options}{Options section}-
306 for more information on incoming options.-
307-
308 \sa option(), {QAuthenticator#qauthenticator-options}{QAuthenticator options}-
309*/-
310QVariantHash QAuthenticator::options() const-
311{-
312 return d ? d->options : QVariantHash();
never executed: return d ? d->options : QVariantHash();
0
313}-
314-
315/*!-
316 \since 4.7-
317-
318 Sets the outgoing option \a opt to value \a value.-
319 See the \l{QAuthenticator#qauthenticator-options}{Options section} for more information on outgoing options.-
320-
321 \sa options(), option(), {QAuthenticator#qauthenticator-options}{QAuthenticator options}-
322*/-
323void QAuthenticator::setOption(const QString &opt, const QVariant &value)-
324{-
325 detach();-
326 d->options.insert(opt, value);-
327}
never executed: end of block
0
328-
329-
330/*!-
331 Returns \c true if the object has not been initialized. Returns-
332 \c false if non-const member functions have been called, or-
333 the content was constructed or copied from another initialized-
334 QAuthenticator object.-
335*/-
336bool QAuthenticator::isNull() const-
337{-
338 return !d;
executed 1220 times by 8 tests: return !d;
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
1220
339}-
340-
341#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)-
342class QNtlmWindowsHandles-
343{-
344public:-
345 CredHandle credHandle;-
346 CtxtHandle ctxHandle;-
347};-
348#endif-
349-
350-
351QAuthenticatorPrivate::QAuthenticatorPrivate()-
352 : method(None)-
353 #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)-
354 , ntlmWindowsHandles(0)-
355 #endif-
356 , hasFailed(false)-
357 , phase(Start)-
358 , nonceCount(0)-
359{-
360 cnonce = QCryptographicHash::hash(QByteArray::number(qrand(), 16) + QByteArray::number(qrand(), 16),-
361 QCryptographicHash::Md5).toHex();-
362 nonceCount = 0;-
363}
executed 2596 times by 15 tests: end of block
Executed by:
  • tst_QAbstractNetworkCache
  • tst_QHttpNetworkConnection
  • tst_QNetworkAccessManager_And_QProgressDialog
  • tst_QNetworkDiskCache
  • tst_QNetworkProxyFactory
  • tst_QNetworkReply
  • tst_QXmlInputSource
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsocks5socketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
2596
364-
365QAuthenticatorPrivate::~QAuthenticatorPrivate()-
366{-
367#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)-
368 if (ntlmWindowsHandles)-
369 delete ntlmWindowsHandles;-
370#endif-
371}-
372-
373void QAuthenticatorPrivate::updateCredentials()-
374{-
375 int separatorPosn = 0;-
376-
377 switch (method) {-
378 case QAuthenticatorPrivate::Ntlm:
executed 8 times by 1 test: case QAuthenticatorPrivate::Ntlm:
Executed by:
  • tst_qauthenticator - unknown status
8
379 if ((separatorPosn = user.indexOf(QLatin1String("\\"))) != -1) {
(separatorPosn...("\\"))) != -1Description
TRUEnever evaluated
FALSEevaluated 8 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
0-8
380 //domain name is present-
381 realm.clear();-
382 userDomain = user.left(separatorPosn);-
383 extractedUser = user.mid(separatorPosn + 1);-
384 } else {
never executed: end of block
0
385 extractedUser = user;-
386 realm.clear();-
387 userDomain.clear();-
388 }
executed 8 times by 1 test: end of block
Executed by:
  • tst_qauthenticator - unknown status
8
389 break;
executed 8 times by 1 test: break;
Executed by:
  • tst_qauthenticator - unknown status
8
390 default:
executed 1688 times by 10 tests: default:
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsocks5socketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
1688
391 userDomain.clear();-
392 break;
executed 1688 times by 10 tests: break;
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsocks5socketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
1688
393 }-
394}-
395-
396void QAuthenticatorPrivate::parseHttpResponse(const QList<QPair<QByteArray, QByteArray> > &values, bool isProxy)-
397{-
398 const char *search = isProxy ? "proxy-authenticate" : "www-authenticate";
isProxyDescription
TRUEevaluated 229 times by 7 tests
Evaluated by:
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
FALSEevaluated 311 times by 3 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_qauthenticator - unknown status
229-311
399-
400 method = None;-
401 /*-
402 Fun from the HTTP 1.1 specs, that we currently ignore:-
403-
404 User agents are advised to take special care in parsing the WWW--
405 Authenticate field value as it might contain more than one challenge,-
406 or if more than one WWW-Authenticate header field is provided, the-
407 contents of a challenge itself can contain a comma-separated list of-
408 authentication parameters.-
409 */-
410-
411 QByteArray headerVal;-
412 for (int i = 0; i < values.size(); ++i) {
i < values.size()Description
TRUEevaluated 4613 times by 9 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
FALSEevaluated 540 times by 9 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
540-4613
413 const QPair<QByteArray, QByteArray> &current = values.at(i);-
414 if (current.first.toLower() != search)
current.first....er() != searchDescription
TRUEevaluated 4074 times by 8 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
FALSEevaluated 539 times by 9 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
539-4074
415 continue;
executed 4074 times by 8 tests: continue;
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
4074
416 QByteArray str = current.second.toLower();-
417 if (method < Basic && str.startsWith("basic")) {
method < BasicDescription
TRUEevaluated 539 times by 9 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
FALSEnever evaluated
str.startsWith("basic")Description
TRUEevaluated 463 times by 9 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
FALSEevaluated 76 times by 4 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
0-539
418 method = Basic;-
419 headerVal = current.second.mid(6);-
420 } else if (method < Ntlm && str.startsWith("ntlm")) {
executed 463 times by 9 tests: end of block
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
method < NtlmDescription
TRUEevaluated 76 times by 4 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
FALSEnever evaluated
str.startsWith("ntlm")Description
TRUEevaluated 8 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
FALSEevaluated 68 times by 3 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_qhttpsocketengine - unknown status
0-463
421 method = Ntlm;-
422 headerVal = current.second.mid(5);-
423 } else if (method < DigestMd5 && str.startsWith("digest")) {
executed 8 times by 1 test: end of block
Executed by:
  • tst_qauthenticator - unknown status
method < DigestMd5Description
TRUEevaluated 68 times by 3 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_qhttpsocketengine - unknown status
FALSEnever evaluated
str.startsWith("digest")Description
TRUEevaluated 67 times by 2 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
FALSEevaluated 1 time by 1 test
Evaluated by:
  • tst_qhttpsocketengine - unknown status
0-68
424 method = DigestMd5;-
425 headerVal = current.second.mid(7);-
426 }
executed 67 times by 2 tests: end of block
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
67
427 }
executed 539 times by 9 tests: end of block
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
539
428-
429 // Reparse credentials since we know the method now-
430 updateCredentials();-
431 challenge = headerVal.trimmed();-
432 QHash<QByteArray, QByteArray> options = parseDigestAuthenticationChallenge(challenge);-
433-
434 switch(method) {-
435 case Basic:
executed 463 times by 9 tests: case Basic:
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
463
436 this->options[QLatin1String("realm")] = realm = QString::fromLatin1(options.value("realm"));-
437 if (user.isEmpty() && password.isEmpty())
user.isEmpty()Description
TRUEevaluated 291 times by 9 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
FALSEevaluated 172 times by 3 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_qhttpsocketengine - unknown status
password.isEmpty()Description
TRUEevaluated 291 times by 9 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
FALSEnever evaluated
0-291
438 phase = Done;
executed 291 times by 9 tests: phase = Done;
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
291
439 break;
executed 463 times by 9 tests: break;
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
463
440 case Ntlm:
executed 8 times by 1 test: case Ntlm:
Executed by:
  • tst_qauthenticator - unknown status
8
441 // work is done in calculateResponse()-
442 break;
executed 8 times by 1 test: break;
Executed by:
  • tst_qauthenticator - unknown status
8
443 case DigestMd5: {
executed 67 times by 2 tests: case DigestMd5:
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
67
444 this->options[QLatin1String("realm")] = realm = QString::fromLatin1(options.value("realm"));-
445 if (options.value("stale").toLower() == "true")
options.value(...er() == "true"Description
TRUEnever evaluated
FALSEevaluated 67 times by 2 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
0-67
446 phase = Start;
never executed: phase = Start;
0
447 if (user.isEmpty() && password.isEmpty())
user.isEmpty()Description
TRUEevaluated 8 times by 2 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
FALSEevaluated 59 times by 2 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
password.isEmpty()Description
TRUEevaluated 8 times by 2 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
FALSEnever evaluated
0-59
448 phase = Done;
executed 8 times by 2 tests: phase = Done;
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
8
449 break;
executed 67 times by 2 tests: break;
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
67
450 }-
451 default:
executed 2 times by 1 test: default:
Executed by:
  • tst_qhttpsocketengine - unknown status
2
452 realm.clear();-
453 challenge = QByteArray();-
454 phase = Invalid;-
455 }
executed 2 times by 1 test: end of block
Executed by:
  • tst_qhttpsocketengine - unknown status
2
456}-
457-
458QByteArray QAuthenticatorPrivate::calculateResponse(const QByteArray &requestMethod, const QByteArray &path)-
459{-
460 QByteArray response;-
461 const char *methodString = 0;-
462 switch(method) {-
463 case QAuthenticatorPrivate::None:
never executed: case QAuthenticatorPrivate::None:
0
464 methodString = "";-
465 phase = Done;-
466 break;
never executed: break;
0
467 case QAuthenticatorPrivate::Plain:
never executed: case QAuthenticatorPrivate::Plain:
0
468 response = '\0' + user.toUtf8() + '\0' + password.toUtf8();-
469 phase = Done;-
470 break;
never executed: break;
0
471 case QAuthenticatorPrivate::Basic:
executed 326 times by 9 tests: case QAuthenticatorPrivate::Basic:
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
326
472 methodString = "Basic ";-
473 response = user.toLatin1() + ':' + password.toLatin1();-
474 response = response.toBase64();-
475 phase = Done;-
476 break;
executed 326 times by 9 tests: break;
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
326
477 case QAuthenticatorPrivate::Login:
never executed: case QAuthenticatorPrivate::Login:
0
478 if (challenge.contains("VXNlciBOYW1lAA==")) {
challenge.cont...ciBOYW1lAA==")Description
TRUEnever evaluated
FALSEnever evaluated
0
479 response = user.toUtf8().toBase64();-
480 phase = Phase2;-
481 } else if (challenge.contains("UGFzc3dvcmQA")) {
never executed: end of block
challenge.cont...UGFzc3dvcmQA")Description
TRUEnever evaluated
FALSEnever evaluated
0
482 response = password.toUtf8().toBase64();-
483 phase = Done;-
484 }
never executed: end of block
0
485 break;
never executed: break;
0
486 case QAuthenticatorPrivate::CramMd5:
never executed: case QAuthenticatorPrivate::CramMd5:
0
487 break;
never executed: break;
0
488 case QAuthenticatorPrivate::DigestMd5:
executed 35 times by 2 tests: case QAuthenticatorPrivate::DigestMd5:
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
35
489 methodString = "Digest ";-
490 response = digestMd5Response(challenge, requestMethod, path);-
491 phase = Done;-
492 break;
executed 35 times by 2 tests: break;
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
35
493 case QAuthenticatorPrivate::Ntlm:
executed 8 times by 1 test: case QAuthenticatorPrivate::Ntlm:
Executed by:
  • tst_qauthenticator - unknown status
8
494 methodString = "NTLM ";-
495 if (challenge.isEmpty()) {
challenge.isEmpty()Description
TRUEevaluated 4 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
FALSEevaluated 4 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
4
496#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)-
497 QByteArray phase1Token;-
498 if (user.isEmpty()) // Only pull from system if no user was specified in authenticator-
499 phase1Token = qNtlmPhase1_SSPI(this);-
500 if (!phase1Token.isEmpty()) {-
501 response = phase1Token.toBase64();-
502 phase = Phase2;-
503 } else-
504#endif-
505 {-
506 response = qNtlmPhase1().toBase64();-
507 if (user.isEmpty())
user.isEmpty()Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
FALSEevaluated 2 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
2
508 phase = Done;
executed 2 times by 1 test: phase = Done;
Executed by:
  • tst_qauthenticator - unknown status
2
509 else-
510 phase = Phase2;
executed 2 times by 1 test: phase = Phase2;
Executed by:
  • tst_qauthenticator - unknown status
2
511 }-
512 } else {-
513#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)-
514 QByteArray phase3Token;-
515 if (ntlmWindowsHandles)-
516 phase3Token = qNtlmPhase3_SSPI(this, QByteArray::fromBase64(challenge));-
517 if (!phase3Token.isEmpty()) {-
518 response = phase3Token.toBase64();-
519 phase = Done;-
520 } else-
521#endif-
522 {-
523 response = qNtlmPhase3(this, QByteArray::fromBase64(challenge)).toBase64();-
524 phase = Done;-
525 }-
526 }
executed 4 times by 1 test: end of block
Executed by:
  • tst_qauthenticator - unknown status
4
527-
528 break;
executed 8 times by 1 test: break;
Executed by:
  • tst_qauthenticator - unknown status
8
529 }-
530 return QByteArray(methodString) + response;
executed 369 times by 9 tests: return QByteArray(methodString) + response;
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
369
531}-
532-
533-
534// ---------------------------- Digest Md5 code -----------------------------------------
535-
536QHash<QByteArray, QByteArray> QAuthenticatorPrivate::parseDigestAuthenticationChallenge(const QByteArray &challenge)-
537{-
538 QHash<QByteArray, QByteArray> options;-
539 // parse the challenge-
540 const char *d = challenge.constData();-
541 const char *end = d + challenge.length();-
542 while (d < end) {
d < endDescription
TRUEevaluated 871 times by 9 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
FALSEevaluated 573 times by 9 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
573-871
543 while (d < end && (*d == ' ' || *d == '\n' || *d == '\r'))
d < endDescription
TRUEevaluated 1177 times by 9 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
FALSEnever evaluated
*d == ' 'Description
TRUEevaluated 306 times by 2 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
FALSEevaluated 871 times by 9 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
*d == '\n'Description
TRUEnever evaluated
FALSEevaluated 871 times by 9 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
*d == '\r'Description
TRUEnever evaluated
FALSEevaluated 871 times by 9 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
0-1177
544 ++d;
executed 306 times by 2 tests: ++d;
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
306
545 const char *start = d;-
546 while (d < end && *d != '=')
d < endDescription
TRUEevaluated 6700 times by 9 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
FALSEevaluated 2 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
*d != '='Description
TRUEevaluated 5831 times by 9 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
FALSEevaluated 869 times by 9 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
2-6700
547 ++d;
executed 5831 times by 9 tests: ++d;
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
5831
548 QByteArray key = QByteArray(start, d - start);-
549 ++d;-
550 if (d >= end)
d >= endDescription
TRUEevaluated 2 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
FALSEevaluated 869 times by 9 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
2-869
551 break;
executed 2 times by 1 test: break;
Executed by:
  • tst_qauthenticator - unknown status
2
552 bool quote = (*d == '"');-
553 if (quote)
quoteDescription
TRUEevaluated 761 times by 8 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
FALSEevaluated 108 times by 4 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
108-761
554 ++d;
executed 761 times by 8 tests: ++d;
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
761
555 if (d >= end)
d >= endDescription
TRUEnever evaluated
FALSEevaluated 869 times by 9 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
0-869
556 break;
never executed: break;
0
557 start = d;-
558 QByteArray value;-
559 while (d < end) {
d < endDescription
TRUEevaluated 19276 times by 9 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
FALSEevaluated 6 times by 2 tests
Evaluated by:
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
6-19276
560 bool backslash = false;-
561 if (*d == '\\' && d < end - 1) {
*d == '\\'Description
TRUEnever evaluated
FALSEevaluated 19276 times by 9 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
d < end - 1Description
TRUEnever evaluated
FALSEnever evaluated
0-19276
562 ++d;-
563 backslash = true;-
564 }
never executed: end of block
0
565 if (!backslash) {
!backslashDescription
TRUEevaluated 19276 times by 9 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
FALSEnever evaluated
0-19276
566 if (quote) {
quoteDescription
TRUEevaluated 18826 times by 8 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
FALSEevaluated 450 times by 4 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
450-18826
567 if (*d == '"')
*d == '"'Description
TRUEevaluated 761 times by 8 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
FALSEevaluated 18065 times by 8 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
761-18065
568 break;
executed 761 times by 8 tests: break;
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
761
569 } else {
executed 18065 times by 8 tests: end of block
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
18065
570 if (*d == ',')
*d == ','Description
TRUEevaluated 102 times by 2 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
FALSEevaluated 348 times by 4 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
102-348
571 break;
executed 102 times by 2 tests: break;
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
102
572 }
executed 348 times by 4 tests: end of block
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
348
573 }-
574 value += *d;-
575 ++d;-
576 }
executed 18413 times by 9 tests: end of block
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
18413
577 while (d < end && *d != ',')
d < endDescription
TRUEevaluated 1067 times by 8 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
FALSEevaluated 563 times by 9 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
*d != ','Description
TRUEevaluated 761 times by 8 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
FALSEevaluated 306 times by 2 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
306-1067
578 ++d;
executed 761 times by 8 tests: ++d;
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
761
579 ++d;-
580 options[key] = value;-
581 }
executed 869 times by 9 tests: end of block
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
869
582-
583 QByteArray qop = options.value("qop");-
584 if (!qop.isEmpty()) {
!qop.isEmpty()Description
TRUEevaluated 102 times by 2 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
FALSEevaluated 473 times by 9 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
102-473
585 QList<QByteArray> qopoptions = qop.split(',');-
586 if (!qopoptions.contains("auth"))
!qopoptions.contains("auth")Description
TRUEnever evaluated
FALSEevaluated 102 times by 2 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
0-102
587 return QHash<QByteArray, QByteArray>();
never executed: return QHash<QByteArray, QByteArray>();
0
588 // #### can't do auth-int currently-
589// if (qop.contains("auth-int"))-
590// qop = "auth-int";-
591// else if (qop.contains("auth"))-
592// qop = "auth";-
593// else-
594// qop = QByteArray();-
595 options["qop"] = "auth";-
596 }
executed 102 times by 2 tests: end of block
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
102
597-
598 return options;
executed 575 times by 9 tests: return options;
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
  • tst_qauthenticator - unknown status
  • tst_qhttpsocketengine - unknown status
  • tst_qsslsocket - unknown status
  • tst_qsslsocket_onDemandCertificates_member - unknown status
  • tst_qsslsocket_onDemandCertificates_static - unknown status
  • tst_qtcpsocket - unknown status
575
599}-
600-
601/*-
602 Digest MD5 implementation-
603-
604 Code taken from RFC 2617-
605-
606 Currently we don't support the full SASL authentication mechanism (which includes cyphers)-
607*/-
608-
609-
610/* calculate request-digest/response-digest as per HTTP Digest spec */-
611static QByteArray digestMd5ResponseHelper(-
612 const QByteArray &alg,-
613 const QByteArray &userName,-
614 const QByteArray &realm,-
615 const QByteArray &password,-
616 const QByteArray &nonce, /* nonce from server */-
617 const QByteArray &nonceCount, /* 8 hex digits */-
618 const QByteArray &cNonce, /* client nonce */-
619 const QByteArray &qop, /* qop-value: "", "auth", "auth-int" */-
620 const QByteArray &method, /* method from the request */-
621 const QByteArray &digestUri, /* requested URL */-
622 const QByteArray &hEntity /* H(entity body) if qop="auth-int" */-
623 )-
624{-
625 QCryptographicHash hash(QCryptographicHash::Md5);-
626 hash.addData(userName);-
627 hash.addData(":", 1);-
628 hash.addData(realm);-
629 hash.addData(":", 1);-
630 hash.addData(password);-
631 QByteArray ha1 = hash.result();-
632 if (alg.toLower() == "md5-sess") {
alg.toLower() == "md5-sess"Description
TRUEnever evaluated
FALSEevaluated 35 times by 2 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
0-35
633 hash.reset();-
634 // RFC 2617 contains an error, it was:-
635 // hash.addData(ha1);-
636 // but according to the errata page at http://www.rfc-editor.org/errata_list.php, ID 1649, it-
637 // must be the following line:-
638 hash.addData(ha1.toHex());-
639 hash.addData(":", 1);-
640 hash.addData(nonce);-
641 hash.addData(":", 1);-
642 hash.addData(cNonce);-
643 ha1 = hash.result();-
644 };
never executed: end of block
0
645 ha1 = ha1.toHex();-
646-
647 // calculate H(A2)-
648 hash.reset();-
649 hash.addData(method);-
650 hash.addData(":", 1);-
651 hash.addData(digestUri);-
652 if (qop.toLower() == "auth-int") {
qop.toLower() == "auth-int"Description
TRUEnever evaluated
FALSEevaluated 35 times by 2 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
0-35
653 hash.addData(":", 1);-
654 hash.addData(hEntity);-
655 }
never executed: end of block
0
656 QByteArray ha2hex = hash.result().toHex();-
657-
658 // calculate response-
659 hash.reset();-
660 hash.addData(ha1);-
661 hash.addData(":", 1);-
662 hash.addData(nonce);-
663 hash.addData(":", 1);-
664 if (!qop.isNull()) {
!qop.isNull()Description
TRUEevaluated 35 times by 2 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
FALSEnever evaluated
0-35
665 hash.addData(nonceCount);-
666 hash.addData(":", 1);-
667 hash.addData(cNonce);-
668 hash.addData(":", 1);-
669 hash.addData(qop);-
670 hash.addData(":", 1);-
671 }
executed 35 times by 2 tests: end of block
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
35
672 hash.addData(ha2hex);-
673 return hash.result().toHex();
executed 35 times by 2 tests: return hash.result().toHex();
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
35
674}-
675-
676QByteArray QAuthenticatorPrivate::digestMd5Response(const QByteArray &challenge, const QByteArray &method, const QByteArray &path)-
677{-
678 QHash<QByteArray,QByteArray> options = parseDigestAuthenticationChallenge(challenge);-
679-
680 ++nonceCount;-
681 QByteArray nonceCountString = QByteArray::number(nonceCount, 16);-
682 while (nonceCountString.length() < 8)
nonceCountString.length() < 8Description
TRUEevaluated 245 times by 2 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
FALSEevaluated 35 times by 2 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
35-245
683 nonceCountString.prepend('0');
executed 245 times by 2 tests: nonceCountString.prepend('0');
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
245
684-
685 QByteArray nonce = options.value("nonce");-
686 QByteArray opaque = options.value("opaque");-
687 QByteArray qop = options.value("qop");-
688-
689// qDebug() << "calculating digest: method=" << method << "path=" << path;-
690 QByteArray response = digestMd5ResponseHelper(options.value("algorithm"), user.toLatin1(),-
691 realm.toLatin1(), password.toLatin1(),-
692 nonce, nonceCountString,-
693 cnonce, qop, method,-
694 path, QByteArray());-
695-
696-
697 QByteArray credentials;-
698 credentials += "username=\"" + user.toLatin1() + "\", ";-
699 credentials += "realm=\"" + realm.toLatin1() + "\", ";-
700 credentials += "nonce=\"" + nonce + "\", ";-
701 credentials += "uri=\"" + path + "\", ";-
702 if (!opaque.isEmpty())
!opaque.isEmpty()Description
TRUEnever evaluated
FALSEevaluated 35 times by 2 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
0-35
703 credentials += "opaque=\"" + opaque + "\", ";
never executed: credentials += "opaque=\"" + opaque + "\", ";
0
704 credentials += "response=\"" + response + '"';-
705 if (!options.value("algorithm").isEmpty())
!options.value...hm").isEmpty()Description
TRUEevaluated 35 times by 2 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
FALSEnever evaluated
0-35
706 credentials += ", algorithm=" + options.value("algorithm");
executed 35 times by 2 tests: credentials += ", algorithm=" + options.value("algorithm");
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
35
707 if (!options.value("qop").isEmpty()) {
!options.value...op").isEmpty()Description
TRUEevaluated 35 times by 2 tests
Evaluated by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
FALSEnever evaluated
0-35
708 credentials += ", qop=" + qop + ", ";-
709 credentials += "nc=" + nonceCountString + ", ";-
710 credentials += "cnonce=\"" + cnonce + '"';-
711 }
executed 35 times by 2 tests: end of block
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
35
712-
713 return credentials;
executed 35 times by 2 tests: return credentials;
Executed by:
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
35
714}-
715-
716// ---------------------------- Digest Md5 code -----------------------------------------
717-
718-
719-
720/*-
721 * NTLM message flags.-
722 *-
723 * Copyright (c) 2004 Andrey Panin <pazke@donpac.ru>-
724 *-
725 * This software is released under the MIT license.-
726 */-
727-
728/*-
729 * Indicates that Unicode strings are supported for use in security-
730 * buffer data.-
731 */-
732#define NTLMSSP_NEGOTIATE_UNICODE 0x00000001-
733-
734/*-
735 * Indicates that OEM strings are supported for use in security buffer data.-
736 */-
737#define NTLMSSP_NEGOTIATE_OEM 0x00000002-
738-
739/*-
740 * Requests that the server's authentication realm be included in the-
741 * Type 2 message.-
742 */-
743#define NTLMSSP_REQUEST_TARGET 0x00000004-
744-
745/*-
746 * Specifies that authenticated communication between the client and server-
747 * should carry a digital signature (message integrity).-
748 */-
749#define NTLMSSP_NEGOTIATE_SIGN 0x00000010-
750-
751/*-
752 * Specifies that authenticated communication between the client and server-
753 * should be encrypted (message confidentiality).-
754 */-
755#define NTLMSSP_NEGOTIATE_SEAL 0x00000020-
756-
757/*-
758 * Indicates that datagram authentication is being used.-
759 */-
760#define NTLMSSP_NEGOTIATE_DATAGRAM 0x00000040-
761-
762/*-
763 * Indicates that the LAN Manager session key should be-
764 * used for signing and sealing authenticated communications.-
765 */-
766#define NTLMSSP_NEGOTIATE_LM_KEY 0x00000080-
767-
768/*-
769 * Indicates that NTLM authentication is being used.-
770 */-
771#define NTLMSSP_NEGOTIATE_NTLM 0x00000200-
772-
773/*-
774 * Sent by the client in the Type 1 message to indicate that the name of the-
775 * domain in which the client workstation has membership is included in the-
776 * message. This is used by the server to determine whether the client is-
777 * eligible for local authentication.-
778 */-
779#define NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED 0x00001000-
780-
781/*-
782 * Sent by the client in the Type 1 message to indicate that the client-
783 * workstation's name is included in the message. This is used by the server-
784 * to determine whether the client is eligible for local authentication.-
785 */-
786#define NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED 0x00002000-
787-
788/*-
789 * Sent by the server to indicate that the server and client are on the same-
790 * machine. Implies that the client may use the established local credentials-
791 * for authentication instead of calculating a response to the challenge.-
792 */-
793#define NTLMSSP_NEGOTIATE_LOCAL_CALL 0x00004000-
794-
795/*-
796 * Indicates that authenticated communication between the client and server-
797 * should be signed with a "dummy" signature.-
798 */-
799#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x00008000-
800-
801/*-
802 * Sent by the server in the Type 2 message to indicate that the target-
803 * authentication realm is a domain.-
804 */-
805#define NTLMSSP_TARGET_TYPE_DOMAIN 0x00010000-
806-
807/*-
808 * Sent by the server in the Type 2 message to indicate that the target-
809 * authentication realm is a server.-
810 */-
811#define NTLMSSP_TARGET_TYPE_SERVER 0x00020000-
812-
813/*-
814 * Sent by the server in the Type 2 message to indicate that the target-
815 * authentication realm is a share. Presumably, this is for share-level-
816 * authentication. Usage is unclear.-
817 */-
818#define NTLMSSP_TARGET_TYPE_SHARE 0x00040000-
819-
820/*-
821 * Indicates that the NTLM2 signing and sealing scheme should be used for-
822 * protecting authenticated communications. Note that this refers to a-
823 * particular session security scheme, and is not related to the use of-
824 * NTLMv2 authentication.-
825 */-
826#define NTLMSSP_NEGOTIATE_NTLM2 0x00080000-
827-
828/*-
829 * Sent by the server in the Type 2 message to indicate that it is including-
830 * a Target Information block in the message. The Target Information block-
831 * is used in the calculation of the NTLMv2 response.-
832 */-
833#define NTLMSSP_NEGOTIATE_TARGET_INFO 0x00800000-
834-
835/*-
836 * Indicates that 128-bit encryption is supported.-
837 */-
838#define NTLMSSP_NEGOTIATE_128 0x20000000-
839-
840/*-
841 * Indicates that the client will provide an encrypted master session key in-
842 * the "Session Key" field of the Type 3 message. This is used in signing and-
843 * sealing, and is RC4-encrypted using the previous session key as the-
844 * encryption key.-
845 */-
846#define NTLMSSP_NEGOTIATE_KEY_EXCHANGE 0x40000000-
847-
848/*-
849 * Indicates that 56-bit encryption is supported.-
850 */-
851#define NTLMSSP_NEGOTIATE_56 0x80000000-
852-
853/*-
854 * AvId values-
855 */-
856#define AVTIMESTAMP 7-
857-
858-
859//************************Global variables***************************-
860-
861const int blockSize = 64; //As per RFC2104 Block-size is 512 bits-
862const quint8 respversion = 1;-
863const quint8 hirespversion = 1;-
864-
865/* usage:-
866 // fill up ctx with what we know.-
867 QByteArray response = qNtlmPhase1(ctx);-
868 // send response (b64 encoded??)-
869 // get response from server (b64 decode?)-
870 Phase2Block pb;-
871 qNtlmDecodePhase2(response, pb);-
872 response = qNtlmPhase3(ctx, pb);-
873 // send response (b64 encoded??)-
874*/-
875-
876/*-
877 TODO:-
878 - Fix unicode handling-
879 - add v2 handling-
880*/-
881-
882class QNtlmBuffer {-
883public:-
884 QNtlmBuffer() : len(0), maxLen(0), offset(0) {}
executed 40 times by 1 test: end of block
Executed by:
  • tst_qauthenticator - unknown status
40
885 quint16 len;-
886 quint16 maxLen;-
887 quint32 offset;-
888 enum { Size = 8 };-
889};-
890-
891class QNtlmPhase1BlockBase-
892{-
893public:-
894 char magic[8];-
895 quint32 type;-
896 quint32 flags;-
897 QNtlmBuffer domain;-
898 QNtlmBuffer workstation;-
899 enum { Size = 32 };-
900};-
901-
902// ################# check paddings-
903class QNtlmPhase2BlockBase-
904{-
905public:-
906 char magic[8];-
907 quint32 type;-
908 QNtlmBuffer targetName;-
909 quint32 flags;-
910 unsigned char challenge[8];-
911 quint32 context[2];-
912 QNtlmBuffer targetInfo;-
913 enum { Size = 48 };-
914};-
915-
916class QNtlmPhase3BlockBase {-
917public:-
918 char magic[8];-
919 quint32 type;-
920 QNtlmBuffer lmResponse;-
921 QNtlmBuffer ntlmResponse;-
922 QNtlmBuffer domain;-
923 QNtlmBuffer user;-
924 QNtlmBuffer workstation;-
925 QNtlmBuffer sessionKey;-
926 quint32 flags;-
927 enum { Size = 64 };-
928};-
929-
930static void qStreamNtlmBuffer(QDataStream& ds, const QByteArray& s)-
931{-
932 ds.writeRawData(s.constData(), s.size());-
933}
executed 8 times by 1 test: end of block
Executed by:
  • tst_qauthenticator - unknown status
8
934-
935-
936static void qStreamNtlmString(QDataStream& ds, const QString& s, bool unicode)-
937{-
938 if (!unicode) {
!unicodeDescription
TRUEnever evaluated
FALSEevaluated 8 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
0-8
939 qStreamNtlmBuffer(ds, s.toLatin1());-
940 return;
never executed: return;
0
941 }-
942 const ushort *d = s.utf16();-
943 for (int i = 0; i < s.length(); ++i)
i < s.length()Description
TRUEevaluated 62 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
FALSEevaluated 8 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
8-62
944 ds << d[i];
executed 62 times by 1 test: ds << d[i];
Executed by:
  • tst_qauthenticator - unknown status
62
945}
executed 8 times by 1 test: end of block
Executed by:
  • tst_qauthenticator - unknown status
8
946-
947-
948-
949static int qEncodeNtlmBuffer(QNtlmBuffer& buf, int offset, const QByteArray& s)-
950{-
951 buf.len = s.size();-
952 buf.maxLen = buf.len;-
953 buf.offset = (offset + 1) & ~1;-
954 return buf.offset + buf.len;
executed 8 times by 1 test: return buf.offset + buf.len;
Executed by:
  • tst_qauthenticator - unknown status
8
955}-
956-
957-
958static int qEncodeNtlmString(QNtlmBuffer& buf, int offset, const QString& s, bool unicode)-
959{-
960 if (!unicode)
!unicodeDescription
TRUEnever evaluated
FALSEevaluated 12 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
0-12
961 return qEncodeNtlmBuffer(buf, offset, s.toLatin1());
never executed: return qEncodeNtlmBuffer(buf, offset, s.toLatin1());
0
962 buf.len = 2 * s.length();-
963 buf.maxLen = buf.len;-
964 buf.offset = (offset + 1) & ~1;-
965 return buf.offset + buf.len;
executed 12 times by 1 test: return buf.offset + buf.len;
Executed by:
  • tst_qauthenticator - unknown status
12
966}-
967-
968-
969static QDataStream& operator<<(QDataStream& s, const QNtlmBuffer& b)-
970{-
971 s << b.len << b.maxLen << b.offset;-
972 return s;
executed 32 times by 1 test: return s;
Executed by:
  • tst_qauthenticator - unknown status
32
973}-
974-
975static QDataStream& operator>>(QDataStream& s, QNtlmBuffer& b)-
976{-
977 s >> b.len >> b.maxLen >> b.offset;-
978 return s;
executed 8 times by 1 test: return s;
Executed by:
  • tst_qauthenticator - unknown status
8
979}-
980-
981-
982class QNtlmPhase1Block : public QNtlmPhase1BlockBase-
983{ // request-
984public:-
985 QNtlmPhase1Block() {-
986 qstrncpy(magic, "NTLMSSP", 8);-
987 type = 1;-
988 flags = NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_ALWAYS_SIGN | NTLMSSP_NEGOTIATE_NTLM2;-
989 }
executed 4 times by 1 test: end of block
Executed by:
  • tst_qauthenticator - unknown status
4
990-
991 // extracted-
992 QString domainStr, workstationStr;-
993};-
994-
995-
996class QNtlmPhase2Block : public QNtlmPhase2BlockBase-
997{ // challenge-
998public:-
999 QNtlmPhase2Block() {-
1000 magic[0] = 0;-
1001 type = 0xffffffff;-
1002 }
executed 4 times by 1 test: end of block
Executed by:
  • tst_qauthenticator - unknown status
4
1003-
1004 // extracted-
1005 QString targetNameStr, targetInfoStr;-
1006 QByteArray targetInfoBuff;-
1007};-
1008-
1009-
1010-
1011class QNtlmPhase3Block : public QNtlmPhase3BlockBase { // response-
1012public:-
1013 QNtlmPhase3Block() {-
1014 qstrncpy(magic, "NTLMSSP", 8);-
1015 type = 3;-
1016 flags = NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO;-
1017 }
executed 4 times by 1 test: end of block
Executed by:
  • tst_qauthenticator - unknown status
4
1018-
1019 // extracted-
1020 QByteArray lmResponseBuf, ntlmResponseBuf;-
1021 QString domainStr, userStr, workstationStr, sessionKeyStr;-
1022 QByteArray v2Hash;-
1023};-
1024-
1025-
1026static QDataStream& operator<<(QDataStream& s, const QNtlmPhase1Block& b) {-
1027 bool unicode = (b.flags & NTLMSSP_NEGOTIATE_UNICODE);-
1028-
1029 s.writeRawData(b.magic, sizeof(b.magic));-
1030 s << b.type;-
1031 s << b.flags;-
1032 s << b.domain;-
1033 s << b.workstation;-
1034 if (!b.domainStr.isEmpty())
!b.domainStr.isEmpty()Description
TRUEnever evaluated
FALSEevaluated 4 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
0-4
1035 qStreamNtlmString(s, b.domainStr, unicode);
never executed: qStreamNtlmString(s, b.domainStr, unicode);
0
1036 if (!b.workstationStr.isEmpty())
!b.workstationStr.isEmpty()Description
TRUEnever evaluated
FALSEevaluated 4 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
0-4
1037 qStreamNtlmString(s, b.workstationStr, unicode);
never executed: qStreamNtlmString(s, b.workstationStr, unicode);
0
1038 return s;
executed 4 times by 1 test: return s;
Executed by:
  • tst_qauthenticator - unknown status
4
1039}-
1040-
1041-
1042static QDataStream& operator<<(QDataStream& s, const QNtlmPhase3Block& b) {-
1043 bool unicode = (b.flags & NTLMSSP_NEGOTIATE_UNICODE);-
1044 s.writeRawData(b.magic, sizeof(b.magic));-
1045 s << b.type;-
1046 s << b.lmResponse;-
1047 s << b.ntlmResponse;-
1048 s << b.domain;-
1049 s << b.user;-
1050 s << b.workstation;-
1051 s << b.sessionKey;-
1052 s << b.flags;-
1053-
1054 if (!b.domainStr.isEmpty())
!b.domainStr.isEmpty()Description
TRUEevaluated 4 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
FALSEnever evaluated
0-4
1055 qStreamNtlmString(s, b.domainStr, unicode);
executed 4 times by 1 test: qStreamNtlmString(s, b.domainStr, unicode);
Executed by:
  • tst_qauthenticator - unknown status
4
1056-
1057 qStreamNtlmString(s, b.userStr, unicode);-
1058-
1059 if (!b.workstationStr.isEmpty())
!b.workstationStr.isEmpty()Description
TRUEnever evaluated
FALSEevaluated 4 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
0-4
1060 qStreamNtlmString(s, b.workstationStr, unicode);
never executed: qStreamNtlmString(s, b.workstationStr, unicode);
0
1061-
1062 // Send auth info-
1063 qStreamNtlmBuffer(s, b.lmResponseBuf);-
1064 qStreamNtlmBuffer(s, b.ntlmResponseBuf);-
1065-
1066-
1067 return s;
executed 4 times by 1 test: return s;
Executed by:
  • tst_qauthenticator - unknown status
4
1068}-
1069-
1070-
1071static QByteArray qNtlmPhase1()-
1072{-
1073 QByteArray rc;-
1074 QDataStream ds(&rc, QIODevice::WriteOnly);-
1075 ds.setByteOrder(QDataStream::LittleEndian);-
1076 QNtlmPhase1Block pb;-
1077 ds << pb;-
1078 return rc;
executed 4 times by 1 test: return rc;
Executed by:
  • tst_qauthenticator - unknown status
4
1079}-
1080-
1081-
1082static QByteArray qStringAsUcs2Le(const QString& src)-
1083{-
1084 QByteArray rc(2*src.length(), 0);-
1085 const unsigned short *s = src.utf16();-
1086 unsigned short *d = (unsigned short*)rc.data();-
1087 for (int i = 0; i < src.length(); ++i) {
i < src.length()Description
TRUEevaluated 84 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
FALSEevaluated 12 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
12-84
1088 d[i] = qToLittleEndian(s[i]);-
1089 }
executed 84 times by 1 test: end of block
Executed by:
  • tst_qauthenticator - unknown status
84
1090 return rc;
executed 12 times by 1 test: return rc;
Executed by:
  • tst_qauthenticator - unknown status
12
1091}-
1092-
1093-
1094static QString qStringFromUcs2Le(QByteArray src)-
1095{-
1096 Q_ASSERT(src.size() % 2 == 0);-
1097 unsigned short *d = (unsigned short*)src.data();-
1098 for (int i = 0; i < src.length() / 2; ++i) {
i < src.length() / 2Description
TRUEevaluated 40 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
FALSEevaluated 4 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
4-40
1099 d[i] = qFromLittleEndian(d[i]);-
1100 }
executed 40 times by 1 test: end of block
Executed by:
  • tst_qauthenticator - unknown status
40
1101 return QString((const QChar *)src.data(), src.size()/2);
executed 4 times by 1 test: return QString((const QChar *)src.data(), src.size()/2);
Executed by:
  • tst_qauthenticator - unknown status
4
1102}-
1103-
1104-
1105/*********************************************************************-
1106* Function Name: qEncodeHmacMd5-
1107* Params:-
1108* key: Type - QByteArray-
1109* - It is the Authentication key-
1110* message: Type - QByteArray-
1111* - This is the actual message which will be encoded-
1112* using HMacMd5 hash algorithm-
1113*-
1114* Return Value:-
1115* hmacDigest: Type - QByteArray-
1116*-
1117* Description:-
1118* This function will be used to encode the input message using-
1119* HMacMd5 hash algorithm.-
1120*-
1121* As per the RFC2104 the HMacMd5 algorithm can be specified-
1122* ----------------------------------------
1123* MD5(K XOR opad, MD5(K XOR ipad, text))-
1124* ----------------------------------------
1125*-
1126*********************************************************************/-
1127QByteArray qEncodeHmacMd5(QByteArray &key, const QByteArray &message)-
1128{-
1129 Q_ASSERT_X(!(message.isEmpty()),"qEncodeHmacMd5", "Empty message check");-
1130 Q_ASSERT_X(!(key.isEmpty()),"qEncodeHmacMd5", "Empty key check");-
1131-
1132 QCryptographicHash hash(QCryptographicHash::Md5);-
1133 QByteArray hMsg;-
1134-
1135 QByteArray iKeyPad(blockSize, 0x36);-
1136 QByteArray oKeyPad(blockSize, 0x5c);-
1137-
1138 hash.reset();-
1139 // Adjust the key length to blockSize-
1140-
1141 if(blockSize < key.length()) {
blockSize < key.length()Description
TRUEnever evaluated
FALSEevaluated 8 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
0-8
1142 hash.addData(key);-
1143 key = hash.result(); //MD5 will always return 16 bytes length output-
1144 }
never executed: end of block
0
1145-
1146 //Key will be <= 16 or 20 bytes as hash function (MD5 or SHA hash algorithms)-
1147 //key size can be max of Block size only-
1148 key = key.leftJustified(blockSize,0,true);-
1149-
1150 //iKeyPad, oKeyPad and key are all of same size "blockSize"-
1151-
1152 //xor of iKeyPad with Key and store the result into iKeyPad-
1153 for(int i = 0; i<key.size();i++) {
i<key.size()Description
TRUEevaluated 512 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
FALSEevaluated 8 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
8-512
1154 iKeyPad[i] = key[i]^iKeyPad[i];-
1155 }
executed 512 times by 1 test: end of block
Executed by:
  • tst_qauthenticator - unknown status
512
1156-
1157 //xor of oKeyPad with Key and store the result into oKeyPad-
1158 for(int i = 0; i<key.size();i++) {
i<key.size()Description
TRUEevaluated 512 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
FALSEevaluated 8 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
8-512
1159 oKeyPad[i] = key[i]^oKeyPad[i];-
1160 }
executed 512 times by 1 test: end of block
Executed by:
  • tst_qauthenticator - unknown status
512
1161-
1162 iKeyPad.append(message); // (K0 xor ipad) || text-
1163-
1164 hash.reset();-
1165 hash.addData(iKeyPad);-
1166 hMsg = hash.result();-
1167 //Digest gen after pass-1: H((K0 xor ipad)||text)-
1168-
1169 QByteArray hmacDigest;-
1170 oKeyPad.append(hMsg);-
1171 hash.reset();-
1172 hash.addData(oKeyPad);-
1173 hmacDigest = hash.result();-
1174 // H((K0 xor opad )|| H((K0 xor ipad) || text))-
1175-
1176 /*hmacDigest should not be less than half the length of the HMAC output-
1177 (to match the birthday attack bound) and not less than 80 bits-
1178 (a suitable lower bound on the number of bits that need to be-
1179 predicted by an attacker).-
1180 Refer RFC 2104 for more details on truncation part */-
1181-
1182 /*MD5 hash always returns 16 byte digest only and HMAC-MD5 spec-
1183 (RFC 2104) also says digest length should be 16 bytes*/-
1184 return hmacDigest;
executed 8 times by 1 test: return hmacDigest;
Executed by:
  • tst_qauthenticator - unknown status
8
1185}-
1186-
1187static QByteArray qCreatev2Hash(const QAuthenticatorPrivate *ctx,-
1188 QNtlmPhase3Block *phase3)-
1189{-
1190 Q_ASSERT(phase3 != 0);-
1191 // since v2 Hash is need for both NTLMv2 and LMv2 it is calculated-
1192 // only once and stored and reused-
1193 if(phase3->v2Hash.size() == 0) {
phase3->v2Hash.size() == 0Description
TRUEevaluated 4 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
FALSEnever evaluated
0-4
1194 QCryptographicHash md4(QCryptographicHash::Md4);-
1195 QByteArray passUnicode = qStringAsUcs2Le(ctx->password);-
1196 md4.addData(passUnicode.data(), passUnicode.size());-
1197-
1198 QByteArray hashKey = md4.result();-
1199 Q_ASSERT(hashKey.size() == 16);-
1200 // Assuming the user and domain is always unicode in challenge-
1201 QByteArray message =-
1202 qStringAsUcs2Le(ctx->extractedUser.toUpper()) +-
1203 qStringAsUcs2Le(phase3->domainStr);-
1204-
1205 phase3->v2Hash = qEncodeHmacMd5(hashKey, message);-
1206 }
executed 4 times by 1 test: end of block
Executed by:
  • tst_qauthenticator - unknown status
4
1207 return phase3->v2Hash;
executed 4 times by 1 test: return phase3->v2Hash;
Executed by:
  • tst_qauthenticator - unknown status
4
1208}-
1209-
1210static QByteArray clientChallenge(const QAuthenticatorPrivate *ctx)-
1211{-
1212 Q_ASSERT(ctx->cnonce.size() >= 8);-
1213 QByteArray clientCh = ctx->cnonce.right(8);-
1214 return clientCh;
executed 4 times by 1 test: return clientCh;
Executed by:
  • tst_qauthenticator - unknown status
4
1215}-
1216-
1217// caller has to ensure a valid targetInfoBuff-
1218static QByteArray qExtractServerTime(const QByteArray& targetInfoBuff)-
1219{-
1220 QByteArray timeArray;-
1221 QDataStream ds(targetInfoBuff);-
1222 ds.setByteOrder(QDataStream::LittleEndian);-
1223-
1224 quint16 avId;-
1225 quint16 avLen;-
1226-
1227 ds >> avId;-
1228 ds >> avLen;-
1229 while(avId != 0) {
avId != 0Description
TRUEevaluated 18 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
FALSEevaluated 4 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
4-18
1230 if(avId == AVTIMESTAMP) {
avId == 7Description
TRUEnever evaluated
FALSEevaluated 18 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
0-18
1231 timeArray.resize(avLen);-
1232 //avLen size of QByteArray is allocated-
1233 ds.readRawData(timeArray.data(), avLen);-
1234 break;
never executed: break;
0
1235 }-
1236 ds.skipRawData(avLen);-
1237 ds >> avId;-
1238 ds >> avLen;-
1239 }
executed 18 times by 1 test: end of block
Executed by:
  • tst_qauthenticator - unknown status
18
1240 return timeArray;
executed 4 times by 1 test: return timeArray;
Executed by:
  • tst_qauthenticator - unknown status
4
1241}-
1242-
1243static QByteArray qEncodeNtlmv2Response(const QAuthenticatorPrivate *ctx,-
1244 const QNtlmPhase2Block& ch,-
1245 QNtlmPhase3Block *phase3)-
1246{-
1247 Q_ASSERT(phase3 != 0);-
1248 // return value stored in phase3-
1249 qCreatev2Hash(ctx, phase3);-
1250-
1251 QByteArray temp;-
1252 QDataStream ds(&temp, QIODevice::WriteOnly);-
1253 ds.setByteOrder(QDataStream::LittleEndian);-
1254-
1255 ds << respversion;-
1256 ds << hirespversion;-
1257-
1258 //Reserved-
1259 QByteArray reserved1(6, 0);-
1260 ds.writeRawData(reserved1.constData(), reserved1.size());-
1261-
1262 quint64 time = 0;-
1263 QByteArray timeArray;-
1264-
1265 if(ch.targetInfo.len)
ch.targetInfo.lenDescription
TRUEevaluated 4 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
FALSEnever evaluated
0-4
1266 {-
1267 timeArray = qExtractServerTime(ch.targetInfoBuff);-
1268 }
executed 4 times by 1 test: end of block
Executed by:
  • tst_qauthenticator - unknown status
4
1269-
1270 //if server sends time, use it instead of current time-
1271 if(timeArray.size()) {
timeArray.size()Description
TRUEnever evaluated
FALSEevaluated 4 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
0-4
1272 ds.writeRawData(timeArray.constData(), timeArray.size());-
1273 } else {
never executed: end of block
0
1274 QDateTime currentTime(QDate::currentDate(),-
1275 QTime::currentTime(), Qt::UTC);-
1276-
1277 // number of seconds between 1601 and epoc(1970)-
1278 // 369 years, 89 leap years-
1279 // ((369 * 365) + 89) * 24 * 3600 = 11644473600-
1280-
1281 time = currentTime.toTime_t() + Q_UINT64_C(11644473600);-
1282-
1283 // represented as 100 nano seconds-
1284 time = time * Q_UINT64_C(10000000);-
1285 ds << time;-
1286 }
executed 4 times by 1 test: end of block
Executed by:
  • tst_qauthenticator - unknown status
4
1287-
1288 //8 byte client challenge-
1289 QByteArray clientCh = clientChallenge(ctx);-
1290 ds.writeRawData(clientCh.constData(), clientCh.size());-
1291-
1292 //Reserved-
1293 QByteArray reserved2(4, 0);-
1294 ds.writeRawData(reserved2.constData(), reserved2.size());-
1295-
1296 if (ch.targetInfo.len > 0) {
ch.targetInfo.len > 0Description
TRUEevaluated 4 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
FALSEnever evaluated
0-4
1297 ds.writeRawData(ch.targetInfoBuff.constData(),-
1298 ch.targetInfoBuff.size());-
1299 }
executed 4 times by 1 test: end of block
Executed by:
  • tst_qauthenticator - unknown status
4
1300-
1301 //Reserved-
1302 QByteArray reserved3(4, 0);-
1303 ds.writeRawData(reserved3.constData(), reserved3.size());-
1304-
1305 QByteArray message((const char*)ch.challenge, sizeof(ch.challenge));-
1306 message.append(temp);-
1307-
1308 QByteArray ntChallengeResp = qEncodeHmacMd5(phase3->v2Hash, message);-
1309 ntChallengeResp.append(temp);-
1310-
1311 return ntChallengeResp;
executed 4 times by 1 test: return ntChallengeResp;
Executed by:
  • tst_qauthenticator - unknown status
4
1312}-
1313-
1314static QByteArray qEncodeLmv2Response(const QAuthenticatorPrivate *ctx,-
1315 const QNtlmPhase2Block& ch,-
1316 QNtlmPhase3Block *phase3)-
1317{-
1318 Q_ASSERT(phase3 != 0);-
1319 // return value stored in phase3-
1320 qCreatev2Hash(ctx, phase3);-
1321-
1322 QByteArray message((const char*)ch.challenge, sizeof(ch.challenge));-
1323 QByteArray clientCh = clientChallenge(ctx);-
1324-
1325 message.append(clientCh);-
1326-
1327 QByteArray lmChallengeResp = qEncodeHmacMd5(phase3->v2Hash, message);-
1328 lmChallengeResp.append(clientCh);-
1329-
1330 return lmChallengeResp;
never executed: return lmChallengeResp;
0
1331}-
1332-
1333static bool qNtlmDecodePhase2(const QByteArray& data, QNtlmPhase2Block& ch)-
1334{-
1335 Q_ASSERT(QNtlmPhase2BlockBase::Size == sizeof(QNtlmPhase2BlockBase));-
1336 if (data.size() < QNtlmPhase2BlockBase::Size)
data.size() < ...lockBase::SizeDescription
TRUEnever evaluated
FALSEevaluated 4 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
0-4
1337 return false;
never executed: return false;
0
1338-
1339-
1340 QDataStream ds(data);-
1341 ds.setByteOrder(QDataStream::LittleEndian);-
1342 if (ds.readRawData(ch.magic, 8) < 8)
ds.readRawData....magic, 8) < 8Description
TRUEnever evaluated
FALSEevaluated 4 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
0-4
1343 return false;
never executed: return false;
0
1344 if (strncmp(ch.magic, "NTLMSSP", 8) != 0)
strncmp(ch.mag...MSSP", 8) != 0Description
TRUEnever evaluated
FALSEevaluated 4 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
0-4
1345 return false;
never executed: return false;
0
1346-
1347 ds >> ch.type;-
1348 if (ch.type != 2)
ch.type != 2Description
TRUEnever evaluated
FALSEevaluated 4 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
0-4
1349 return false;
never executed: return false;
0
1350-
1351 ds >> ch.targetName;-
1352 ds >> ch.flags;-
1353 if (ds.readRawData((char *)ch.challenge, 8) < 8)
ds.readRawData...llenge, 8) < 8Description
TRUEnever evaluated
FALSEevaluated 4 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
0-4
1354 return false;
never executed: return false;
0
1355 ds >> ch.context[0] >> ch.context[1];-
1356 ds >> ch.targetInfo;-
1357-
1358 if (ch.targetName.len > 0) {
ch.targetName.len > 0Description
TRUEevaluated 4 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
FALSEnever evaluated
0-4
1359 if (ch.targetName.len + ch.targetName.offset > (unsigned)data.size())
ch.targetName....ed)data.size()Description
TRUEnever evaluated
FALSEevaluated 4 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
0-4
1360 return false;
never executed: return false;
0
1361-
1362 ch.targetNameStr = qStringFromUcs2Le(data.mid(ch.targetName.offset, ch.targetName.len));-
1363 }
executed 4 times by 1 test: end of block
Executed by:
  • tst_qauthenticator - unknown status
4
1364-
1365 if (ch.targetInfo.len > 0) {
ch.targetInfo.len > 0Description
TRUEevaluated 4 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
FALSEnever evaluated
0-4
1366 if (ch.targetInfo.len + ch.targetInfo.offset > (unsigned)data.size())
ch.targetInfo....ed)data.size()Description
TRUEnever evaluated
FALSEevaluated 4 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
0-4
1367 return false;
never executed: return false;
0
1368-
1369 ch.targetInfoBuff = data.mid(ch.targetInfo.offset, ch.targetInfo.len);-
1370 }
executed 4 times by 1 test: end of block
Executed by:
  • tst_qauthenticator - unknown status
4
1371-
1372 return true;
executed 4 times by 1 test: return true;
Executed by:
  • tst_qauthenticator - unknown status
4
1373}-
1374-
1375-
1376static QByteArray qNtlmPhase3(QAuthenticatorPrivate *ctx, const QByteArray& phase2data)-
1377{-
1378 QNtlmPhase2Block ch;-
1379 if (!qNtlmDecodePhase2(phase2data, ch))
!qNtlmDecodePh...hase2data, ch)Description
TRUEnever evaluated
FALSEevaluated 4 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
0-4
1380 return QByteArray();
never executed: return QByteArray();
0
1381-
1382 QByteArray rc;-
1383 QDataStream ds(&rc, QIODevice::WriteOnly);-
1384 ds.setByteOrder(QDataStream::LittleEndian);-
1385 QNtlmPhase3Block pb;-
1386-
1387 // set NTLMv2-
1388 if (ch.flags & NTLMSSP_NEGOTIATE_NTLM2)
ch.flags & 0x00080000Description
TRUEnever evaluated
FALSEevaluated 4 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
0-4
1389 pb.flags |= NTLMSSP_NEGOTIATE_NTLM2;
never executed: pb.flags |= 0x00080000;
0
1390-
1391 // set Always Sign-
1392 if (ch.flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)
ch.flags & 0x00008000Description
TRUEnever evaluated
FALSEevaluated 4 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
0-4
1393 pb.flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
never executed: pb.flags |= 0x00008000;
0
1394-
1395 bool unicode = ch.flags & NTLMSSP_NEGOTIATE_UNICODE;-
1396-
1397 if (unicode)
unicodeDescription
TRUEevaluated 4 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
FALSEnever evaluated
0-4
1398 pb.flags |= NTLMSSP_NEGOTIATE_UNICODE;
executed 4 times by 1 test: pb.flags |= 0x00000001;
Executed by:
  • tst_qauthenticator - unknown status
4
1399 else-
1400 pb.flags |= NTLMSSP_NEGOTIATE_OEM;
never executed: pb.flags |= 0x00000002;
0
1401-
1402-
1403 int offset = QNtlmPhase3BlockBase::Size;-
1404 Q_ASSERT(QNtlmPhase3BlockBase::Size == sizeof(QNtlmPhase3BlockBase));-
1405-
1406 // for kerberos style user@domain logins, NTLM domain string should be left empty-
1407 if (ctx->userDomain.isEmpty() && !ctx->extractedUser.contains(QLatin1Char('@'))) {
ctx->userDomain.isEmpty()Description
TRUEevaluated 4 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
FALSEnever evaluated
!ctx->extracte...tin1Char('@'))Description
TRUEevaluated 4 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
FALSEnever evaluated
0-4
1408 offset = qEncodeNtlmString(pb.domain, offset, ch.targetNameStr, unicode);-
1409 pb.domainStr = ch.targetNameStr;-
1410 } else {
executed 4 times by 1 test: end of block
Executed by:
  • tst_qauthenticator - unknown status
4
1411 offset = qEncodeNtlmString(pb.domain, offset, ctx->userDomain, unicode);-
1412 pb.domainStr = ctx->userDomain;-
1413 }
never executed: end of block
0
1414-
1415 offset = qEncodeNtlmString(pb.user, offset, ctx->extractedUser, unicode);-
1416 pb.userStr = ctx->extractedUser;-
1417-
1418 offset = qEncodeNtlmString(pb.workstation, offset, ctx->workstation, unicode);-
1419 pb.workstationStr = ctx->workstation;-
1420-
1421 // Get LM response-
1422 if (ch.targetInfo.len > 0) {
ch.targetInfo.len > 0Description
TRUEevaluated 4 times by 1 test
Evaluated by:
  • tst_qauthenticator - unknown status
FALSEnever evaluated
0-4
1423 pb.lmResponseBuf = QByteArray();-
1424 } else {
executed 4 times by 1 test: end of block
Executed by:
  • tst_qauthenticator - unknown status
4
1425 pb.lmResponseBuf = qEncodeLmv2Response(ctx, ch, &pb);-
1426 }
never executed: end of block
0
1427 offset = qEncodeNtlmBuffer(pb.lmResponse, offset, pb.lmResponseBuf);-
1428-
1429 // Get NTLM response-
1430 pb.ntlmResponseBuf = qEncodeNtlmv2Response(ctx, ch, &pb);-
1431 offset = qEncodeNtlmBuffer(pb.ntlmResponse, offset, pb.ntlmResponseBuf);-
1432-
1433-
1434 // Encode and send-
1435 ds << pb;-
1436-
1437 return rc;
executed 4 times by 1 test: return rc;
Executed by:
  • tst_qauthenticator - unknown status
4
1438}-
1439-
1440#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)-
1441// See http://davenport.sourceforge.net/ntlm.html-
1442// and libcurl http_ntlm.c-
1443-
1444// Handle of secur32.dll-
1445static HMODULE securityDLLHandle = NULL;-
1446// Pointer to SSPI dispatch table-
1447static PSecurityFunctionTable pSecurityFunctionTable = NULL;-
1448-
1449-
1450static bool q_NTLM_SSPI_library_load()-
1451{-
1452 QMutexLocker locker(QMutexPool::globalInstanceGet((void *)&pSecurityFunctionTable));-
1453-
1454 // Initialize security interface-
1455 if (pSecurityFunctionTable == NULL) {-
1456 securityDLLHandle = LoadLibrary(L"secur32.dll");-
1457 if (securityDLLHandle != NULL) {-
1458#if defined(Q_OS_WINCE)-
1459 INIT_SECURITY_INTERFACE pInitSecurityInterface =-
1460 (INIT_SECURITY_INTERFACE)GetProcAddress(securityDLLHandle,-
1461 L"InitSecurityInterfaceW");-
1462#else-
1463 INIT_SECURITY_INTERFACE pInitSecurityInterface =-
1464 (INIT_SECURITY_INTERFACE)GetProcAddress(securityDLLHandle,-
1465 "InitSecurityInterfaceW");-
1466#endif-
1467 if (pInitSecurityInterface != NULL)-
1468 pSecurityFunctionTable = pInitSecurityInterface();-
1469 }-
1470 }-
1471-
1472 if (pSecurityFunctionTable == NULL)-
1473 return false;-
1474-
1475 return true;-
1476}-
1477-
1478// Phase 1:-
1479static QByteArray qNtlmPhase1_SSPI(QAuthenticatorPrivate *ctx)-
1480{-
1481 QByteArray result;-
1482-
1483 if (!q_NTLM_SSPI_library_load())-
1484 return result;-
1485-
1486 // 1. The client obtains a representation of the credential set-
1487 // for the user via the SSPI AcquireCredentialsHandle function.-
1488 if (!ctx->ntlmWindowsHandles)-
1489 ctx->ntlmWindowsHandles = new QNtlmWindowsHandles;-
1490 memset(&ctx->ntlmWindowsHandles->credHandle, 0, sizeof(CredHandle));-
1491 TimeStamp tsDummy;-
1492 SECURITY_STATUS secStatus = pSecurityFunctionTable->AcquireCredentialsHandle(-
1493 NULL, (SEC_WCHAR*)L"NTLM", SECPKG_CRED_OUTBOUND, NULL, NULL,-
1494 NULL, NULL, &ctx->ntlmWindowsHandles->credHandle, &tsDummy);-
1495 if (secStatus != SEC_E_OK) {-
1496 delete ctx->ntlmWindowsHandles;-
1497 ctx->ntlmWindowsHandles = 0;-
1498 return result;-
1499 }-
1500-
1501 // 2. The client calls the SSPI InitializeSecurityContext function-
1502 // to obtain an authentication request token (in our case, a Type 1 message).-
1503 // The client sends this token to the server.-
1504 SecBufferDesc desc;-
1505 SecBuffer buf;-
1506 desc.ulVersion = SECBUFFER_VERSION;-
1507 desc.cBuffers = 1;-
1508 desc.pBuffers = &buf;-
1509 buf.cbBuffer = 0;-
1510 buf.BufferType = SECBUFFER_TOKEN;-
1511 buf.pvBuffer = NULL;-
1512 ULONG attrs;-
1513-
1514 secStatus = pSecurityFunctionTable->InitializeSecurityContext(&ctx->ntlmWindowsHandles->credHandle, NULL,-
1515 const_cast<SEC_WCHAR*>(L"") /* host */,-
1516 ISC_REQ_ALLOCATE_MEMORY,-
1517 0, SECURITY_NETWORK_DREP,-
1518 NULL, 0,-
1519 &ctx->ntlmWindowsHandles->ctxHandle, &desc,-
1520 &attrs, &tsDummy);-
1521 if (secStatus == SEC_I_COMPLETE_AND_CONTINUE ||-
1522 secStatus == SEC_I_CONTINUE_NEEDED) {-
1523 pSecurityFunctionTable->CompleteAuthToken(&ctx->ntlmWindowsHandles->ctxHandle, &desc);-
1524 } else if (secStatus != SEC_E_OK) {-
1525 if ((const char*)buf.pvBuffer)-
1526 pSecurityFunctionTable->FreeContextBuffer(buf.pvBuffer);-
1527 pSecurityFunctionTable->FreeCredentialsHandle(&ctx->ntlmWindowsHandles->credHandle);-
1528 delete ctx->ntlmWindowsHandles;-
1529 ctx->ntlmWindowsHandles = 0;-
1530 return result;-
1531 }-
1532-
1533 result = QByteArray((const char*)buf.pvBuffer, buf.cbBuffer);-
1534 pSecurityFunctionTable->FreeContextBuffer(buf.pvBuffer);-
1535 return result;-
1536}-
1537-
1538// Phase 2:-
1539// 3. The server receives the token from the client, and uses it as input to the-
1540// AcceptSecurityContext SSPI function. This creates a local security context on-
1541// the server to represent the client, and yields an authentication response token-
1542// (the Type 2 message), which is sent to the client.-
1543-
1544// Phase 3:-
1545static QByteArray qNtlmPhase3_SSPI(QAuthenticatorPrivate *ctx, const QByteArray& phase2data)-
1546{-
1547 // 4. The client receives the response token from the server and calls-
1548 // InitializeSecurityContext again, passing the server's token as input.-
1549 // This provides us with another authentication request token (the Type 3 message).-
1550 // The return value indicates that the security context was successfully initialized;-
1551 // the token is sent to the server.-
1552-
1553 QByteArray result;-
1554-
1555 if (pSecurityFunctionTable == NULL)-
1556 return result;-
1557-
1558 SecBuffer type_2, type_3;-
1559 SecBufferDesc type_2_desc, type_3_desc;-
1560 ULONG attrs;-
1561 TimeStamp tsDummy; // For Windows 9x compatibility of SPPI calls-
1562-
1563 type_2_desc.ulVersion = type_3_desc.ulVersion = SECBUFFER_VERSION;-
1564 type_2_desc.cBuffers = type_3_desc.cBuffers = 1;-
1565 type_2_desc.pBuffers = &type_2;-
1566 type_3_desc.pBuffers = &type_3;-
1567-
1568 type_2.BufferType = SECBUFFER_TOKEN;-
1569 type_2.pvBuffer = (PVOID)phase2data.data();-
1570 type_2.cbBuffer = phase2data.length();-
1571 type_3.BufferType = SECBUFFER_TOKEN;-
1572 type_3.pvBuffer = 0;-
1573 type_3.cbBuffer = 0;-
1574-
1575 SECURITY_STATUS secStatus = pSecurityFunctionTable->InitializeSecurityContext(&ctx->ntlmWindowsHandles->credHandle,-
1576 &ctx->ntlmWindowsHandles->ctxHandle,-
1577 const_cast<SEC_WCHAR*>(L"") /* host */,-
1578 ISC_REQ_ALLOCATE_MEMORY,-
1579 0, SECURITY_NETWORK_DREP, &type_2_desc,-
1580 0, &ctx->ntlmWindowsHandles->ctxHandle, &type_3_desc,-
1581 &attrs, &tsDummy);-
1582-
1583 if (secStatus == SEC_E_OK && ((const char*)type_3.pvBuffer)) {-
1584 result = QByteArray((const char*)type_3.pvBuffer, type_3.cbBuffer);-
1585 pSecurityFunctionTable->FreeContextBuffer(type_3.pvBuffer);-
1586 }-
1587-
1588 pSecurityFunctionTable->FreeCredentialsHandle(&ctx->ntlmWindowsHandles->credHandle);-
1589 pSecurityFunctionTable->DeleteSecurityContext(&ctx->ntlmWindowsHandles->ctxHandle);-
1590 delete ctx->ntlmWindowsHandles;-
1591 ctx->ntlmWindowsHandles = 0;-
1592-
1593 return result;-
1594}-
1595#endif // Q_OS_WIN && !Q_OS_WINRT-
1596-
1597QT_END_NAMESPACE-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9