cookie_store_util.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/net/cookie_store_util.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/bind.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/callback.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/command_line.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/lazy_instance.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/browser_process.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/chrome_notification_types.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/net/chrome_cookie_notification_details.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/net/evicted_domain_cookie_counter.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h"
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/common/chrome_constants.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "components/os_crypt/os_crypt.h"
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/cookie_crypto_delegate.h"
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/cookie_store_factory.h"
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/notification_service.h"
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/common/content_constants.h"
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/common/constants.h"
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using content::BrowserThread;
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class ChromeCookieMonsterDelegate : public net::CookieMonsterDelegate {
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  explicit ChromeCookieMonsterDelegate(Profile* profile)
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : profile_getter_(
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          base::Bind(&GetProfileOnUI, g_browser_process->profile_manager(),
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     profile)) {
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(profile);
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // net::CookieMonster::Delegate implementation.
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void OnCookieChanged(
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const net::CanonicalCookie& cookie,
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      bool removed,
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      net::CookieMonster::Delegate::ChangeCause cause) OVERRIDE {
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    BrowserThread::PostTask(
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        BrowserThread::UI, FROM_HERE,
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::Bind(&ChromeCookieMonsterDelegate::OnCookieChangedAsyncHelper,
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   this, cookie, removed, cause));
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~ChromeCookieMonsterDelegate() {}
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static Profile* GetProfileOnUI(ProfileManager* profile_manager,
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 Profile* profile) {
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (profile_manager->IsValidProfile(profile))
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return profile;
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return NULL;
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void OnCookieChangedAsyncHelper(
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const net::CanonicalCookie& cookie,
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      bool removed,
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      net::CookieMonster::Delegate::ChangeCause cause) {
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    Profile* profile = profile_getter_.Run();
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (profile) {
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ChromeCookieDetails cookie_details(&cookie, removed, cause);
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      content::NotificationService::current()->Notify(
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          chrome::NOTIFICATION_COOKIE_CHANGED,
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          content::Source<Profile>(profile),
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          content::Details<ChromeCookieDetails>(&cookie_details));
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::Callback<Profile*(void)> profile_getter_;
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace chrome_browser_net {
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool IsCookieRecordMode() {
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Only allow Record Mode if we are in a Debug build or where we are running
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // a cycle, and the user has limited control.
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return command_line.HasSwitch(switches::kRecordMode) &&
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      chrome::kRecordModeEnabled;
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool ShouldUseInMemoryCookiesAndCache() {
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return IsCookieRecordMode() ||
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      command_line.HasSwitch(switches::kPlaybackMode);
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)net::CookieMonsterDelegate* CreateCookieDelegate(Profile* profile) {
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return new EvictedDomainCookieCounter(
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new ChromeCookieMonsterDelegate(profile));
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use the operating system's mechanisms to encrypt cookies before writing
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// them to persistent store.  Currently this only is done with desktop OS's
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// because ChromeOS and Android already protect the entire profile contents.
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// TODO(bcwhite): Enable on MACOSX -- requires all Cookie tests to call
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// OSCrypt::UseMockKeychain or will hang waiting for user input.
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class CookieOSCryptoDelegate : public content::CookieCryptoDelegate {
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual bool EncryptString(const std::string& plaintext,
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             std::string* ciphertext) OVERRIDE;
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual bool DecryptString(const std::string& ciphertext,
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             std::string* plaintext) OVERRIDE;
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool CookieOSCryptoDelegate::EncryptString(const std::string& plaintext,
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           std::string* ciphertext) {
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return OSCrypt::EncryptString(plaintext, ciphertext);
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool CookieOSCryptoDelegate::DecryptString(const std::string& ciphertext,
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           std::string* plaintext) {
126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return OSCrypt::DecryptString(ciphertext, plaintext);
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Using a LazyInstance is safe here because this class is stateless and
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// requires 0 initialization.
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::LazyInstance<CookieOSCryptoDelegate> g_cookie_crypto_delegate =
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    LAZY_INSTANCE_INITIALIZER;
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)content::CookieCryptoDelegate* GetCookieCryptoDelegate() {
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return g_cookie_crypto_delegate.Pointer();
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#else  // defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)content::CookieCryptoDelegate* GetCookieCryptoDelegate() {
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return NULL;
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif  // defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace chrome_browser_net
146