This source file includes following definitions.
- mock_database_manager
- CreateDatabaseManager
- fetcher_id_
- OnRequestStart
- OnChunkUpload
- OnRequestEnd
- WaitForRequest
- ACTION_P
- ACTION_P
- ACTION_P
- OnSafeBrowsingResult
- ACTION_P
- SetUp
- TearDown
- RequestContainsResource
- RequestContainsServerIp
- FlushThreadMessageLoops
- GetCertificateWhitelistStrings
- ReadTestCertificate
- RunAllPendingAndQuitUI
- QuitMessageLoop
- PostRunMessageLoopTask
- FlushMessageLoop
- CheckDoneCallback
- SyncCheckDoneCallback
- SendURLFetchComplete
- IsResult
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
#include "chrome/browser/safe_browsing/download_protection_service.h"
#include <map>
#include <string>
#include "base/base_paths.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/threading/sequenced_worker_pool.h"
#include "chrome/browser/history/history_service.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/safe_browsing/binary_feature_extractor.h"
#include "chrome/browser/safe_browsing/database_manager.h"
#include "chrome/browser/safe_browsing/download_feedback_service.h"
#include "chrome/browser/safe_browsing/safe_browsing_service.h"
#include "chrome/common/safe_browsing/csd.pb.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/test/mock_download_item.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_utils.h"
#include "net/cert/x509_certificate.h"
#include "net/http/http_status_code.h"
#include "net/url_request/test_url_fetcher_factory.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "net/url_request/url_request_status.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/zlib/google/zip.h"
#include "url/gurl.h"
using ::testing::Assign;
using ::testing::ContainerEq;
using ::testing::DoAll;
using ::testing::ElementsAre;
using ::testing::Mock;
using ::testing::NotNull;
using ::testing::Return;
using ::testing::ReturnRef;
using ::testing::SaveArg;
using ::testing::StrictMock;
using ::testing::_;
using base::MessageLoop;
using content::BrowserThread;
namespace safe_browsing {
namespace {
class MockSafeBrowsingDatabaseManager : public SafeBrowsingDatabaseManager {
public:
explicit MockSafeBrowsingDatabaseManager(SafeBrowsingService* service)
: SafeBrowsingDatabaseManager(service) { }
MOCK_METHOD1(MatchDownloadWhitelistUrl, bool(const GURL&));
MOCK_METHOD1(MatchDownloadWhitelistString, bool(const std::string&));
MOCK_METHOD2(CheckDownloadUrl, bool(
const std::vector<GURL>& url_chain,
SafeBrowsingDatabaseManager::Client* client));
private:
virtual ~MockSafeBrowsingDatabaseManager() {}
DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingDatabaseManager);
};
class FakeSafeBrowsingService : public SafeBrowsingService {
public:
FakeSafeBrowsingService() { }
MockSafeBrowsingDatabaseManager* mock_database_manager() {
return mock_database_manager_;
}
protected:
virtual ~FakeSafeBrowsingService() { }
virtual SafeBrowsingDatabaseManager* CreateDatabaseManager() OVERRIDE {
mock_database_manager_ = new MockSafeBrowsingDatabaseManager(this);
return mock_database_manager_;
}
private:
MockSafeBrowsingDatabaseManager* mock_database_manager_;
DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingService);
};
class MockBinaryFeatureExtractor : public BinaryFeatureExtractor {
public:
MockBinaryFeatureExtractor() {}
MOCK_METHOD2(CheckSignature, void (const base::FilePath&,
ClientDownloadRequest_SignatureInfo*));
MOCK_METHOD2(ExtractImageHeaders, void (const base::FilePath&,
ClientDownloadRequest_ImageHeaders*));
protected:
virtual ~MockBinaryFeatureExtractor() {}
private:
DISALLOW_COPY_AND_ASSIGN(MockBinaryFeatureExtractor);
};
class TestURLFetcherWatcher : public net::TestURLFetcherDelegateForTests {
public:
explicit TestURLFetcherWatcher(net::TestURLFetcherFactory* factory)
: factory_(factory), fetcher_id_(-1) {
factory_->SetDelegateForTests(this);
}
~TestURLFetcherWatcher() {
factory_->SetDelegateForTests(NULL);
}
virtual void OnRequestStart(int fetcher_id) OVERRIDE {
fetcher_id_ = fetcher_id;
run_loop_.Quit();
}
virtual void OnChunkUpload(int fetcher_id) OVERRIDE {}
virtual void OnRequestEnd(int fetcher_id) OVERRIDE {}
int WaitForRequest() {
run_loop_.Run();
return fetcher_id_;
}
private:
net::TestURLFetcherFactory* factory_;
int fetcher_id_;
base::RunLoop run_loop_;
};
}
ACTION_P(SetCertificateContents, contents) {
arg1->add_certificate_chain()->add_element()->set_certificate(contents);
}
ACTION_P(SetDosHeaderContents, contents) {
arg1->mutable_pe_headers()->set_dos_header(contents);
}
ACTION_P(TrustSignature, certificate_file) {
arg1->set_trusted(true);
std::string cert_data;
ASSERT_TRUE(base::ReadFileToString(certificate_file, &cert_data));
ClientDownloadRequest_CertificateChain* chain =
arg1->add_certificate_chain();
chain->add_element()->set_certificate(cert_data);
chain->add_element()->set_certificate(cert_data);
}
void OnSafeBrowsingResult(
SafeBrowsingDatabaseManager::SafeBrowsingCheck* check) {
check->client->OnSafeBrowsingResult(*check);
}
ACTION_P(CheckDownloadUrlDone, threat_type) {
SafeBrowsingDatabaseManager::SafeBrowsingCheck* check =
new SafeBrowsingDatabaseManager::SafeBrowsingCheck(
arg0,
std::vector<SBFullHash>(),
arg1,
safe_browsing_util::BINURL,
std::vector<SBThreatType>(1, SB_THREAT_TYPE_BINARY_MALWARE_URL));
for (size_t i = 0; i < check->url_results.size(); ++i)
check->url_results[i] = threat_type;
BrowserThread::PostTask(BrowserThread::IO,
FROM_HERE,
base::Bind(&OnSafeBrowsingResult,
base::Owned(check)));
}
class DownloadProtectionServiceTest : public testing::Test {
protected:
DownloadProtectionServiceTest()
: test_browser_thread_bundle_(
content::TestBrowserThreadBundle::IO_MAINLOOP) {
}
virtual void SetUp() {
sb_service_ = new StrictMock<FakeSafeBrowsingService>();
sb_service_->Initialize();
binary_feature_extractor_ = new StrictMock<MockBinaryFeatureExtractor>();
download_service_ = sb_service_->download_protection_service();
download_service_->binary_feature_extractor_ = binary_feature_extractor_;
download_service_->SetEnabled(true);
base::RunLoop().RunUntilIdle();
has_result_ = false;
base::FilePath source_path;
ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &source_path));
testdata_path_ = source_path
.AppendASCII("chrome")
.AppendASCII("test")
.AppendASCII("data")
.AppendASCII("safe_browsing")
.AppendASCII("download_protection");
}
virtual void TearDown() {
sb_service_->ShutDown();
FlushThreadMessageLoops();
sb_service_ = NULL;
}
bool RequestContainsResource(const ClientDownloadRequest& request,
ClientDownloadRequest::ResourceType type,
const std::string& url,
const std::string& referrer) {
for (int i = 0; i < request.resources_size(); ++i) {
if (request.resources(i).url() == url &&
request.resources(i).type() == type &&
(referrer.empty() || request.resources(i).referrer() == referrer)) {
return true;
}
}
return false;
}
bool RequestContainsServerIp(const ClientDownloadRequest& request,
const std::string& remote_address) {
for (int i = 0; i < request.resources_size(); ++i) {
if (request.resources(i).type() == ClientDownloadRequest::DOWNLOAD_URL &&
(i + 1 == request.resources_size() ||
request.resources(i + 1).type() !=
ClientDownloadRequest::DOWNLOAD_URL)) {
return remote_address == request.resources(i).remote_ip();
}
}
return false;
}
void FlushThreadMessageLoops() {
BrowserThread::GetBlockingPool()->FlushForTesting();
FlushMessageLoop(BrowserThread::IO);
base::RunLoop().RunUntilIdle();
}
static void GetCertificateWhitelistStrings(
const net::X509Certificate& certificate,
const net::X509Certificate& issuer,
std::vector<std::string>* whitelist_strings) {
DownloadProtectionService::GetCertificateWhitelistStrings(
certificate, issuer, whitelist_strings);
}
scoped_refptr<net::X509Certificate> ReadTestCertificate(
const std::string& filename) {
std::string cert_data;
if (!base::ReadFileToString(testdata_path_.AppendASCII(filename),
&cert_data)) {
return NULL;
}
net::CertificateList certs =
net::X509Certificate::CreateCertificateListFromBytes(
cert_data.data(),
cert_data.size(),
net::X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
return certs.empty() ? NULL : certs[0];
}
private:
void RunAllPendingAndQuitUI() {
base::MessageLoop::current()->RunUntilIdle();
BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
base::Bind(&DownloadProtectionServiceTest::QuitMessageLoop,
base::Unretained(this)));
}
void QuitMessageLoop() {
base::MessageLoop::current()->Quit();
}
void PostRunMessageLoopTask(BrowserThread::ID thread) {
BrowserThread::PostTask(
thread,
FROM_HERE,
base::Bind(&DownloadProtectionServiceTest::RunAllPendingAndQuitUI,
base::Unretained(this)));
}
void FlushMessageLoop(BrowserThread::ID thread) {
BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
base::Bind(&DownloadProtectionServiceTest::PostRunMessageLoopTask,
base::Unretained(this), thread));
MessageLoop::current()->Run();
}
public:
void CheckDoneCallback(
DownloadProtectionService::DownloadCheckResult result) {
result_ = result;
has_result_ = true;
MessageLoop::current()->Quit();
}
void SyncCheckDoneCallback(
DownloadProtectionService::DownloadCheckResult result) {
result_ = result;
has_result_ = true;
}
void SendURLFetchComplete(net::TestURLFetcher* fetcher) {
fetcher->delegate()->OnURLFetchComplete(fetcher);
}
testing::AssertionResult IsResult(
DownloadProtectionService::DownloadCheckResult expected) {
if (!has_result_)
return testing::AssertionFailure() << "No result";
has_result_ = false;
return result_ == expected ?
testing::AssertionSuccess() :
testing::AssertionFailure() << "Expected " << expected <<
", got " << result_;
}
protected:
scoped_refptr<FakeSafeBrowsingService> sb_service_;
scoped_refptr<MockBinaryFeatureExtractor> binary_feature_extractor_;
DownloadProtectionService* download_service_;
DownloadProtectionService::DownloadCheckResult result_;
bool has_result_;
content::TestBrowserThreadBundle test_browser_thread_bundle_;
content::InProcessUtilityThreadHelper in_process_utility_thread_helper_;
base::FilePath testdata_path_;
};
TEST_F(DownloadProtectionServiceTest, CheckClientDownloadInvalidUrl) {
base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
base::FilePath a_exe(FILE_PATH_LITERAL("a.exe"));
std::vector<GURL> url_chain;
GURL referrer("http://www.google.com/");
content::MockDownloadItem item;
EXPECT_CALL(item, AddObserver(_));
EXPECT_CALL(item, RemoveObserver(_));
EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
EXPECT_CALL(item, GetTabReferrerUrl())
.WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
download_service_->CheckClientDownload(
&item,
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this)));
MessageLoop::current()->Run();
EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
Mock::VerifyAndClearExpectations(&item);
url_chain.push_back(GURL("file://www.google.com/"));
EXPECT_CALL(item, AddObserver(_));
EXPECT_CALL(item, RemoveObserver(_));
EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
EXPECT_CALL(item, GetTabReferrerUrl())
.WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
download_service_->CheckClientDownload(
&item,
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this)));
MessageLoop::current()->Run();
EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
}
TEST_F(DownloadProtectionServiceTest, CheckClientDownloadWhitelistedUrl) {
ClientDownloadResponse response;
response.set_verdict(ClientDownloadResponse::DANGEROUS);
net::FakeURLFetcherFactory factory(NULL);
factory.SetFakeResponse(
DownloadProtectionService::GetDownloadRequestUrl(),
response.SerializeAsString(),
net::HTTP_OK, net::URLRequestStatus::SUCCESS);
std::string hash = "hash";
base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
base::FilePath a_exe(FILE_PATH_LITERAL("a.exe"));
std::vector<GURL> url_chain;
GURL referrer;
content::MockDownloadItem item;
EXPECT_CALL(item, AddObserver(_)).Times(4);
EXPECT_CALL(item, RemoveObserver(_)).Times(4);
EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
EXPECT_CALL(item, GetTabReferrerUrl())
.WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(a_tmp, _))
.Times(4);
EXPECT_CALL(*binary_feature_extractor_.get(), ExtractImageHeaders(a_tmp, _))
.Times(4);
EXPECT_CALL(*sb_service_->mock_database_manager(),
MatchDownloadWhitelistUrl(_)).Times(0);
EXPECT_CALL(*sb_service_->mock_database_manager(),
MatchDownloadWhitelistUrl(GURL("http://www.evil.com/bla.exe")))
.WillRepeatedly(Return(false));
EXPECT_CALL(*sb_service_->mock_database_manager(),
MatchDownloadWhitelistUrl(GURL("http://www.google.com/a.exe")))
.WillRepeatedly(Return(true));
url_chain.push_back(GURL("http://www.evil.com/bla.exe"));
download_service_->CheckClientDownload(
&item,
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this)));
MessageLoop::current()->Run();
#if defined(OS_WIN)
EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
#else
EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
#endif
referrer = GURL("http://www.google.com/");
download_service_->CheckClientDownload(
&item,
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this)));
MessageLoop::current()->Run();
#if defined(OS_WIN)
EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
#else
EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
#endif
url_chain.insert(url_chain.begin(), GURL("http://www.google.com/redirect"));
download_service_->CheckClientDownload(
&item,
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this)));
MessageLoop::current()->Run();
#if defined(OS_WIN)
EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
#else
EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
#endif
url_chain.push_back(GURL("http://www.google.com/a.exe"));
download_service_->CheckClientDownload(
&item,
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this)));
MessageLoop::current()->Run();
EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
}
TEST_F(DownloadProtectionServiceTest, CheckClientDownloadFetchFailed) {
net::FakeURLFetcherFactory factory(NULL);
factory.SetFakeResponse(
DownloadProtectionService::GetDownloadRequestUrl(), std::string(),
net::HTTP_INTERNAL_SERVER_ERROR, net::URLRequestStatus::FAILED);
base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
base::FilePath a_exe(FILE_PATH_LITERAL("a.exe"));
std::vector<GURL> url_chain;
url_chain.push_back(GURL("http://www.evil.com/a.exe"));
GURL referrer("http://www.google.com/");
std::string hash = "hash";
content::MockDownloadItem item;
EXPECT_CALL(item, AddObserver(_));
EXPECT_CALL(item, RemoveObserver(_));
EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
EXPECT_CALL(item, GetTabReferrerUrl())
.WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
EXPECT_CALL(*sb_service_->mock_database_manager(),
MatchDownloadWhitelistUrl(_))
.WillRepeatedly(Return(false));
EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(a_tmp, _));
EXPECT_CALL(*binary_feature_extractor_.get(), ExtractImageHeaders(a_tmp, _));
download_service_->CheckClientDownload(
&item,
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this)));
MessageLoop::current()->Run();
EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
}
TEST_F(DownloadProtectionServiceTest, CheckClientDownloadSuccess) {
ClientDownloadResponse response;
response.set_verdict(ClientDownloadResponse::SAFE);
net::FakeURLFetcherFactory factory(NULL);
factory.SetFakeResponse(
DownloadProtectionService::GetDownloadRequestUrl(),
response.SerializeAsString(),
net::HTTP_OK, net::URLRequestStatus::SUCCESS);
base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
base::FilePath a_exe(FILE_PATH_LITERAL("a.exe"));
std::vector<GURL> url_chain;
url_chain.push_back(GURL("http://www.evil.com/a.exe"));
GURL referrer("http://www.google.com/");
std::string hash = "hash";
content::MockDownloadItem item;
EXPECT_CALL(item, AddObserver(_)).Times(6);
EXPECT_CALL(item, RemoveObserver(_)).Times(6);
EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
EXPECT_CALL(item, GetTabReferrerUrl())
.WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
EXPECT_CALL(*sb_service_->mock_database_manager(),
MatchDownloadWhitelistUrl(_))
.WillRepeatedly(Return(false));
EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(a_tmp, _))
.Times(6);
EXPECT_CALL(*binary_feature_extractor_.get(), ExtractImageHeaders(a_tmp, _))
.Times(6);
download_service_->CheckClientDownload(
&item,
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this)));
MessageLoop::current()->Run();
EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
response.Clear();
factory.SetFakeResponse(
DownloadProtectionService::GetDownloadRequestUrl(),
response.SerializePartialAsString(),
net::HTTP_OK, net::URLRequestStatus::SUCCESS);
download_service_->CheckClientDownload(
&item,
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this)));
MessageLoop::current()->Run();
EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
std::string feedback_ping;
std::string feedback_response;
EXPECT_FALSE(DownloadFeedbackService::GetPingsForDownloadForTesting(
item, &feedback_ping, &feedback_response));
response.set_verdict(ClientDownloadResponse::DANGEROUS);
factory.SetFakeResponse(
DownloadProtectionService::GetDownloadRequestUrl(),
response.SerializeAsString(),
net::HTTP_OK, net::URLRequestStatus::SUCCESS);
download_service_->CheckClientDownload(
&item,
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this)));
MessageLoop::current()->Run();
EXPECT_FALSE(DownloadFeedbackService::GetPingsForDownloadForTesting(
item, &feedback_ping, &feedback_response));
#if defined(OS_WIN)
EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
#else
EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
#endif
response.set_verdict(ClientDownloadResponse::UNCOMMON);
factory.SetFakeResponse(
DownloadProtectionService::GetDownloadRequestUrl(),
response.SerializeAsString(),
net::HTTP_OK, net::URLRequestStatus::SUCCESS);
download_service_->CheckClientDownload(
&item,
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this)));
MessageLoop::current()->Run();
#if defined(OS_WIN)
EXPECT_TRUE(IsResult(DownloadProtectionService::UNCOMMON));
EXPECT_TRUE(DownloadFeedbackService::GetPingsForDownloadForTesting(
item, &feedback_ping, &feedback_response));
ClientDownloadRequest decoded_request;
EXPECT_TRUE(decoded_request.ParseFromString(feedback_ping));
EXPECT_EQ(url_chain.back().spec(), decoded_request.url());
EXPECT_EQ(response.SerializeAsString(), feedback_response);
#else
EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
#endif
response.set_verdict(ClientDownloadResponse::DANGEROUS_HOST);
factory.SetFakeResponse(
DownloadProtectionService::GetDownloadRequestUrl(),
response.SerializeAsString(),
net::HTTP_OK, net::URLRequestStatus::SUCCESS);
download_service_->CheckClientDownload(
&item,
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this)));
MessageLoop::current()->Run();
#if defined(OS_WIN)
EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS_HOST));
EXPECT_TRUE(DownloadFeedbackService::GetPingsForDownloadForTesting(
item, &feedback_ping, &feedback_response));
EXPECT_EQ(response.SerializeAsString(), feedback_response);
#else
EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
#endif
response.set_verdict(ClientDownloadResponse::POTENTIALLY_UNWANTED);
factory.SetFakeResponse(
DownloadProtectionService::GetDownloadRequestUrl(),
response.SerializeAsString(),
net::HTTP_OK, net::URLRequestStatus::SUCCESS);
download_service_->CheckClientDownload(
&item,
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this)));
MessageLoop::current()->Run();
#if defined(OS_WIN)
EXPECT_TRUE(IsResult(DownloadProtectionService::POTENTIALLY_UNWANTED));
#else
EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
#endif
}
TEST_F(DownloadProtectionServiceTest, CheckClientDownloadHTTPS) {
ClientDownloadResponse response;
response.set_verdict(ClientDownloadResponse::DANGEROUS);
net::FakeURLFetcherFactory factory(NULL);
factory.SetFakeResponse(
DownloadProtectionService::GetDownloadRequestUrl(),
response.SerializeAsString(),
net::HTTP_OK, net::URLRequestStatus::SUCCESS);
base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
base::FilePath a_exe(FILE_PATH_LITERAL("a.exe"));
std::vector<GURL> url_chain;
url_chain.push_back(GURL("http://www.evil.com/a.exe"));
GURL referrer("http://www.google.com/");
std::string hash = "hash";
content::MockDownloadItem item;
EXPECT_CALL(item, AddObserver(_)).Times(1);
EXPECT_CALL(item, RemoveObserver(_)).Times(1);
EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
EXPECT_CALL(item, GetTabReferrerUrl())
.WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
EXPECT_CALL(*sb_service_->mock_database_manager(),
MatchDownloadWhitelistUrl(_))
.WillRepeatedly(Return(false));
EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(a_tmp, _))
.Times(1);
EXPECT_CALL(*binary_feature_extractor_.get(), ExtractImageHeaders(a_tmp, _))
.Times(1);
download_service_->CheckClientDownload(
&item,
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this)));
MessageLoop::current()->Run();
#if defined(OS_WIN)
EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
#else
EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
#endif
}
TEST_F(DownloadProtectionServiceTest, CheckClientDownloadZip) {
ClientDownloadResponse response;
response.set_verdict(ClientDownloadResponse::SAFE);
net::FakeURLFetcherFactory factory(NULL);
factory.SetFakeResponse(
DownloadProtectionService::GetDownloadRequestUrl(),
response.SerializeAsString(),
net::HTTP_OK, net::URLRequestStatus::SUCCESS);
base::ScopedTempDir download_dir;
ASSERT_TRUE(download_dir.CreateUniqueTempDir());
base::FilePath a_tmp(download_dir.path().Append(FILE_PATH_LITERAL("a.tmp")));
base::FilePath a_zip(FILE_PATH_LITERAL("a.zip"));
std::vector<GURL> url_chain;
url_chain.push_back(GURL("http://www.evil.com/a.zip"));
GURL referrer("http://www.google.com/");
std::string hash = "hash";
content::MockDownloadItem item;
EXPECT_CALL(item, AddObserver(_)).Times(3);
EXPECT_CALL(item, RemoveObserver(_)).Times(3);
EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_zip));
EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
EXPECT_CALL(item, GetTabReferrerUrl())
.WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
base::ScopedTempDir zip_source_dir;
ASSERT_TRUE(zip_source_dir.CreateUniqueTempDir());
std::string file_contents = "dummy file";
ASSERT_EQ(static_cast<int>(file_contents.size()), base::WriteFile(
zip_source_dir.path().Append(FILE_PATH_LITERAL("file.txt")),
file_contents.data(), file_contents.size()));
ASSERT_TRUE(zip::Zip(zip_source_dir.path(), a_tmp, false));
download_service_->CheckClientDownload(
&item,
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this)));
MessageLoop::current()->Run();
EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
Mock::VerifyAndClearExpectations(sb_service_.get());
Mock::VerifyAndClearExpectations(binary_feature_extractor_.get());
ASSERT_EQ(static_cast<int>(file_contents.size()), base::WriteFile(
zip_source_dir.path().Append(FILE_PATH_LITERAL("file.exe")),
file_contents.data(), file_contents.size()));
ASSERT_TRUE(zip::Zip(zip_source_dir.path(), a_tmp, false));
EXPECT_CALL(*sb_service_->mock_database_manager(),
MatchDownloadWhitelistUrl(_))
.WillRepeatedly(Return(false));
download_service_->CheckClientDownload(
&item,
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this)));
MessageLoop::current()->Run();
EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
Mock::VerifyAndClearExpectations(binary_feature_extractor_.get());
response.set_verdict(ClientDownloadResponse::DANGEROUS);
factory.SetFakeResponse(
DownloadProtectionService::GetDownloadRequestUrl(),
response.SerializeAsString(),
net::HTTP_OK, net::URLRequestStatus::SUCCESS);
download_service_->CheckClientDownload(
&item,
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this)));
MessageLoop::current()->Run();
#if defined(OS_WIN)
EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
#else
EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
#endif
Mock::VerifyAndClearExpectations(binary_feature_extractor_.get());
}
TEST_F(DownloadProtectionServiceTest, CheckClientDownloadCorruptZip) {
base::ScopedTempDir download_dir;
ASSERT_TRUE(download_dir.CreateUniqueTempDir());
base::FilePath a_tmp(download_dir.path().Append(FILE_PATH_LITERAL("a.tmp")));
base::FilePath a_zip(FILE_PATH_LITERAL("a.zip"));
std::vector<GURL> url_chain;
url_chain.push_back(GURL("http://www.evil.com/a.zip"));
GURL referrer("http://www.google.com/");
std::string hash = "hash";
content::MockDownloadItem item;
EXPECT_CALL(item, AddObserver(_)).Times(1);
EXPECT_CALL(item, RemoveObserver(_)).Times(1);
EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_zip));
EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
EXPECT_CALL(item, GetTabReferrerUrl())
.WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
std::string file_contents = "corrupt zip file";
ASSERT_EQ(static_cast<int>(file_contents.size()), base::WriteFile(
a_tmp, file_contents.data(), file_contents.size()));
download_service_->CheckClientDownload(
&item,
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this)));
MessageLoop::current()->Run();
EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
Mock::VerifyAndClearExpectations(sb_service_.get());
Mock::VerifyAndClearExpectations(binary_feature_extractor_.get());
}
TEST_F(DownloadProtectionServiceTest, CheckClientCrxDownloadSuccess) {
ClientDownloadResponse response;
response.set_verdict(ClientDownloadResponse::DANGEROUS);
net::FakeURLFetcherFactory factory(NULL);
factory.SetFakeResponse(
DownloadProtectionService::GetDownloadRequestUrl(),
response.SerializeAsString(),
net::HTTP_OK, net::URLRequestStatus::SUCCESS);
base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
base::FilePath a_crx(FILE_PATH_LITERAL("a.crx"));
std::vector<GURL> url_chain;
url_chain.push_back(GURL("http://www.evil.com/a.crx"));
GURL referrer("http://www.google.com/");
std::string hash = "hash";
content::MockDownloadItem item;
EXPECT_CALL(item, AddObserver(_)).Times(1);
EXPECT_CALL(item, RemoveObserver(_)).Times(1);
EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_crx));
EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
EXPECT_CALL(item, GetTabReferrerUrl())
.WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
EXPECT_CALL(*sb_service_->mock_database_manager(),
MatchDownloadWhitelistUrl(_))
.WillRepeatedly(Return(false));
EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(a_tmp, _))
.Times(1);
EXPECT_CALL(*binary_feature_extractor_.get(), ExtractImageHeaders(a_tmp, _))
.Times(1);
EXPECT_FALSE(download_service_->IsSupportedDownload(item, a_crx));
download_service_->CheckClientDownload(
&item,
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this)));
MessageLoop::current()->Run();
EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
}
TEST_F(DownloadProtectionServiceTest, CheckClientDownloadValidateRequest) {
net::TestURLFetcherFactory factory;
base::FilePath tmp_path(FILE_PATH_LITERAL("bla.tmp"));
base::FilePath final_path(FILE_PATH_LITERAL("bla.exe"));
std::vector<GURL> url_chain;
url_chain.push_back(GURL("http://www.google.com/"));
url_chain.push_back(GURL("http://www.google.com/bla.exe"));
GURL referrer("http://www.google.com/");
std::string hash = "hash";
std::string remote_address = "10.11.12.13";
content::MockDownloadItem item;
EXPECT_CALL(item, AddObserver(_)).Times(1);
EXPECT_CALL(item, RemoveObserver(_)).Times(1);
EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path));
EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path));
EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
EXPECT_CALL(item, GetTabReferrerUrl())
.WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(remote_address));
EXPECT_CALL(*sb_service_->mock_database_manager(),
MatchDownloadWhitelistUrl(_))
.WillRepeatedly(Return(false));
EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path, _))
.WillOnce(SetCertificateContents("dummy cert data"));
EXPECT_CALL(*binary_feature_extractor_.get(),
ExtractImageHeaders(tmp_path, _))
.WillOnce(SetDosHeaderContents("dummy dos header"));
download_service_->CheckClientDownload(
&item,
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this)));
#if !defined(OS_WIN)
MessageLoop::current()->Run();
net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
EXPECT_EQ(NULL, fetcher);
#else
FlushThreadMessageLoops();
net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
ASSERT_TRUE(fetcher);
ClientDownloadRequest request;
EXPECT_TRUE(request.ParseFromString(fetcher->upload_data()));
EXPECT_EQ("http://www.google.com/bla.exe", request.url());
EXPECT_EQ(hash, request.digests().sha256());
EXPECT_EQ(item.GetReceivedBytes(), request.length());
EXPECT_EQ(item.HasUserGesture(), request.user_initiated());
EXPECT_TRUE(RequestContainsServerIp(request, remote_address));
EXPECT_EQ(2, request.resources_size());
EXPECT_TRUE(RequestContainsResource(request,
ClientDownloadRequest::DOWNLOAD_REDIRECT,
"http://www.google.com/", ""));
EXPECT_TRUE(RequestContainsResource(request,
ClientDownloadRequest::DOWNLOAD_URL,
"http://www.google.com/bla.exe",
referrer.spec()));
EXPECT_TRUE(request.has_signature());
ASSERT_EQ(1, request.signature().certificate_chain_size());
const ClientDownloadRequest_CertificateChain& chain =
request.signature().certificate_chain(0);
ASSERT_EQ(1, chain.element_size());
EXPECT_EQ("dummy cert data", chain.element(0).certificate());
EXPECT_TRUE(request.has_image_headers());
const ClientDownloadRequest_ImageHeaders& headers =
request.image_headers();
EXPECT_TRUE(headers.has_pe_headers());
EXPECT_TRUE(headers.pe_headers().has_dos_header());
EXPECT_EQ("dummy dos header", headers.pe_headers().dos_header());
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete,
base::Unretained(this), fetcher));
MessageLoop::current()->Run();
#endif
}
TEST_F(DownloadProtectionServiceTest,
CheckClientDownloadValidateRequestNoSignature) {
net::TestURLFetcherFactory factory;
base::FilePath tmp_path(FILE_PATH_LITERAL("bla.tmp"));
base::FilePath final_path(FILE_PATH_LITERAL("bla.exe"));
std::vector<GURL> url_chain;
url_chain.push_back(GURL("http://www.google.com/"));
url_chain.push_back(GURL("ftp://www.google.com/bla.exe"));
GURL referrer("http://www.google.com/");
std::string hash = "hash";
std::string remote_address = "10.11.12.13";
content::MockDownloadItem item;
EXPECT_CALL(item, AddObserver(_)).Times(1);
EXPECT_CALL(item, RemoveObserver(_)).Times(1);
EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path));
EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path));
EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
EXPECT_CALL(item, GetTabReferrerUrl())
.WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(remote_address));
EXPECT_CALL(*sb_service_->mock_database_manager(),
MatchDownloadWhitelistUrl(_))
.WillRepeatedly(Return(false));
EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path, _));
EXPECT_CALL(*binary_feature_extractor_.get(),
ExtractImageHeaders(tmp_path, _));
download_service_->CheckClientDownload(
&item,
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this)));
#if !defined(OS_WIN)
MessageLoop::current()->Run();
net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
EXPECT_EQ(NULL, fetcher);
#else
FlushThreadMessageLoops();
net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
ASSERT_TRUE(fetcher);
ClientDownloadRequest request;
EXPECT_TRUE(request.ParseFromString(fetcher->upload_data()));
EXPECT_EQ("ftp://www.google.com/bla.exe", request.url());
EXPECT_EQ(hash, request.digests().sha256());
EXPECT_EQ(item.GetReceivedBytes(), request.length());
EXPECT_EQ(item.HasUserGesture(), request.user_initiated());
EXPECT_EQ(2, request.resources_size());
EXPECT_TRUE(RequestContainsResource(request,
ClientDownloadRequest::DOWNLOAD_REDIRECT,
"http://www.google.com/", ""));
EXPECT_TRUE(RequestContainsResource(request,
ClientDownloadRequest::DOWNLOAD_URL,
"ftp://www.google.com/bla.exe",
referrer.spec()));
EXPECT_TRUE(request.has_signature());
EXPECT_EQ(0, request.signature().certificate_chain_size());
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete,
base::Unretained(this), fetcher));
MessageLoop::current()->Run();
#endif
}
TEST_F(DownloadProtectionServiceTest,
CheckClientDownloadValidateRequestTabHistory) {
net::TestURLFetcherFactory factory;
base::ScopedTempDir profile_dir;
ASSERT_TRUE(profile_dir.CreateUniqueTempDir());
TestingProfile profile(profile_dir.path());
ASSERT_TRUE(
profile.CreateHistoryService(true , false ));
base::FilePath tmp_path(FILE_PATH_LITERAL("bla.tmp"));
base::FilePath final_path(FILE_PATH_LITERAL("bla.exe"));
std::vector<GURL> url_chain;
url_chain.push_back(GURL("http://www.google.com/"));
url_chain.push_back(GURL("http://www.google.com/bla.exe"));
GURL referrer("http://www.google.com/");
GURL tab_url("http://tab.com/final");
GURL tab_referrer("http://tab.com/referrer");
std::string hash = "hash";
std::string remote_address = "10.11.12.13";
content::MockDownloadItem item;
EXPECT_CALL(item, AddObserver(_)).Times(2);
EXPECT_CALL(item, RemoveObserver(_)).Times(2);
EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path));
EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path));
EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(tab_url));
EXPECT_CALL(item, GetTabReferrerUrl())
.WillRepeatedly(ReturnRef(tab_referrer));
EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(remote_address));
EXPECT_CALL(item, GetBrowserContext()).WillRepeatedly(Return(&profile));
EXPECT_CALL(*sb_service_->mock_database_manager(),
MatchDownloadWhitelistUrl(_))
.WillRepeatedly(Return(false));
EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path, _))
.WillRepeatedly(SetCertificateContents("dummy cert data"));
EXPECT_CALL(*binary_feature_extractor_.get(),
ExtractImageHeaders(tmp_path, _))
.WillRepeatedly(SetDosHeaderContents("dummy dos header"));
{
TestURLFetcherWatcher fetcher_watcher(&factory);
download_service_->CheckClientDownload(
&item,
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this)));
#if !defined(OS_WIN)
MessageLoop::current()->Run();
net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
EXPECT_EQ(NULL, fetcher);
#else
EXPECT_EQ(0, fetcher_watcher.WaitForRequest());
net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
ASSERT_TRUE(fetcher);
ClientDownloadRequest request;
EXPECT_TRUE(request.ParseFromString(fetcher->upload_data()));
EXPECT_EQ("http://www.google.com/bla.exe", request.url());
EXPECT_EQ(hash, request.digests().sha256());
EXPECT_EQ(item.GetReceivedBytes(), request.length());
EXPECT_EQ(item.HasUserGesture(), request.user_initiated());
EXPECT_TRUE(RequestContainsServerIp(request, remote_address));
EXPECT_EQ(3, request.resources_size());
EXPECT_TRUE(
RequestContainsResource(request,
ClientDownloadRequest::DOWNLOAD_REDIRECT,
"http://www.google.com/",
""));
EXPECT_TRUE(RequestContainsResource(request,
ClientDownloadRequest::DOWNLOAD_URL,
"http://www.google.com/bla.exe",
referrer.spec()));
EXPECT_TRUE(RequestContainsResource(request,
ClientDownloadRequest::TAB_URL,
tab_url.spec(),
tab_referrer.spec()));
EXPECT_TRUE(request.has_signature());
ASSERT_EQ(1, request.signature().certificate_chain_size());
const ClientDownloadRequest_CertificateChain& chain =
request.signature().certificate_chain(0);
ASSERT_EQ(1, chain.element_size());
EXPECT_EQ("dummy cert data", chain.element(0).certificate());
EXPECT_TRUE(request.has_image_headers());
const ClientDownloadRequest_ImageHeaders& headers =
request.image_headers();
EXPECT_TRUE(headers.has_pe_headers());
EXPECT_TRUE(headers.pe_headers().has_dos_header());
EXPECT_EQ("dummy dos header", headers.pe_headers().dos_header());
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete,
base::Unretained(this),
fetcher));
MessageLoop::current()->Run();
#endif
}
{
history::RedirectList redirects;
redirects.push_back(GURL("http://tab.com/ref1"));
redirects.push_back(GURL("http://tab.com/ref2"));
redirects.push_back(tab_url);
HistoryServiceFactory::GetForProfile(&profile, Profile::EXPLICIT_ACCESS)
->AddPage(tab_url,
base::Time::Now(),
static_cast<void*>(this),
0,
GURL(),
redirects,
content::PAGE_TRANSITION_TYPED,
history::SOURCE_BROWSED,
false);
TestURLFetcherWatcher fetcher_watcher(&factory);
download_service_->CheckClientDownload(
&item,
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this)));
#if !defined(OS_WIN)
MessageLoop::current()->Run();
net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
EXPECT_EQ(NULL, fetcher);
#else
EXPECT_EQ(0, fetcher_watcher.WaitForRequest());
net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
ASSERT_TRUE(fetcher);
ClientDownloadRequest request;
EXPECT_TRUE(request.ParseFromString(fetcher->upload_data()));
EXPECT_EQ("http://www.google.com/bla.exe", request.url());
EXPECT_EQ(hash, request.digests().sha256());
EXPECT_EQ(item.GetReceivedBytes(), request.length());
EXPECT_EQ(item.HasUserGesture(), request.user_initiated());
EXPECT_TRUE(RequestContainsServerIp(request, remote_address));
EXPECT_EQ(5, request.resources_size());
EXPECT_TRUE(
RequestContainsResource(request,
ClientDownloadRequest::DOWNLOAD_REDIRECT,
"http://www.google.com/",
""));
EXPECT_TRUE(RequestContainsResource(request,
ClientDownloadRequest::DOWNLOAD_URL,
"http://www.google.com/bla.exe",
referrer.spec()));
EXPECT_TRUE(RequestContainsResource(request,
ClientDownloadRequest::TAB_REDIRECT,
"http://tab.com/ref1",
""));
EXPECT_TRUE(RequestContainsResource(request,
ClientDownloadRequest::TAB_REDIRECT,
"http://tab.com/ref2",
""));
EXPECT_TRUE(RequestContainsResource(request,
ClientDownloadRequest::TAB_URL,
tab_url.spec(),
tab_referrer.spec()));
EXPECT_TRUE(request.has_signature());
ASSERT_EQ(1, request.signature().certificate_chain_size());
const ClientDownloadRequest_CertificateChain& chain =
request.signature().certificate_chain(0);
ASSERT_EQ(1, chain.element_size());
EXPECT_EQ("dummy cert data", chain.element(0).certificate());
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete,
base::Unretained(this),
fetcher));
MessageLoop::current()->Run();
#endif
}
}
TEST_F(DownloadProtectionServiceTest, TestCheckDownloadUrl) {
std::vector<GURL> url_chain;
url_chain.push_back(GURL("http://www.google.com/"));
url_chain.push_back(GURL("http://www.google.com/bla.exe"));
GURL referrer("http://www.google.com/");
std::string hash = "hash";
content::MockDownloadItem item;
EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
EXPECT_CALL(*sb_service_->mock_database_manager(),
CheckDownloadUrl(ContainerEq(url_chain), NotNull()))
.WillOnce(Return(true));
download_service_->CheckDownloadUrl(
item,
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this)));
MessageLoop::current()->Run();
EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
Mock::VerifyAndClearExpectations(sb_service_.get());
EXPECT_CALL(*sb_service_->mock_database_manager(),
CheckDownloadUrl(ContainerEq(url_chain), NotNull()))
.WillOnce(DoAll(CheckDownloadUrlDone(SB_THREAT_TYPE_SAFE),
Return(false)));
download_service_->CheckDownloadUrl(
item,
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this)));
MessageLoop::current()->Run();
EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
Mock::VerifyAndClearExpectations(sb_service_.get());
EXPECT_CALL(*sb_service_->mock_database_manager(),
CheckDownloadUrl(ContainerEq(url_chain), NotNull()))
.WillOnce(DoAll(
CheckDownloadUrlDone(SB_THREAT_TYPE_URL_MALWARE),
Return(false)));
download_service_->CheckDownloadUrl(
item,
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this)));
MessageLoop::current()->Run();
EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
Mock::VerifyAndClearExpectations(sb_service_.get());
EXPECT_CALL(*sb_service_->mock_database_manager(),
CheckDownloadUrl(ContainerEq(url_chain),
NotNull()))
.WillOnce(DoAll(
CheckDownloadUrlDone(SB_THREAT_TYPE_BINARY_MALWARE_URL),
Return(false)));
download_service_->CheckDownloadUrl(
item,
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this)));
MessageLoop::current()->Run();
EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
}
TEST_F(DownloadProtectionServiceTest, TestDownloadRequestTimeout) {
net::TestURLFetcherFactory factory;
std::vector<GURL> url_chain;
url_chain.push_back(GURL("http://www.evil.com/bla.exe"));
GURL referrer("http://www.google.com/");
base::FilePath tmp_path(FILE_PATH_LITERAL("a.tmp"));
base::FilePath final_path(FILE_PATH_LITERAL("a.exe"));
std::string hash = "hash";
content::MockDownloadItem item;
EXPECT_CALL(item, AddObserver(_)).Times(1);
EXPECT_CALL(item, RemoveObserver(_)).Times(1);
EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path));
EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path));
EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
EXPECT_CALL(item, GetTabReferrerUrl())
.WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
EXPECT_CALL(*sb_service_->mock_database_manager(),
MatchDownloadWhitelistUrl(_))
.WillRepeatedly(Return(false));
EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path, _));
EXPECT_CALL(*binary_feature_extractor_.get(),
ExtractImageHeaders(tmp_path, _));
download_service_->download_request_timeout_ms_ = 10;
download_service_->CheckClientDownload(
&item,
base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
base::Unretained(this)));
MessageLoop::current()->Run();
EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
}
TEST_F(DownloadProtectionServiceTest, TestDownloadItemDestroyed) {
net::TestURLFetcherFactory factory;
std::vector<GURL> url_chain;
url_chain.push_back(GURL("http://www.evil.com/bla.exe"));
GURL referrer("http://www.google.com/");
base::FilePath tmp_path(FILE_PATH_LITERAL("a.tmp"));
base::FilePath final_path(FILE_PATH_LITERAL("a.exe"));
std::string hash = "hash";
content::MockDownloadItem item;
content::DownloadItem::Observer* observer = NULL;
EXPECT_CALL(item, AddObserver(_)).WillOnce(SaveArg<0>(&observer));
EXPECT_CALL(item, RemoveObserver(_)).WillOnce(Assign(
&observer, static_cast<content::DownloadItem::Observer*>(NULL)));
EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path));
EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path));
EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
EXPECT_CALL(item, GetTabReferrerUrl())
.WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
EXPECT_CALL(*sb_service_->mock_database_manager(),
MatchDownloadWhitelistUrl(_))
.WillRepeatedly(Return(false));
EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path, _));
EXPECT_CALL(*binary_feature_extractor_.get(),
ExtractImageHeaders(tmp_path, _));
download_service_->CheckClientDownload(
&item,
base::Bind(&DownloadProtectionServiceTest::SyncCheckDoneCallback,
base::Unretained(this)));
ASSERT_TRUE(observer != NULL);
observer->OnDownloadDestroyed(&item);
EXPECT_TRUE(observer == NULL);
EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
}
TEST_F(DownloadProtectionServiceTest, GetCertificateWhitelistStrings) {
scoped_refptr<net::X509Certificate> issuer_cert(
ReadTestCertificate("issuer.pem"));
ASSERT_TRUE(issuer_cert.get());
std::string cert_base = "cert/" + base::HexEncode(
issuer_cert->fingerprint().data,
sizeof(issuer_cert->fingerprint().data));
scoped_refptr<net::X509Certificate> cert(ReadTestCertificate("test_cn.pem"));
ASSERT_TRUE(cert.get());
std::vector<std::string> whitelist_strings;
GetCertificateWhitelistStrings(
*cert.get(), *issuer_cert.get(), &whitelist_strings);
EXPECT_THAT(whitelist_strings, ElementsAre(
cert_base + "/CN=subject%2F%251"));
cert = ReadTestCertificate("test_cn_o.pem");
ASSERT_TRUE(cert.get());
whitelist_strings.clear();
GetCertificateWhitelistStrings(
*cert.get(), *issuer_cert.get(), &whitelist_strings);
EXPECT_THAT(whitelist_strings,
ElementsAre(cert_base + "/CN=subject",
cert_base + "/CN=subject/O=org",
cert_base + "/O=org"));
cert = ReadTestCertificate("test_cn_o_ou.pem");
ASSERT_TRUE(cert.get());
whitelist_strings.clear();
GetCertificateWhitelistStrings(
*cert.get(), *issuer_cert.get(), &whitelist_strings);
EXPECT_THAT(whitelist_strings,
ElementsAre(cert_base + "/CN=subject",
cert_base + "/CN=subject/O=org",
cert_base + "/CN=subject/O=org/OU=unit",
cert_base + "/CN=subject/OU=unit",
cert_base + "/O=org",
cert_base + "/O=org/OU=unit",
cert_base + "/OU=unit"));
cert = ReadTestCertificate("test_cn_ou.pem");
ASSERT_TRUE(cert.get());
whitelist_strings.clear();
GetCertificateWhitelistStrings(
*cert.get(), *issuer_cert.get(), &whitelist_strings);
EXPECT_THAT(whitelist_strings,
ElementsAre(cert_base + "/CN=subject",
cert_base + "/CN=subject/OU=unit",
cert_base + "/OU=unit"));
cert = ReadTestCertificate("test_o.pem");
ASSERT_TRUE(cert.get());
whitelist_strings.clear();
GetCertificateWhitelistStrings(
*cert.get(), *issuer_cert.get(), &whitelist_strings);
EXPECT_THAT(whitelist_strings, ElementsAre(cert_base + "/O=org"));
cert = ReadTestCertificate("test_o_ou.pem");
ASSERT_TRUE(cert.get());
whitelist_strings.clear();
GetCertificateWhitelistStrings(
*cert.get(), *issuer_cert.get(), &whitelist_strings);
EXPECT_THAT(whitelist_strings,
ElementsAre(cert_base + "/O=org",
cert_base + "/O=org/OU=unit",
cert_base + "/OU=unit"));
cert = ReadTestCertificate("test_ou.pem");
ASSERT_TRUE(cert.get());
whitelist_strings.clear();
GetCertificateWhitelistStrings(
*cert.get(), *issuer_cert.get(), &whitelist_strings);
EXPECT_THAT(whitelist_strings, ElementsAre(cert_base + "/OU=unit"));
cert = ReadTestCertificate("test_c.pem");
ASSERT_TRUE(cert.get());
whitelist_strings.clear();
GetCertificateWhitelistStrings(
*cert.get(), *issuer_cert.get(), &whitelist_strings);
EXPECT_THAT(whitelist_strings, ElementsAre());
}
}