| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/browser/net/chrome_network_delegate.h" | 5 #include "chrome/browser/net/chrome_network_delegate.h" |
| 6 | 6 |
| 7 #include "base/base64.h" |
| 7 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/metrics/histogram.h" |
| 8 #include "chrome/browser/browser_process.h" | 10 #include "chrome/browser/browser_process.h" |
| 9 #include "chrome/browser/content_settings/cookie_settings.h" | 11 #include "chrome/browser/content_settings/cookie_settings.h" |
| 10 #include "chrome/browser/content_settings/tab_specific_content_settings.h" | 12 #include "chrome/browser/content_settings/tab_specific_content_settings.h" |
| 11 #include "chrome/browser/custom_handlers/protocol_handler_registry.h" | 13 #include "chrome/browser/custom_handlers/protocol_handler_registry.h" |
| 12 #include "chrome/browser/extensions/api/proxy/proxy_api.h" | 14 #include "chrome/browser/extensions/api/proxy/proxy_api.h" |
| 13 #include "chrome/browser/extensions/api/web_request/web_request_api.h" | 15 #include "chrome/browser/extensions/api/web_request/web_request_api.h" |
| 14 #include "chrome/browser/extensions/extension_event_router_forwarder.h" | 16 #include "chrome/browser/extensions/extension_event_router_forwarder.h" |
| 15 #include "chrome/browser/extensions/extension_info_map.h" | 17 #include "chrome/browser/extensions/extension_info_map.h" |
| 16 #include "chrome/browser/extensions/extension_process_manager.h" | 18 #include "chrome/browser/extensions/extension_process_manager.h" |
| 17 #include "chrome/browser/prefs/pref_member.h" | 19 #include "chrome/browser/prefs/pref_member.h" |
| 18 #include "chrome/browser/profiles/profile_manager.h" | 20 #include "chrome/browser/profiles/profile_manager.h" |
| 19 #include "chrome/browser/task_manager/task_manager.h" | 21 #include "chrome/browser/task_manager/task_manager.h" |
| 20 #include "chrome/common/pref_names.h" | 22 #include "chrome/common/pref_names.h" |
| 21 #include "content/public/browser/browser_thread.h" | 23 #include "content/public/browser/browser_thread.h" |
| 22 #include "content/public/browser/render_view_host.h" | 24 #include "content/public/browser/render_view_host.h" |
| 23 #include "content/public/browser/resource_request_info.h" | 25 #include "content/public/browser/resource_request_info.h" |
| 24 #include "net/base/host_port_pair.h" | 26 #include "net/base/host_port_pair.h" |
| 27 #include "net/base/dns_util.h" |
| 28 #include "net/base/dnsrr_resolver.h" |
| 25 #include "net/base/net_errors.h" | 29 #include "net/base/net_errors.h" |
| 26 #include "net/base/net_log.h" | 30 #include "net/base/net_log.h" |
| 31 #include "net/base/public_key_hashes.h" |
| 27 #include "net/cookies/cookie_monster.h" | 32 #include "net/cookies/cookie_monster.h" |
| 28 #include "net/http/http_request_headers.h" | 33 #include "net/http/http_request_headers.h" |
| 29 #include "net/http/http_response_headers.h" | 34 #include "net/http/http_response_headers.h" |
| 30 #include "net/url_request/url_request.h" | 35 #include "net/url_request/url_request.h" |
| 31 | 36 |
| 32 #if defined(ENABLE_CONFIGURATION_POLICY) | 37 #if defined(ENABLE_CONFIGURATION_POLICY) |
| 33 #include "chrome/browser/policy/url_blacklist_manager.h" | 38 #include "chrome/browser/policy/url_blacklist_manager.h" |
| 34 #endif | 39 #endif |
| 35 | 40 |
| 36 using content::BrowserThread; | 41 using content::BrowserThread; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 return; | 101 return; |
| 97 | 102 |
| 98 int process_id, render_view_id; | 103 int process_id, render_view_id; |
| 99 if (info->GetAssociatedRenderView(&process_id, &render_view_id)) { | 104 if (info->GetAssociatedRenderView(&process_id, &render_view_id)) { |
| 100 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 105 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 101 base::Bind(&NotifyEPMRequestStatus, | 106 base::Bind(&NotifyEPMRequestStatus, |
| 102 status, profile_id, process_id, render_view_id)); | 107 status, profile_id, process_id, render_view_id)); |
| 103 } | 108 } |
| 104 } | 109 } |
| 105 | 110 |
| 111 const char* const kComodoCerts[] = { |
| 112 kSPKIHash_AAACertificateServices, |
| 113 kSPKIHash_AddTrustClass1CARoot, |
| 114 kSPKIHash_AddTrustExternalCARoot, |
| 115 kSPKIHash_AddTrustPublicCARoot, |
| 116 kSPKIHash_AddTrustQualifiedCARoot, |
| 117 kSPKIHash_COMODOCertificationAuthority, |
| 118 kSPKIHash_SecureCertificateServices, |
| 119 kSPKIHash_TrustedCertificateServices, |
| 120 kSPKIHash_UTNDATACorpSGC, |
| 121 kSPKIHash_UTNUSERFirstClientAuthenticationandEmail, |
| 122 kSPKIHash_UTNUSERFirstHardware, |
| 123 kSPKIHash_UTNUSERFirstObject, |
| 124 }; |
| 125 |
| 126 // IsComodoCertificate returns true if a known Comodo public key appears in |
| 127 // |public_key_hashes|. |
| 128 // TODO(agl): remove once experiment is complete, by July 2012. |
| 129 static bool IsComodoCertificate( |
| 130 const std::vector<net::SHA1Fingerprint>& public_key_hashes) { |
| 131 for (std::vector<net::SHA1Fingerprint>::const_iterator |
| 132 i = public_key_hashes.begin(); i != public_key_hashes.end(); ++i) { |
| 133 std::string base64_hash; |
| 134 base::Base64Encode( |
| 135 base::StringPiece(reinterpret_cast<const char*>(i->data), |
| 136 arraysize(i->data)), |
| 137 &base64_hash); |
| 138 base64_hash = "sha1/" + base64_hash; |
| 139 |
| 140 for (size_t j = 0; j < arraysize(kComodoCerts); j++) { |
| 141 if (base64_hash == kComodoCerts[j]) |
| 142 return true; |
| 143 } |
| 144 } |
| 145 |
| 146 return false; |
| 147 } |
| 148 |
| 149 // RecordComodoDNSResult is a callback from a DNS resolution. It records the |
| 150 // elapsed time in a histogram. |
| 151 // TODO(agl): remove once experiment is complete, by July 2012. |
| 152 static void RecordComodoDNSResult(net::RRResponse* response, |
| 153 base::TimeTicks start_time, |
| 154 int result) { |
| 155 base::TimeDelta total_time = base::TimeTicks::Now() - start_time; |
| 156 if (total_time.InMilliseconds() > 10) { |
| 157 // If the reply took > 10 ms there's a good chance that it didn't come from |
| 158 // a local DNS cache. |
| 159 if (result == net::OK && |
| 160 response->rrdatas.size() && |
| 161 response->rrdatas[0].find("wibble") != std::string::npos) { |
| 162 UMA_HISTOGRAM_TIMES("Net.ComodoDNSExperimentSuccessTime", total_time); |
| 163 } else { |
| 164 UMA_HISTOGRAM_TIMES("Net.ComodoDNSExperimentFailureTime", total_time); |
| 165 } |
| 166 } |
| 167 } |
| 168 |
| 169 bool g_comodo_dns_experiment_enabled = false; |
| 170 |
| 106 } // namespace | 171 } // namespace |
| 107 | 172 |
| 108 ChromeNetworkDelegate::ChromeNetworkDelegate( | 173 ChromeNetworkDelegate::ChromeNetworkDelegate( |
| 109 ExtensionEventRouterForwarder* event_router, | 174 ExtensionEventRouterForwarder* event_router, |
| 110 ExtensionInfoMap* extension_info_map, | 175 ExtensionInfoMap* extension_info_map, |
| 111 const policy::URLBlacklistManager* url_blacklist_manager, | 176 const policy::URLBlacklistManager* url_blacklist_manager, |
| 112 void* profile, | 177 void* profile, |
| 113 CookieSettings* cookie_settings, | 178 CookieSettings* cookie_settings, |
| 114 BooleanPrefMember* enable_referrers) | 179 BooleanPrefMember* enable_referrers) |
| 115 : event_router_(event_router), | 180 : event_router_(event_router), |
| (...skipping 11 matching lines...) Expand all Loading... |
| 127 | 192 |
| 128 // static | 193 // static |
| 129 void ChromeNetworkDelegate::InitializeReferrersEnabled( | 194 void ChromeNetworkDelegate::InitializeReferrersEnabled( |
| 130 BooleanPrefMember* enable_referrers, | 195 BooleanPrefMember* enable_referrers, |
| 131 PrefService* pref_service) { | 196 PrefService* pref_service) { |
| 132 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 197 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 133 enable_referrers->Init(prefs::kEnableReferrers, pref_service, NULL); | 198 enable_referrers->Init(prefs::kEnableReferrers, pref_service, NULL); |
| 134 enable_referrers->MoveToThread(BrowserThread::IO); | 199 enable_referrers->MoveToThread(BrowserThread::IO); |
| 135 } | 200 } |
| 136 | 201 |
| 202 // static |
| 203 void ChromeNetworkDelegate::EnableComodoDNSExperiment() { |
| 204 g_comodo_dns_experiment_enabled = true; |
| 205 } |
| 206 |
| 137 int ChromeNetworkDelegate::OnBeforeURLRequest( | 207 int ChromeNetworkDelegate::OnBeforeURLRequest( |
| 138 net::URLRequest* request, | 208 net::URLRequest* request, |
| 139 const net::CompletionCallback& callback, | 209 const net::CompletionCallback& callback, |
| 140 GURL* new_url) { | 210 GURL* new_url) { |
| 141 #if defined(ENABLE_CONFIGURATION_POLICY) | 211 #if defined(ENABLE_CONFIGURATION_POLICY) |
| 142 // TODO(joaodasilva): This prevents extensions from seeing URLs that are | 212 // TODO(joaodasilva): This prevents extensions from seeing URLs that are |
| 143 // blocked. However, an extension might redirect the request to another URL, | 213 // blocked. However, an extension might redirect the request to another URL, |
| 144 // which is not blocked. | 214 // which is not blocked. |
| 145 if (url_blacklist_manager_ && | 215 if (url_blacklist_manager_ && |
| 146 url_blacklist_manager_->IsURLBlocked(request->url())) { | 216 url_blacklist_manager_->IsURLBlocked(request->url())) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 const GURL& new_location) { | 260 const GURL& new_location) { |
| 191 ExtensionWebRequestEventRouter::GetInstance()->OnBeforeRedirect( | 261 ExtensionWebRequestEventRouter::GetInstance()->OnBeforeRedirect( |
| 192 profile_, extension_info_map_.get(), request, new_location); | 262 profile_, extension_info_map_.get(), request, new_location); |
| 193 } | 263 } |
| 194 | 264 |
| 195 | 265 |
| 196 void ChromeNetworkDelegate::OnResponseStarted(net::URLRequest* request) { | 266 void ChromeNetworkDelegate::OnResponseStarted(net::URLRequest* request) { |
| 197 ExtensionWebRequestEventRouter::GetInstance()->OnResponseStarted( | 267 ExtensionWebRequestEventRouter::GetInstance()->OnResponseStarted( |
| 198 profile_, extension_info_map_.get(), request); | 268 profile_, extension_info_map_.get(), request); |
| 199 ForwardProxyErrors(request, event_router_.get(), profile_); | 269 ForwardProxyErrors(request, event_router_.get(), profile_); |
| 270 |
| 271 if (g_comodo_dns_experiment_enabled) { |
| 272 // This is a temporary experiment, in conjuction with Comodo, to measure the |
| 273 // effectiveness of a possible DNS-based revocation mechanism. |
| 274 // TODO(agl): remove once experiment is complete, by July 2012. |
| 275 const net::SSLInfo& ssl_info = request->response_info().ssl_info; |
| 276 if (request->response_info().was_cached == false && |
| 277 ssl_info.is_valid() && |
| 278 ssl_info.is_issued_by_known_root && |
| 279 IsComodoCertificate(ssl_info.public_key_hashes)) { |
| 280 if (dnsrr_resolver_.get() == NULL) |
| 281 dnsrr_resolver_.reset(new net::DnsRRResolver); |
| 282 |
| 283 // The Comodo DNS record has a 20 minute TTL, so we won't actually |
| 284 // request it more than three times an hour because it'll be in the |
| 285 // DnsRRResolver's cache. However, just in case something goes wrong we |
| 286 // also implement a hard stop to prevent resolutions more than once |
| 287 // every ten minutes. |
| 288 const base::TimeTicks now(base::TimeTicks::Now()); |
| 289 if (!last_comodo_resolution_time_.is_null() && |
| 290 (now - last_comodo_resolution_time_).InMinutes() < 10) { |
| 291 return; |
| 292 } |
| 293 last_comodo_resolution_time_ = now; |
| 294 |
| 295 net::RRResponse* response = new net::RRResponse; |
| 296 base::TimeTicks start_time(now); |
| 297 dnsrr_resolver_->Resolve( |
| 298 "wibble.comodoca.com", net::kDNS_TXT, 0 /* flags */, |
| 299 Bind(RecordComodoDNSResult, base::Owned(response), start_time), |
| 300 response, 0 /* priority */, |
| 301 request->net_log()); |
| 302 } |
| 303 } |
| 200 } | 304 } |
| 201 | 305 |
| 202 void ChromeNetworkDelegate::OnRawBytesRead(const net::URLRequest& request, | 306 void ChromeNetworkDelegate::OnRawBytesRead(const net::URLRequest& request, |
| 203 int bytes_read) { | 307 int bytes_read) { |
| 204 TaskManager::GetInstance()->model()->NotifyBytesRead(request, bytes_read); | 308 TaskManager::GetInstance()->model()->NotifyBytesRead(request, bytes_read); |
| 205 } | 309 } |
| 206 | 310 |
| 207 void ChromeNetworkDelegate::OnCompleted(net::URLRequest* request, | 311 void ChromeNetworkDelegate::OnCompleted(net::URLRequest* request, |
| 208 bool started) { | 312 bool started) { |
| 209 if (request->status().status() == net::URLRequestStatus::SUCCESS || | 313 if (request->status().status() == net::URLRequestStatus::SUCCESS || |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 293 request, &render_process_id, &render_view_id)) { | 397 request, &render_process_id, &render_view_id)) { |
| 294 BrowserThread::PostTask( | 398 BrowserThread::PostTask( |
| 295 BrowserThread::UI, FROM_HERE, | 399 BrowserThread::UI, FROM_HERE, |
| 296 base::Bind(&TabSpecificContentSettings::CookieChanged, | 400 base::Bind(&TabSpecificContentSettings::CookieChanged, |
| 297 render_process_id, render_view_id, | 401 render_process_id, render_view_id, |
| 298 request->url(), cookie_line, *options, !allow)); | 402 request->url(), cookie_line, *options, !allow)); |
| 299 } | 403 } |
| 300 | 404 |
| 301 return allow; | 405 return allow; |
| 302 } | 406 } |
| OLD | NEW |