| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/net/cookie_store_util.h" |
| |
| #include "base/bind.h" |
| #include "base/callback.h" |
| #include "base/command_line.h" |
| #include "base/lazy_instance.h" |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/chrome_notification_types.h" |
| #include "chrome/browser/net/chrome_cookie_notification_details.h" |
| #include "chrome/browser/net/evicted_domain_cookie_counter.h" |
| #include "chrome/browser/prerender/prerender_manager.h" |
| #include "chrome/browser/prerender/prerender_manager_factory.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/profiles/profile_manager.h" |
| #include "chrome/common/chrome_constants.h" |
| #include "chrome/common/chrome_switches.h" |
| #include "components/os_crypt/os_crypt.h" |
| #include "content/public/browser/browser_thread.h" |
| #include "content/public/browser/cookie_crypto_delegate.h" |
| #include "content/public/browser/cookie_store_factory.h" |
| #include "content/public/browser/notification_service.h" |
| #include "content/public/common/content_constants.h" |
| #include "extensions/common/constants.h" |
| |
| using content::BrowserThread; |
| |
| namespace { |
| |
| class ChromeCookieMonsterDelegate : public net::CookieMonsterDelegate { |
| public: |
| explicit ChromeCookieMonsterDelegate(Profile* profile) |
| : profile_getter_( |
| base::Bind(&GetProfileOnUI, g_browser_process->profile_manager(), |
| profile)) { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| DCHECK(profile); |
| } |
| |
| // net::CookieMonster::Delegate implementation. |
| virtual void OnCookieChanged( |
| const net::CanonicalCookie& cookie, |
| bool removed, |
| net::CookieMonster::Delegate::ChangeCause cause) OVERRIDE { |
| BrowserThread::PostTask( |
| BrowserThread::UI, FROM_HERE, |
| base::Bind(&ChromeCookieMonsterDelegate::OnCookieChangedAsyncHelper, |
| this, cookie, removed, cause)); |
| } |
| |
| virtual void OnLoaded() OVERRIDE { |
| BrowserThread::PostTask( |
| BrowserThread::UI, FROM_HERE, |
| base::Bind(&ChromeCookieMonsterDelegate::OnLoadedAsyncHelper, |
| this)); |
| } |
| |
| private: |
| virtual ~ChromeCookieMonsterDelegate() {} |
| |
| static Profile* GetProfileOnUI(ProfileManager* profile_manager, |
| Profile* profile) { |
| if (profile_manager->IsValidProfile(profile)) |
| return profile; |
| return NULL; |
| } |
| |
| void OnCookieChangedAsyncHelper( |
| const net::CanonicalCookie& cookie, |
| bool removed, |
| net::CookieMonster::Delegate::ChangeCause cause) { |
| Profile* profile = profile_getter_.Run(); |
| if (profile) { |
| ChromeCookieDetails cookie_details(&cookie, removed, cause); |
| content::NotificationService::current()->Notify( |
| chrome::NOTIFICATION_COOKIE_CHANGED, |
| content::Source<Profile>(profile), |
| content::Details<ChromeCookieDetails>(&cookie_details)); |
| } |
| } |
| |
| void OnLoadedAsyncHelper() { |
| Profile* profile = profile_getter_.Run(); |
| if (profile) { |
| prerender::PrerenderManager* prerender_manager = |
| prerender::PrerenderManagerFactory::GetForProfile(profile); |
| if (prerender_manager) |
| prerender_manager->OnCookieStoreLoaded(); |
| } |
| } |
| |
| const base::Callback<Profile*(void)> profile_getter_; |
| }; |
| |
| } // namespace |
| |
| namespace chrome_browser_net { |
| |
| bool IsCookieRecordMode() { |
| const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
| // Only allow Record Mode if we are in a Debug build or where we are running |
| // a cycle, and the user has limited control. |
| return command_line.HasSwitch(switches::kRecordMode) && |
| chrome::kRecordModeEnabled; |
| } |
| |
| bool ShouldUseInMemoryCookiesAndCache() { |
| const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
| return IsCookieRecordMode() || |
| command_line.HasSwitch(switches::kPlaybackMode); |
| } |
| |
| net::CookieMonsterDelegate* CreateCookieDelegate(Profile* profile) { |
| return new EvictedDomainCookieCounter( |
| new ChromeCookieMonsterDelegate(profile)); |
| } |
| |
| #if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) |
| namespace { |
| |
| // Use the operating system's mechanisms to encrypt cookies before writing |
| // them to persistent store. Currently this only is done with desktop OS's |
| // because ChromeOS and Android already protect the entire profile contents. |
| // |
| // TODO(bcwhite): Enable on MACOSX -- requires all Cookie tests to call |
| // OSCrypt::UseMockKeychain or will hang waiting for user input. |
| class CookieOSCryptoDelegate : public content::CookieCryptoDelegate { |
| public: |
| virtual bool EncryptString(const std::string& plaintext, |
| std::string* ciphertext) OVERRIDE; |
| virtual bool DecryptString(const std::string& ciphertext, |
| std::string* plaintext) OVERRIDE; |
| }; |
| |
| bool CookieOSCryptoDelegate::EncryptString(const std::string& plaintext, |
| std::string* ciphertext) { |
| return OSCrypt::EncryptString(plaintext, ciphertext); |
| } |
| |
| bool CookieOSCryptoDelegate::DecryptString(const std::string& ciphertext, |
| std::string* plaintext) { |
| return OSCrypt::DecryptString(ciphertext, plaintext); |
| } |
| |
| // Using a LazyInstance is safe here because this class is stateless and |
| // requires 0 initialization. |
| base::LazyInstance<CookieOSCryptoDelegate> g_cookie_crypto_delegate = |
| LAZY_INSTANCE_INITIALIZER; |
| |
| } // namespace |
| |
| content::CookieCryptoDelegate* GetCookieCryptoDelegate() { |
| return g_cookie_crypto_delegate.Pointer(); |
| } |
| #else // defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) |
| content::CookieCryptoDelegate* GetCookieCryptoDelegate() { |
| return NULL; |
| } |
| #endif // defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) |
| |
| } // namespace chrome_browser_net |