| 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/safe_browsing/client_side_detection_service.h" | 5 #include "chrome/browser/safe_browsing/client_side_detection_service.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 #include "chrome/common/safe_browsing/csd.pb.h" | 23 #include "chrome/common/safe_browsing/csd.pb.h" |
| 24 #include "chrome/common/safe_browsing/safebrowsing_messages.h" | 24 #include "chrome/common/safe_browsing/safebrowsing_messages.h" |
| 25 #include "content/public/browser/browser_thread.h" | 25 #include "content/public/browser/browser_thread.h" |
| 26 #include "content/public/browser/notification_service.h" | 26 #include "content/public/browser/notification_service.h" |
| 27 #include "content/public/browser/notification_types.h" | 27 #include "content/public/browser/notification_types.h" |
| 28 #include "content/public/browser/render_process_host.h" | 28 #include "content/public/browser/render_process_host.h" |
| 29 #include "crypto/sha2.h" | 29 #include "crypto/sha2.h" |
| 30 #include "google_apis/google_api_keys.h" | 30 #include "google_apis/google_api_keys.h" |
| 31 #include "net/base/escape.h" | 31 #include "net/base/escape.h" |
| 32 #include "net/base/load_flags.h" | 32 #include "net/base/load_flags.h" |
| 33 #include "net/base/net_util.h" |
| 33 #include "net/http/http_response_headers.h" | 34 #include "net/http/http_response_headers.h" |
| 34 #include "net/http/http_status_code.h" | 35 #include "net/http/http_status_code.h" |
| 35 #include "net/url_request/url_fetcher.h" | 36 #include "net/url_request/url_fetcher.h" |
| 36 #include "net/url_request/url_request_context_getter.h" | 37 #include "net/url_request/url_request_context_getter.h" |
| 37 #include "net/url_request/url_request_status.h" | 38 #include "net/url_request/url_request_status.h" |
| 38 #include "url/gurl.h" | 39 #include "url/gurl.h" |
| 39 | 40 |
| 40 using content::BrowserThread; | 41 using content::BrowserThread; |
| 41 | 42 |
| 42 namespace safe_browsing { | 43 namespace safe_browsing { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 client_phishing_reports_.clear(); | 111 client_phishing_reports_.clear(); |
| 111 STLDeleteContainerPairPointers(client_malware_reports_.begin(), | 112 STLDeleteContainerPairPointers(client_malware_reports_.begin(), |
| 112 client_malware_reports_.end()); | 113 client_malware_reports_.end()); |
| 113 client_malware_reports_.clear(); | 114 client_malware_reports_.clear(); |
| 114 } | 115 } |
| 115 | 116 |
| 116 // static | 117 // static |
| 117 ClientSideDetectionService* ClientSideDetectionService::Create( | 118 ClientSideDetectionService* ClientSideDetectionService::Create( |
| 118 net::URLRequestContextGetter* request_context_getter) { | 119 net::URLRequestContextGetter* request_context_getter) { |
| 119 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 120 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 120 scoped_ptr<ClientSideDetectionService> service( | 121 return new ClientSideDetectionService(request_context_getter); |
| 121 new ClientSideDetectionService(request_context_getter)); | |
| 122 if (!service->InitializePrivateNetworks()) { | |
| 123 UMA_HISTOGRAM_COUNTS("SBClientPhishing.InitPrivateNetworksFailed", 1); | |
| 124 return NULL; | |
| 125 } | |
| 126 return service.release(); | |
| 127 } | 122 } |
| 128 | 123 |
| 129 void ClientSideDetectionService::SetEnabledAndRefreshState(bool enabled) { | 124 void ClientSideDetectionService::SetEnabledAndRefreshState(bool enabled) { |
| 130 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 125 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 131 SendModelToRenderers(); // always refresh the renderer state | 126 SendModelToRenderers(); // always refresh the renderer state |
| 132 if (enabled == enabled_) | 127 if (enabled == enabled_) |
| 133 return; | 128 return; |
| 134 enabled_ = enabled; | 129 enabled_ = enabled; |
| 135 if (enabled_) { | 130 if (enabled_) { |
| 136 // Refresh the model when the service is enabled. This can happen when the | 131 // Refresh the model when the service is enabled. This can happen when the |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 | 184 |
| 190 bool ClientSideDetectionService::IsPrivateIPAddress( | 185 bool ClientSideDetectionService::IsPrivateIPAddress( |
| 191 const std::string& ip_address) const { | 186 const std::string& ip_address) const { |
| 192 net::IPAddressNumber ip_number; | 187 net::IPAddressNumber ip_number; |
| 193 if (!net::ParseIPLiteralToNumber(ip_address, &ip_number)) { | 188 if (!net::ParseIPLiteralToNumber(ip_address, &ip_number)) { |
| 194 VLOG(2) << "Unable to parse IP address: '" << ip_address << "'"; | 189 VLOG(2) << "Unable to parse IP address: '" << ip_address << "'"; |
| 195 // Err on the side of safety and assume this might be private. | 190 // Err on the side of safety and assume this might be private. |
| 196 return true; | 191 return true; |
| 197 } | 192 } |
| 198 | 193 |
| 199 for (std::vector<AddressRange>::const_iterator it = | 194 return net::IsIPAddressReserved(ip_number); |
| 200 private_networks_.begin(); | |
| 201 it != private_networks_.end(); ++it) { | |
| 202 if (net::IPNumberMatchesPrefix(ip_number, it->first, it->second)) { | |
| 203 return true; | |
| 204 } | |
| 205 } | |
| 206 return false; | |
| 207 } | 195 } |
| 208 | 196 |
| 209 void ClientSideDetectionService::OnURLFetchComplete( | 197 void ClientSideDetectionService::OnURLFetchComplete( |
| 210 const net::URLFetcher* source) { | 198 const net::URLFetcher* source) { |
| 211 std::string data; | 199 std::string data; |
| 212 source->GetResponseAsString(&data); | 200 source->GetResponseAsString(&data); |
| 213 if (source == model_fetcher_.get()) { | 201 if (source == model_fetcher_.get()) { |
| 214 HandleModelResponse( | 202 HandleModelResponse( |
| 215 source, source->GetURL(), source->GetStatus(), | 203 source, source->GetURL(), source->GetStatus(), |
| 216 source->GetResponseCode(), source->GetCookies(), data); | 204 source->GetResponseCode(), source->GetCookies(), data); |
| (...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 587 // Erase items older than cutoff because we will never care about them again. | 575 // Erase items older than cutoff because we will never care about them again. |
| 588 while (!report_times->empty() && | 576 while (!report_times->empty() && |
| 589 report_times->front() < cutoff) { | 577 report_times->front() < cutoff) { |
| 590 report_times->pop(); | 578 report_times->pop(); |
| 591 } | 579 } |
| 592 | 580 |
| 593 // Return the number of elements that are above the cutoff. | 581 // Return the number of elements that are above the cutoff. |
| 594 return report_times->size(); | 582 return report_times->size(); |
| 595 } | 583 } |
| 596 | 584 |
| 597 bool ClientSideDetectionService::InitializePrivateNetworks() { | |
| 598 static const char* const kPrivateNetworks[] = { | |
| 599 "10.0.0.0/8", | |
| 600 "127.0.0.0/8", | |
| 601 "172.16.0.0/12", | |
| 602 "192.168.0.0/16", | |
| 603 // IPv6 address ranges | |
| 604 "fc00::/7", | |
| 605 "fec0::/10", | |
| 606 "::1/128", | |
| 607 }; | |
| 608 | |
| 609 for (size_t i = 0; i < arraysize(kPrivateNetworks); ++i) { | |
| 610 net::IPAddressNumber ip_number; | |
| 611 size_t prefix_length; | |
| 612 if (net::ParseCIDRBlock(kPrivateNetworks[i], &ip_number, &prefix_length)) { | |
| 613 private_networks_.push_back(std::make_pair(ip_number, prefix_length)); | |
| 614 } else { | |
| 615 DLOG(FATAL) << "Unable to parse IP address range: " | |
| 616 << kPrivateNetworks[i]; | |
| 617 return false; | |
| 618 } | |
| 619 } | |
| 620 return true; | |
| 621 } | |
| 622 | |
| 623 // static | 585 // static |
| 624 void ClientSideDetectionService::SetBadSubnets(const ClientSideModel& model, | 586 void ClientSideDetectionService::SetBadSubnets(const ClientSideModel& model, |
| 625 BadSubnetMap* bad_subnets) { | 587 BadSubnetMap* bad_subnets) { |
| 626 bad_subnets->clear(); | 588 bad_subnets->clear(); |
| 627 for (int i = 0; i < model.bad_subnet_size(); ++i) { | 589 for (int i = 0; i < model.bad_subnet_size(); ++i) { |
| 628 int size = model.bad_subnet(i).size(); | 590 int size = model.bad_subnet(i).size(); |
| 629 if (size < 0 || size > static_cast<int>(net::kIPv6AddressSize) * 8) { | 591 if (size < 0 || size > static_cast<int>(net::kIPv6AddressSize) * 8) { |
| 630 DLOG(ERROR) << "Invalid bad subnet size: " << size; | 592 DLOG(ERROR) << "Invalid bad subnet size: " << size; |
| 631 continue; | 593 continue; |
| 632 } | 594 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 671 GURL ClientSideDetectionService::GetClientReportUrl( | 633 GURL ClientSideDetectionService::GetClientReportUrl( |
| 672 const std::string& report_url) { | 634 const std::string& report_url) { |
| 673 GURL url(report_url); | 635 GURL url(report_url); |
| 674 std::string api_key = google_apis::GetAPIKey(); | 636 std::string api_key = google_apis::GetAPIKey(); |
| 675 if (!api_key.empty()) | 637 if (!api_key.empty()) |
| 676 url = url.Resolve("?key=" + net::EscapeQueryParamValue(api_key, true)); | 638 url = url.Resolve("?key=" + net::EscapeQueryParamValue(api_key, true)); |
| 677 | 639 |
| 678 return url; | 640 return url; |
| 679 } | 641 } |
| 680 } // namespace safe_browsing | 642 } // namespace safe_browsing |
| OLD | NEW |