| 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 <algorithm> | 7 #include <algorithm> |
| 8 #include <memory> | 8 #include <memory> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/location.h" | 11 #include "base/location.h" |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/memory/ptr_util.h" |
| 13 #include "base/metrics/histogram.h" | 14 #include "base/metrics/histogram.h" |
| 14 #include "base/metrics/sparse_histogram.h" | 15 #include "base/metrics/sparse_histogram.h" |
| 15 #include "base/single_thread_task_runner.h" | 16 #include "base/single_thread_task_runner.h" |
| 16 #include "base/stl_util.h" | 17 #include "base/stl_util.h" |
| 17 #include "base/threading/thread_task_runner_handle.h" | 18 #include "base/threading/thread_task_runner_handle.h" |
| 18 #include "base/time/time.h" | 19 #include "base/time/time.h" |
| 19 #include "chrome/browser/browser_process.h" | 20 #include "chrome/browser/browser_process.h" |
| 20 #include "chrome/browser/profiles/profile.h" | 21 #include "chrome/browser/profiles/profile.h" |
| 21 #include "chrome/common/pref_names.h" | 22 #include "chrome/common/pref_names.h" |
| 22 #include "chrome/common/safe_browsing/client_model.pb.h" | 23 #include "chrome/common/safe_browsing/client_model.pb.h" |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 const int ClientSideDetectionService::kReportsIntervalDays = 1; | 68 const int ClientSideDetectionService::kReportsIntervalDays = 1; |
| 68 const int ClientSideDetectionService::kMaxReportsPerInterval = 3; | 69 const int ClientSideDetectionService::kMaxReportsPerInterval = 3; |
| 69 const int ClientSideDetectionService::kNegativeCacheIntervalDays = 1; | 70 const int ClientSideDetectionService::kNegativeCacheIntervalDays = 1; |
| 70 const int ClientSideDetectionService::kPositiveCacheIntervalMinutes = 30; | 71 const int ClientSideDetectionService::kPositiveCacheIntervalMinutes = 30; |
| 71 | 72 |
| 72 const char ClientSideDetectionService::kClientReportPhishingUrl[] = | 73 const char ClientSideDetectionService::kClientReportPhishingUrl[] = |
| 73 "https://sb-ssl.google.com/safebrowsing/clientreport/phishing"; | 74 "https://sb-ssl.google.com/safebrowsing/clientreport/phishing"; |
| 74 const char ClientSideDetectionService::kClientReportMalwareUrl[] = | 75 const char ClientSideDetectionService::kClientReportMalwareUrl[] = |
| 75 "https://sb-ssl.google.com/safebrowsing/clientreport/malware-check"; | 76 "https://sb-ssl.google.com/safebrowsing/clientreport/malware-check"; |
| 76 | 77 |
| 77 struct ClientSideDetectionService::ClientReportInfo { | 78 struct ClientSideDetectionService::ClientPhishingReportInfo { |
| 79 std::unique_ptr<net::URLFetcher> fetcher; |
| 78 ClientReportPhishingRequestCallback callback; | 80 ClientReportPhishingRequestCallback callback; |
| 79 GURL phishing_url; | 81 GURL phishing_url; |
| 80 }; | 82 }; |
| 81 | 83 |
| 82 struct ClientSideDetectionService::ClientMalwareReportInfo { | 84 struct ClientSideDetectionService::ClientMalwareReportInfo { |
| 85 std::unique_ptr<net::URLFetcher> fetcher; |
| 83 ClientReportMalwareRequestCallback callback; | 86 ClientReportMalwareRequestCallback callback; |
| 84 // This is the original landing url, may not be the malware url. | 87 // This is the original landing url, may not be the malware url. |
| 85 GURL original_url; | 88 GURL original_url; |
| 86 }; | 89 }; |
| 87 | 90 |
| 88 ClientSideDetectionService::CacheState::CacheState(bool phish, base::Time time) | 91 ClientSideDetectionService::CacheState::CacheState(bool phish, base::Time time) |
| 89 : is_phishing(phish), | 92 : is_phishing(phish), |
| 90 timestamp(time) {} | 93 timestamp(time) {} |
| 91 | 94 |
| 92 ClientSideDetectionService::ClientSideDetectionService( | 95 ClientSideDetectionService::ClientSideDetectionService( |
| 93 net::URLRequestContextGetter* request_context_getter) | 96 net::URLRequestContextGetter* request_context_getter) |
| 94 : enabled_(false), | 97 : enabled_(false), |
| 95 request_context_getter_(request_context_getter), | 98 request_context_getter_(request_context_getter), |
| 96 weak_factory_(this) { | 99 weak_factory_(this) { |
| 97 base::Closure update_renderers = | 100 base::Closure update_renderers = |
| 98 base::Bind(&ClientSideDetectionService::SendModelToRenderers, | 101 base::Bind(&ClientSideDetectionService::SendModelToRenderers, |
| 99 base::Unretained(this)); | 102 base::Unretained(this)); |
| 100 model_loader_standard_.reset( | 103 model_loader_standard_.reset( |
| 101 new ModelLoader(update_renderers, request_context_getter, false)); | 104 new ModelLoader(update_renderers, request_context_getter, false)); |
| 102 model_loader_extended_.reset( | 105 model_loader_extended_.reset( |
| 103 new ModelLoader(update_renderers, request_context_getter, true)); | 106 new ModelLoader(update_renderers, request_context_getter, true)); |
| 104 | 107 |
| 105 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CREATED, | 108 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CREATED, |
| 106 content::NotificationService::AllBrowserContextsAndSources()); | 109 content::NotificationService::AllBrowserContextsAndSources()); |
| 107 } | 110 } |
| 108 | 111 |
| 109 ClientSideDetectionService::~ClientSideDetectionService() { | 112 ClientSideDetectionService::~ClientSideDetectionService() { |
| 110 weak_factory_.InvalidateWeakPtrs(); | 113 weak_factory_.InvalidateWeakPtrs(); |
| 111 base::STLDeleteContainerPairPointers(client_phishing_reports_.begin(), | |
| 112 client_phishing_reports_.end()); | |
| 113 client_phishing_reports_.clear(); | |
| 114 base::STLDeleteContainerPairPointers(client_malware_reports_.begin(), | |
| 115 client_malware_reports_.end()); | |
| 116 client_malware_reports_.clear(); | |
| 117 } | 114 } |
| 118 | 115 |
| 119 // static | 116 // static |
| 120 ClientSideDetectionService* ClientSideDetectionService::Create( | 117 ClientSideDetectionService* ClientSideDetectionService::Create( |
| 121 net::URLRequestContextGetter* request_context_getter) { | 118 net::URLRequestContextGetter* request_context_getter) { |
| 122 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 119 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 123 return new ClientSideDetectionService(request_context_getter); | 120 return new ClientSideDetectionService(request_context_getter); |
| 124 } | 121 } |
| 125 | 122 |
| 126 void ClientSideDetectionService::SetEnabledAndRefreshState(bool enabled) { | 123 void ClientSideDetectionService::SetEnabledAndRefreshState(bool enabled) { |
| 127 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 124 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 128 SendModelToRenderers(); // always refresh the renderer state | 125 SendModelToRenderers(); // always refresh the renderer state |
| 129 if (enabled == enabled_) | 126 if (enabled == enabled_) |
| 130 return; | 127 return; |
| 131 enabled_ = enabled; | 128 enabled_ = enabled; |
| 132 if (enabled_) { | 129 if (enabled_) { |
| 133 // Refresh the models when the service is enabled. This can happen when | 130 // Refresh the models when the service is enabled. This can happen when |
| 134 // either of the preferences are toggled, or early during startup if | 131 // either of the preferences are toggled, or early during startup if |
| 135 // safe browsing is already enabled. In a lot of cases the model will be | 132 // safe browsing is already enabled. In a lot of cases the model will be |
| 136 // in the cache so it won't actually be fetched from the network. | 133 // in the cache so it won't actually be fetched from the network. |
| 137 // We delay the first model fetches to avoid slowing down browser startup. | 134 // We delay the first model fetches to avoid slowing down browser startup. |
| 138 model_loader_standard_->ScheduleFetch(kInitialClientModelFetchDelayMs); | 135 model_loader_standard_->ScheduleFetch(kInitialClientModelFetchDelayMs); |
| 139 model_loader_extended_->ScheduleFetch(kInitialClientModelFetchDelayMs); | 136 model_loader_extended_->ScheduleFetch(kInitialClientModelFetchDelayMs); |
| 140 } else { | 137 } else { |
| 141 // Cancel model loads in progress. | 138 // Cancel model loads in progress. |
| 142 model_loader_standard_->CancelFetcher(); | 139 model_loader_standard_->CancelFetcher(); |
| 143 model_loader_extended_->CancelFetcher(); | 140 model_loader_extended_->CancelFetcher(); |
| 144 // Invoke pending callbacks with a false verdict. | 141 // Invoke pending callbacks with a false verdict. |
| 145 for (std::map<const net::URLFetcher*, ClientReportInfo*>::iterator it = | 142 for (auto it = client_phishing_reports_.begin(); |
| 146 client_phishing_reports_.begin(); | |
| 147 it != client_phishing_reports_.end(); ++it) { | 143 it != client_phishing_reports_.end(); ++it) { |
| 148 ClientReportInfo* info = it->second; | 144 ClientPhishingReportInfo* info = it->second.get(); |
| 149 if (!info->callback.is_null()) | 145 if (!info->callback.is_null()) |
| 150 info->callback.Run(info->phishing_url, false); | 146 info->callback.Run(info->phishing_url, false); |
| 151 } | 147 } |
| 152 base::STLDeleteContainerPairPointers(client_phishing_reports_.begin(), | |
| 153 client_phishing_reports_.end()); | |
| 154 client_phishing_reports_.clear(); | 148 client_phishing_reports_.clear(); |
| 155 for (std::map<const net::URLFetcher*, ClientMalwareReportInfo*>::iterator it | 149 for (auto it = client_malware_reports_.begin(); |
| 156 = client_malware_reports_.begin(); | |
| 157 it != client_malware_reports_.end(); ++it) { | 150 it != client_malware_reports_.end(); ++it) { |
| 158 ClientMalwareReportInfo* info = it->second; | 151 ClientMalwareReportInfo* info = it->second.get(); |
| 159 if (!info->callback.is_null()) | 152 if (!info->callback.is_null()) |
| 160 info->callback.Run(info->original_url, info->original_url, false); | 153 info->callback.Run(info->original_url, info->original_url, false); |
| 161 } | 154 } |
| 162 base::STLDeleteContainerPairPointers(client_malware_reports_.begin(), | |
| 163 client_malware_reports_.end()); | |
| 164 client_malware_reports_.clear(); | 155 client_malware_reports_.clear(); |
| 165 cache_.clear(); | 156 cache_.clear(); |
| 166 } | 157 } |
| 167 } | 158 } |
| 168 | 159 |
| 169 void ClientSideDetectionService::SendClientReportPhishingRequest( | 160 void ClientSideDetectionService::SendClientReportPhishingRequest( |
| 170 ClientPhishingRequest* verdict, | 161 ClientPhishingRequest* verdict, |
| 171 bool is_extended_reporting, | 162 bool is_extended_reporting, |
| 172 const ClientReportPhishingRequestCallback& callback) { | 163 const ClientReportPhishingRequestCallback& callback) { |
| 173 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 164 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 198 } | 189 } |
| 199 | 190 |
| 200 return address.IsReserved(); | 191 return address.IsReserved(); |
| 201 } | 192 } |
| 202 | 193 |
| 203 void ClientSideDetectionService::OnURLFetchComplete( | 194 void ClientSideDetectionService::OnURLFetchComplete( |
| 204 const net::URLFetcher* source) { | 195 const net::URLFetcher* source) { |
| 205 std::string data; | 196 std::string data; |
| 206 source->GetResponseAsString(&data); | 197 source->GetResponseAsString(&data); |
| 207 | 198 |
| 208 if (client_phishing_reports_.find(source) != client_phishing_reports_.end()) { | 199 if (base::ContainsKey(client_phishing_reports_, source)) { |
| 209 HandlePhishingVerdict(source, source->GetURL(), source->GetStatus(), | 200 HandlePhishingVerdict(source, source->GetURL(), source->GetStatus(), |
| 210 source->GetResponseCode(), data); | 201 source->GetResponseCode(), data); |
| 211 } else if (client_malware_reports_.find(source) != | 202 } else if (base::ContainsKey(client_malware_reports_, source)) { |
| 212 client_malware_reports_.end()) { | |
| 213 HandleMalwareVerdict(source, source->GetURL(), source->GetStatus(), | 203 HandleMalwareVerdict(source, source->GetURL(), source->GetStatus(), |
| 214 source->GetResponseCode(), data); | 204 source->GetResponseCode(), data); |
| 215 } else { | 205 } else { |
| 216 NOTREACHED(); | 206 NOTREACHED(); |
| 217 } | 207 } |
| 218 } | 208 } |
| 219 | 209 |
| 220 void ClientSideDetectionService::Observe( | 210 void ClientSideDetectionService::Observe( |
| 221 int type, | 211 int type, |
| 222 const content::NotificationSource& source, | 212 const content::NotificationSource& source, |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 | 278 |
| 289 std::string request_data; | 279 std::string request_data; |
| 290 if (!request->SerializeToString(&request_data)) { | 280 if (!request->SerializeToString(&request_data)) { |
| 291 UMA_HISTOGRAM_COUNTS("SBClientPhishing.RequestNotSerialized", 1); | 281 UMA_HISTOGRAM_COUNTS("SBClientPhishing.RequestNotSerialized", 1); |
| 292 DVLOG(1) << "Unable to serialize the CSD request. Proto file changed?"; | 282 DVLOG(1) << "Unable to serialize the CSD request. Proto file changed?"; |
| 293 if (!callback.is_null()) | 283 if (!callback.is_null()) |
| 294 callback.Run(GURL(request->url()), false); | 284 callback.Run(GURL(request->url()), false); |
| 295 return; | 285 return; |
| 296 } | 286 } |
| 297 | 287 |
| 298 net::URLFetcher* fetcher = | 288 std::unique_ptr<net::URLFetcher> fetcher( |
| 299 net::URLFetcher::Create(0 /* ID used for testing */, | 289 net::URLFetcher::Create(0 /* ID used for testing */, |
| 300 GetClientReportUrl(kClientReportPhishingUrl), | 290 GetClientReportUrl(kClientReportPhishingUrl), |
| 301 net::URLFetcher::POST, this).release(); | 291 net::URLFetcher::POST, this)); |
| 292 net::URLFetcher* fetcher_ptr = fetcher.get(); |
| 302 | 293 |
| 303 // Remember which callback and URL correspond to the current fetcher object. | 294 // Remember which callback and URL correspond to the current fetcher object. |
| 304 ClientReportInfo* info = new ClientReportInfo; | 295 std::unique_ptr<ClientPhishingReportInfo> info(new ClientPhishingReportInfo); |
| 296 info->fetcher = std::move(fetcher); |
| 305 info->callback = callback; | 297 info->callback = callback; |
| 306 info->phishing_url = GURL(request->url()); | 298 info->phishing_url = GURL(request->url()); |
| 307 client_phishing_reports_[fetcher] = info; | 299 client_phishing_reports_[fetcher_ptr] = std::move(info); |
| 308 | 300 |
| 309 fetcher->SetLoadFlags(net::LOAD_DISABLE_CACHE); | 301 fetcher_ptr->SetLoadFlags(net::LOAD_DISABLE_CACHE); |
| 310 fetcher->SetRequestContext(request_context_getter_.get()); | 302 fetcher_ptr->SetRequestContext(request_context_getter_.get()); |
| 311 fetcher->SetUploadData("application/octet-stream", request_data); | 303 fetcher_ptr->SetUploadData("application/octet-stream", request_data); |
| 312 fetcher->Start(); | 304 fetcher_ptr->Start(); |
| 313 | 305 |
| 314 // Record that we made a request | 306 // Record that we made a request |
| 315 phishing_report_times_.push(base::Time::Now()); | 307 phishing_report_times_.push(base::Time::Now()); |
| 316 } | 308 } |
| 317 | 309 |
| 318 void ClientSideDetectionService::StartClientReportMalwareRequest( | 310 void ClientSideDetectionService::StartClientReportMalwareRequest( |
| 319 ClientMalwareRequest* verdict, | 311 ClientMalwareRequest* verdict, |
| 320 const ClientReportMalwareRequestCallback& callback) { | 312 const ClientReportMalwareRequestCallback& callback) { |
| 321 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 313 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 322 std::unique_ptr<ClientMalwareRequest> request(verdict); | 314 std::unique_ptr<ClientMalwareRequest> request(verdict); |
| 323 | 315 |
| 324 if (!enabled_) { | 316 if (!enabled_) { |
| 325 if (!callback.is_null()) | 317 if (!callback.is_null()) |
| 326 callback.Run(GURL(request->url()), GURL(request->url()), false); | 318 callback.Run(GURL(request->url()), GURL(request->url()), false); |
| 327 return; | 319 return; |
| 328 } | 320 } |
| 329 | 321 |
| 330 std::string request_data; | 322 std::string request_data; |
| 331 if (!request->SerializeToString(&request_data)) { | 323 if (!request->SerializeToString(&request_data)) { |
| 332 UpdateEnumUMAHistogram(REPORT_FAILED_SERIALIZATION); | 324 UpdateEnumUMAHistogram(REPORT_FAILED_SERIALIZATION); |
| 333 DVLOG(1) << "Unable to serialize the CSD request. Proto file changed?"; | 325 DVLOG(1) << "Unable to serialize the CSD request. Proto file changed?"; |
| 334 if (!callback.is_null()) | 326 if (!callback.is_null()) |
| 335 callback.Run(GURL(request->url()), GURL(request->url()), false); | 327 callback.Run(GURL(request->url()), GURL(request->url()), false); |
| 336 return; | 328 return; |
| 337 } | 329 } |
| 338 | 330 |
| 339 net::URLFetcher* fetcher = | 331 std::unique_ptr<net::URLFetcher> fetcher( |
| 340 net::URLFetcher::Create(0 /* ID used for testing */, | 332 net::URLFetcher::Create(0 /* ID used for testing */, |
| 341 GetClientReportUrl(kClientReportMalwareUrl), | 333 GetClientReportUrl(kClientReportMalwareUrl), |
| 342 net::URLFetcher::POST, this).release(); | 334 net::URLFetcher::POST, this)); |
| 335 net::URLFetcher* fetcher_ptr = fetcher.get(); |
| 343 | 336 |
| 344 // Remember which callback and URL correspond to the current fetcher object. | 337 // Remember which callback and URL correspond to the current fetcher object. |
| 345 ClientMalwareReportInfo* info = new ClientMalwareReportInfo; | 338 std::unique_ptr<ClientMalwareReportInfo> info(new ClientMalwareReportInfo); |
| 339 info->fetcher = std::move(fetcher); |
| 346 info->callback = callback; | 340 info->callback = callback; |
| 347 info->original_url = GURL(request->url()); | 341 info->original_url = GURL(request->url()); |
| 348 client_malware_reports_[fetcher] = info; | 342 client_malware_reports_[fetcher_ptr] = std::move(info); |
| 349 | 343 |
| 350 fetcher->SetLoadFlags(net::LOAD_DISABLE_CACHE); | 344 fetcher_ptr->SetLoadFlags(net::LOAD_DISABLE_CACHE); |
| 351 fetcher->SetRequestContext(request_context_getter_.get()); | 345 fetcher_ptr->SetRequestContext(request_context_getter_.get()); |
| 352 fetcher->SetUploadData("application/octet-stream", request_data); | 346 fetcher_ptr->SetUploadData("application/octet-stream", request_data); |
| 353 fetcher->Start(); | 347 fetcher_ptr->Start(); |
| 354 | 348 |
| 355 UMA_HISTOGRAM_ENUMERATION("SBClientMalware.SentReports", | 349 UMA_HISTOGRAM_ENUMERATION("SBClientMalware.SentReports", |
| 356 REPORT_SENT, REPORT_RESULT_MAX); | 350 REPORT_SENT, REPORT_RESULT_MAX); |
| 357 | 351 |
| 358 UMA_HISTOGRAM_COUNTS("SBClientMalware.IPBlacklistRequestPayloadSize", | 352 UMA_HISTOGRAM_COUNTS("SBClientMalware.IPBlacklistRequestPayloadSize", |
| 359 request_data.size()); | 353 request_data.size()); |
| 360 | 354 |
| 361 // Record that we made a malware request | 355 // Record that we made a malware request |
| 362 malware_report_times_.push(base::Time::Now()); | 356 malware_report_times_.push(base::Time::Now()); |
| 363 } | 357 } |
| 364 | 358 |
| 365 | 359 |
| 366 void ClientSideDetectionService::HandlePhishingVerdict( | 360 void ClientSideDetectionService::HandlePhishingVerdict( |
| 367 const net::URLFetcher* source, | 361 const net::URLFetcher* source, |
| 368 const GURL& url, | 362 const GURL& url, |
| 369 const net::URLRequestStatus& status, | 363 const net::URLRequestStatus& status, |
| 370 int response_code, | 364 int response_code, |
| 371 const std::string& data) { | 365 const std::string& data) { |
| 372 ClientPhishingResponse response; | 366 ClientPhishingResponse response; |
| 373 std::unique_ptr<ClientReportInfo> info(client_phishing_reports_[source]); | 367 std::unique_ptr<ClientPhishingReportInfo> info = |
| 368 std::move(client_phishing_reports_[source]); |
| 369 client_phishing_reports_.erase(source); |
| 370 |
| 374 bool is_phishing = false; | 371 bool is_phishing = false; |
| 375 if (status.is_success() && net::HTTP_OK == response_code && | 372 if (status.is_success() && net::HTTP_OK == response_code && |
| 376 response.ParseFromString(data)) { | 373 response.ParseFromString(data)) { |
| 377 // Cache response, possibly flushing an old one. | 374 // Cache response, possibly flushing an old one. |
| 378 cache_[info->phishing_url] = | 375 cache_[info->phishing_url] = |
| 379 make_linked_ptr(new CacheState(response.phishy(), base::Time::Now())); | 376 base::WrapUnique(new CacheState(response.phishy(), base::Time::Now())); |
| 380 is_phishing = response.phishy(); | 377 is_phishing = response.phishy(); |
| 381 } else { | 378 } else { |
| 382 DLOG(ERROR) << "Unable to get the server verdict for URL: " | 379 DLOG(ERROR) << "Unable to get the server verdict for URL: " |
| 383 << info->phishing_url << " status: " << status.status() << " " | 380 << info->phishing_url << " status: " << status.status() << " " |
| 384 << "response_code:" << response_code; | 381 << "response_code:" << response_code; |
| 385 } | 382 } |
| 386 if (!info->callback.is_null()) | 383 if (!info->callback.is_null()) |
| 387 info->callback.Run(info->phishing_url, is_phishing); | 384 info->callback.Run(info->phishing_url, is_phishing); |
| 388 client_phishing_reports_.erase(source); | |
| 389 delete source; | |
| 390 } | 385 } |
| 391 | 386 |
| 392 void ClientSideDetectionService::HandleMalwareVerdict( | 387 void ClientSideDetectionService::HandleMalwareVerdict( |
| 393 const net::URLFetcher* source, | 388 const net::URLFetcher* source, |
| 394 const GURL& url, | 389 const GURL& url, |
| 395 const net::URLRequestStatus& status, | 390 const net::URLRequestStatus& status, |
| 396 int response_code, | 391 int response_code, |
| 397 const std::string& data) { | 392 const std::string& data) { |
| 398 if (status.is_success()) { | 393 if (status.is_success()) { |
| 399 UMA_HISTOGRAM_SPARSE_SLOWLY( | 394 UMA_HISTOGRAM_SPARSE_SLOWLY( |
| 400 "SBClientMalware.IPBlacklistRequestResponseCode", response_code); | 395 "SBClientMalware.IPBlacklistRequestResponseCode", response_code); |
| 401 } | 396 } |
| 402 // status error is negative, so we put - in front of it. | 397 // status error is negative, so we put - in front of it. |
| 403 UMA_HISTOGRAM_SPARSE_SLOWLY( | 398 UMA_HISTOGRAM_SPARSE_SLOWLY( |
| 404 "SBClientMalware.IPBlacklistRequestNetError", -status.error()); | 399 "SBClientMalware.IPBlacklistRequestNetError", -status.error()); |
| 405 | 400 |
| 406 ClientMalwareResponse response; | 401 ClientMalwareResponse response; |
| 407 std::unique_ptr<ClientMalwareReportInfo> info( | 402 std::unique_ptr<ClientMalwareReportInfo> info = |
| 408 client_malware_reports_[source]); | 403 std::move(client_malware_reports_[source]); |
| 404 client_malware_reports_.erase(source); |
| 405 |
| 409 bool should_blacklist = false; | 406 bool should_blacklist = false; |
| 410 if (status.is_success() && net::HTTP_OK == response_code && | 407 if (status.is_success() && net::HTTP_OK == response_code && |
| 411 response.ParseFromString(data)) { | 408 response.ParseFromString(data)) { |
| 412 should_blacklist = response.blacklist(); | 409 should_blacklist = response.blacklist(); |
| 413 } else { | 410 } else { |
| 414 DLOG(ERROR) << "Unable to get the server verdict for URL: " | 411 DLOG(ERROR) << "Unable to get the server verdict for URL: " |
| 415 << info->original_url << " status: " << status.status() << " " | 412 << info->original_url << " status: " << status.status() << " " |
| 416 << "response_code:" << response_code; | 413 << "response_code:" << response_code; |
| 417 } | 414 } |
| 418 | 415 |
| 419 if (!info->callback.is_null()) { | 416 if (!info->callback.is_null()) { |
| 420 if (response.has_bad_url()) | 417 if (response.has_bad_url()) |
| 421 info->callback.Run(info->original_url, GURL(response.bad_url()), | 418 info->callback.Run(info->original_url, GURL(response.bad_url()), |
| 422 should_blacklist); | 419 should_blacklist); |
| 423 else | 420 else |
| 424 info->callback.Run(info->original_url, info->original_url, false); | 421 info->callback.Run(info->original_url, info->original_url, false); |
| 425 } | 422 } |
| 426 | 423 |
| 427 client_malware_reports_.erase(source); | |
| 428 delete source; | |
| 429 } | 424 } |
| 430 | 425 |
| 431 bool ClientSideDetectionService::IsInCache(const GURL& url) { | 426 bool ClientSideDetectionService::IsInCache(const GURL& url) { |
| 432 UpdateCache(); | 427 UpdateCache(); |
| 433 | 428 |
| 434 return cache_.find(url) != cache_.end(); | 429 return cache_.find(url) != cache_.end(); |
| 435 } | 430 } |
| 436 | 431 |
| 437 bool ClientSideDetectionService::GetValidCachedResult(const GURL& url, | 432 bool ClientSideDetectionService::GetValidCachedResult(const GURL& url, |
| 438 bool* is_phishing) { | 433 bool* is_phishing) { |
| 439 UpdateCache(); | 434 UpdateCache(); |
| 440 | 435 |
| 441 PhishingCache::iterator it = cache_.find(url); | 436 auto it = cache_.find(url); |
| 442 if (it == cache_.end()) { | 437 if (it == cache_.end()) { |
| 443 return false; | 438 return false; |
| 444 } | 439 } |
| 445 | 440 |
| 446 // We still need to check if the result is valid. | 441 // We still need to check if the result is valid. |
| 447 const CacheState& cache_state = *it->second; | 442 const CacheState& cache_state = *it->second; |
| 448 if (cache_state.is_phishing ? | 443 if (cache_state.is_phishing ? |
| 449 cache_state.timestamp > base::Time::Now() - | 444 cache_state.timestamp > base::Time::Now() - |
| 450 base::TimeDelta::FromMinutes(kPositiveCacheIntervalMinutes) : | 445 base::TimeDelta::FromMinutes(kPositiveCacheIntervalMinutes) : |
| 451 cache_state.timestamp > base::Time::Now() - | 446 cache_state.timestamp > base::Time::Now() - |
| (...skipping 10 matching lines...) Expand all Loading... |
| 462 // could be used for this purpose even if we will not use the entry to | 457 // could be used for this purpose even if we will not use the entry to |
| 463 // satisfy the request from the cache. | 458 // satisfy the request from the cache. |
| 464 base::TimeDelta positive_cache_interval = | 459 base::TimeDelta positive_cache_interval = |
| 465 std::max(base::TimeDelta::FromMinutes(kPositiveCacheIntervalMinutes), | 460 std::max(base::TimeDelta::FromMinutes(kPositiveCacheIntervalMinutes), |
| 466 base::TimeDelta::FromDays(kReportsIntervalDays)); | 461 base::TimeDelta::FromDays(kReportsIntervalDays)); |
| 467 base::TimeDelta negative_cache_interval = | 462 base::TimeDelta negative_cache_interval = |
| 468 std::max(base::TimeDelta::FromDays(kNegativeCacheIntervalDays), | 463 std::max(base::TimeDelta::FromDays(kNegativeCacheIntervalDays), |
| 469 base::TimeDelta::FromDays(kReportsIntervalDays)); | 464 base::TimeDelta::FromDays(kReportsIntervalDays)); |
| 470 | 465 |
| 471 // Remove elements from the cache that will no longer be used. | 466 // Remove elements from the cache that will no longer be used. |
| 472 for (PhishingCache::iterator it = cache_.begin(); it != cache_.end();) { | 467 for (auto it = cache_.begin(); it != cache_.end();) { |
| 473 const CacheState& cache_state = *it->second; | 468 const CacheState& cache_state = *it->second; |
| 474 if (cache_state.is_phishing ? | 469 if (cache_state.is_phishing ? |
| 475 cache_state.timestamp > base::Time::Now() - positive_cache_interval : | 470 cache_state.timestamp > base::Time::Now() - positive_cache_interval : |
| 476 cache_state.timestamp > base::Time::Now() - negative_cache_interval) { | 471 cache_state.timestamp > base::Time::Now() - negative_cache_interval) { |
| 477 ++it; | 472 ++it; |
| 478 } else { | 473 } else { |
| 479 cache_.erase(it++); | 474 cache_.erase(it++); |
| 480 } | 475 } |
| 481 } | 476 } |
| 482 } | 477 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 517 const std::string& report_url) { | 512 const std::string& report_url) { |
| 518 GURL url(report_url); | 513 GURL url(report_url); |
| 519 std::string api_key = google_apis::GetAPIKey(); | 514 std::string api_key = google_apis::GetAPIKey(); |
| 520 if (!api_key.empty()) | 515 if (!api_key.empty()) |
| 521 url = url.Resolve("?key=" + net::EscapeQueryParamValue(api_key, true)); | 516 url = url.Resolve("?key=" + net::EscapeQueryParamValue(api_key, true)); |
| 522 | 517 |
| 523 return url; | 518 return url; |
| 524 } | 519 } |
| 525 | 520 |
| 526 } // namespace safe_browsing | 521 } // namespace safe_browsing |
| OLD | NEW |