This source file includes following definitions.
- render_view_id
- StopOnIOThread
- LogPauseDelay
- CanReportStats
- OnBlockingPageDone
- DisplayBlockingPage
- ReportSafeBrowsingHit
- AddObserver
- RemoveObserver
- ReportSafeBrowsingHitOnIOThread
- SendSerializedMalwareDetails
- UpdateWhitelist
- IsWhitelisted
#include "chrome/browser/safe_browsing/ui_manager.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/debug/leak_tracker.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/metrics/metrics_service.h"
#include "chrome/browser/safe_browsing/malware_details.h"
#include "chrome/browser/safe_browsing/ping_manager.h"
#include "chrome/browser/safe_browsing/safe_browsing_blocking_page.h"
#include "chrome/browser/safe_browsing/safe_browsing_service.h"
#include "chrome/browser/tab_contents/tab_util.h"
#include "chrome/common/url_constants.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/web_contents.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
using content::BrowserThread;
using content::NavigationEntry;
using content::WebContents;
struct SafeBrowsingUIManager::WhiteListedEntry {
int render_process_host_id;
int render_view_id;
std::string domain;
SBThreatType threat_type;
};
SafeBrowsingUIManager::UnsafeResource::UnsafeResource()
: is_subresource(false),
threat_type(SB_THREAT_TYPE_SAFE),
render_process_host_id(-1),
render_view_id(-1) {
}
SafeBrowsingUIManager::UnsafeResource::~UnsafeResource() { }
SafeBrowsingUIManager::SafeBrowsingUIManager(
const scoped_refptr<SafeBrowsingService>& service)
: sb_service_(service) {
}
SafeBrowsingUIManager::~SafeBrowsingUIManager() { }
void SafeBrowsingUIManager::StopOnIOThread(bool shutdown) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
if (shutdown)
sb_service_ = NULL;
}
void SafeBrowsingUIManager::LogPauseDelay(base::TimeDelta time) {
UMA_HISTOGRAM_LONG_TIMES("SB2.Delay", time);
}
bool SafeBrowsingUIManager::CanReportStats() const {
const MetricsService* metrics = g_browser_process->metrics_service();
return metrics && metrics->reporting_active();
}
void SafeBrowsingUIManager::OnBlockingPageDone(
const std::vector<UnsafeResource>& resources,
bool proceed) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
for (std::vector<UnsafeResource>::const_iterator iter = resources.begin();
iter != resources.end(); ++iter) {
const UnsafeResource& resource = *iter;
if (!resource.callback.is_null())
resource.callback.Run(proceed);
if (proceed) {
BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
base::Bind(&SafeBrowsingUIManager::UpdateWhitelist, this, resource));
}
}
}
void SafeBrowsingUIManager::DisplayBlockingPage(
const UnsafeResource& resource) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (resource.threat_type != SB_THREAT_TYPE_SAFE) {
FOR_EACH_OBSERVER(Observer, observer_list_, OnSafeBrowsingMatch(resource));
}
if (IsWhitelisted(resource)) {
if (!resource.callback.is_null()) {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE, base::Bind(resource.callback, true));
}
return;
}
WebContents* web_contents =
tab_util::GetWebContentsByID(resource.render_process_host_id,
resource.render_view_id);
if (!web_contents) {
std::vector<UnsafeResource> resources;
resources.push_back(resource);
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&SafeBrowsingUIManager::OnBlockingPageDone,
this, resources, false));
return;
}
if (resource.threat_type != SB_THREAT_TYPE_SAFE &&
CanReportStats()) {
GURL page_url = web_contents->GetURL();
GURL referrer_url;
NavigationEntry* entry = web_contents->GetController().GetActiveEntry();
if (entry)
referrer_url = entry->GetReferrer().url;
if (!resource.is_subresource &&
!resource.original_url.is_empty() &&
resource.original_url != resource.url) {
referrer_url = page_url;
page_url = resource.original_url;
}
ReportSafeBrowsingHit(resource.url, page_url, referrer_url,
resource.is_subresource, resource.threat_type,
std::string() );
}
if (resource.threat_type != SB_THREAT_TYPE_SAFE) {
FOR_EACH_OBSERVER(Observer, observer_list_, OnSafeBrowsingHit(resource));
}
SafeBrowsingBlockingPage::ShowBlockingPage(this, resource);
}
void SafeBrowsingUIManager::ReportSafeBrowsingHit(
const GURL& malicious_url,
const GURL& page_url,
const GURL& referrer_url,
bool is_subresource,
SBThreatType threat_type,
const std::string& post_data) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (!CanReportStats())
return;
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&SafeBrowsingUIManager::ReportSafeBrowsingHitOnIOThread, this,
malicious_url, page_url, referrer_url, is_subresource,
threat_type, post_data));
}
void SafeBrowsingUIManager::AddObserver(Observer* observer) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
observer_list_.AddObserver(observer);
}
void SafeBrowsingUIManager::RemoveObserver(Observer* observer) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
observer_list_.RemoveObserver(observer);
}
void SafeBrowsingUIManager::ReportSafeBrowsingHitOnIOThread(
const GURL& malicious_url,
const GURL& page_url,
const GURL& referrer_url,
bool is_subresource,
SBThreatType threat_type,
const std::string& post_data) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
if (sb_service_.get() == NULL || sb_service_->ping_manager() == NULL)
return;
DVLOG(1) << "ReportSafeBrowsingHit: " << malicious_url << " " << page_url
<< " " << referrer_url << " " << is_subresource << " "
<< threat_type;
sb_service_->ping_manager()->ReportSafeBrowsingHit(
malicious_url, page_url,
referrer_url, is_subresource,
threat_type, post_data);
}
void SafeBrowsingUIManager::SendSerializedMalwareDetails(
const std::string& serialized) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
if (sb_service_.get() == NULL || sb_service_->ping_manager() == NULL)
return;
if (!serialized.empty()) {
DVLOG(1) << "Sending serialized malware details.";
sb_service_->ping_manager()->ReportMalwareDetails(serialized);
}
}
void SafeBrowsingUIManager::UpdateWhitelist(const UnsafeResource& resource) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
WhiteListedEntry entry;
entry.render_process_host_id = resource.render_process_host_id;
entry.render_view_id = resource.render_view_id;
entry.domain = net::registry_controlled_domains::GetDomainAndRegistry(
resource.url,
net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES);
entry.threat_type = resource.threat_type;
white_listed_entries_.push_back(entry);
}
bool SafeBrowsingUIManager::IsWhitelisted(const UnsafeResource& resource) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
for (size_t i = 0; i < white_listed_entries_.size(); ++i) {
const WhiteListedEntry& entry = white_listed_entries_[i];
if (entry.render_process_host_id == resource.render_process_host_id &&
entry.render_view_id == resource.render_view_id &&
(entry.threat_type == resource.threat_type ||
(entry.threat_type == SB_THREAT_TYPE_URL_PHISHING &&
resource.threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL) ||
(entry.threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL &&
resource.threat_type == SB_THREAT_TYPE_URL_PHISHING) ||
(entry.threat_type == SB_THREAT_TYPE_URL_MALWARE &&
resource.threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) ||
(entry.threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL &&
resource.threat_type == SB_THREAT_TYPE_URL_MALWARE))) {
return entry.domain ==
net::registry_controlled_domains::GetDomainAndRegistry(
resource.url,
net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES);
}
}
return false;
}