Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(400)

Side by Side Diff: net/cup_request.cc

Issue 624713003: Keep only base/extractor.[cc|h]. (Closed) Base URL: https://chromium.googlesource.com/external/omaha.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/cup_request.h ('k') | net/cup_request_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2008-2010 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 // ========================================================================
15 //
16 // TODO(omaha): to minimize conversions from UNICODE to UTF-8 consider an
17 // API that takes the request body as UTF-8 and it stores it as UTF-8.
18
19 #include "omaha/net/cup_request.h"
20
21 #include <atlconv.h>
22 #include <atlstr.h>
23 #include <vector>
24 #include "omaha/base/const_addresses.h"
25 #include "omaha/base/debug.h"
26 #include "omaha/base/error.h"
27 #include "omaha/base/encrypt.h"
28 #include "omaha/base/logging.h"
29 #include "omaha/base/path.h"
30 #include "omaha/base/safe_format.h"
31 #include "omaha/base/security/b64.h"
32 #include "omaha/base/security/hmac.h"
33 #include "omaha/base/security/rsa.h"
34 #include "omaha/base/security/sha.h"
35 #include "omaha/base/string.h"
36 #include "omaha/base/utils.h"
37 #include "omaha/net/cup_utils.h"
38 #include "omaha/net/http_client.h"
39 #include "omaha/net/net_utils.h"
40 #include "omaha/net/network_config.h"
41
42 using omaha::encrypt::EncryptData;
43 using omaha::encrypt::DecryptData;
44
45 namespace omaha {
46
47 namespace detail {
48
49 class CupRequestImpl {
50 public:
51 explicit CupRequestImpl(HttpRequestInterface* http_request);
52 ~CupRequestImpl();
53
54 HRESULT Close();
55 HRESULT Send();
56 HRESULT Cancel();
57 HRESULT Pause();
58 HRESULT Resume();
59 std::vector<uint8> GetResponse() const;
60 HRESULT QueryHeadersString(uint32 info_level,
61 const TCHAR* name,
62 CString* value) const;
63 CString GetResponseHeaders() const;
64 int GetHttpStatusCode() const;
65 CString ToString() const;
66 void SetEntropy(const void* data, size_t data_length);
67
68 void set_session_handle(HINTERNET session_handle);
69 void set_url(const CString& url);
70 void set_request_buffer(const void* buffer, size_t buffer_length);
71 void set_proxy_configuration(const ProxyConfig& proxy_config);
72 void set_filename(const CString& filename);
73 void set_low_priority(bool low_priority);
74 void set_callback(NetworkRequestCallback* callback);
75 void set_additional_headers(const CString& additional_headers);
76 void set_preserve_protocol(bool preserve_protocol);
77 CString user_agent() const;
78 void set_user_agent(const CString& user_agent);
79 void set_proxy_auth_config(const ProxyAuthConfig& proxy_auth_config);
80
81 private:
82 HRESULT DoSend();
83 HRESULT BuildRequest();
84 HRESULT BuildChallengeHash();
85 HRESULT BuildClientProof();
86 HRESULT InitializeEntropy();
87 HRESULT AuthenticateResponse();
88
89 // Loads the {sk, c} credentials from persistent storage.
90 HRESULT LoadCredentials(std::vector<uint8>* sk, CStringA* c);
91
92 // Saves the {sk, c} credentials. The key is encrypted before saving it.
93 HRESULT SaveCredentials(const std::vector<uint8>& sk, const CStringA& c);
94
95 // Replaces the https protocol scheme with http if changing protocol is
96 // allowed.
97 HRESULT BuildInnerRequestUrl(const CString& url, CString* inner_url);
98
99 // The transient state of the request, so that we can start always with a
100 // clean slate even though the same instance is being reuse across requests.
101 struct TransientCupState {
102 std::vector<uint8> entropy;
103 std::vector<uint8> r; // Random bytes (r).
104 std::vector<uint8> sk; // Cached shared key (sk)
105 std::vector<uint8> new_sk; // Current shared_key (sk').
106 std::vector<uint8> hw; // Challenge hash (hw).
107 std::vector<uint8> hm; // Response hash (hm).
108
109 CStringA cp; // Client proof (cp).
110 CStringA sp; // Server proof (sp).
111 CStringA vw; // Versioned challenge (v|w).
112 std::vector<uint8> response; // The received response.
113 CStringA c; // Cached client cookie (c)
114 CStringA new_cookie; // The cookie returned by the server (c').
115
116 // The url of the request. It includes the original url plus the versioned
117 // challenge (v|w).
118 CStringA request_url;
119 };
120 scoped_ptr<TransientCupState> cup_;
121
122 CStringA url_; // The original url.
123 CString additional_headers_;
124 bool preserve_protocol_; // Should not change request scheme if
125 // true.
126 const void* request_buffer_; // Contains the request body for POST.
127 size_t request_buffer_length_; // Length of the request body.
128 std::vector<uint8> entropy_; // Optional entropy pass by the caller,
129 // mostly for testing purpose.
130
131 // {sk, c} credentials. They are persisted in the registry when the object is
132 // destroyed. The vast majority of network code runs impersonated. Writing
133 // through the credentials is likely to fail. However, due to how the
134 // CUP object is being used by the upper layers of the network code, a
135 // write back policy is possible.
136 std::vector<uint8> persisted_sk_;
137 CStringA persisted_c_;
138
139 scoped_ptr<RSA> rsa_;
140 RSA::PublicKey public_key_; // Server public key (pk[v]).
141 scoped_ptr<HttpRequestInterface> http_request_; // Inner http request.
142
143 static const RSA::PublicKeyInstance kCupProductionPublicKey;
144 static const RSA::PublicKeyInstance kCupTestPublicKey;
145
146 DISALLOW_EVIL_CONSTRUCTORS(CupRequestImpl);
147 };
148
149 const RSA::PublicKeyInstance CupRequestImpl::kCupProductionPublicKey =
150 #include "omaha/net/cup_pubkey.3.h"
151 ; // NOLINT
152
153 const RSA::PublicKeyInstance CupRequestImpl::kCupTestPublicKey =
154 #include "omaha/net/cup_pubkey.2.h"
155 ; // NOLINT
156
157 CupRequestImpl::CupRequestImpl(HttpRequestInterface* http_request)
158 : preserve_protocol_(false),
159 request_buffer_(NULL),
160 request_buffer_length_(0),
161 public_key_(NULL) {
162 ASSERT1(http_request);
163 bool is_using_cup_test_keys = NetworkConfig::IsUsingCupTestKeys();
164 public_key_ = is_using_cup_test_keys ? kCupTestPublicKey :
165 kCupProductionPublicKey;
166
167 // Try to retrieve the credentials if we have any. If we have succeeded, then
168 // we must have a {sk, c} pair. If we have failed, then we will generate
169 // a fresh set of credentials later on.
170 HRESULT hr = LoadCredentials(&persisted_sk_, &persisted_c_);
171 if (FAILED(hr)) {
172 ASSERT1(persisted_sk_.empty());
173 ASSERT1(persisted_c_.IsEmpty());
174 }
175
176 rsa_.reset(new RSA(public_key_));
177 http_request_.reset(http_request);
178
179 // Decorate the user agent by appending the "CUP" suffix. This overrides
180 // the user agent of the inner http request.
181 CString user_agent(http_request_->user_agent());
182 user_agent += _T(";cup");
183 http_request_->set_user_agent(user_agent);
184 }
185
186 CupRequestImpl::~CupRequestImpl() {
187 Close();
188 }
189
190 HRESULT CupRequestImpl::Close() {
191 cup_.reset();
192
193 // TODO(omaha): optimize so that if the credentials did not change then
194 // there would be not need to write back.
195 if (!persisted_sk_.empty() && !persisted_c_.IsEmpty()) {
196 VERIFY1(SUCCEEDED(SaveCredentials(persisted_sk_, persisted_c_)));
197 }
198 return http_request_->Close();
199 }
200
201 HRESULT CupRequestImpl::Send() {
202 // Start with a fresh CUP state. This is important as the client may
203 // reuse the same CUP request for subsequent requests.
204 cup_.reset(new TransientCupState);
205
206 // First, build a request, send it, and then authenticate the response.
207 HRESULT hr = BuildRequest();
208 if (FAILED(hr)) {
209 return hr;
210 }
211 hr = DoSend();
212 if (FAILED(hr)) {
213 return hr;
214 }
215 hr = AuthenticateResponse();
216 if (FAILED(hr)) {
217 return hr;
218 }
219 return S_OK;
220 }
221
222 HRESULT CupRequestImpl::BuildRequest() {
223 HRESULT hr(InitializeEntropy());
224 if (FAILED(hr)) {
225 return hr;
226 }
227 // Start with some random bytes.
228 cup_->r = cup_utils::RsaPad(rsa_->size(),
229 &cup_->entropy.front(), cup_->entropy.size());
230
231 // Derive a new shared key (sk') as the hash of the random bytes.
232 // TODO(omaha): consider protecting the key using ::CryptProtectmemory when
233 // not being used.
234 cup_->new_sk = cup_utils::Hash(cup_->r);
235
236 // Compute the challenge (w) by encrypting in place (r) with the server
237 // public key pk[v].
238 size_t encrypted_size = rsa_->raw(&cup_->r.front(), cup_->r.size());
239 ASSERT1(encrypted_size == cup_->r.size());
240
241 // Compute the versioned challenge (v|w) as
242 // decimal-v:base64-encoded-rsa-wrapper.
243 SafeCStringAFormat(&cup_->vw, "%d:%s",
244 rsa_->version(),
245 cup_utils::B64Encode(&cup_->r.front(), cup_->r.size()));
246
247 // Compute the url of the CUP request.
248 // Append a query string or append to the existing query string if any.
249 const char* format_string = url_.Find('?') != -1 ? "%1&w=%2" : "%1?w=%2";
250 cup_->request_url.FormatMessage(format_string, url_, cup_->vw);
251
252 // Compute the challenge hash (hw) as HASH(HASH(v|w)|HASH(req))
253 hr = BuildChallengeHash();
254 if (FAILED(hr)) {
255 return hr;
256 }
257
258 // Compute the client proof as SYMsign[sk](0|hw|HASH(c)) if we have a
259 // {sk, c} pair or as SYMsign[sk'](3|hw) if we do not.
260 hr = BuildClientProof();
261 if (FAILED(hr)) {
262 return hr;
263 }
264
265 NET_LOG(L4, (_T("[hw: %s]"), BytesToHex(cup_->hw)));
266
267 // This is what the client sends up along with the request: a versioned
268 // challenge, a client proof, and a client cookie if it has one.
269
270 NET_LOG(L4, (_T("[request: %s]"), CA2T(cup_->request_url)));
271 NET_LOG(L4, (_T("[ifmatch: %s]"), CA2T(cup_->cp)));
272 NET_LOG(L4, (_T("[cookie: %s]"), CA2T(cup_->c)));
273
274 return S_OK;
275 }
276
277 HRESULT CupRequestImpl::BuildChallengeHash() {
278 // The hash of the request if carried through all the cryptographic proofs.
279 // The challenge hash hw is computed as:
280 // HASH(HASH(v|w)|HASH(request_url)|HASH(body)).
281 // For simplicity, the protocol scheme and the port are dropped before
282 // hashing. The hash is computed over the CUP request url, which includes
283 // the versioned hash.
284 scoped_ptr<HttpClient> http_client(CreateHttpClient());
285 if (!http_client.get()) {
286 return OMAHA_NET_E_CUP_NO_HTTP_CLIENT;
287 }
288 HRESULT hr = http_client->Initialize();
289 if (FAILED(hr)) {
290 return hr;
291 }
292 ASSERT1(!cup_->request_url.IsEmpty());
293 CString url(cup_->request_url);
294 CString scheme, server, url_path, query_string;
295 hr = http_client->CrackUrl(url,
296 0,
297 &scheme,
298 &server,
299 NULL,
300 &url_path,
301 &query_string);
302 if (FAILED(hr)) {
303 return hr;
304 }
305
306 ASSERT1(!scheme.IsEmpty());
307 ASSERT1(!server.IsEmpty());
308 ASSERT1(!url_path.IsEmpty());
309 url.FormatMessage(_T("//%1%2%3"), server, url_path, query_string);
310
311 CStringA req(url);
312
313 // Compute hw as HASH(HASH(v|w)|HASH(request_url)|HASH(body)).
314 ASSERT1(!cup_->vw.IsEmpty());
315 ASSERT1(!url.IsEmpty());
316 cup_->hw = cup_utils::HashBuffers(cup_->vw.GetString(), cup_->vw.GetLength(),
317 req.GetString(), req.GetLength(),
318 request_buffer_, request_buffer_length_);
319 return S_OK;
320 }
321
322 HRESULT CupRequestImpl::BuildClientProof() {
323 // Use persisted {sk, c} or start with empty credentials otherwise.
324 ASSERT1(cup_->sk.empty());
325 ASSERT1(cup_->c.IsEmpty());
326 if (!persisted_sk_.empty() && !persisted_c_.IsEmpty()) {
327 cup_->sk = persisted_sk_;
328 cup_->c = persisted_c_;
329 }
330
331 std::vector<uint8> hcp; // hmac of the client proof.
332 if (!cup_->sk.empty() && !cup_->c.IsEmpty()) {
333 // Use the cached shared key (sk) and the cookie (c) if we have them.
334 ASSERT1(cup_->sk.size() == SHA_DIGEST_SIZE);
335 NET_LOG(L4, (_T("[using sk: %s]"), BytesToHex(cup_->sk)));
336
337 // Compute 'cp' as SYMsign[sk](0|HASH(w)|HASH(c))
338 std::vector<uint8> hc = cup_utils::Hash(cup_->c);
339 hcp = cup_utils::SymSign(cup_->sk, 0, &cup_->hw, &hc, NULL);
340 } else {
341 // There is no saved shared key. Use current shared key (new_sk).
342 ASSERT1(cup_->new_sk.size() == SHA_DIGEST_SIZE);
343 NET_LOG(L4, (_T("[using sk': %s]"), BytesToHex(cup_->new_sk)));
344
345 // Compute 'cp' as SYMsign[sk'](3|HASH(w))
346 hcp = cup_utils::SymSign(cup_->new_sk, 3, &cup_->hw, NULL, NULL);
347 }
348
349 NET_LOG(L4, (_T("[client proof hmac: %s]"), BytesToHex(hcp)));
350 cup_->cp = cup_utils::B64Encode(hcp);
351 return S_OK;
352 }
353
354 HRESULT CupRequestImpl::AuthenticateResponse() {
355 // This is what the server has sent down along with the response:
356 // a server proof, and optionally a new cookie for the client.
357 NET_LOG(L4, (_T("[etag: %s]"), CA2T(cup_->sp)));
358 NET_LOG(L4, (_T("[svr cookie: %s]"), CA2T(cup_->new_cookie)));
359
360 if (cup_->sp.IsEmpty()) {
361 // We can't authenticate anything without the server proof.
362 return OMAHA_NET_E_CUP_NO_SERVER_PROOF;
363 }
364
365 // Compute the hash of the response (hm).
366 cup_->hm = cup_utils::Hash(cup_->response);
367 NET_LOG(L4, (_T("[hm: %s]"), BytesToHex(cup_->hm)));
368
369 // Verify the response and the challenge w are authenticated by the
370 // client shared key. The validation has at least one subtle aspect: the
371 // client must try two signatures. First, it tries to authenticate using
372 // the new sk and the new cookie. If the response does not authenticate but
373 // the client has an old key, it should try authenticating with the old key.
374 // This second step is important in the case of an attacker or server
375 // misconfiguration where the server is signing with the old key but still
376 // sending a cookie.
377 std::vector<uint8> hmac;
378 if (!cup_->new_cookie.IsEmpty() && !cup_->new_sk.empty()) {
379 // The server has sent down a new cookie because the client proof or the
380 // client cookie were not good or missing. Try to authenticate using the
381 // new shared key and the new cookie {sk', c'}.
382 std::vector<uint8> hnew_c = cup_utils::Hash(cup_->new_cookie); // HASH(c')
383
384 // Compute the server proof (sp) as SYMsign[sk'](1|hw|hm|hc').
385 hmac = cup_utils::SymSign(cup_->new_sk, 1, &cup_->hw, &cup_->hm, &hnew_c);
386 CStringA expected_sp = cup_utils::B64Encode(hmac);
387
388 if (expected_sp == cup_->sp) {
389 // Copy the credentials to write them back when this object is destroyed.
390 persisted_sk_ = cup_->new_sk;
391 persisted_c_ = cup_->new_cookie;
392 return S_OK;
393 }
394 }
395
396 if (!cup_->sk.empty()) {
397 // The server has accepted our client proof (cp) and consequently the sk.
398
399 // Compute the server proof as SYMsign[sk](2|hw|hm).
400 hmac = cup_utils::SymSign(cup_->sk, 2, &cup_->hw, &cup_->hm, NULL);
401 CStringA expected_sp = cup_utils::B64Encode(hmac);
402
403 if (expected_sp == cup_->sp) {
404 return S_OK;
405 }
406 }
407
408 NET_LOG(L4, (_T("[expected server proof: %s]"), BytesToHex(hmac)));
409
410 // The server proof does not authenticate. We reject this response.
411 return OMAHA_NET_E_CUP_NOT_TRUSTED;
412 }
413
414 HRESULT CupRequestImpl::LoadCredentials(std::vector<uint8>* sk, CStringA* c) {
415 ASSERT1(sk);
416 ASSERT1(c);
417 NetworkConfig* network_config = NULL;
418 NetworkConfigManager& network_manager = NetworkConfigManager::Instance();
419 HRESULT hr = network_manager.GetUserNetworkConfig(&network_config);
420 if (FAILED(hr)) {
421 return hr;
422 }
423 CupCredentials cup_credentials;
424 hr = network_config->GetCupCredentials(&cup_credentials);
425 if (SUCCEEDED(hr)) {
426 sk->swap(cup_credentials.sk);
427 *c = cup_credentials.c;
428 }
429 return hr;
430 }
431
432 HRESULT CupRequestImpl::SaveCredentials(const std::vector<uint8>& sk,
433 const CStringA& c) {
434 NetworkConfig* network_config = NULL;
435 NetworkConfigManager& network_manager = NetworkConfigManager::Instance();
436 HRESULT hr = network_manager.GetUserNetworkConfig(&network_config);
437 if (FAILED(hr)) {
438 return hr;
439 }
440
441 CupCredentials cup_credentials;
442 cup_credentials.sk = sk;
443 cup_credentials.c = c;
444 return network_config->SetCupCredentials(&cup_credentials);
445 }
446
447 HRESULT CupRequestImpl::DoSend() {
448 // The url of the inner request includes the versioned challenge.
449 // It replaces the protocol from https to http since CUP over https is
450 // not supported.
451 CString inner_request_url;
452 HRESULT hr = BuildInnerRequestUrl(CString(cup_->request_url),
453 &inner_request_url);
454 if (FAILED(hr)) {
455 return hr;
456 }
457 http_request_->set_url(inner_request_url);
458
459 // Prepare additional headers to send.
460 CString additional_headers(additional_headers_);
461
462 // The client proof (cp) is sent as the "If-Match" header.
463 ASSERT1(!cup_->cp.IsEmpty());
464 CStringA if_match_header;
465 SafeCStringAFormat(&if_match_header, "\"%s\"", cup_->cp);
466 additional_headers += HttpClient::BuildRequestHeader(_T("If-Match"),
467 CA2T(if_match_header));
468
469 // Send the client cookie (c) if we have one.
470 if (!cup_->c.IsEmpty()) {
471 additional_headers += HttpClient::BuildRequestHeader(_T("Cookie"),
472 CA2T(cup_->c));
473 }
474 http_request_->set_additional_headers(additional_headers);
475
476 NET_LOG(L5, (_T("[CUP request][%s]"),
477 BufferToPrintableString(request_buffer_,
478 request_buffer_length_)));
479 hr = http_request_->Send();
480 if (FAILED(hr)) {
481 return hr;
482 }
483 http_request_->GetResponse().swap(cup_->response);
484 int status_code(http_request_->GetHttpStatusCode());
485 if (status_code != HTTP_STATUS_OK &&
486 status_code != HTTP_STATUS_PARTIAL_CONTENT) {
487 return HRESULTFromHttpStatusCode(status_code);
488 }
489 NET_LOG(L5, (_T("[CUP response][%s]"),
490 VectorToPrintableString(cup_->response)));
491
492 // Get the server proof (sp).
493 CString etag_header;
494 http_request_->QueryHeadersString(WINHTTP_QUERY_ETAG, NULL, &etag_header);
495 UnenclosePath(&etag_header); // Remove the quotes.
496 cup_->sp = CT2A(etag_header);
497
498 // Get the client cookie c'. The cookie may or may not be there. If the
499 // server has accepted both client proof (sp) then no
500 // new cookie is sent down. This is an indication for the client to
501 // use its {sk, c} pair.
502 CString set_cookie_header;
503 http_request_->QueryHeadersString(WINHTTP_QUERY_SET_COOKIE,
504 NULL, &set_cookie_header);
505
506 // Parse the cookie header to extract c=xxx cookie.
507 cup_->new_cookie = CT2A(cup_utils::ParseCupCookie(set_cookie_header));
508 return S_OK;
509 }
510
511 HRESULT CupRequestImpl::Cancel() {
512 return http_request_->Cancel();
513 }
514
515 HRESULT CupRequestImpl::Pause() {
516 return http_request_->Pause();
517 }
518
519 HRESULT CupRequestImpl::Resume() {
520 return http_request_->Resume();
521 }
522
523 std::vector<uint8> CupRequestImpl::GetResponse() const {
524 return http_request_->GetResponse();
525 }
526
527 HRESULT CupRequestImpl::QueryHeadersString(uint32 info_level,
528 const TCHAR* name,
529 CString* value) const {
530 return http_request_->QueryHeadersString(info_level, name, value);
531 }
532
533 CString CupRequestImpl::GetResponseHeaders() const {
534 return http_request_->GetResponseHeaders();
535 }
536
537 int CupRequestImpl::GetHttpStatusCode() const {
538 return http_request_->GetHttpStatusCode();
539 }
540
541 CString CupRequestImpl::ToString() const {
542 return CString("CUP:") + http_request_->ToString();
543 }
544
545 void CupRequestImpl::set_session_handle(HINTERNET session_handle) {
546 http_request_->set_session_handle(session_handle);
547 }
548
549 void CupRequestImpl::set_url(const CString& url) {
550 url_ = CT2A(url, CP_UTF8);
551 }
552
553 void CupRequestImpl::set_request_buffer(const void* buffer,
554 size_t buffer_length) {
555 request_buffer_ = buffer;
556 request_buffer_length_ = buffer_length;
557 http_request_->set_request_buffer(request_buffer_, request_buffer_length_);
558 }
559
560 void CupRequestImpl::set_proxy_configuration(const ProxyConfig& proxy_config) {
561 http_request_->set_proxy_configuration(proxy_config);
562 }
563
564 void CupRequestImpl::set_filename(const CString& filename) {
565 http_request_->set_filename(filename);
566 }
567
568 void CupRequestImpl::set_low_priority(bool low_priority) {
569 http_request_->set_low_priority(low_priority);
570 }
571
572 void CupRequestImpl::set_callback(NetworkRequestCallback* callback) {
573 http_request_->set_callback(callback);
574 }
575
576 void CupRequestImpl::set_additional_headers(const CString& additional_headers) {
577 additional_headers_ = additional_headers;
578 }
579
580 void CupRequestImpl::set_preserve_protocol(bool preserve_protocol) {
581 preserve_protocol_ = preserve_protocol;
582 }
583
584 CString CupRequestImpl::user_agent() const {
585 return http_request_->user_agent();
586 }
587
588 void CupRequestImpl::set_user_agent(const CString& user_agent) {
589 http_request_->set_user_agent(user_agent);
590 }
591
592 void CupRequestImpl::set_proxy_auth_config(const ProxyAuthConfig& config) {
593 http_request_->set_proxy_auth_config(config);
594 }
595
596 void CupRequestImpl::SetEntropy(const void* data, size_t data_length) {
597 ASSERT(false, (_T("Do not call from production code")));
598 ASSERT1(data);
599 const uint8* first(static_cast<const uint8*>(data));
600 const uint8* last(first + data_length);
601 std::vector<uint8> new_entropy(first, last);
602 entropy_.swap(new_entropy);
603 }
604
605 HRESULT CupRequestImpl::InitializeEntropy() {
606 if (entropy_.empty()) {
607 cup_->entropy.resize(rsa_->size() - SHA_DIGEST_SIZE);
608 if (!GenRandom(&cup_->entropy.front(), cup_->entropy.size())) {
609 return OMAHA_NET_E_CUP_NO_ENTROPY;
610 }
611 } else {
612 cup_->entropy = entropy_;
613 }
614 return S_OK;
615 }
616
617 HRESULT CupRequestImpl::BuildInnerRequestUrl(const CString& url,
618 CString* inner_url) {
619 ASSERT1(inner_url);
620 if (!String_StartsWith(url, kHttpsProtoScheme, true)) {
621 *inner_url = url;
622 return S_OK;
623 }
624
625 if (preserve_protocol_) {
626 // Request must be sent through https. So return error here so we can
627 // fall back to the next request type in the chain without CUP.
628 return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
629 }
630
631 *inner_url = url.Mid(_tcslen(kHttpsProtoScheme));
632 inner_url->Insert(0, kHttpProtoScheme);
633 return S_OK;
634 }
635
636 } // namespace detail
637
638
639 CupRequest::CupRequest(HttpRequestInterface* http_request) {
640 ASSERT1(http_request);
641 impl_.reset(new detail::CupRequestImpl(http_request));
642 }
643
644 CupRequest::~CupRequest() {
645 }
646
647 HRESULT CupRequest::Close() {
648 return impl_->Close();
649 }
650
651 HRESULT CupRequest::Send() {
652 return impl_->Send();
653 }
654
655 HRESULT CupRequest::Cancel() {
656 return impl_->Cancel();
657 }
658
659 HRESULT CupRequest::Pause() {
660 return impl_->Pause();
661 }
662
663 HRESULT CupRequest::Resume() {
664 return impl_->Resume();
665 }
666
667 std::vector<uint8> CupRequest::GetResponse() const {
668 return impl_->GetResponse();
669 }
670
671 int CupRequest::GetHttpStatusCode() const {
672 return impl_->GetHttpStatusCode();
673 }
674
675 HRESULT CupRequest::QueryHeadersString(uint32 info_level,
676 const TCHAR* name,
677 CString* value) const {
678 return impl_->QueryHeadersString(info_level, name, value);
679 }
680
681 CString CupRequest::GetResponseHeaders() const {
682 return impl_->GetResponseHeaders();
683 }
684
685 CString CupRequest::ToString() const {
686 return impl_->ToString();
687 }
688
689 void CupRequest::set_session_handle(HINTERNET session_handle) {
690 return impl_->set_session_handle(session_handle);
691 }
692
693 void CupRequest::set_url(const CString& url) {
694 impl_->set_url(url);
695 }
696
697 void CupRequest::set_request_buffer(const void* buffer, size_t buffer_length) {
698 impl_->set_request_buffer(buffer, buffer_length);
699 }
700
701 void CupRequest::set_proxy_configuration(const ProxyConfig& proxy_config) {
702 impl_->set_proxy_configuration(proxy_config);
703 }
704
705 void CupRequest::set_filename(const CString& filename) {
706 impl_->set_filename(filename);
707 }
708
709 void CupRequest::set_low_priority(bool low_priority) {
710 impl_->set_low_priority(low_priority);
711 }
712
713 void CupRequest::set_callback(NetworkRequestCallback* callback) {
714 impl_->set_callback(callback);
715 }
716
717 void CupRequest::set_additional_headers(const CString& additional_headers) {
718 impl_->set_additional_headers(additional_headers);
719 }
720
721 void CupRequest::set_preserve_protocol(bool preserve_protocol) {
722 impl_->set_preserve_protocol(preserve_protocol);
723 }
724
725 CString CupRequest::user_agent() const {
726 return impl_->user_agent();
727 }
728
729 void CupRequest::set_user_agent(const CString& user_agent) {
730 impl_->set_user_agent(user_agent);
731 }
732
733 void CupRequest::set_proxy_auth_config(const ProxyAuthConfig& config) {
734 impl_->set_proxy_auth_config(config);
735 }
736
737 void CupRequest::SetEntropy(const void* data, size_t data_length) {
738 return impl_->SetEntropy(data, data_length);
739 }
740
741 } // namespace omaha
742
OLDNEW
« no previous file with comments | « net/cup_request.h ('k') | net/cup_request_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698