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

Side by Side Diff: components/data_reduction_proxy/browser/data_reduction_proxy_auth_request_handler.cc

Issue 333113002: Move data reduction proxy to Chrome-Proxy header for authentication (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@flywheel-refactor-net-fake-a-redirect-response-headers-chrome-proxy-auth
Patch Set: Created 6 years, 6 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/data_reduction_proxy/browser/data_reduction_proxy_auth_requ est_handler.h" 5 #include "components/data_reduction_proxy/browser/data_reduction_proxy_auth_requ est_handler.h"
6 6
7 #include "base/command_line.h"
8 #include "base/strings/stringprintf.h"
7 #include "base/strings/utf_string_conversions.h" 9 #include "base/strings/utf_string_conversions.h"
8 #include "base/time/time.h" 10 #include "base/time/time.h"
11 #include "components/data_reduction_proxy/browser/data_reduction_proxy_params.h"
12 #include "components/data_reduction_proxy/browser/data_reduction_proxy_protocol. h"
9 #include "components/data_reduction_proxy/browser/data_reduction_proxy_settings. h" 13 #include "components/data_reduction_proxy/browser/data_reduction_proxy_settings. h"
10 #include "net/base/auth.h" 14 #include "components/data_reduction_proxy/common/data_reduction_proxy_headers.h"
11 15 #include "components/data_reduction_proxy/common/data_reduction_proxy_switches.h "
12 namespace { 16 #include "crypto/random.h"
13 // The minimum interval allowed, in milliseconds, between data reduction proxy 17 #include "net/proxy/proxy_server.h"
14 // auth requests. 18 #include "net/url_request/url_request.h"
15 const int64 kMinAuthRequestIntervalMs = 500; 19 #include "url/gurl.h"
16
17 // The minimum interval allowed, in milliseconds, between data reduction proxy
18 // auth token invalidation.
19 const int64 kMinTokenInvalidationIntervalMs = 60 * 60 * 1000;
20
21 // The maximum number of data reduction proxy authentication failures to
22 // accept before giving up.
23 const int kMaxBackToBackFailures = 5;
24 }
25 20
26 namespace data_reduction_proxy { 21 namespace data_reduction_proxy {
27 22
28 int64 DataReductionProxyAuthRequestHandler::auth_request_timestamp_ = 0; 23 // static
29 24 bool DataReductionProxyAuthRequestHandler::IsKeySetOnCommandLine() {
30 int DataReductionProxyAuthRequestHandler::back_to_back_failure_count_ = 0; 25 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
31 26 return command_line.HasSwitch(
32 int64 27 data_reduction_proxy::switches::kDataReductionProxyKey);
33 DataReductionProxyAuthRequestHandler::auth_token_invalidation_timestamp_ = 0; 28 }
34
35 29
36 DataReductionProxyAuthRequestHandler::DataReductionProxyAuthRequestHandler( 30 DataReductionProxyAuthRequestHandler::DataReductionProxyAuthRequestHandler(
37 DataReductionProxySettings* settings) : settings_(settings) { 31 DataReductionProxyParams* params)
38 DCHECK(settings); 32 : data_reduction_proxy_params_(params) {
33 version_ = "0";
34 #if defined(OS_ANDROID)
35 client_ = "android";
36 #elif defined(OS_IOS)
37 client_ = "ios";
38 #endif
39 Init();
39 } 40 }
40 41
42 void DataReductionProxyAuthRequestHandler::Init() {
43 InitAuthentication(GetDefaultKey());
44 }
45
46
41 DataReductionProxyAuthRequestHandler::~DataReductionProxyAuthRequestHandler() { 47 DataReductionProxyAuthRequestHandler::~DataReductionProxyAuthRequestHandler() {
42 } 48 }
43 49
44 DataReductionProxyAuthRequestHandler::TryHandleResult 50 // static
45 DataReductionProxyAuthRequestHandler::TryHandleAuthentication( 51 base::string16 DataReductionProxyAuthRequestHandler::AuthHashForSalt(
46 net::AuthChallengeInfo* auth_info, 52 int64 salt,
47 base::string16* user, 53 const std::string& key) {
48 base::string16* password) { 54 std::string salted_key =
49 if (!auth_info) { 55 base::StringPrintf("%lld%s%lld",
50 return TRY_HANDLE_RESULT_IGNORE; 56 static_cast<long long>(salt),
51 } 57 key.c_str(),
52 DCHECK(user); 58 static_cast<long long>(salt));
53 DCHECK(password); 59 return base::UTF8ToUTF16(base::MD5String(salted_key));
54 60 }
55 if (!IsAcceptableAuthChallenge(auth_info)) {
56 *user = base::string16();
57 *password = base::string16();
58 return TRY_HANDLE_RESULT_IGNORE;
59 }
60
61 base::TimeTicks auth_request =
62 base::TimeTicks::FromInternalValue(auth_request_timestamp_);
63 base::TimeTicks auth_token_invalidation =
64 base::TimeTicks::FromInternalValue(auth_token_invalidation_timestamp_);
65 61
66 62
67 base::TimeTicks now = Now();
68 if ((now - auth_request).InMilliseconds() < kMinAuthRequestIntervalMs) {
69 // We've received back-to-back failures. There are two possibilities:
70 // 1) Our auth token has expired and we should invalidate it, or
71 // 2) We're receiving spurious failures from the service.
72 //
73 // If we haven't recently invalidated our token, we do that here
74 // and make several attempts to authenticate. Otherwise, we fail.
75 back_to_back_failure_count_++;
76 if ((now - auth_token_invalidation).InMilliseconds() <
77 kMinTokenInvalidationIntervalMs) {
78 auth_token_invalidation_timestamp_ = now.ToInternalValue();
79 back_to_back_failure_count_ = 0;
80 } else {
81 if (back_to_back_failure_count_ > kMaxBackToBackFailures) {
82 DLOG(WARNING) << "Interpreting frequent data reduction proxy auth "
83 << "requests as an authorization failure.";
84 back_to_back_failure_count_ = 0;
85 *user = base::string16();
86 *password = base::string16();
87 return TRY_HANDLE_RESULT_CANCEL;
88 }
89 }
90 } else {
91 back_to_back_failure_count_ = 0;
92 }
93 auth_request_timestamp_ = now.ToInternalValue();
94 63
95 *password = GetTokenForAuthChallenge(auth_info); 64 base::Time DataReductionProxyAuthRequestHandler::Now() const {
96 65 return base::Time::Now();
97 if (*password == base::string16()) {
98 *user = base::string16();
99 DLOG(WARNING) << "Data reduction proxy auth produced null token.";
100 return TRY_HANDLE_RESULT_CANCEL;
101 }
102 *user = base::UTF8ToUTF16("fw-cookie");
103 return TRY_HANDLE_RESULT_PROCEED;
104 } 66 }
105 67
106 bool DataReductionProxyAuthRequestHandler::IsAcceptableAuthChallenge( 68 void DataReductionProxyAuthRequestHandler::RandBytes(
107 net::AuthChallengeInfo* auth_info) { 69 void* output, size_t length) {
108 return settings_->IsAcceptableAuthChallenge(auth_info); 70 crypto::RandBytes(output, length);
109 } 71 }
110 72
111 base::string16 DataReductionProxyAuthRequestHandler::GetTokenForAuthChallenge( 73 void DataReductionProxyAuthRequestHandler::MaybeAddRequestHeader(
112 net::AuthChallengeInfo* auth_info) { 74 net::URLRequest* request,
113 DCHECK(settings_); 75 const net::ProxyServer& proxy_server,
114 return settings_->GetTokenForAuthChallenge(auth_info); 76 net::HttpRequestHeaders* request_headers) {
77 if (!proxy_server.is_valid()) {
78 LOG(WARNING) << "Invalid proxy";
79 return;
80 } else {
81 LOG(WARNING) << "Valid proxy";
82 }
83 if (data_reduction_proxy_params_ &&
84 data_reduction_proxy_params_->IsDataReductionProxy(
85 proxy_server.host_port_pair(), NULL)) {
86 LOG(WARNING) << "DRP";
87 AddAuthorizationHeader(request_headers);
88 }
89 else {
90 LOG(WARNING) << "Not DRP";
91 }
115 } 92 }
116 93
117 base::TimeTicks DataReductionProxyAuthRequestHandler::Now() { 94 void DataReductionProxyAuthRequestHandler::AddAuthorizationHeader(
118 return base::TimeTicks::Now(); 95 net::HttpRequestHeaders* headers) {
96 const char kChromeProxyHeader[] = "Chrome-Proxy";
97 std::string header_value;
98 if (headers->HasHeader(kChromeProxyHeader)) {
99 headers->GetHeader(kChromeProxyHeader, &header_value);
100 headers->RemoveHeader(kChromeProxyHeader);
101 header_value += ", ";
102 }
103 header_value +=
104 "ps=" + session_ + ", sid=" + credentials_ + ", v=" + version_;
105 if (!client_.empty())
106 header_value += ", c=" + client_;
107 headers->SetHeader(kChromeProxyHeader, header_value);
108 }
109
110 void DataReductionProxyAuthRequestHandler::InitAuthentication(
111 const std::string& key) {
112 key_ = key;
113 int64 timestamp =
114 (Now() - base::Time::UnixEpoch()).InMilliseconds() / 1000;
115
116 int32 rand[3];
117 RandBytes(rand, 3 * sizeof(rand[0]));
118 session_ = base::StringPrintf("%lld-%u-%u-%u",
119 static_cast<long long>(timestamp),
120 rand[0],
121 rand[1],
122 rand[2]);
123 credentials_ = UTF16ToUTF8(AuthHashForSalt(timestamp, key_));
124
125 DVLOG(1) << "session: [" << session_ << "] password: [" << credentials_
126 << "]";
127 }
128
129 void DataReductionProxyAuthRequestHandler::SetKey(const std::string& key,
130 const std::string& client,
131 const std::string& version) {
132 client_ = client;
133 version_ = version;
134 if (!key.empty())
135 InitAuthentication(key);
136 }
137
138
139 std::string DataReductionProxyAuthRequestHandler::GetDefaultKey() const {
140 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
141 std::string key =
142 command_line.GetSwitchValueASCII(switches::kDataReductionProxyKey);
143 #if defined(SPDY_PROXY_AUTH_VALUE)
144 if (key.empty())
145 key = SPDY_PROXY_AUTH_VALUE;
146 #endif
147 return key;
119 } 148 }
120 149
121 } // namespace data_reduction_proxy 150 } // namespace data_reduction_proxy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698