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