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