diff options
Diffstat (limited to 'net/cookies')
-rw-r--r-- | net/cookies/canonical_cookie.cc | 11 | ||||
-rw-r--r-- | net/cookies/canonical_cookie.h | 3 | ||||
-rw-r--r-- | net/cookies/cookie_monster.cc | 8 | ||||
-rw-r--r-- | net/cookies/cookie_options.h | 13 | ||||
-rw-r--r-- | net/cookies/cookie_store_unittest.h | 27 |
5 files changed, 55 insertions, 7 deletions
diff --git a/net/cookies/canonical_cookie.cc b/net/cookies/canonical_cookie.cc index 5ae65f6..306b8fc 100644 --- a/net/cookies/canonical_cookie.cc +++ b/net/cookies/canonical_cookie.cc @@ -139,7 +139,7 @@ CanonicalCookie::CanonicalCookie(const GURL& url, const ParsedCookie& pc) secure_(pc.IsSecure()), httponly_(pc.IsHttpOnly()) { if (pc.HasExpires()) - expiry_date_ = CanonExpiration(pc, creation_date_); + expiry_date_ = CanonExpiration(pc, creation_date_, creation_date_); // Do the best we can with the domain. std::string cookie_domain; @@ -181,7 +181,8 @@ std::string CanonicalCookie::CanonPath(const GURL& url, // static Time CanonicalCookie::CanonExpiration(const ParsedCookie& pc, - const Time& current) { + const Time& current, + const Time& server_time) { // First, try the Max-Age attribute. uint64 max_age = 0; if (pc.HasMaxAge() && @@ -195,8 +196,10 @@ Time CanonicalCookie::CanonExpiration(const ParsedCookie& pc, } // Try the Expires attribute. - if (pc.HasExpires()) - return cookie_util::ParseCookieTime(pc.Expires()); + if (pc.HasExpires()) { + // Adjust for clock skew between server and host. + return current + (cookie_util::ParseCookieTime(pc.Expires()) - server_time); + } // Invalid or no expiration, persistent cookie. return Time(); diff --git a/net/cookies/canonical_cookie.h b/net/cookies/canonical_cookie.h index 1b1ca77..ba50dfc 100644 --- a/net/cookies/canonical_cookie.h +++ b/net/cookies/canonical_cookie.h @@ -117,7 +117,8 @@ class NET_EXPORT CanonicalCookie { static std::string GetCookieSourceFromURL(const GURL& url); static std::string CanonPath(const GURL& url, const ParsedCookie& pc); static base::Time CanonExpiration(const ParsedCookie& pc, - const base::Time& current); + const base::Time& current, + const base::Time& server_time); private: // The source member of a canonical cookie is the origin of the URL that tried diff --git a/net/cookies/cookie_monster.cc b/net/cookies/cookie_monster.cc index d1f3426..eab2e0e 100644 --- a/net/cookies/cookie_monster.cc +++ b/net/cookies/cookie_monster.cc @@ -1703,6 +1703,11 @@ bool CookieMonster::SetCookieWithCreationTimeAndOptions( creation_time = CurrentTime(); last_time_seen_ = creation_time; } + Time server_time; + if (options.has_server_time()) + server_time = options.server_time(); + else + server_time = creation_time; // Parse the cookie. ParsedCookie pc(cookie_line); @@ -1728,7 +1733,8 @@ bool CookieMonster::SetCookieWithCreationTimeAndOptions( pc.MACAlgorithm() : std::string(); scoped_ptr<CanonicalCookie> cc; - Time cookie_expires = CanonicalCookie::CanonExpiration(pc, creation_time); + Time cookie_expires = + CanonicalCookie::CanonExpiration(pc, creation_time, server_time); cc.reset(new CanonicalCookie(url, pc.Name(), pc.Value(), cookie_domain, cookie_path, mac_key, mac_algorithm, diff --git a/net/cookies/cookie_options.h b/net/cookies/cookie_options.h index 8370702..ed5e2ef 100644 --- a/net/cookies/cookie_options.h +++ b/net/cookies/cookie_options.h @@ -15,15 +15,26 @@ class CookieOptions { // - reading operations will not return httponly cookies. // - writing operations will not write httponly cookies. CookieOptions() - : exclude_httponly_(true) { + : exclude_httponly_(true), + server_time_() { } void set_exclude_httponly() { exclude_httponly_ = true; } void set_include_httponly() { exclude_httponly_ = false; } bool exclude_httponly() const { return exclude_httponly_; } + // |server_time| indicates what the server sending us the Cookie thought the + // current time was when the cookie was produced. This is used to adjust for + // clock skew between server and host. + void set_server_time(const base::Time& server_time) { + server_time_ = server_time; + } + bool has_server_time() const { return !server_time_.is_null(); } + base::Time server_time() const { return server_time_; } + private: bool exclude_httponly_; + base::Time server_time_; }; } // namespace net diff --git a/net/cookies/cookie_store_unittest.h b/net/cookies/cookie_store_unittest.h index 575b0cd..51c389d 100644 --- a/net/cookies/cookie_store_unittest.h +++ b/net/cookies/cookie_store_unittest.h @@ -147,6 +147,17 @@ class CookieStoreTest : public testing::Test { return callback.result(); } + bool SetCookieWithServerTime(CookieStore* cs, + const GURL& url, + const std::string& cookie_line, + const base::Time& server_time) { + CookieOptions options; + if (!CookieStoreTestTraits::supports_http_only) + options.set_include_httponly(); + options.set_server_time(server_time); + return SetCookieWithOptions(cs, url, cookie_line, options); + } + bool SetCookie(CookieStore* cs, const GURL& url, const std::string& cookie_line) { @@ -702,6 +713,22 @@ TYPED_TEST_P(CookieStoreTest, TestCookieDeletion) { std::string(kValidCookieLine) + "; expires=Mon, 18-Apr-22 22:50:13 GMT")); this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_)); + // Check that it is not deleted with significant enough clock skew. + base::Time server_time; + EXPECT_TRUE(base::Time::FromString("Sun, 17-Apr-1977 22:50:13 GMT", + &server_time)); + EXPECT_TRUE(this->SetCookieWithServerTime( + cs, this->url_google_, + std::string(kValidCookieLine) + + "; expires=Mon, 18-Apr-1977 22:50:13 GMT", + server_time)); + this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_)); + + // Create a persistent cookie. + EXPECT_TRUE(this->SetCookie(cs, this->url_google_, + std::string(kValidCookieLine) + + "; expires=Mon, 18-Apr-22 22:50:13 GMT")); + this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_)); // Delete it via Expires, with a unix epoch of 0. EXPECT_TRUE(this->SetCookie(cs, this->url_google_, std::string(kValidCookieLine) + |