1//
2// HTTPCredentials.cpp
3//
4// Library: Net
5// Package: HTTP
6// Module: HTTPCredentials
7//
8// Copyright (c) 2011, Anton V. Yabchinskiy (arn at bestmx dot ru).
9// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
10// and Contributors.
11//
12// SPDX-License-Identifier: BSL-1.0
13//
14
15
16#include "Poco/Net/HTTPAuthenticationParams.h"
17#include "Poco/Net/HTTPBasicCredentials.h"
18#include "Poco/Net/HTTPCredentials.h"
19#include "Poco/Net/HTTPRequest.h"
20#include "Poco/Net/HTTPResponse.h"
21#include "Poco/Net/NetException.h"
22#include "Poco/String.h"
23#include "Poco/Ascii.h"
24#include "Poco/URI.h"
25
26
27using Poco::icompare;
28
29
30namespace Poco {
31namespace Net {
32
33
34HTTPCredentials::HTTPCredentials()
35{
36}
37
38
39HTTPCredentials::HTTPCredentials(const std::string& username, const std::string& password):
40 _digest(username, password)
41{
42}
43
44
45HTTPCredentials::~HTTPCredentials()
46{
47}
48
49
50void HTTPCredentials::fromUserInfo(const std::string& userInfo)
51{
52 std::string username;
53 std::string password;
54
55 extractCredentials(userInfo, username, password);
56 setUsername(username);
57 setPassword(password);
58 _digest.reset();
59}
60
61
62void HTTPCredentials::fromURI(const URI& uri)
63{
64 std::string username;
65 std::string password;
66
67 extractCredentials(uri, username, password);
68 setUsername(username);
69 setPassword(password);
70 _digest.reset();
71}
72
73
74void HTTPCredentials::authenticate(HTTPRequest& request, const HTTPResponse& response)
75{
76 for (HTTPResponse::ConstIterator iter = response.find(HTTPAuthenticationParams::WWW_AUTHENTICATE); iter != response.end(); ++iter)
77 {
78 if (isBasicCredentials(iter->second))
79 {
80 HTTPBasicCredentials(_digest.getUsername(), _digest.getPassword()).authenticate(request);
81 return;
82 }
83 else if (isDigestCredentials(iter->second))
84 {
85 _digest.authenticate(request, HTTPAuthenticationParams(iter->second.substr(7)));
86 return;
87 }
88 }
89}
90
91
92void HTTPCredentials::updateAuthInfo(HTTPRequest& request)
93{
94 if (request.has(HTTPRequest::AUTHORIZATION))
95 {
96 const std::string& authorization = request.get(HTTPRequest::AUTHORIZATION);
97
98 if (isBasicCredentials(authorization))
99 {
100 HTTPBasicCredentials(_digest.getUsername(), _digest.getPassword()).authenticate(request);
101 }
102 else if (isDigestCredentials(authorization))
103 {
104 _digest.updateAuthInfo(request);
105 }
106 }
107}
108
109
110void HTTPCredentials::proxyAuthenticate(HTTPRequest& request, const HTTPResponse& response)
111{
112 for (HTTPResponse::ConstIterator iter = response.find(HTTPAuthenticationParams::PROXY_AUTHENTICATE); iter != response.end(); ++iter)
113 {
114 if (isBasicCredentials(iter->second))
115 {
116 HTTPBasicCredentials(_digest.getUsername(), _digest.getPassword()).proxyAuthenticate(request);
117 return;
118 }
119 else if (isDigestCredentials(iter->second))
120 {
121 _digest.proxyAuthenticate(request, HTTPAuthenticationParams(iter->second.substr(7)));
122 return;
123 }
124 }
125}
126
127
128void HTTPCredentials::updateProxyAuthInfo(HTTPRequest& request)
129{
130 if (request.has(HTTPRequest::PROXY_AUTHORIZATION))
131 {
132 const std::string& authorization = request.get(HTTPRequest::PROXY_AUTHORIZATION);
133
134 if (isBasicCredentials(authorization))
135 {
136 HTTPBasicCredentials(_digest.getUsername(), _digest.getPassword()).proxyAuthenticate(request);
137 }
138 else if (isDigestCredentials(authorization))
139 {
140 _digest.updateProxyAuthInfo(request);
141 }
142 }
143}
144
145
146bool HTTPCredentials::isBasicCredentials(const std::string& header)
147{
148 return icompare(header, 0, 5, "Basic") == 0 && (header.size() > 5 ? Poco::Ascii::isSpace(header[5]) : true);
149}
150
151
152bool HTTPCredentials::isDigestCredentials(const std::string& header)
153{
154 return icompare(header, 0, 6, "Digest") == 0 && (header.size() > 6 ? Poco::Ascii::isSpace(header[6]) : true);
155}
156
157
158bool HTTPCredentials::hasBasicCredentials(const HTTPRequest& request)
159{
160 return request.has(HTTPRequest::AUTHORIZATION) && isBasicCredentials(request.get(HTTPRequest::AUTHORIZATION));
161}
162
163
164bool HTTPCredentials::hasDigestCredentials(const HTTPRequest& request)
165{
166 return request.has(HTTPRequest::AUTHORIZATION) && isDigestCredentials(request.get(HTTPRequest::AUTHORIZATION));
167}
168
169
170bool HTTPCredentials::hasProxyBasicCredentials(const HTTPRequest& request)
171{
172 return request.has(HTTPRequest::PROXY_AUTHORIZATION) && isBasicCredentials(request.get(HTTPRequest::PROXY_AUTHORIZATION));
173}
174
175
176bool HTTPCredentials::hasProxyDigestCredentials(const HTTPRequest& request)
177{
178 return request.has(HTTPRequest::PROXY_AUTHORIZATION) && isDigestCredentials(request.get(HTTPRequest::PROXY_AUTHORIZATION));
179}
180
181
182void HTTPCredentials::extractCredentials(const std::string& userInfo, std::string& username, std::string& password)
183{
184 const std::string::size_type p = userInfo.find(':');
185
186 if (p != std::string::npos)
187 {
188 username.assign(userInfo, 0, p);
189 password.assign(userInfo, p + 1, std::string::npos);
190 }
191 else
192 {
193 username.assign(userInfo);
194 password.clear();
195 }
196}
197
198
199void HTTPCredentials::extractCredentials(const Poco::URI& uri, std::string& username, std::string& password)
200{
201 if (!uri.getUserInfo().empty())
202 {
203 extractCredentials(uri.getUserInfo(), username, password);
204 }
205}
206
207
208} } // namespace Poco::Net
209