kernel/qauthenticator.cpp

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

Generated by Squish Coco Non-Commercial