| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 base::TimeDelta::FromDays(1); | 53 base::TimeDelta::FromDays(1); |
| 54 const base::TimeDelta ClientSideDetectionService::kPositiveCacheInterval = | 54 const base::TimeDelta ClientSideDetectionService::kPositiveCacheInterval = |
| 55 base::TimeDelta::FromMinutes(30); | 55 base::TimeDelta::FromMinutes(30); |
| 56 | 56 |
| 57 const char ClientSideDetectionService::kClientReportPhishingUrl[] = | 57 const char ClientSideDetectionService::kClientReportPhishingUrl[] = |
| 58 "https://sb-ssl.google.com/safebrowsing/clientreport/phishing"; | 58 "https://sb-ssl.google.com/safebrowsing/clientreport/phishing"; |
| 59 const char ClientSideDetectionService::kClientModelUrl[] = | 59 const char ClientSideDetectionService::kClientModelUrl[] = |
| 60 "https://ssl.gstatic.com/safebrowsing/csd/client_model_v4.pb"; | 60 "https://ssl.gstatic.com/safebrowsing/csd/client_model_v4.pb"; |
| 61 | 61 |
| 62 struct ClientSideDetectionService::ClientReportInfo { | 62 struct ClientSideDetectionService::ClientReportInfo { |
| 63 scoped_ptr<ClientReportPhishingRequestCallback> callback; | 63 ClientReportPhishingRequestCallback callback; |
| 64 GURL phishing_url; | 64 GURL phishing_url; |
| 65 }; | 65 }; |
| 66 | 66 |
| 67 ClientSideDetectionService::CacheState::CacheState(bool phish, base::Time time) | 67 ClientSideDetectionService::CacheState::CacheState(bool phish, base::Time time) |
| 68 : is_phishing(phish), | 68 : is_phishing(phish), |
| 69 timestamp(time) {} | 69 timestamp(time) {} |
| 70 | 70 |
| 71 ClientSideDetectionService::ClientSideDetectionService( | 71 ClientSideDetectionService::ClientSideDetectionService( |
| 72 net::URLRequestContextGetter* request_context_getter) | 72 net::URLRequestContextGetter* request_context_getter) |
| 73 : enabled_(false), | 73 : enabled_(false), |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 // We delay the first model fetch to avoid slowing down browser startup. | 111 // We delay the first model fetch to avoid slowing down browser startup. |
| 112 ScheduleFetchModel(kInitialClientModelFetchDelayMs); | 112 ScheduleFetchModel(kInitialClientModelFetchDelayMs); |
| 113 } else { | 113 } else { |
| 114 // Cancel pending requests. | 114 // Cancel pending requests. |
| 115 model_fetcher_.reset(); | 115 model_fetcher_.reset(); |
| 116 // Invoke pending callbacks with a false verdict. | 116 // Invoke pending callbacks with a false verdict. |
| 117 for (std::map<const content::URLFetcher*, ClientReportInfo*>::iterator it = | 117 for (std::map<const content::URLFetcher*, ClientReportInfo*>::iterator it = |
| 118 client_phishing_reports_.begin(); | 118 client_phishing_reports_.begin(); |
| 119 it != client_phishing_reports_.end(); ++it) { | 119 it != client_phishing_reports_.end(); ++it) { |
| 120 ClientReportInfo* info = it->second; | 120 ClientReportInfo* info = it->second; |
| 121 if (info->callback.get()) | 121 if (!info->callback.is_null()) |
| 122 info->callback->Run(info->phishing_url, false); | 122 info->callback.Run(info->phishing_url, false); |
| 123 } | 123 } |
| 124 STLDeleteContainerPairPointers(client_phishing_reports_.begin(), | 124 STLDeleteContainerPairPointers(client_phishing_reports_.begin(), |
| 125 client_phishing_reports_.end()); | 125 client_phishing_reports_.end()); |
| 126 client_phishing_reports_.clear(); | 126 client_phishing_reports_.clear(); |
| 127 cache_.clear(); | 127 cache_.clear(); |
| 128 } | 128 } |
| 129 } | 129 } |
| 130 | 130 |
| 131 void ClientSideDetectionService::SendClientReportPhishingRequest( | 131 void ClientSideDetectionService::SendClientReportPhishingRequest( |
| 132 ClientPhishingRequest* verdict, | 132 ClientPhishingRequest* verdict, |
| 133 ClientReportPhishingRequestCallback* callback) { | 133 const ClientReportPhishingRequestCallback& callback) { |
| 134 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 134 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 135 MessageLoop::current()->PostTask( | 135 MessageLoop::current()->PostTask( |
| 136 FROM_HERE, | 136 FROM_HERE, |
| 137 base::Bind(&ClientSideDetectionService::StartClientReportPhishingRequest, | 137 base::Bind(&ClientSideDetectionService::StartClientReportPhishingRequest, |
| 138 weak_factory_.GetWeakPtr(), verdict, callback)); | 138 weak_factory_.GetWeakPtr(), verdict, callback)); |
| 139 } | 139 } |
| 140 | 140 |
| 141 bool ClientSideDetectionService::IsPrivateIPAddress( | 141 bool ClientSideDetectionService::IsPrivateIPAddress( |
| 142 const std::string& ip_address) const { | 142 const std::string& ip_address) const { |
| 143 net::IPAddressNumber ip_number; | 143 net::IPAddressNumber ip_number; |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 delay_ms = model_max_age_->InMilliseconds(); | 282 delay_ms = model_max_age_->InMilliseconds(); |
| 283 } | 283 } |
| 284 model_max_age_.reset(); | 284 model_max_age_.reset(); |
| 285 | 285 |
| 286 // Schedule the next model reload. | 286 // Schedule the next model reload. |
| 287 ScheduleFetchModel(delay_ms); | 287 ScheduleFetchModel(delay_ms); |
| 288 } | 288 } |
| 289 | 289 |
| 290 void ClientSideDetectionService::StartClientReportPhishingRequest( | 290 void ClientSideDetectionService::StartClientReportPhishingRequest( |
| 291 ClientPhishingRequest* verdict, | 291 ClientPhishingRequest* verdict, |
| 292 ClientReportPhishingRequestCallback* callback) { | 292 const ClientReportPhishingRequestCallback& callback) { |
| 293 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 293 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 294 scoped_ptr<ClientPhishingRequest> request(verdict); | 294 scoped_ptr<ClientPhishingRequest> request(verdict); |
| 295 scoped_ptr<ClientReportPhishingRequestCallback> cb(callback); | |
| 296 | 295 |
| 297 if (!enabled_) { | 296 if (!enabled_) { |
| 298 if (cb.get()) | 297 if (!callback.is_null()) |
| 299 cb->Run(GURL(request->url()), false); | 298 callback.Run(GURL(request->url()), false); |
| 300 return; | 299 return; |
| 301 } | 300 } |
| 302 | 301 |
| 303 std::string request_data; | 302 std::string request_data; |
| 304 if (!request->SerializeToString(&request_data)) { | 303 if (!request->SerializeToString(&request_data)) { |
| 305 UMA_HISTOGRAM_COUNTS("SBClientPhishing.RequestNotSerialized", 1); | 304 UMA_HISTOGRAM_COUNTS("SBClientPhishing.RequestNotSerialized", 1); |
| 306 VLOG(1) << "Unable to serialize the CSD request. Proto file changed?"; | 305 VLOG(1) << "Unable to serialize the CSD request. Proto file changed?"; |
| 307 if (cb.get()) { | 306 if (!callback.is_null()) |
| 308 cb->Run(GURL(request->url()), false); | 307 callback.Run(GURL(request->url()), false); |
| 309 } | |
| 310 return; | 308 return; |
| 311 } | 309 } |
| 312 | 310 |
| 313 content::URLFetcher* fetcher = content::URLFetcher::Create( | 311 content::URLFetcher* fetcher = content::URLFetcher::Create( |
| 314 0 /* ID used for testing */, GURL(kClientReportPhishingUrl), | 312 0 /* ID used for testing */, GURL(kClientReportPhishingUrl), |
| 315 content::URLFetcher::POST, this); | 313 content::URLFetcher::POST, this); |
| 316 | 314 |
| 317 // Remember which callback and URL correspond to the current fetcher object. | 315 // Remember which callback and URL correspond to the current fetcher object. |
| 318 ClientReportInfo* info = new ClientReportInfo; | 316 ClientReportInfo* info = new ClientReportInfo; |
| 319 info->callback.swap(cb); // takes ownership of the callback. | 317 info->callback = callback; |
| 320 info->phishing_url = GURL(request->url()); | 318 info->phishing_url = GURL(request->url()); |
| 321 client_phishing_reports_[fetcher] = info; | 319 client_phishing_reports_[fetcher] = info; |
| 322 | 320 |
| 323 fetcher->SetLoadFlags(net::LOAD_DISABLE_CACHE); | 321 fetcher->SetLoadFlags(net::LOAD_DISABLE_CACHE); |
| 324 fetcher->SetRequestContext(request_context_getter_.get()); | 322 fetcher->SetRequestContext(request_context_getter_.get()); |
| 325 fetcher->SetUploadData("application/octet-stream", request_data); | 323 fetcher->SetUploadData("application/octet-stream", request_data); |
| 326 fetcher->Start(); | 324 fetcher->Start(); |
| 327 | 325 |
| 328 // Record that we made a request | 326 // Record that we made a request |
| 329 phishing_report_times_.push(base::Time::Now()); | 327 phishing_report_times_.push(base::Time::Now()); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 385 // Cache response, possibly flushing an old one. | 383 // Cache response, possibly flushing an old one. |
| 386 cache_[info->phishing_url] = | 384 cache_[info->phishing_url] = |
| 387 make_linked_ptr(new CacheState(response.phishy(), base::Time::Now())); | 385 make_linked_ptr(new CacheState(response.phishy(), base::Time::Now())); |
| 388 is_phishing = (response.phishy() && | 386 is_phishing = (response.phishy() && |
| 389 !IsFalsePositiveResponse(info->phishing_url, response)); | 387 !IsFalsePositiveResponse(info->phishing_url, response)); |
| 390 } else { | 388 } else { |
| 391 DLOG(ERROR) << "Unable to get the server verdict for URL: " | 389 DLOG(ERROR) << "Unable to get the server verdict for URL: " |
| 392 << info->phishing_url << " status: " << status.status() << " " | 390 << info->phishing_url << " status: " << status.status() << " " |
| 393 << "response_code:" << response_code; | 391 << "response_code:" << response_code; |
| 394 } | 392 } |
| 395 if (info->callback.get()) { | 393 if (!info->callback.is_null()) |
| 396 info->callback->Run(info->phishing_url, is_phishing); | 394 info->callback.Run(info->phishing_url, is_phishing); |
| 397 } | |
| 398 client_phishing_reports_.erase(source); | 395 client_phishing_reports_.erase(source); |
| 399 delete source; | 396 delete source; |
| 400 } | 397 } |
| 401 | 398 |
| 402 bool ClientSideDetectionService::IsInCache(const GURL& url) { | 399 bool ClientSideDetectionService::IsInCache(const GURL& url) { |
| 403 UpdateCache(); | 400 UpdateCache(); |
| 404 | 401 |
| 405 return cache_.find(url) != cache_.end(); | 402 return cache_.find(url) != cache_.end(); |
| 406 } | 403 } |
| 407 | 404 |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 577 &whitelist_patterns); | 574 &whitelist_patterns); |
| 578 for (size_t j = 0; j < whitelist_patterns.size(); ++j) { | 575 for (size_t j = 0; j < whitelist_patterns.size(); ++j) { |
| 579 if (whitelist_patterns[j] == canonical_url_as_pattern) { | 576 if (whitelist_patterns[j] == canonical_url_as_pattern) { |
| 580 return true; | 577 return true; |
| 581 } | 578 } |
| 582 } | 579 } |
| 583 } | 580 } |
| 584 return false; | 581 return false; |
| 585 } | 582 } |
| 586 } // namespace safe_browsing | 583 } // namespace safe_browsing |
| OLD | NEW |