cookie_store_util.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/net/cookie_store_util.h"
6
7#include "base/bind.h"
8#include "base/callback.h"
9#include "base/command_line.h"
10#include "base/lazy_instance.h"
11#include "chrome/browser/browser_process.h"
12#include "chrome/browser/chrome_notification_types.h"
13#include "chrome/browser/net/chrome_cookie_notification_details.h"
14#include "chrome/browser/net/evicted_domain_cookie_counter.h"
15#include "chrome/browser/prerender/prerender_manager.h"
16#include "chrome/browser/prerender/prerender_manager_factory.h"
17#include "chrome/browser/profiles/profile.h"
18#include "chrome/browser/profiles/profile_manager.h"
19#include "chrome/common/chrome_constants.h"
20#include "chrome/common/chrome_switches.h"
21#include "components/os_crypt/os_crypt.h"
22#include "content/public/browser/browser_thread.h"
23#include "content/public/browser/cookie_crypto_delegate.h"
24#include "content/public/browser/cookie_store_factory.h"
25#include "content/public/browser/notification_service.h"
26#include "content/public/common/content_constants.h"
27#include "extensions/common/constants.h"
28
29using content::BrowserThread;
30
31namespace {
32
33class ChromeCookieMonsterDelegate : public net::CookieMonsterDelegate {
34 public:
35  explicit ChromeCookieMonsterDelegate(Profile* profile)
36      : profile_getter_(
37          base::Bind(&GetProfileOnUI, g_browser_process->profile_manager(),
38                     profile)) {
39    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
40    DCHECK(profile);
41  }
42
43  // net::CookieMonster::Delegate implementation.
44  virtual void OnCookieChanged(
45      const net::CanonicalCookie& cookie,
46      bool removed,
47      net::CookieMonster::Delegate::ChangeCause cause) OVERRIDE {
48    BrowserThread::PostTask(
49        BrowserThread::UI, FROM_HERE,
50        base::Bind(&ChromeCookieMonsterDelegate::OnCookieChangedAsyncHelper,
51                   this, cookie, removed, cause));
52  }
53
54  virtual void OnLoaded() OVERRIDE {
55    BrowserThread::PostTask(
56        BrowserThread::UI, FROM_HERE,
57        base::Bind(&ChromeCookieMonsterDelegate::OnLoadedAsyncHelper,
58                   this));
59  }
60
61 private:
62  virtual ~ChromeCookieMonsterDelegate() {}
63
64  static Profile* GetProfileOnUI(ProfileManager* profile_manager,
65                                 Profile* profile) {
66    if (profile_manager->IsValidProfile(profile))
67      return profile;
68    return NULL;
69  }
70
71  void OnCookieChangedAsyncHelper(
72      const net::CanonicalCookie& cookie,
73      bool removed,
74      net::CookieMonster::Delegate::ChangeCause cause) {
75    Profile* profile = profile_getter_.Run();
76    if (profile) {
77      ChromeCookieDetails cookie_details(&cookie, removed, cause);
78      content::NotificationService::current()->Notify(
79          chrome::NOTIFICATION_COOKIE_CHANGED,
80          content::Source<Profile>(profile),
81          content::Details<ChromeCookieDetails>(&cookie_details));
82    }
83  }
84
85  void OnLoadedAsyncHelper() {
86    Profile* profile = profile_getter_.Run();
87    if (profile) {
88      prerender::PrerenderManager* prerender_manager =
89          prerender::PrerenderManagerFactory::GetForProfile(profile);
90      if (prerender_manager)
91        prerender_manager->OnCookieStoreLoaded();
92    }
93  }
94
95  const base::Callback<Profile*(void)> profile_getter_;
96};
97
98}  // namespace
99
100namespace chrome_browser_net {
101
102bool IsCookieRecordMode() {
103  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
104  // Only allow Record Mode if we are in a Debug build or where we are running
105  // a cycle, and the user has limited control.
106  return command_line.HasSwitch(switches::kRecordMode) &&
107      chrome::kRecordModeEnabled;
108}
109
110bool ShouldUseInMemoryCookiesAndCache() {
111  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
112  return IsCookieRecordMode() ||
113      command_line.HasSwitch(switches::kPlaybackMode);
114}
115
116net::CookieMonsterDelegate* CreateCookieDelegate(Profile* profile) {
117  return new EvictedDomainCookieCounter(
118      new ChromeCookieMonsterDelegate(profile));
119}
120
121#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)
122namespace {
123
124// Use the operating system's mechanisms to encrypt cookies before writing
125// them to persistent store.  Currently this only is done with desktop OS's
126// because ChromeOS and Android already protect the entire profile contents.
127//
128// TODO(bcwhite): Enable on MACOSX -- requires all Cookie tests to call
129// OSCrypt::UseMockKeychain or will hang waiting for user input.
130class CookieOSCryptoDelegate : public content::CookieCryptoDelegate {
131 public:
132  virtual bool EncryptString(const std::string& plaintext,
133                             std::string* ciphertext) OVERRIDE;
134  virtual bool DecryptString(const std::string& ciphertext,
135                             std::string* plaintext) OVERRIDE;
136};
137
138bool CookieOSCryptoDelegate::EncryptString(const std::string& plaintext,
139                                           std::string* ciphertext) {
140  return OSCrypt::EncryptString(plaintext, ciphertext);
141}
142
143bool CookieOSCryptoDelegate::DecryptString(const std::string& ciphertext,
144                                           std::string* plaintext) {
145  return OSCrypt::DecryptString(ciphertext, plaintext);
146}
147
148// Using a LazyInstance is safe here because this class is stateless and
149// requires 0 initialization.
150base::LazyInstance<CookieOSCryptoDelegate> g_cookie_crypto_delegate =
151    LAZY_INSTANCE_INITIALIZER;
152
153}  // namespace
154
155content::CookieCryptoDelegate* GetCookieCryptoDelegate() {
156  return g_cookie_crypto_delegate.Pointer();
157}
158#else  // defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)
159content::CookieCryptoDelegate* GetCookieCryptoDelegate() {
160  return NULL;
161}
162#endif  // defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)
163
164}  // namespace chrome_browser_net
165