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" 15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/prerender/prerender_manager.h" 16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/prerender/prerender_manager_factory.h" 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h" 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/common/chrome_constants.h" 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/common/chrome_switches.h" 21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "components/os_crypt/os_crypt.h" 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/cookie_crypto_delegate.h" 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/cookie_store_factory.h" 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/notification_service.h" 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/common/content_constants.h" 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/common/constants.h" 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using content::BrowserThread; 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class ChromeCookieMonsterDelegate : public net::CookieMonsterDelegate { 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) explicit ChromeCookieMonsterDelegate(Profile* profile) 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : profile_getter_( 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&GetProfileOnUI, g_browser_process->profile_manager(), 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) profile)) { 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(profile); 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // net::CookieMonster::Delegate implementation. 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void OnCookieChanged( 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const net::CanonicalCookie& cookie, 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool removed, 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) net::CookieMonster::Delegate::ChangeCause cause) OVERRIDE { 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BrowserThread::PostTask( 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BrowserThread::UI, FROM_HERE, 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&ChromeCookieMonsterDelegate::OnCookieChangedAsyncHelper, 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this, cookie, removed, cause)); 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual void OnLoaded() OVERRIDE { 55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) BrowserThread::PostTask( 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) BrowserThread::UI, FROM_HERE, 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&ChromeCookieMonsterDelegate::OnLoadedAsyncHelper, 58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this)); 59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ~ChromeCookieMonsterDelegate() {} 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static Profile* GetProfileOnUI(ProfileManager* profile_manager, 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Profile* profile) { 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (profile_manager->IsValidProfile(profile)) 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return profile; 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return NULL; 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void OnCookieChangedAsyncHelper( 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const net::CanonicalCookie& cookie, 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool removed, 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) net::CookieMonster::Delegate::ChangeCause cause) { 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Profile* profile = profile_getter_.Run(); 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (profile) { 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ChromeCookieDetails cookie_details(&cookie, removed, cause); 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::NotificationService::current()->Notify( 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) chrome::NOTIFICATION_COOKIE_CHANGED, 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::Source<Profile>(profile), 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::Details<ChromeCookieDetails>(&cookie_details)); 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void OnLoadedAsyncHelper() { 86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Profile* profile = profile_getter_.Run(); 87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (profile) { 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) prerender::PrerenderManager* prerender_manager = 89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) prerender::PrerenderManagerFactory::GetForProfile(profile); 90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (prerender_manager) 91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) prerender_manager->OnCookieStoreLoaded(); 92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::Callback<Profile*(void)> profile_getter_; 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace chrome_browser_net { 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool IsCookieRecordMode() { 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Only allow Record Mode if we are in a Debug build or where we are running 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // a cycle, and the user has limited control. 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return command_line.HasSwitch(switches::kRecordMode) && 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) chrome::kRecordModeEnabled; 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool ShouldUseInMemoryCookiesAndCache() { 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return IsCookieRecordMode() || 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) command_line.HasSwitch(switches::kPlaybackMode); 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)net::CookieMonsterDelegate* CreateCookieDelegate(Profile* profile) { 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return new EvictedDomainCookieCounter( 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new ChromeCookieMonsterDelegate(profile)); 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use the operating system's mechanisms to encrypt cookies before writing 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// them to persistent store. Currently this only is done with desktop OS's 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// because ChromeOS and Android already protect the entire profile contents. 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// TODO(bcwhite): Enable on MACOSX -- requires all Cookie tests to call 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// OSCrypt::UseMockKeychain or will hang waiting for user input. 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class CookieOSCryptoDelegate : public content::CookieCryptoDelegate { 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual bool EncryptString(const std::string& plaintext, 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string* ciphertext) OVERRIDE; 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual bool DecryptString(const std::string& ciphertext, 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string* plaintext) OVERRIDE; 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool CookieOSCryptoDelegate::EncryptString(const std::string& plaintext, 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string* ciphertext) { 140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return OSCrypt::EncryptString(plaintext, ciphertext); 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool CookieOSCryptoDelegate::DecryptString(const std::string& ciphertext, 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string* plaintext) { 145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return OSCrypt::DecryptString(ciphertext, plaintext); 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Using a LazyInstance is safe here because this class is stateless and 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// requires 0 initialization. 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::LazyInstance<CookieOSCryptoDelegate> g_cookie_crypto_delegate = 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LAZY_INSTANCE_INITIALIZER; 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)content::CookieCryptoDelegate* GetCookieCryptoDelegate() { 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return g_cookie_crypto_delegate.Pointer(); 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#else // defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)content::CookieCryptoDelegate* GetCookieCryptoDelegate() { 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return NULL; 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif // defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace chrome_browser_net 165