This source file includes following definitions.
- get
- set
- callback_
- StartCheck
- OnCheckExtensionsResult
- CheckOneExtensionState
- GetMalwareFromBlacklistStateMap
- GetBlacklistedIDs
- GetMalwareIDs
- IsBlacklisted
- GetBlacklistStateForIDs
- ReturnBlacklistStateMap
- RequestExtensionsBlacklistState
- OnBlacklistStateReceived
- SetBlacklistStateFetcherForTest
- ResetBlacklistStateFetcherForTest
- AddObserver
- RemoveObserver
- SetDatabaseManager
- GetDatabaseManager
- Observe
#include "chrome/browser/extensions/blacklist.h"
#include <algorithm>
#include <iterator>
#include "base/bind.h"
#include "base/lazy_instance.h"
#include "base/memory/ref_counted.h"
#include "base/prefs/pref_service.h"
#include "base/stl_util.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/blacklist_state_fetcher.h"
#include "chrome/browser/safe_browsing/safe_browsing_service.h"
#include "chrome/browser/safe_browsing/safe_browsing_util.h"
#include "chrome/common/pref_names.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
#include "extensions/browser/extension_prefs.h"
using content::BrowserThread;
namespace extensions {
namespace {
class LazySafeBrowsingDatabaseManager {
public:
LazySafeBrowsingDatabaseManager() {
#if defined(FULL_SAFE_BROWSING) || defined(MOBILE_SAFE_BROWSING)
if (g_browser_process && g_browser_process->safe_browsing_service()) {
instance_ =
g_browser_process->safe_browsing_service()->database_manager();
}
#endif
}
scoped_refptr<SafeBrowsingDatabaseManager> get() {
return instance_;
}
void set(scoped_refptr<SafeBrowsingDatabaseManager> instance) {
instance_ = instance;
}
private:
scoped_refptr<SafeBrowsingDatabaseManager> instance_;
};
static base::LazyInstance<LazySafeBrowsingDatabaseManager> g_database_manager =
LAZY_INSTANCE_INITIALIZER;
class SafeBrowsingClientImpl
: public SafeBrowsingDatabaseManager::Client,
public base::RefCountedThreadSafe<SafeBrowsingClientImpl> {
public:
typedef base::Callback<void(const std::set<std::string>&)> OnResultCallback;
SafeBrowsingClientImpl(
const std::set<std::string>& extension_ids,
const OnResultCallback& callback)
: callback_message_loop_(base::MessageLoopProxy::current()),
callback_(callback) {
BrowserThread::PostTask(
BrowserThread::IO,
FROM_HERE,
base::Bind(&SafeBrowsingClientImpl::StartCheck, this,
g_database_manager.Get().get(),
extension_ids));
}
private:
friend class base::RefCountedThreadSafe<SafeBrowsingClientImpl>;
virtual ~SafeBrowsingClientImpl() {}
void StartCheck(scoped_refptr<SafeBrowsingDatabaseManager> database_manager,
const std::set<std::string>& extension_ids) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (database_manager->CheckExtensionIDs(extension_ids, this)) {
callback_message_loop_->PostTask(
FROM_HERE,
base::Bind(callback_, std::set<std::string>()));
return;
}
AddRef();
}
virtual void OnCheckExtensionsResult(
const std::set<std::string>& hits) OVERRIDE {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
callback_message_loop_->PostTask(FROM_HERE, base::Bind(callback_, hits));
Release();
}
scoped_refptr<base::MessageLoopProxy> callback_message_loop_;
OnResultCallback callback_;
DISALLOW_COPY_AND_ASSIGN(SafeBrowsingClientImpl);
};
void CheckOneExtensionState(
const Blacklist::IsBlacklistedCallback& callback,
const Blacklist::BlacklistStateMap& state_map) {
callback.Run(state_map.empty() ? NOT_BLACKLISTED : state_map.begin()->second);
}
void GetMalwareFromBlacklistStateMap(
const Blacklist::GetMalwareIDsCallback& callback,
const Blacklist::BlacklistStateMap& state_map) {
std::set<std::string> malware;
for (Blacklist::BlacklistStateMap::const_iterator it = state_map.begin();
it != state_map.end(); ++it) {
if (it->second == BLACKLISTED_MALWARE || it->second == BLACKLISTED_UNKNOWN)
malware.insert(it->first);
}
callback.Run(malware);
}
}
Blacklist::Observer::Observer(Blacklist* blacklist) : blacklist_(blacklist) {
blacklist_->AddObserver(this);
}
Blacklist::Observer::~Observer() {
blacklist_->RemoveObserver(this);
}
Blacklist::ScopedDatabaseManagerForTest::ScopedDatabaseManagerForTest(
scoped_refptr<SafeBrowsingDatabaseManager> database_manager)
: original_(GetDatabaseManager()) {
SetDatabaseManager(database_manager);
}
Blacklist::ScopedDatabaseManagerForTest::~ScopedDatabaseManagerForTest() {
SetDatabaseManager(original_);
}
Blacklist::Blacklist(ExtensionPrefs* prefs) {
scoped_refptr<SafeBrowsingDatabaseManager> database_manager =
g_database_manager.Get().get();
if (database_manager) {
registrar_.Add(
this,
chrome::NOTIFICATION_SAFE_BROWSING_UPDATE_COMPLETE,
content::Source<SafeBrowsingDatabaseManager>(database_manager.get()));
}
std::set<std::string> blacklisted = prefs->GetBlacklistedExtensions();
for (std::set<std::string>::iterator it = blacklisted.begin();
it != blacklisted.end(); ++it) {
if (!prefs->GetInstalledExtensionInfo(*it))
prefs->DeleteExtensionPrefs(*it);
}
}
Blacklist::~Blacklist() {
}
void Blacklist::GetBlacklistedIDs(const std::set<std::string>& ids,
const GetBlacklistedIDsCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (ids.empty() || !g_database_manager.Get().get().get()) {
base::MessageLoopProxy::current()->PostTask(
FROM_HERE, base::Bind(callback, BlacklistStateMap()));
return;
}
new SafeBrowsingClientImpl(
ids, base::Bind(&Blacklist::GetBlacklistStateForIDs, AsWeakPtr(),
callback));
}
void Blacklist::GetMalwareIDs(const std::set<std::string>& ids,
const GetMalwareIDsCallback& callback) {
GetBlacklistedIDs(ids, base::Bind(&GetMalwareFromBlacklistStateMap,
callback));
}
void Blacklist::IsBlacklisted(const std::string& extension_id,
const IsBlacklistedCallback& callback) {
std::set<std::string> check;
check.insert(extension_id);
GetBlacklistedIDs(check, base::Bind(&CheckOneExtensionState, callback));
}
void Blacklist::GetBlacklistStateForIDs(
const GetBlacklistedIDsCallback& callback,
const std::set<std::string>& blacklisted_ids) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
std::set<std::string> ids_unknown_state;
BlacklistStateMap extensions_state;
for (std::set<std::string>::const_iterator it = blacklisted_ids.begin();
it != blacklisted_ids.end(); ++it) {
BlacklistStateMap::const_iterator cache_it =
blacklist_state_cache_.find(*it);
if (cache_it == blacklist_state_cache_.end() ||
cache_it->second == BLACKLISTED_UNKNOWN)
ids_unknown_state.insert(*it);
else
extensions_state[*it] = cache_it->second;
}
if (ids_unknown_state.empty()) {
callback.Run(extensions_state);
} else {
RequestExtensionsBlacklistState(
ids_unknown_state,
base::Bind(&Blacklist::ReturnBlacklistStateMap, AsWeakPtr(),
callback, blacklisted_ids));
}
}
void Blacklist::ReturnBlacklistStateMap(
const GetBlacklistedIDsCallback& callback,
const std::set<std::string>& blacklisted_ids) {
BlacklistStateMap extensions_state;
for (std::set<std::string>::const_iterator it = blacklisted_ids.begin();
it != blacklisted_ids.end(); ++it) {
BlacklistStateMap::const_iterator cache_it =
blacklist_state_cache_.find(*it);
if (cache_it != blacklist_state_cache_.end())
extensions_state[*it] = cache_it->second;
}
callback.Run(extensions_state);
}
void Blacklist::RequestExtensionsBlacklistState(
const std::set<std::string>& ids, const base::Callback<void()>& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!state_fetcher_)
state_fetcher_.reset(new BlacklistStateFetcher());
state_requests_.push_back(
make_pair(std::vector<std::string>(ids.begin(), ids.end()), callback));
for (std::set<std::string>::const_iterator it = ids.begin();
it != ids.end();
++it) {
state_fetcher_->Request(
*it,
base::Bind(&Blacklist::OnBlacklistStateReceived, AsWeakPtr(), *it));
}
}
void Blacklist::OnBlacklistStateReceived(const std::string& id,
BlacklistState state) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
blacklist_state_cache_[id] = state;
StateRequestsList::iterator requests_it = state_requests_.begin();
while (requests_it != state_requests_.end()) {
const std::vector<std::string>& ids = requests_it->first;
bool have_all_in_cache = true;
for (std::vector<std::string>::const_iterator ids_it = ids.begin();
ids_it != ids.end();
++ids_it) {
if (!ContainsKey(blacklist_state_cache_, *ids_it)) {
have_all_in_cache = false;
break;
}
}
if (have_all_in_cache) {
requests_it->second.Run();
requests_it = state_requests_.erase(requests_it);
} else {
++requests_it;
}
}
}
void Blacklist::SetBlacklistStateFetcherForTest(
BlacklistStateFetcher* fetcher) {
state_fetcher_.reset(fetcher);
}
BlacklistStateFetcher* Blacklist::ResetBlacklistStateFetcherForTest() {
return state_fetcher_.release();
}
void Blacklist::AddObserver(Observer* observer) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
observers_.AddObserver(observer);
}
void Blacklist::RemoveObserver(Observer* observer) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
observers_.RemoveObserver(observer);
}
void Blacklist::SetDatabaseManager(
scoped_refptr<SafeBrowsingDatabaseManager> database_manager) {
g_database_manager.Get().set(database_manager);
}
scoped_refptr<SafeBrowsingDatabaseManager> Blacklist::GetDatabaseManager() {
return g_database_manager.Get().get();
}
void Blacklist::Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
DCHECK_EQ(chrome::NOTIFICATION_SAFE_BROWSING_UPDATE_COMPLETE, type);
FOR_EACH_OBSERVER(Observer, observers_, OnBlacklistUpdated());
}
}