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 // Portions of this code based on Mozilla: | 5 // Portions of this code based on Mozilla: |
6 // (netwerk/cookie/src/nsCookieService.cpp) | 6 // (netwerk/cookie/src/nsCookieService.cpp) |
7 /* ***** BEGIN LICENSE BLOCK ***** | 7 /* ***** BEGIN LICENSE BLOCK ***** |
8 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | 8 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
9 * | 9 * |
10 * The contents of this file are subject to the Mozilla Public License Version | 10 * The contents of this file are subject to the Mozilla Public License Version |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 * ***** END LICENSE BLOCK ***** */ | 43 * ***** END LICENSE BLOCK ***** */ |
44 | 44 |
45 #include "net/cookies/canonical_cookie.h" | 45 #include "net/cookies/canonical_cookie.h" |
46 | 46 |
47 #include "base/format_macros.h" | 47 #include "base/format_macros.h" |
48 #include "base/logging.h" | 48 #include "base/logging.h" |
49 #include "base/memory/ptr_util.h" | 49 #include "base/memory/ptr_util.h" |
50 #include "base/metrics/histogram_macros.h" | 50 #include "base/metrics/histogram_macros.h" |
51 #include "base/strings/string_util.h" | 51 #include "base/strings/string_util.h" |
52 #include "base/strings/stringprintf.h" | 52 #include "base/strings/stringprintf.h" |
| 53 #include "net/base/url_util.h" |
53 #include "net/cookies/cookie_util.h" | 54 #include "net/cookies/cookie_util.h" |
54 #include "net/cookies/parsed_cookie.h" | 55 #include "net/cookies/parsed_cookie.h" |
55 #include "url/gurl.h" | 56 #include "url/gurl.h" |
56 #include "url/url_canon.h" | 57 #include "url/url_canon.h" |
| 58 #include "url/url_util.h" |
57 | 59 |
58 using base::Time; | 60 using base::Time; |
59 using base::TimeDelta; | 61 using base::TimeDelta; |
60 | 62 |
61 namespace net { | 63 namespace net { |
62 | 64 |
63 namespace { | 65 namespace { |
64 | 66 |
65 const int kVlogSetCookies = 7; | 67 const int kVlogSetCookies = 7; |
66 | 68 |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 url, parsed_cookie.HasPath() ? parsed_cookie.Path() : std::string()); | 223 url, parsed_cookie.HasPath() ? parsed_cookie.Path() : std::string()); |
222 | 224 |
223 Time server_time(creation_time); | 225 Time server_time(creation_time); |
224 if (options.has_server_time()) | 226 if (options.has_server_time()) |
225 server_time = options.server_time(); | 227 server_time = options.server_time(); |
226 | 228 |
227 Time cookie_expires = CanonicalCookie::CanonExpiration(parsed_cookie, | 229 Time cookie_expires = CanonicalCookie::CanonExpiration(parsed_cookie, |
228 creation_time, | 230 creation_time, |
229 server_time); | 231 server_time); |
230 | 232 |
231 CookiePrefix prefix = CanonicalCookie::GetCookiePrefix(parsed_cookie.Name()); | 233 CookiePrefix prefix = GetCookiePrefix(parsed_cookie.Name()); |
232 bool is_cookie_valid = | 234 bool is_cookie_valid = IsCookiePrefixValid(prefix, url, parsed_cookie); |
233 CanonicalCookie::IsCookiePrefixValid(prefix, url, parsed_cookie); | 235 RecordCookiePrefixMetrics(prefix, is_cookie_valid); |
234 CanonicalCookie::RecordCookiePrefixMetrics(prefix, is_cookie_valid); | |
235 if (!is_cookie_valid) { | 236 if (!is_cookie_valid) { |
236 VLOG(kVlogSetCookies) | 237 VLOG(kVlogSetCookies) |
237 << "Create() failed because the cookie violated prefix rules."; | 238 << "Create() failed because the cookie violated prefix rules."; |
238 return nullptr; | 239 return nullptr; |
239 } | 240 } |
240 | 241 |
241 return base::WrapUnique(new CanonicalCookie( | 242 std::unique_ptr<CanonicalCookie> cc(base::MakeUnique<CanonicalCookie>( |
242 parsed_cookie.Name(), parsed_cookie.Value(), cookie_domain, cookie_path, | 243 parsed_cookie.Name(), parsed_cookie.Value(), cookie_domain, cookie_path, |
243 creation_time, cookie_expires, creation_time, parsed_cookie.IsSecure(), | 244 creation_time, cookie_expires, creation_time, parsed_cookie.IsSecure(), |
244 parsed_cookie.IsHttpOnly(), parsed_cookie.SameSite(), | 245 parsed_cookie.IsHttpOnly(), parsed_cookie.SameSite(), |
245 parsed_cookie.Priority())); | 246 parsed_cookie.Priority())); |
| 247 DCHECK(cc->IsCanonical()); |
| 248 return cc; |
246 } | 249 } |
247 | 250 |
248 bool CanonicalCookie::IsEquivalentForSecureCookieMatching( | 251 bool CanonicalCookie::IsEquivalentForSecureCookieMatching( |
249 const CanonicalCookie& ecc) const { | 252 const CanonicalCookie& ecc) const { |
250 return (name_ == ecc.Name() && (ecc.IsDomainMatch(DomainWithoutDot()) || | 253 return (name_ == ecc.Name() && (ecc.IsDomainMatch(DomainWithoutDot()) || |
251 IsDomainMatch(ecc.DomainWithoutDot())) && | 254 IsDomainMatch(ecc.DomainWithoutDot())) && |
252 ecc.IsOnPath(Path())); | 255 ecc.IsOnPath(Path())); |
253 } | 256 } |
254 | 257 |
255 bool CanonicalCookie::IsOnPath(const std::string& url_path) const { | 258 bool CanonicalCookie::IsOnPath(const std::string& url_path) const { |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 | 395 |
393 if (IsSecure() != other.IsSecure()) | 396 if (IsSecure() != other.IsSecure()) |
394 return IsSecure(); | 397 return IsSecure(); |
395 | 398 |
396 if (IsHttpOnly() != other.IsHttpOnly()) | 399 if (IsHttpOnly() != other.IsHttpOnly()) |
397 return IsHttpOnly(); | 400 return IsHttpOnly(); |
398 | 401 |
399 return Priority() < other.Priority(); | 402 return Priority() < other.Priority(); |
400 } | 403 } |
401 | 404 |
| 405 bool CanonicalCookie::IsCanonical() const { |
| 406 // Not checking domain against ParsedCookie as it may have come purely |
| 407 // from the URL. |
| 408 if (ParsedCookie::ParseTokenString(name_) != name_ || |
| 409 ParsedCookie::ParseValueString(value_) != value_ || |
| 410 ParsedCookie::ParseValueString(path_) != path_ || |
| 411 !ParsedCookie::IsValidCookieAttributeValue(name_) || |
| 412 !ParsedCookie::IsValidCookieAttributeValue(value_) || |
| 413 !ParsedCookie::IsValidCookieAttributeValue(path_)) { |
| 414 return false; |
| 415 } |
| 416 |
| 417 if (!last_access_date_.is_null() && creation_date_.is_null()) |
| 418 return false; |
| 419 |
| 420 url::CanonHostInfo canon_host_info; |
| 421 std::string canonical_domain(CanonicalizeHost(domain_, &canon_host_info)); |
| 422 // TODO(rdsmith): This specifically allows for empty domains. The spec |
| 423 // suggests this is invalid (if a domain attribute is empty, the cookie's |
| 424 // domain is set to the canonicalized request host; see |
| 425 // https://tools.ietf.org/html/rfc6265#section-5.3). However, it is |
| 426 // needed for Chrome extension cookies. |
| 427 // See http://crbug.com/730633 for more information. |
| 428 if (canonical_domain != domain_) |
| 429 return false; |
| 430 |
| 431 if (path_.empty() || path_[0] != '/') |
| 432 return false; |
| 433 |
| 434 switch (GetCookiePrefix(name_)) { |
| 435 case COOKIE_PREFIX_HOST: |
| 436 if (!secure_ || path_ != "/" || domain_.empty() || domain_[0] == '.') |
| 437 return false; |
| 438 break; |
| 439 case COOKIE_PREFIX_SECURE: |
| 440 if (!secure_) |
| 441 return false; |
| 442 break; |
| 443 default: |
| 444 break; |
| 445 } |
| 446 |
| 447 return true; |
| 448 } |
| 449 |
402 // static | 450 // static |
403 CanonicalCookie::CookiePrefix CanonicalCookie::GetCookiePrefix( | 451 CanonicalCookie::CookiePrefix CanonicalCookie::GetCookiePrefix( |
404 const std::string& name) { | 452 const std::string& name) { |
405 const char kSecurePrefix[] = "__Secure-"; | 453 const char kSecurePrefix[] = "__Secure-"; |
406 const char kHostPrefix[] = "__Host-"; | 454 const char kHostPrefix[] = "__Host-"; |
407 if (base::StartsWith(name, kSecurePrefix, base::CompareCase::SENSITIVE)) | 455 if (base::StartsWith(name, kSecurePrefix, base::CompareCase::SENSITIVE)) |
408 return CanonicalCookie::COOKIE_PREFIX_SECURE; | 456 return CanonicalCookie::COOKIE_PREFIX_SECURE; |
409 if (base::StartsWith(name, kHostPrefix, base::CompareCase::SENSITIVE)) | 457 if (base::StartsWith(name, kHostPrefix, base::CompareCase::SENSITIVE)) |
410 return CanonicalCookie::COOKIE_PREFIX_HOST; | 458 return CanonicalCookie::COOKIE_PREFIX_HOST; |
411 return CanonicalCookie::COOKIE_PREFIX_NONE; | 459 return CanonicalCookie::COOKIE_PREFIX_NONE; |
(...skipping 30 matching lines...) Expand all Loading... |
442 return true; | 490 return true; |
443 } | 491 } |
444 | 492 |
445 std::string CanonicalCookie::DomainWithoutDot() const { | 493 std::string CanonicalCookie::DomainWithoutDot() const { |
446 if (domain_.empty() || domain_[0] != '.') | 494 if (domain_.empty() || domain_[0] != '.') |
447 return domain_; | 495 return domain_; |
448 return domain_.substr(1); | 496 return domain_.substr(1); |
449 } | 497 } |
450 | 498 |
451 } // namespace net | 499 } // namespace net |
OLD | NEW |