Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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 "components/safe_browsing/password_protection/password_protection_servi ce.h" | 5 #include "components/safe_browsing/password_protection/password_protection_servi ce.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback.h" | 8 #include "base/callback.h" |
| 9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
| 10 #include "base/metrics/histogram_macros.h" | 10 #include "base/metrics/histogram_macros.h" |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 56 // e.g., "https://www.foo.com:80/bar/test.cgi" -> "http://www.foo.com". | 56 // e.g., "https://www.foo.com:80/bar/test.cgi" -> "http://www.foo.com". |
| 57 GURL GetHostNameWithHTTPScheme(const GURL& url) { | 57 GURL GetHostNameWithHTTPScheme(const GURL& url) { |
| 58 DCHECK(url.SchemeIsHTTPOrHTTPS()); | 58 DCHECK(url.SchemeIsHTTPOrHTTPS()); |
| 59 std::string result(url::kHttpScheme); | 59 std::string result(url::kHttpScheme); |
| 60 result.append(url::kStandardSchemeSeparator).append(url.HostNoBrackets()); | 60 result.append(url::kStandardSchemeSeparator).append(url.HostNoBrackets()); |
| 61 return GURL(result); | 61 return GURL(result); |
| 62 } | 62 } |
| 63 | 63 |
| 64 } // namespace | 64 } // namespace |
| 65 | 65 |
| 66 PasswordProtectionFrame::PasswordProtectionFrame() { | |
|
Nathan Parker
2017/04/17 20:28:02
I wonder if you can delete this default ctor.
Mayb
Jialiu Lin
2017/04/18 00:58:26
Done.
| |
| 67 NOTIMPLEMENTED(); | |
| 68 } | |
| 69 | |
| 70 PasswordProtectionFrame::~PasswordProtectionFrame() = default; | |
| 71 | |
| 66 PasswordProtectionService::PasswordProtectionService( | 72 PasswordProtectionService::PasswordProtectionService( |
| 67 const scoped_refptr<SafeBrowsingDatabaseManager>& database_manager, | 73 const scoped_refptr<SafeBrowsingDatabaseManager>& database_manager, |
| 68 scoped_refptr<net::URLRequestContextGetter> request_context_getter, | 74 scoped_refptr<net::URLRequestContextGetter> request_context_getter, |
| 69 HistoryService* history_service, | 75 HistoryService* history_service, |
| 70 HostContentSettingsMap* host_content_settings_map) | 76 HostContentSettingsMap* host_content_settings_map) |
| 71 : stored_verdict_count_(-1), | 77 : stored_verdict_count_(-1), |
| 72 database_manager_(database_manager), | 78 database_manager_(database_manager), |
| 73 request_context_getter_(request_context_getter), | 79 request_context_getter_(request_context_getter), |
| 74 history_service_observer_(this), | 80 history_service_observer_(this), |
| 75 content_settings_(host_content_settings_map), | 81 content_settings_(host_content_settings_map), |
| 76 weak_factory_(this) { | 82 weak_factory_(this) { |
| 77 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 83 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 78 if (history_service) | 84 if (history_service) |
| 79 history_service_observer_.Add(history_service); | 85 history_service_observer_.Add(history_service); |
| 80 } | 86 } |
| 81 | 87 |
| 82 PasswordProtectionService::~PasswordProtectionService() { | 88 PasswordProtectionService::~PasswordProtectionService() { |
| 89 tracker_.TryCancelAll(); | |
| 83 CancelPendingRequests(); | 90 CancelPendingRequests(); |
| 84 history_service_observer_.RemoveAll(); | 91 history_service_observer_.RemoveAll(); |
| 85 weak_factory_.InvalidateWeakPtrs(); | 92 weak_factory_.InvalidateWeakPtrs(); |
| 86 } | 93 } |
| 87 | 94 |
| 88 void PasswordProtectionService::RecordPasswordReuse(const GURL& url) { | 95 void PasswordProtectionService::RecordPasswordReuse(const GURL& url) { |
| 89 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 96 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 90 DCHECK(database_manager_); | 97 DCHECK(database_manager_); |
| 91 if (!url.is_valid()) | 98 bool* match_whitelist = new bool(false); |
|
Nathan Parker
2017/04/17 20:28:02
bare pointer alert. :-)
Could this be a unique_p
Jialiu Lin
2017/04/18 00:58:26
Similar to my reply in PasswordProtectionRequest c
| |
| 92 return; | 99 tracker_.PostTaskAndReply( |
| 93 | 100 BrowserThread::GetTaskRunnerForThread(BrowserThread::IO).get(), FROM_HERE, |
| 94 BrowserThread::PostTask( | 101 base::Bind(&PasswordProtectionService::CheckCsdWhitelistOnIOThread, |
| 95 BrowserThread::IO, FROM_HERE, | 102 base::Unretained(this), url, match_whitelist), |
| 96 base::Bind( | 103 base::Bind(&PasswordProtectionService::OnMatchCsdWhiteListResult, |
| 97 &PasswordProtectionService::CheckCsdWhitelistOnIOThread, GetWeakPtr(), | 104 base::Unretained(this), base::Owned(match_whitelist))); |
| 98 url, | |
| 99 base::Bind(&PasswordProtectionService::OnMatchCsdWhiteListResult, | |
| 100 base::Unretained(this)))); | |
| 101 } | 105 } |
| 102 | 106 |
| 103 void PasswordProtectionService::CheckCsdWhitelistOnIOThread( | 107 void PasswordProtectionService::CheckCsdWhitelistOnIOThread( |
| 104 const GURL& url, | 108 const GURL& url, |
| 105 const CheckCsdWhitelistCallback& callback) { | 109 bool* check_result) { |
| 106 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 110 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 107 DCHECK(database_manager_); | 111 if (url.is_valid()) |
|
Nathan Parker
2017/04/17 20:28:02
So no-standard URLs will default to "whitelisted=f
Jialiu Lin
2017/04/18 00:58:27
Thanks for pointing this out. Changed default to t
| |
| 108 bool check_result = database_manager_->MatchCsdWhitelistUrl(url); | 112 *check_result = database_manager_->MatchCsdWhitelistUrl(url); |
| 109 DCHECK(callback); | |
| 110 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | |
| 111 base::Bind(callback, check_result)); | |
| 112 } | 113 } |
| 113 | 114 |
| 114 LoginReputationClientResponse::VerdictType | 115 LoginReputationClientResponse::VerdictType |
| 115 PasswordProtectionService::GetCachedVerdict( | 116 PasswordProtectionService::GetCachedVerdict( |
| 116 const GURL& url, | 117 const GURL& url, |
| 117 LoginReputationClientResponse* out_response) { | 118 LoginReputationClientResponse* out_response) { |
| 118 if (!url.is_valid()) | 119 if (!url.is_valid()) |
| 119 return LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED; | 120 return LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED; |
| 120 | 121 |
| 121 DCHECK(content_settings_); | 122 DCHECK(content_settings_); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 194 // override it. | 195 // override it. |
| 195 verdict_dictionary->SetWithoutPathExpansion(verdict->cache_expression(), | 196 verdict_dictionary->SetWithoutPathExpansion(verdict->cache_expression(), |
| 196 std::move(verdict_entry)); | 197 std::move(verdict_entry)); |
| 197 content_settings_->SetWebsiteSettingDefaultScope( | 198 content_settings_->SetWebsiteSettingDefaultScope( |
| 198 hostname, GURL(), CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, | 199 hostname, GURL(), CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, |
| 199 std::string(), std::move(verdict_dictionary)); | 200 std::string(), std::move(verdict_dictionary)); |
| 200 } | 201 } |
| 201 | 202 |
| 202 void PasswordProtectionService::StartRequest( | 203 void PasswordProtectionService::StartRequest( |
| 203 const GURL& main_frame_url, | 204 const GURL& main_frame_url, |
| 204 LoginReputationClientRequest::TriggerType type) { | 205 LoginReputationClientRequest::TriggerType type, |
| 206 std::unique_ptr<PasswordProtectionFrames> pending_password_frames) { | |
| 205 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 207 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 206 if (!IsPingingEnabled()) | 208 scoped_refptr<PasswordProtectionRequest> request( |
| 207 return; | 209 new PasswordProtectionRequest( |
| 208 std::unique_ptr<PasswordProtectionRequest> request = | 210 main_frame_url, type, std::move(pending_password_frames), |
| 209 base::MakeUnique<PasswordProtectionRequest>( | 211 GetWeakPtr(), database_manager_, GetRequestTimeoutInMS())); |
| 210 main_frame_url, type, IsExtendedReporting(), IsIncognito(), | |
| 211 GetWeakPtr(), GetRequestTimeoutInMS()); | |
| 212 DCHECK(request); | 212 DCHECK(request); |
| 213 request->Start(); | 213 request->Start(); |
| 214 requests_.insert(std::move(request)); | 214 requests_.insert(std::move(request)); |
| 215 } | 215 } |
| 216 | 216 |
| 217 void PasswordProtectionService::MaybeStartLowReputationRequest( | |
| 218 const GURL& main_frame_url, | |
| 219 std::unique_ptr<PasswordProtectionFrames> pending_password_frames) { | |
| 220 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 221 if (!IsPingingEnabled()) | |
| 222 return; | |
| 223 | |
| 224 // Don't start request if |main_frame_url| is invalid or is NOT http or https. | |
|
Nathan Parker
2017/04/17 20:28:02
nit: this comment isn't necessary, since the code
Jialiu Lin
2017/04/18 00:58:27
Done.
| |
| 225 if (!main_frame_url.is_valid() || !main_frame_url.SchemeIsHTTPOrHTTPS()) { | |
| 226 return; | |
| 227 } | |
| 228 | |
| 229 StartRequest(main_frame_url, | |
| 230 LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, | |
| 231 std::move(pending_password_frames)); | |
| 232 } | |
| 233 | |
| 217 void PasswordProtectionService::RequestFinished( | 234 void PasswordProtectionService::RequestFinished( |
| 218 PasswordProtectionRequest* request, | 235 PasswordProtectionRequest* request, |
| 219 std::unique_ptr<LoginReputationClientResponse> response) { | 236 std::unique_ptr<LoginReputationClientResponse> response) { |
| 220 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 237 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 221 | 238 |
| 222 DCHECK(request); | 239 DCHECK(request); |
| 223 // TODO(jialiul): We don't cache verdict for incognito mode for now. | 240 // TODO(jialiul): We don't cache verdict for incognito mode for now. |
| 224 // Later we may consider temporarily caching verdict. | 241 // Later we may consider temporarily caching verdict. |
| 225 if (!request->is_incognito() && response) | 242 if (response && !IsIncognito()) |
| 226 CacheVerdict(request->main_frame_url(), response.get(), base::Time::Now()); | 243 CacheVerdict(request->main_frame_url(), response.get(), base::Time::Now()); |
| 227 | 244 |
| 228 // Finished processing this request. Remove it from pending list. | 245 // Finished processing this request. Remove it from pending list. |
| 229 for (auto it = requests_.begin(); it != requests_.end(); it++) { | 246 for (auto it = requests_.begin(); it != requests_.end(); it++) { |
| 230 if (it->get() == request) { | 247 if (it->get() == request) { |
| 231 requests_.erase(it); | 248 requests_.erase(it); |
| 232 break; | 249 break; |
| 233 } | 250 } |
| 234 } | 251 } |
| 235 } | 252 } |
| 236 | 253 |
| 237 void PasswordProtectionService::CancelPendingRequests() { | 254 void PasswordProtectionService::CancelPendingRequests() { |
| 238 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 255 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 239 for (auto it = requests_.begin(); it != requests_.end();) { | 256 for (auto it = requests_.begin(); it != requests_.end();) { |
| 240 // We need to advance the iterator before we cancel because canceling | 257 // We need to advance the iterator before we cancel because canceling |
| 241 // the request will invalidate it when RequestFinished is called. | 258 // the request will invalidate it when RequestFinished is called. |
| 242 PasswordProtectionRequest* request = it->get(); | 259 PasswordProtectionRequest* request = it->get(); |
| 243 it++; | 260 it++; |
| 244 request->Cancel(false); | 261 request->Cancel(false); |
| 245 } | 262 } |
| 246 DCHECK(requests_.empty()); | 263 DCHECK(requests_.empty()); |
| 247 } | 264 } |
| 248 | 265 |
| 266 scoped_refptr<SafeBrowsingDatabaseManager> | |
| 267 PasswordProtectionService::database_manager() { | |
| 268 return database_manager_; | |
| 269 } | |
| 270 | |
| 249 GURL PasswordProtectionService::GetPasswordProtectionRequestUrl() { | 271 GURL PasswordProtectionService::GetPasswordProtectionRequestUrl() { |
| 250 GURL url(kPasswordProtectionRequestUrl); | 272 GURL url(kPasswordProtectionRequestUrl); |
| 251 std::string api_key = google_apis::GetAPIKey(); | 273 std::string api_key = google_apis::GetAPIKey(); |
| 252 DCHECK(!api_key.empty()); | 274 DCHECK(!api_key.empty()); |
| 253 return url.Resolve("?key=" + net::EscapeQueryParamValue(api_key, true)); | 275 return url.Resolve("?key=" + net::EscapeQueryParamValue(api_key, true)); |
| 254 } | 276 } |
| 255 | 277 |
| 256 int PasswordProtectionService::GetStoredVerdictCount() { | 278 int PasswordProtectionService::GetStoredVerdictCount() { |
| 257 DCHECK(content_settings_); | 279 DCHECK(content_settings_); |
| 258 // If we have already computed this, return its value. | 280 // If we have already computed this, return its value. |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 277 stored_verdict_count_ += static_cast<int>(verdict_dictionary->size()); | 299 stored_verdict_count_ += static_cast<int>(verdict_dictionary->size()); |
| 278 } | 300 } |
| 279 return stored_verdict_count_; | 301 return stored_verdict_count_; |
| 280 } | 302 } |
| 281 | 303 |
| 282 int PasswordProtectionService::GetRequestTimeoutInMS() { | 304 int PasswordProtectionService::GetRequestTimeoutInMS() { |
| 283 return kRequestTimeoutMs; | 305 return kRequestTimeoutMs; |
| 284 } | 306 } |
| 285 | 307 |
| 286 void PasswordProtectionService::OnMatchCsdWhiteListResult( | 308 void PasswordProtectionService::OnMatchCsdWhiteListResult( |
| 287 bool match_whitelist) { | 309 const bool* match_whitelist) { |
| 288 UMA_HISTOGRAM_BOOLEAN( | 310 UMA_HISTOGRAM_BOOLEAN( |
| 289 "PasswordManager.PasswordReuse.MainFrameMatchCsdWhitelist", | 311 "PasswordManager.PasswordReuse.MainFrameMatchCsdWhitelist", |
| 290 match_whitelist); | 312 *match_whitelist); |
| 291 } | 313 } |
| 292 | 314 |
| 293 void PasswordProtectionService::OnURLsDeleted( | 315 void PasswordProtectionService::OnURLsDeleted( |
| 294 history::HistoryService* history_service, | 316 history::HistoryService* history_service, |
| 295 bool all_history, | 317 bool all_history, |
| 296 bool expired, | 318 bool expired, |
| 297 const history::URLRows& deleted_rows, | 319 const history::URLRows& deleted_rows, |
| 298 const std::set<GURL>& favicon_urls) { | 320 const std::set<GURL>& favicon_urls) { |
| 299 BrowserThread::PostTask( | 321 BrowserThread::PostTask( |
| 300 BrowserThread::UI, FROM_HERE, | 322 BrowserThread::UI, FROM_HERE, |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 393 V4ProtocolManagerUtil::GeneratePathVariantsToCheck(canonical_path, | 415 V4ProtocolManagerUtil::GeneratePathVariantsToCheck(canonical_path, |
| 394 std::string(), paths); | 416 std::string(), paths); |
| 395 } | 417 } |
| 396 | 418 |
| 397 // Return the path of the cache expression. e.g.: | 419 // Return the path of the cache expression. e.g.: |
| 398 // "www.google.com" -> "/" | 420 // "www.google.com" -> "/" |
| 399 // "www.google.com/abc" -> "/abc/" | 421 // "www.google.com/abc" -> "/abc/" |
| 400 // "foo.com/foo/bar/" -> "/foo/bar/" | 422 // "foo.com/foo/bar/" -> "/foo/bar/" |
| 401 std::string PasswordProtectionService::GetCacheExpressionPath( | 423 std::string PasswordProtectionService::GetCacheExpressionPath( |
| 402 const std::string& cache_expression) { | 424 const std::string& cache_expression) { |
| 403 DCHECK(!cache_expression.empty()); | 425 // TODO(jialiul): Change this to a DCHECk when SB server is ready. |
| 426 if (cache_expression.empty()) | |
| 427 return std::string("/"); | |
| 428 | |
| 404 std::string out_put(cache_expression); | 429 std::string out_put(cache_expression); |
| 405 // Append a trailing slash if needed. | 430 // Append a trailing slash if needed. |
| 406 if (out_put[out_put.length() - 1] != '/') | 431 if (out_put[out_put.length() - 1] != '/') |
| 407 out_put.append("/"); | 432 out_put.append("/"); |
| 408 | 433 |
| 409 size_t first_slash_pos = out_put.find_first_of("/"); | 434 size_t first_slash_pos = out_put.find_first_of("/"); |
| 410 DCHECK_NE(std::string::npos, first_slash_pos); | 435 DCHECK_NE(std::string::npos, first_slash_pos); |
| 411 return out_put.substr(first_slash_pos); | 436 return out_put.substr(first_slash_pos); |
| 412 } | 437 } |
| 413 | 438 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 426 const std::vector<char> verdict_blob(serialized_proto.begin(), | 451 const std::vector<char> verdict_blob(serialized_proto.begin(), |
| 427 serialized_proto.end()); | 452 serialized_proto.end()); |
| 428 std::unique_ptr<base::Value> binary_value = | 453 std::unique_ptr<base::Value> binary_value = |
| 429 base::MakeUnique<base::Value>(verdict_blob); | 454 base::MakeUnique<base::Value>(verdict_blob); |
| 430 DCHECK_EQ(base::Value::Type::BINARY, binary_value->type()); | 455 DCHECK_EQ(base::Value::Type::BINARY, binary_value->type()); |
| 431 result->Set(kVerdictProto, std::move(binary_value)); | 456 result->Set(kVerdictProto, std::move(binary_value)); |
| 432 return result; | 457 return result; |
| 433 } | 458 } |
| 434 | 459 |
| 435 } // namespace safe_browsing | 460 } // namespace safe_browsing |
| OLD | NEW |