OpenCoverage

qnetworkaccessauthenticationmanager.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/network/access/qnetworkaccessauthenticationmanager.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2016 The Qt Company Ltd.-
4** Contact: https://www.qt.io/licensing/-
5**-
6** This file is part of the QtNetwork module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL$-
9** Commercial License Usage-
10** Licensees holding valid commercial Qt licenses may use this file in-
11** accordance with the commercial license agreement provided with the-
12** Software or, alternatively, in accordance with the terms contained in-
13** a written agreement between you and The Qt Company. For licensing terms-
14** and conditions see https://www.qt.io/terms-conditions. For further-
15** information use the contact form at https://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 3 as published by the Free Software-
20** Foundation and appearing in the file LICENSE.LGPL3 included in the-
21** packaging of this file. Please review the following information to-
22** ensure the GNU Lesser General Public License version 3 requirements-
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
24**-
25** GNU General Public License Usage-
26** Alternatively, this file may be used under the terms of the GNU-
27** General Public License version 2.0 or (at your option) the GNU General-
28** Public license version 3 or any later version approved by the KDE Free-
29** Qt Foundation. The licenses are as published by the Free Software-
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
31** included in the packaging of this file. Please review the following-
32** information to ensure the GNU General Public License requirements will-
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
34** https://www.gnu.org/licenses/gpl-3.0.html.-
35**-
36** $QT_END_LICENSE$-
37**-
38****************************************************************************/-
39-
40#include "qnetworkaccessauthenticationmanager_p.h"-
41#include "qnetworkaccessmanager.h"-
42#include "qnetworkaccessmanager_p.h"-
43-
44#include "QtCore/qbuffer.h"-
45#include "QtCore/qurl.h"-
46#include "QtCore/qvector.h"-
47#include "QtCore/QMutexLocker"-
48#include "QtNetwork/qauthenticator.h"-
49-
50#include <algorithm>-
51-
52QT_BEGIN_NAMESPACE-
53-
54-
55-
56-
57class QNetworkAuthenticationCache: private QVector<QNetworkAuthenticationCredential>,-
58 public QNetworkAccessCache::CacheableObject-
59{-
60public:-
61 QNetworkAuthenticationCache()-
62 {-
63 setExpires(false);-
64 setShareable(true);-
65 reserve(1);-
66 }
executed 315 times by 2 tests: end of block
Executed by:
  • tst_QNetworkReply
  • tst_Spdy
315
67-
68 QNetworkAuthenticationCredential *findClosestMatch(const QString &domain)-
69 {-
70 iterator it = std::lower_bound(begin(), end(), domain);-
71 if (it == end() && !isEmpty())
it == end()Description
TRUEevaluated 346 times by 2 tests
Evaluated by:
  • tst_QNetworkReply
  • tst_Spdy
FALSEevaluated 366 times by 1 test
Evaluated by:
  • tst_QNetworkReply
!isEmpty()Description
TRUEevaluated 31 times by 1 test
Evaluated by:
  • tst_QNetworkReply
FALSEevaluated 315 times by 2 tests
Evaluated by:
  • tst_QNetworkReply
  • tst_Spdy
31-366
72 --it;
executed 31 times by 1 test: --it;
Executed by:
  • tst_QNetworkReply
31
73 if (it == end() || !domain.startsWith(it->domain))
it == end()Description
TRUEevaluated 315 times by 2 tests
Evaluated by:
  • tst_QNetworkReply
  • tst_Spdy
FALSEevaluated 397 times by 1 test
Evaluated by:
  • tst_QNetworkReply
!domain.startsWith(it->domain)Description
TRUEnever evaluated
FALSEevaluated 397 times by 1 test
Evaluated by:
  • tst_QNetworkReply
0-397
74 return 0;
executed 315 times by 2 tests: return 0;
Executed by:
  • tst_QNetworkReply
  • tst_Spdy
315
75 return &*it;
executed 397 times by 1 test: return &*it;
Executed by:
  • tst_QNetworkReply
397
76 }-
77-
78 void insert(const QString &domain, const QString &user, const QString &password)-
79 {-
80 QNetworkAuthenticationCredential *closestMatch = findClosestMatch(domain);-
81 if (closestMatch && closestMatch->domain == domain) {
closestMatchDescription
TRUEevaluated 358 times by 1 test
Evaluated by:
  • tst_QNetworkReply
FALSEevaluated 315 times by 2 tests
Evaluated by:
  • tst_QNetworkReply
  • tst_Spdy
closestMatch->domain == domainDescription
TRUEevaluated 358 times by 1 test
Evaluated by:
  • tst_QNetworkReply
FALSEnever evaluated
0-358
82 // we're overriding the current credentials-
83 closestMatch->user = user;-
84 closestMatch->password = password;-
85 } else {
executed 358 times by 1 test: end of block
Executed by:
  • tst_QNetworkReply
358
86 QNetworkAuthenticationCredential newCredential;-
87 newCredential.domain = domain;-
88 newCredential.user = user;-
89 newCredential.password = password;-
90-
91 if (closestMatch)
closestMatchDescription
TRUEnever evaluated
FALSEevaluated 315 times by 2 tests
Evaluated by:
  • tst_QNetworkReply
  • tst_Spdy
0-315
92 QVector<QNetworkAuthenticationCredential>::insert(++closestMatch, newCredential);
never executed: QVector<QNetworkAuthenticationCredential>::insert(++closestMatch, newCredential);
0
93 else-
94 QVector<QNetworkAuthenticationCredential>::insert(end(), newCredential);
executed 315 times by 2 tests: QVector<QNetworkAuthenticationCredential>::insert(end(), newCredential);
Executed by:
  • tst_QNetworkReply
  • tst_Spdy
315
95 }-
96 }-
97-
98 virtual void dispose() Q_DECL_OVERRIDE { delete this; }
executed 315 times by 2 tests: end of block
Executed by:
  • tst_QNetworkReply
  • tst_Spdy
315
99};-
100-
101#ifndef QT_NO_NETWORKPROXY-
102static QByteArray proxyAuthenticationKey(const QNetworkProxy &proxy, const QString &realm)-
103{-
104 QUrl key;-
105-
106 switch (proxy.type()) {-
107 case QNetworkProxy::Socks5Proxy:
executed 78 times by 2 tests: case QNetworkProxy::Socks5Proxy:
Executed by:
  • tst_QNetworkReply
  • tst_Spdy
78
108 key.setScheme(QLatin1String("proxy-socks5"));-
109 break;
executed 78 times by 2 tests: break;
Executed by:
  • tst_QNetworkReply
  • tst_Spdy
78
110-
111 case QNetworkProxy::HttpProxy:
executed 104 times by 2 tests: case QNetworkProxy::HttpProxy:
Executed by:
  • tst_QNetworkReply
  • tst_Spdy
104
112 case QNetworkProxy::HttpCachingProxy:
executed 21 times by 1 test: case QNetworkProxy::HttpCachingProxy:
Executed by:
  • tst_QNetworkReply
21
113 key.setScheme(QLatin1String("proxy-http"));-
114 break;
executed 125 times by 2 tests: break;
Executed by:
  • tst_QNetworkReply
  • tst_Spdy
125
115-
116 case QNetworkProxy::FtpCachingProxy:
never executed: case QNetworkProxy::FtpCachingProxy:
0
117 key.setScheme(QLatin1String("proxy-ftp"));-
118 break;
never executed: break;
0
119-
120 case QNetworkProxy::DefaultProxy:
never executed: case QNetworkProxy::DefaultProxy:
0
121 case QNetworkProxy::NoProxy:
never executed: case QNetworkProxy::NoProxy:
0
122 // shouldn't happen-
123 return QByteArray();
never executed: return QByteArray();
0
124-
125 // no default:-
126 // let there be errors if a new proxy type is added in the future-
127 }-
128-
129 if (key.scheme().isEmpty())
key.scheme().isEmpty()Description
TRUEnever evaluated
FALSEevaluated 203 times by 2 tests
Evaluated by:
  • tst_QNetworkReply
  • tst_Spdy
0-203
130 // proxy type not handled-
131 return QByteArray();
never executed: return QByteArray();
0
132-
133 key.setUserName(proxy.user());-
134 key.setHost(proxy.hostName());-
135 key.setPort(proxy.port());-
136 key.setFragment(realm);-
137 return "auth:" + key.toEncoded();
executed 203 times by 2 tests: return "auth:" + key.toEncoded();
Executed by:
  • tst_QNetworkReply
  • tst_Spdy
203
138}-
139#endif-
140-
141static inline QByteArray authenticationKey(const QUrl &url, const QString &realm)-
142{-
143 QUrl copy = url;-
144 copy.setFragment(realm);-
145 return "auth:" + copy.toEncoded(QUrl::RemovePassword | QUrl::RemovePath | QUrl::RemoveQuery);
executed 932 times by 4 tests: return "auth:" + copy.toEncoded(QUrl::RemovePassword | QUrl::RemovePath | QUrl::RemoveQuery);
Executed by:
  • tst_QAbstractNetworkCache
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
932
146}-
147-
148-
149#ifndef QT_NO_NETWORKPROXY-
150void QNetworkAccessAuthenticationManager::cacheProxyCredentials(const QNetworkProxy &p,-
151 const QAuthenticator *authenticator)-
152{-
153 Q_ASSERT(authenticator);-
154 Q_ASSERT(p.type() != QNetworkProxy::DefaultProxy);-
155 Q_ASSERT(p.type() != QNetworkProxy::NoProxy);-
156-
157 QMutexLocker mutexLocker(&mutex);-
158-
159 QString realm = authenticator->realm();-
160 QNetworkProxy proxy = p;-
161 proxy.setUser(authenticator->user());-
162-
163 // don't cache null passwords, empty password may be valid though-
164 if (authenticator->password().isNull())
authenticator-...ord().isNull()Description
TRUEevaluated 6 times by 2 tests
Evaluated by:
  • tst_QNetworkReply
  • tst_Spdy
FALSEevaluated 54 times by 2 tests
Evaluated by:
  • tst_QNetworkReply
  • tst_Spdy
6-54
165 return;
executed 6 times by 2 tests: return;
Executed by:
  • tst_QNetworkReply
  • tst_Spdy
6
166-
167 // Set two credentials: one with the username and one without-
168 do {-
169 // Set two credentials actually: one with and one without the realm-
170 do {-
171 QByteArray cacheKey = proxyAuthenticationKey(proxy, realm);-
172 if (cacheKey.isEmpty())
cacheKey.isEmpty()Description
TRUEnever evaluated
FALSEevaluated 138 times by 2 tests
Evaluated by:
  • tst_QNetworkReply
  • tst_Spdy
0-138
173 return; // should not happen
never executed: return;
0
174-
175 QNetworkAuthenticationCache *auth = new QNetworkAuthenticationCache;-
176 auth->insert(QString(), authenticator->user(), authenticator->password());-
177 authenticationCache.addEntry(cacheKey, auth); // replace the existing one, if there's any-
178-
179 if (realm.isEmpty()) {
realm.isEmpty()Description
TRUEevaluated 108 times by 2 tests
Evaluated by:
  • tst_QNetworkReply
  • tst_Spdy
FALSEevaluated 30 times by 2 tests
Evaluated by:
  • tst_QNetworkReply
  • tst_Spdy
30-108
180 break;
executed 108 times by 2 tests: break;
Executed by:
  • tst_QNetworkReply
  • tst_Spdy
108
181 } else {-
182 realm.clear();-
183 }
executed 30 times by 2 tests: end of block
Executed by:
  • tst_QNetworkReply
  • tst_Spdy
30
184 } while (true);-
185-
186 if (proxy.user().isEmpty())
proxy.user().isEmpty()Description
TRUEevaluated 54 times by 2 tests
Evaluated by:
  • tst_QNetworkReply
  • tst_Spdy
FALSEevaluated 54 times by 2 tests
Evaluated by:
  • tst_QNetworkReply
  • tst_Spdy
54
187 break;
executed 54 times by 2 tests: break;
Executed by:
  • tst_QNetworkReply
  • tst_Spdy
54
188 else-
189 proxy.setUser(QString());
executed 54 times by 2 tests: proxy.setUser(QString());
Executed by:
  • tst_QNetworkReply
  • tst_Spdy
54
190 } while (true);-
191}
executed 54 times by 2 tests: end of block
Executed by:
  • tst_QNetworkReply
  • tst_Spdy
54
192-
193QNetworkAuthenticationCredential-
194QNetworkAccessAuthenticationManager::fetchCachedProxyCredentials(const QNetworkProxy &p,-
195 const QAuthenticator *authenticator)-
196{-
197 QNetworkProxy proxy = p;-
198 if (proxy.type() == QNetworkProxy::DefaultProxy) {
proxy.type() =...::DefaultProxyDescription
TRUEnever evaluated
FALSEevaluated 65 times by 2 tests
Evaluated by:
  • tst_QNetworkReply
  • tst_Spdy
0-65
199 proxy = QNetworkProxy::applicationProxy();-
200 }
never executed: end of block
0
201 if (!proxy.password().isEmpty())
!proxy.password().isEmpty()Description
TRUEnever evaluated
FALSEevaluated 65 times by 2 tests
Evaluated by:
  • tst_QNetworkReply
  • tst_Spdy
0-65
202 return QNetworkAuthenticationCredential(); // no need to set credentials if it already has them
never executed: return QNetworkAuthenticationCredential();
0
203-
204 QString realm;-
205 if (authenticator)
authenticatorDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • tst_QNetworkReply
FALSEevaluated 64 times by 2 tests
Evaluated by:
  • tst_QNetworkReply
  • tst_Spdy
1-64
206 realm = authenticator->realm();
executed 1 time by 1 test: realm = authenticator->realm();
Executed by:
  • tst_QNetworkReply
1
207-
208 QMutexLocker mutexLocker(&mutex);-
209 QByteArray cacheKey = proxyAuthenticationKey(proxy, realm);-
210 if (cacheKey.isEmpty())
cacheKey.isEmpty()Description
TRUEnever evaluated
FALSEevaluated 65 times by 2 tests
Evaluated by:
  • tst_QNetworkReply
  • tst_Spdy
0-65
211 return QNetworkAuthenticationCredential();
never executed: return QNetworkAuthenticationCredential();
0
212 if (!authenticationCache.hasEntry(cacheKey))
!authenticatio...ntry(cacheKey)Description
TRUEevaluated 57 times by 2 tests
Evaluated by:
  • tst_QNetworkReply
  • tst_Spdy
FALSEevaluated 8 times by 1 test
Evaluated by:
  • tst_QNetworkReply
8-57
213 return QNetworkAuthenticationCredential();
executed 57 times by 2 tests: return QNetworkAuthenticationCredential();
Executed by:
  • tst_QNetworkReply
  • tst_Spdy
57
214-
215 QNetworkAuthenticationCache *auth =-
216 static_cast<QNetworkAuthenticationCache *>(authenticationCache.requestEntryNow(cacheKey));-
217 QNetworkAuthenticationCredential cred = *auth->findClosestMatch(QString());-
218 authenticationCache.releaseEntry(cacheKey);-
219-
220 // proxy cache credentials always have exactly one item-
221 Q_ASSERT_X(!cred.isNull(), "QNetworkAccessManager",-
222 "Internal inconsistency: found a cache key for a proxy, but it's empty");-
223 return cred;
executed 8 times by 1 test: return cred;
Executed by:
  • tst_QNetworkReply
8
224}-
225-
226#endif-
227-
228void QNetworkAccessAuthenticationManager::cacheCredentials(const QUrl &url,-
229 const QAuthenticator *authenticator)-
230{-
231 Q_ASSERT(authenticator);-
232 if (authenticator->isNull())
authenticator->isNull()Description
TRUEevaluated 3 times by 1 test
Evaluated by:
  • tst_QNetworkReply
FALSEevaluated 273 times by 1 test
Evaluated by:
  • tst_QNetworkReply
3-273
233 return;
executed 3 times by 1 test: return;
Executed by:
  • tst_QNetworkReply
3
234 QString domain = QString::fromLatin1("/"); // FIXME: make QAuthenticator return the domain-
235 QString realm = authenticator->realm();-
236-
237 QMutexLocker mutexLocker(&mutex);-
238-
239 // Set two credentials actually: one with and one without the username in the URL-
240 QUrl copy = url;-
241 copy.setUserName(authenticator->user());-
242 do {-
243 QByteArray cacheKey = authenticationKey(copy, realm);-
244 if (authenticationCache.hasEntry(cacheKey)) {
authentication...ntry(cacheKey)Description
TRUEevaluated 358 times by 1 test
Evaluated by:
  • tst_QNetworkReply
FALSEevaluated 177 times by 1 test
Evaluated by:
  • tst_QNetworkReply
177-358
245 QNetworkAuthenticationCache *auth =-
246 static_cast<QNetworkAuthenticationCache *>(authenticationCache.requestEntryNow(cacheKey));-
247 auth->insert(domain, authenticator->user(), authenticator->password());-
248 authenticationCache.releaseEntry(cacheKey);-
249 } else {
executed 358 times by 1 test: end of block
Executed by:
  • tst_QNetworkReply
358
250 QNetworkAuthenticationCache *auth = new QNetworkAuthenticationCache;-
251 auth->insert(domain, authenticator->user(), authenticator->password());-
252 authenticationCache.addEntry(cacheKey, auth);-
253 }
executed 177 times by 1 test: end of block
Executed by:
  • tst_QNetworkReply
177
254-
255 if (copy.userName().isEmpty()) {
copy.userName().isEmpty()Description
TRUEevaluated 273 times by 1 test
Evaluated by:
  • tst_QNetworkReply
FALSEevaluated 262 times by 1 test
Evaluated by:
  • tst_QNetworkReply
262-273
256 break;
executed 273 times by 1 test: break;
Executed by:
  • tst_QNetworkReply
273
257 } else {-
258 copy.setUserName(QString());-
259 }
executed 262 times by 1 test: end of block
Executed by:
  • tst_QNetworkReply
262
260 } while (true);-
261}
executed 273 times by 1 test: end of block
Executed by:
  • tst_QNetworkReply
273
262-
263/*!-
264 Fetch the credential data from the credential cache.-
265-
266 If auth is 0 (as it is when called from createRequest()), this will try to-
267 look up with an empty realm. That fails in most cases for HTTP (because the-
268 realm is seldom empty for HTTP challenges). In any case, QHttpNetworkConnection-
269 never sends the credentials on the first attempt: it needs to find out what-
270 authentication methods the server supports.-
271-
272 For FTP, realm is always empty.-
273*/-
274QNetworkAuthenticationCredential-
275QNetworkAccessAuthenticationManager::fetchCachedCredentials(const QUrl &url,-
276 const QAuthenticator *authentication)-
277{-
278 if (!url.password().isEmpty())
!url.password().isEmpty()Description
TRUEevaluated 16 times by 1 test
Evaluated by:
  • tst_QNetworkReply
FALSEevaluated 397 times by 4 tests
Evaluated by:
  • tst_QAbstractNetworkCache
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
16-397
279 return QNetworkAuthenticationCredential(); // no need to set credentials if it already has them
executed 16 times by 1 test: return QNetworkAuthenticationCredential();
Executed by:
  • tst_QNetworkReply
16
280-
281 QString realm;-
282 if (authentication)
authenticationDescription
TRUEevaluated 89 times by 1 test
Evaluated by:
  • tst_QNetworkReply
FALSEevaluated 308 times by 4 tests
Evaluated by:
  • tst_QAbstractNetworkCache
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
89-308
283 realm = authentication->realm();
executed 89 times by 1 test: realm = authentication->realm();
Executed by:
  • tst_QNetworkReply
89
284-
285 QByteArray cacheKey = authenticationKey(url, realm);-
286-
287 QMutexLocker mutexLocker(&mutex);-
288 if (!authenticationCache.hasEntry(cacheKey))
!authenticatio...ntry(cacheKey)Description
TRUEevaluated 366 times by 4 tests
Evaluated by:
  • tst_QAbstractNetworkCache
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
FALSEevaluated 31 times by 1 test
Evaluated by:
  • tst_QNetworkReply
31-366
289 return QNetworkAuthenticationCredential();
executed 366 times by 4 tests: return QNetworkAuthenticationCredential();
Executed by:
  • tst_QAbstractNetworkCache
  • tst_QHttpNetworkConnection
  • tst_QNetworkReply
  • tst_Spdy
366
290-
291 QNetworkAuthenticationCache *auth =-
292 static_cast<QNetworkAuthenticationCache *>(authenticationCache.requestEntryNow(cacheKey));-
293 QNetworkAuthenticationCredential *cred = auth->findClosestMatch(url.path());-
294 QNetworkAuthenticationCredential ret;-
295 if (cred)
credDescription
TRUEevaluated 31 times by 1 test
Evaluated by:
  • tst_QNetworkReply
FALSEnever evaluated
0-31
296 ret = *cred;
executed 31 times by 1 test: ret = *cred;
Executed by:
  • tst_QNetworkReply
31
297 authenticationCache.releaseEntry(cacheKey);-
298 return ret;
executed 31 times by 1 test: return ret;
Executed by:
  • tst_QNetworkReply
31
299}-
300-
301void QNetworkAccessAuthenticationManager::clearCache()-
302{-
303 authenticationCache.clear();-
304}
executed 646 times by 2 tests: end of block
Executed by:
  • tst_QNetworkReply
  • tst_Spdy
646
305-
306QT_END_NAMESPACE-
307-
Source codeSwitch to Preprocessed file

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