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

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: Callback returns void Created 6 years, 5 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 // The version of the authentication protocol.
24 const char kProtocolVersion[] = "0";
29 25
30 int DataReductionProxyAuthRequestHandler::back_to_back_failure_count_ = 0; 26 // The clients supported by the data reduction proxy.
27 const char kClientAndroidWebview[] = "webview";
28 const char kClientChromeAndroid[] = "android";
29 const char kClientChromeIOS[] = "ios";
31 30
32 int64 31 // static
33 DataReductionProxyAuthRequestHandler::auth_token_invalidation_timestamp_ = 0; 32 bool DataReductionProxyAuthRequestHandler::IsKeySetOnCommandLine() {
34 33 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
34 return command_line.HasSwitch(
35 data_reduction_proxy::switches::kDataReductionProxyKey);
36 }
35 37
36 DataReductionProxyAuthRequestHandler::DataReductionProxyAuthRequestHandler( 38 DataReductionProxyAuthRequestHandler::DataReductionProxyAuthRequestHandler(
37 DataReductionProxySettings* settings) : settings_(settings) { 39 DataReductionProxyParams* params)
38 DCHECK(settings); 40 : data_reduction_proxy_params_(params) {
41 version_ = kProtocolVersion;
42 #if defined(OS_ANDROID)
43 client_ = kClientChromeAndroid;
44 #elif defined(OS_IOS)
45 client_ = kClientChromeIOS;
46 #endif
47 Init();
39 } 48 }
40 49
50 void DataReductionProxyAuthRequestHandler::Init() {
51 InitAuthentication(GetDefaultKey());
52 }
53
54
41 DataReductionProxyAuthRequestHandler::~DataReductionProxyAuthRequestHandler() { 55 DataReductionProxyAuthRequestHandler::~DataReductionProxyAuthRequestHandler() {
42 } 56 }
43 57
44 DataReductionProxyAuthRequestHandler::TryHandleResult 58 // static
45 DataReductionProxyAuthRequestHandler::TryHandleAuthentication( 59 base::string16 DataReductionProxyAuthRequestHandler::AuthHashForSalt(
46 net::AuthChallengeInfo* auth_info, 60 int64 salt,
47 base::string16* user, 61 const std::string& key) {
48 base::string16* password) { 62 std::string salted_key =
49 if (!auth_info) { 63 base::StringPrintf("%lld%s%lld",
50 return TRY_HANDLE_RESULT_IGNORE; 64 static_cast<long long>(salt),
51 } 65 key.c_str(),
52 DCHECK(user); 66 static_cast<long long>(salt));
53 DCHECK(password); 67 return base::UTF8ToUTF16(base::MD5String(salted_key));
54 68 }
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 69
66 70
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 71
95 *password = GetTokenForAuthChallenge(auth_info); 72 base::Time DataReductionProxyAuthRequestHandler::Now() const {
96 73 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 } 74 }
105 75
106 bool DataReductionProxyAuthRequestHandler::IsAcceptableAuthChallenge( 76 void DataReductionProxyAuthRequestHandler::RandBytes(
107 net::AuthChallengeInfo* auth_info) { 77 void* output, size_t length) {
108 return settings_->IsAcceptableAuthChallenge(auth_info); 78 crypto::RandBytes(output, length);
109 } 79 }
110 80
111 base::string16 DataReductionProxyAuthRequestHandler::GetTokenForAuthChallenge( 81 void DataReductionProxyAuthRequestHandler::MaybeAddRequestHeader(
112 net::AuthChallengeInfo* auth_info) { 82 net::URLRequest* request,
113 DCHECK(settings_); 83 const net::ProxyServer& proxy_server,
114 return settings_->GetTokenForAuthChallenge(auth_info); 84 net::HttpRequestHeaders* request_headers) {
85 if (!proxy_server.is_valid()) {
86 LOG(WARNING) << "Invalid proxy";
87 return;
88 } else {
89 LOG(WARNING) << "Valid proxy";
90 }
91 if (data_reduction_proxy_params_ &&
92 data_reduction_proxy_params_->IsDataReductionProxy(
93 proxy_server.host_port_pair(), NULL)) {
94 LOG(WARNING) << "DRP";
95 AddAuthorizationHeader(request_headers);
96 }
97 else {
98 LOG(WARNING) << "Not DRP";
99 }
115 } 100 }
116 101
117 base::TimeTicks DataReductionProxyAuthRequestHandler::Now() { 102 void DataReductionProxyAuthRequestHandler::AddAuthorizationHeader(
118 return base::TimeTicks::Now(); 103 net::HttpRequestHeaders* headers) {
104 const char kChromeProxyHeader[] = "Chrome-Proxy";
105 std::string header_value;
106 if (headers->HasHeader(kChromeProxyHeader)) {
107 headers->GetHeader(kChromeProxyHeader, &header_value);
108 headers->RemoveHeader(kChromeProxyHeader);
109 header_value += ", ";
110 }
111 header_value +=
112 "ps=" + session_ + ", sid=" + credentials_ + ", v=" + version_;
113 if (!client_.empty())
114 header_value += ", c=" + client_;
115 headers->SetHeader(kChromeProxyHeader, header_value);
116 }
117
118 void DataReductionProxyAuthRequestHandler::InitAuthentication(
119 const std::string& key) {
120 key_ = key;
121 int64 timestamp =
122 (Now() - base::Time::UnixEpoch()).InMilliseconds() / 1000;
123
124 int32 rand[3];
125 RandBytes(rand, 3 * sizeof(rand[0]));
126 session_ = base::StringPrintf("%lld-%u-%u-%u",
127 static_cast<long long>(timestamp),
128 rand[0],
129 rand[1],
130 rand[2]);
131 credentials_ = UTF16ToUTF8(AuthHashForSalt(timestamp, key_));
132
133 DVLOG(1) << "session: [" << session_ << "] password: [" << credentials_
134 << "]";
135 }
136
137 void DataReductionProxyAuthRequestHandler::SetKey(const std::string& key,
138 const std::string& client,
139 const std::string& version) {
140 client_ = client;
141 version_ = version;
142 if (!key.empty())
143 InitAuthentication(key);
144 }
145
146
147 std::string DataReductionProxyAuthRequestHandler::GetDefaultKey() const {
148 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
149 std::string key =
150 command_line.GetSwitchValueASCII(switches::kDataReductionProxyKey);
151 #if defined(SPDY_PROXY_AUTH_VALUE)
152 if (key.empty())
153 key = SPDY_PROXY_AUTH_VALUE;
154 #endif
155 return key;
119 } 156 }
120 157
121 } // namespace data_reduction_proxy 158 } // namespace data_reduction_proxy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698