12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/blacklist.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <algorithm> 858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include <iterator> 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/lazy_instance.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/ref_counted.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h" 143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/stl_util.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/browser_process.h" 167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/extension_prefs.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/safe_browsing/safe_browsing_service.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/safe_browsing/safe_browsing_util.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/pref_names.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/notification_details.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/notification_source.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::BrowserThread; 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace extensions { 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The safe browsing database manager to use. Make this a global/static variable 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// rather than a member of Blacklist because Blacklist accesses the real 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// database manager before it has a chance to get a fake one. 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class LazySafeBrowsingDatabaseManager { 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LazySafeBrowsingDatabaseManager() { 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(FULL_SAFE_BROWSING) || defined(MOBILE_SAFE_BROWSING) 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (g_browser_process && g_browser_process->safe_browsing_service()) { 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) instance_ = 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) g_browser_process->safe_browsing_service()->database_manager(); 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<SafeBrowsingDatabaseManager> get() { 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return instance_; 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void set(scoped_refptr<SafeBrowsingDatabaseManager> instance) { 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) instance_ = instance; 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<SafeBrowsingDatabaseManager> instance_; 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static base::LazyInstance<LazySafeBrowsingDatabaseManager> g_database_manager = 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LAZY_INSTANCE_INITIALIZER; 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Implementation of SafeBrowsingDatabaseManager::Client, the class which is 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// called back from safebrowsing queries. 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Constructed on any thread but lives on the IO from then on. 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class SafeBrowsingClientImpl 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : public SafeBrowsingDatabaseManager::Client, 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public base::RefCountedThreadSafe<SafeBrowsingClientImpl> { 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef base::Callback<void(const std::set<std::string>&)> OnResultCallback; 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Constructs a client to query the database manager for |extension_ids| and 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // run |callback| with the IDs of those which have been blacklisted. 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SafeBrowsingClientImpl( 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::set<std::string>& extension_ids, 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const OnResultCallback& callback) 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : callback_message_loop_(base::MessageLoopProxy::current()), 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_(callback) { 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::PostTask( 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::IO, 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&SafeBrowsingClientImpl::StartCheck, this, 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) g_database_manager.Get().get(), 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_ids)); 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) friend class base::RefCountedThreadSafe<SafeBrowsingClientImpl>; 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~SafeBrowsingClientImpl() {} 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Pass |database_manager| as a parameter to avoid touching 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // SafeBrowsingService on the IO thread. 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void StartCheck(scoped_refptr<SafeBrowsingDatabaseManager> database_manager, 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::set<std::string>& extension_ids) { 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (database_manager->CheckExtensionIDs(extension_ids, this)) { 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Definitely not blacklisted. Callback immediately. 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_message_loop_->PostTask( 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback_, std::set<std::string>())); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Something might be blacklisted, response will come in 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // OnCheckExtensionsResult. 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddRef(); // Balanced in OnCheckExtensionsResult 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnCheckExtensionsResult( 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::set<std::string>& hits) OVERRIDE { 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_message_loop_->PostTask(FROM_HERE, base::Bind(callback_, hits)); 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Release(); // Balanced in StartCheck. 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<base::MessageLoopProxy> callback_message_loop_; 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnResultCallback callback_; 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(SafeBrowsingClientImpl); 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void CheckOneExtensionState( 1191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const Blacklist::IsBlacklistedCallback& callback, 1201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const Blacklist::BlacklistStateMap& state_map) { 1211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) callback.Run(state_map.empty() ? Blacklist::NOT_BLACKLISTED 1221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) : state_map.begin()->second); 1231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void GetMalwareFromBlacklistStateMap( 1261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const Blacklist::GetMalwareIDsCallback& callback, 1271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const Blacklist::BlacklistStateMap& state_map) { 1281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) std::set<std::string> malware; 1291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) for (Blacklist::BlacklistStateMap::const_iterator it = state_map.begin(); 1301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) it != state_map.end(); ++it) { 1311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (it->second == Blacklist::BLACKLISTED_MALWARE) 1321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) malware.insert(it->first); 1331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 1341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) callback.Run(malware); 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Blacklist::Observer::Observer(Blacklist* blacklist) : blacklist_(blacklist) { 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) blacklist_->AddObserver(this); 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Blacklist::Observer::~Observer() { 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) blacklist_->RemoveObserver(this); 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Blacklist::ScopedDatabaseManagerForTest::ScopedDatabaseManagerForTest( 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<SafeBrowsingDatabaseManager> database_manager) 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : original_(GetDatabaseManager()) { 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetDatabaseManager(database_manager); 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Blacklist::ScopedDatabaseManagerForTest::~ScopedDatabaseManagerForTest() { 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetDatabaseManager(original_); 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 15768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)Blacklist::Blacklist(ExtensionPrefs* prefs) { 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<SafeBrowsingDatabaseManager> database_manager = 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) g_database_manager.Get().get(); 16068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (database_manager) { 161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) registrar_.Add( 162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) this, 163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) chrome::NOTIFICATION_SAFE_BROWSING_UPDATE_COMPLETE, 164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) content::Source<SafeBrowsingDatabaseManager>(database_manager.get())); 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 16768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Clear out the old prefs-backed blacklist, stored as empty extension entries 16868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // with just a "blacklisted" property. 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 17068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // TODO(kalman): Delete this block of code, see http://crbug.com/295882. 17168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::set<std::string> blacklisted = prefs->GetBlacklistedExtensions(); 17268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (std::set<std::string>::iterator it = blacklisted.begin(); 17368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) it != blacklisted.end(); ++it) { 17468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!prefs->GetInstalledExtensionInfo(*it)) 17568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) prefs->DeleteExtensionPrefs(*it); 17668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Blacklist::~Blacklist() { 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Blacklist::GetBlacklistedIDs(const std::set<std::string>& ids, 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GetBlacklistedIDsCallback& callback) { 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (ids.empty() || !g_database_manager.Get().get().get()) { 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 1881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) FROM_HERE, base::Bind(callback, BlacklistStateMap())); 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Constructing the SafeBrowsingClientImpl begins the process of asking 1931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // safebrowsing for the blacklisted extensions. The set of blacklisted 1941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // extensions returned by SafeBrowsing will then be passed to 1951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // GetBlacklistStateIDs to get the particular BlacklistState for each id. 1961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) new SafeBrowsingClientImpl( 1971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ids, base::Bind(&Blacklist::GetBlacklistStateForIDs, AsWeakPtr(), 1981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) callback)); 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void Blacklist::GetMalwareIDs(const std::set<std::string>& ids, 2021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const GetMalwareIDsCallback& callback) { 2031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) GetBlacklistedIDs(ids, base::Bind(&GetMalwareFromBlacklistStateMap, 2041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) callback)); 2051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 2061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Blacklist::IsBlacklisted(const std::string& extension_id, 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const IsBlacklistedCallback& callback) { 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::set<std::string> check; 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) check.insert(extension_id); 2121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) GetBlacklistedIDs(check, base::Bind(&CheckOneExtensionState, callback)); 2131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 2141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void Blacklist::GetBlacklistStateForIDs( 2161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const GetBlacklistedIDsCallback& callback, 2171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const std::set<std::string>& blacklisted_ids) { 2181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) std::set<std::string> ids_unknown_state; 2211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) BlacklistStateMap extensions_state; 2221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) for (std::set<std::string>::const_iterator it = blacklisted_ids.begin(); 2231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) it != blacklisted_ids.end(); ++it) { 2241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) BlacklistStateMap::const_iterator cache_it = 2251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) blacklist_state_cache_.find(*it); 2261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (cache_it == blacklist_state_cache_.end()) 2271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ids_unknown_state.insert(*it); 2281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) else 2291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) extensions_state[*it] = cache_it->second; 2301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 2311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (ids_unknown_state.empty()) { 2331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) callback.Run(extensions_state); 2341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } else { 2351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // After the extension blacklist states have been downloaded, call this 2361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // functions again, but prevent infinite cycle in case server is offline 2371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // or some other reason prevents us from receiving the blacklist state for 2381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // these extensions. 2391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) RequestExtensionsBlacklistState( 2401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ids_unknown_state, 2411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::Bind(&Blacklist::ReturnBlacklistStateMap, AsWeakPtr(), 2421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) callback, blacklisted_ids)); 2431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 2441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 2451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void Blacklist::ReturnBlacklistStateMap( 2471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const GetBlacklistedIDsCallback& callback, 2481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const std::set<std::string>& blacklisted_ids) { 2491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) BlacklistStateMap extensions_state; 2501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) for (std::set<std::string>::const_iterator it = blacklisted_ids.begin(); 2511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) it != blacklisted_ids.end(); ++it) { 2521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) BlacklistStateMap::const_iterator cache_it = 2531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) blacklist_state_cache_.find(*it); 2541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (cache_it != blacklist_state_cache_.end()) 2551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) extensions_state[*it] = cache_it->second; 2561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // If for some reason we still haven't cached the state of this extension, 2571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // we silently skip it. 2581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 2591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) callback.Run(extensions_state); 2611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 2621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void Blacklist::RequestExtensionsBlacklistState( 2641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const std::set<std::string> ids, base::Callback<void()> callback) { 2651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // This is a stub. The request will be made here, but the server is not up 2671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // yet. For compatibility with current blacklist logic, mark all extensions 2681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // as malicious. 2691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) for (std::set<std::string>::const_iterator it = ids.begin(); 2701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) it != ids.end(); 2711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ++it) { 2721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) blacklist_state_cache_[*it] = BLACKLISTED_MALWARE; 2731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 2741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) callback.Run(); 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Blacklist::AddObserver(Observer* observer) { 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) observers_.AddObserver(observer); 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Blacklist::RemoveObserver(Observer* observer) { 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) observers_.RemoveObserver(observer); 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Blacklist::SetDatabaseManager( 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<SafeBrowsingDatabaseManager> database_manager) { 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) g_database_manager.Get().set(database_manager); 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<SafeBrowsingDatabaseManager> Blacklist::GetDatabaseManager() { 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return g_database_manager.Get().get(); 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Blacklist::Observe(int type, 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const content::NotificationSource& source, 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const content::NotificationDetails& details) { 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(chrome::NOTIFICATION_SAFE_BROWSING_UPDATE_COMPLETE, type); 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FOR_EACH_OBSERVER(Observer, observers_, OnBlacklistUpdated()); 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace extensions 306