| 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/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/time.h" | 9 #include "base/time.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 104 // Refresh the model when the service is enabled. This can happen when the | 104 // Refresh the model when the service is enabled. This can happen when the |
| 105 // preference is toggled, or early during startup if the preference is | 105 // preference is toggled, or early during startup if the preference is |
| 106 // already enabled. In a lot of cases the model will be in the cache so it | 106 // already enabled. In a lot of cases the model will be in the cache so it |
| 107 // won't actually be fetched from the network. | 107 // won't actually be fetched from the network. |
| 108 // We delay the first model fetch to avoid slowing down browser startup. | 108 // We delay the first model fetch to avoid slowing down browser startup. |
| 109 ScheduleFetchModel(kInitialClientModelFetchDelayMs); | 109 ScheduleFetchModel(kInitialClientModelFetchDelayMs); |
| 110 } else { | 110 } else { |
| 111 // Cancel pending requests. | 111 // Cancel pending requests. |
| 112 model_fetcher_.reset(); | 112 model_fetcher_.reset(); |
| 113 // Invoke pending callbacks with a false verdict. | 113 // Invoke pending callbacks with a false verdict. |
| 114 for (std::map<const URLFetcher*, ClientReportInfo*>::iterator it = | 114 for (std::map<const content::URLFetcher*, ClientReportInfo*>::iterator it = |
| 115 client_phishing_reports_.begin(); | 115 client_phishing_reports_.begin(); |
| 116 it != client_phishing_reports_.end(); ++it) { | 116 it != client_phishing_reports_.end(); ++it) { |
| 117 ClientReportInfo* info = it->second; | 117 ClientReportInfo* info = it->second; |
| 118 if (info->callback.get()) | 118 if (info->callback.get()) |
| 119 info->callback->Run(info->phishing_url, false); | 119 info->callback->Run(info->phishing_url, false); |
| 120 } | 120 } |
| 121 STLDeleteContainerPairPointers(client_phishing_reports_.begin(), | 121 STLDeleteContainerPairPointers(client_phishing_reports_.begin(), |
| 122 client_phishing_reports_.end()); | 122 client_phishing_reports_.end()); |
| 123 client_phishing_reports_.clear(); | 123 client_phishing_reports_.clear(); |
| 124 cache_.clear(); | 124 cache_.clear(); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 for (size_t i = 0; i < net::kIPv6AddressSize; ++i) { | 177 for (size_t i = 0; i < net::kIPv6AddressSize; ++i) { |
| 178 subnet[i] = ip_number[i] & mask[i]; | 178 subnet[i] = ip_number[i] & mask[i]; |
| 179 } | 179 } |
| 180 if (it->second.count(crypto::SHA256HashString(subnet)) > 0) { | 180 if (it->second.count(crypto::SHA256HashString(subnet)) > 0) { |
| 181 return true; | 181 return true; |
| 182 } | 182 } |
| 183 } | 183 } |
| 184 return false; | 184 return false; |
| 185 } | 185 } |
| 186 | 186 |
| 187 void ClientSideDetectionService::OnURLFetchComplete(const URLFetcher* source) { | 187 void ClientSideDetectionService::OnURLFetchComplete( |
| 188 const content::URLFetcher* source) { |
| 188 std::string data; | 189 std::string data; |
| 189 source->GetResponseAsString(&data); | 190 source->GetResponseAsString(&data); |
| 190 if (source == model_fetcher_.get()) { | 191 if (source == model_fetcher_.get()) { |
| 191 HandleModelResponse( | 192 HandleModelResponse( |
| 192 source, source->url(), source->status(), source->response_code(), | 193 source, source->GetUrl(), source->GetStatus(), |
| 193 source->cookies(), data); | 194 source->GetResponseCode(), source->GetCookies(), data); |
| 194 } else if (client_phishing_reports_.find(source) != | 195 } else if (client_phishing_reports_.find(source) != |
| 195 client_phishing_reports_.end()) { | 196 client_phishing_reports_.end()) { |
| 196 HandlePhishingVerdict( | 197 HandlePhishingVerdict( |
| 197 source, source->url(), source->status(), source->response_code(), | 198 source, source->GetUrl(), source->GetStatus(), |
| 198 source->cookies(), data); | 199 source->GetResponseCode(), source->GetCookies(), data); |
| 199 } else { | 200 } else { |
| 200 NOTREACHED(); | 201 NOTREACHED(); |
| 201 } | 202 } |
| 202 } | 203 } |
| 203 | 204 |
| 204 void ClientSideDetectionService::Observe( | 205 void ClientSideDetectionService::Observe( |
| 205 int type, | 206 int type, |
| 206 const content::NotificationSource& source, | 207 const content::NotificationSource& source, |
| 207 const content::NotificationDetails& details) { | 208 const content::NotificationDetails& details) { |
| 208 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 209 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 247 } | 248 } |
| 248 | 249 |
| 249 void ClientSideDetectionService::StartFetchModel() { | 250 void ClientSideDetectionService::StartFetchModel() { |
| 250 if (enabled_) { | 251 if (enabled_) { |
| 251 // Start fetching the model either from the cache or possibly from the | 252 // Start fetching the model either from the cache or possibly from the |
| 252 // network if the model isn't in the cache. | 253 // network if the model isn't in the cache. |
| 253 model_fetcher_.reset(URLFetcher::Create(0 /* ID is not used */, | 254 model_fetcher_.reset(URLFetcher::Create(0 /* ID is not used */, |
| 254 GURL(kClientModelUrl), | 255 GURL(kClientModelUrl), |
| 255 URLFetcher::GET, | 256 URLFetcher::GET, |
| 256 this)); | 257 this)); |
| 257 model_fetcher_->set_request_context(request_context_getter_.get()); | 258 model_fetcher_->SetRequestContext(request_context_getter_.get()); |
| 258 model_fetcher_->Start(); | 259 model_fetcher_->Start(); |
| 259 } | 260 } |
| 260 } | 261 } |
| 261 | 262 |
| 262 void ClientSideDetectionService::EndFetchModel(ClientModelStatus status) { | 263 void ClientSideDetectionService::EndFetchModel(ClientModelStatus status) { |
| 263 UMA_HISTOGRAM_ENUMERATION("SBClientPhishing.ClientModelStatus", | 264 UMA_HISTOGRAM_ENUMERATION("SBClientPhishing.ClientModelStatus", |
| 264 status, | 265 status, |
| 265 MODEL_STATUS_MAX); | 266 MODEL_STATUS_MAX); |
| 266 if (status == MODEL_SUCCESS) { | 267 if (status == MODEL_SUCCESS) { |
| 267 SetBadSubnets(*model_, &bad_subnets_); | 268 SetBadSubnets(*model_, &bad_subnets_); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 GURL(kClientReportPhishingUrl), | 311 GURL(kClientReportPhishingUrl), |
| 311 URLFetcher::POST, | 312 URLFetcher::POST, |
| 312 this); | 313 this); |
| 313 | 314 |
| 314 // Remember which callback and URL correspond to the current fetcher object. | 315 // Remember which callback and URL correspond to the current fetcher object. |
| 315 ClientReportInfo* info = new ClientReportInfo; | 316 ClientReportInfo* info = new ClientReportInfo; |
| 316 info->callback.swap(cb); // takes ownership of the callback. | 317 info->callback.swap(cb); // takes ownership of the callback. |
| 317 info->phishing_url = GURL(request->url()); | 318 info->phishing_url = GURL(request->url()); |
| 318 client_phishing_reports_[fetcher] = info; | 319 client_phishing_reports_[fetcher] = info; |
| 319 | 320 |
| 320 fetcher->set_load_flags(net::LOAD_DISABLE_CACHE); | 321 fetcher->SetLoadFlags(net::LOAD_DISABLE_CACHE); |
| 321 fetcher->set_request_context(request_context_getter_.get()); | 322 fetcher->SetRequestContext(request_context_getter_.get()); |
| 322 fetcher->set_upload_data("application/octet-stream", request_data); | 323 fetcher->SetUploadData("application/octet-stream", request_data); |
| 323 fetcher->Start(); | 324 fetcher->Start(); |
| 324 | 325 |
| 325 // Record that we made a request | 326 // Record that we made a request |
| 326 phishing_report_times_.push(base::Time::Now()); | 327 phishing_report_times_.push(base::Time::Now()); |
| 327 } | 328 } |
| 328 | 329 |
| 329 void ClientSideDetectionService::HandleModelResponse( | 330 void ClientSideDetectionService::HandleModelResponse( |
| 330 const URLFetcher* source, | 331 const content::URLFetcher* source, |
| 331 const GURL& url, | 332 const GURL& url, |
| 332 const net::URLRequestStatus& status, | 333 const net::URLRequestStatus& status, |
| 333 int response_code, | 334 int response_code, |
| 334 const net::ResponseCookies& cookies, | 335 const net::ResponseCookies& cookies, |
| 335 const std::string& data) { | 336 const std::string& data) { |
| 336 base::TimeDelta max_age; | 337 base::TimeDelta max_age; |
| 337 if (status.is_success() && RC_REQUEST_OK == response_code && | 338 if (status.is_success() && RC_REQUEST_OK == response_code && |
| 338 source->response_headers() && | 339 source->GetResponseHeaders() && |
| 339 source->response_headers()->GetMaxAgeValue(&max_age)) { | 340 source->GetResponseHeaders()->GetMaxAgeValue(&max_age)) { |
| 340 model_max_age_.reset(new base::TimeDelta(max_age)); | 341 model_max_age_.reset(new base::TimeDelta(max_age)); |
| 341 } | 342 } |
| 342 scoped_ptr<ClientSideModel> model(new ClientSideModel()); | 343 scoped_ptr<ClientSideModel> model(new ClientSideModel()); |
| 343 ClientModelStatus model_status; | 344 ClientModelStatus model_status; |
| 344 if (!status.is_success() || RC_REQUEST_OK != response_code) { | 345 if (!status.is_success() || RC_REQUEST_OK != response_code) { |
| 345 model_status = MODEL_FETCH_FAILED; | 346 model_status = MODEL_FETCH_FAILED; |
| 346 } else if (data.empty()) { | 347 } else if (data.empty()) { |
| 347 model_status = MODEL_EMPTY; | 348 model_status = MODEL_EMPTY; |
| 348 } else if (data.size() > kMaxModelSizeBytes) { | 349 } else if (data.size() > kMaxModelSizeBytes) { |
| 349 model_status = MODEL_TOO_LARGE; | 350 model_status = MODEL_TOO_LARGE; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 361 } else { | 362 } else { |
| 362 // The model is valid => replace the existing model with the new one. | 363 // The model is valid => replace the existing model with the new one. |
| 363 model_str_.assign(data); | 364 model_str_.assign(data); |
| 364 model_.swap(model); | 365 model_.swap(model); |
| 365 model_status = MODEL_SUCCESS; | 366 model_status = MODEL_SUCCESS; |
| 366 } | 367 } |
| 367 EndFetchModel(model_status); | 368 EndFetchModel(model_status); |
| 368 } | 369 } |
| 369 | 370 |
| 370 void ClientSideDetectionService::HandlePhishingVerdict( | 371 void ClientSideDetectionService::HandlePhishingVerdict( |
| 371 const URLFetcher* source, | 372 const content::URLFetcher* source, |
| 372 const GURL& url, | 373 const GURL& url, |
| 373 const net::URLRequestStatus& status, | 374 const net::URLRequestStatus& status, |
| 374 int response_code, | 375 int response_code, |
| 375 const net::ResponseCookies& cookies, | 376 const net::ResponseCookies& cookies, |
| 376 const std::string& data) { | 377 const std::string& data) { |
| 377 ClientPhishingResponse response; | 378 ClientPhishingResponse response; |
| 378 scoped_ptr<ClientReportInfo> info(client_phishing_reports_[source]); | 379 scoped_ptr<ClientReportInfo> info(client_phishing_reports_[source]); |
| 379 bool is_phishing = false; | 380 bool is_phishing = false; |
| 380 if (status.is_success() && RC_REQUEST_OK == response_code && | 381 if (status.is_success() && RC_REQUEST_OK == response_code && |
| 381 response.ParseFromString(data)) { | 382 response.ParseFromString(data)) { |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 &whitelist_patterns); | 575 &whitelist_patterns); |
| 575 for (size_t j = 0; j < whitelist_patterns.size(); ++j) { | 576 for (size_t j = 0; j < whitelist_patterns.size(); ++j) { |
| 576 if (whitelist_patterns[j] == canonical_url_as_pattern) { | 577 if (whitelist_patterns[j] == canonical_url_as_pattern) { |
| 577 return true; | 578 return true; |
| 578 } | 579 } |
| 579 } | 580 } |
| 580 } | 581 } |
| 581 return false; | 582 return false; |
| 582 } | 583 } |
| 583 } // namespace safe_browsing | 584 } // namespace safe_browsing |
| OLD | NEW |