1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/safe_browsing/download_protection_service.h"
6
7 #include <map>
8 #include <string>
9
10 #include "base/base_paths.h"
11 #include "base/bind.h"
12 #include "base/callback.h"
13 #include "base/file_util.h"
14 #include "base/files/file_path.h"
15 #include "base/files/scoped_temp_dir.h"
16 #include "base/memory/ref_counted.h"
17 #include "base/memory/scoped_ptr.h"
18 #include "base/message_loop/message_loop.h"
19 #include "base/path_service.h"
20 #include "base/run_loop.h"
21 #include "base/strings/string_number_conversions.h"
22 #include "base/threading/sequenced_worker_pool.h"
23 #include "chrome/browser/history/history_service.h"
24 #include "chrome/browser/history/history_service_factory.h"
25 #include "chrome/browser/safe_browsing/binary_feature_extractor.h"
26 #include "chrome/browser/safe_browsing/database_manager.h"
27 #include "chrome/browser/safe_browsing/download_feedback_service.h"
28 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
29 #include "chrome/common/safe_browsing/csd.pb.h"
30 #include "chrome/test/base/testing_profile.h"
31 #include "content/public/test/mock_download_item.h"
32 #include "content/public/test/test_browser_thread_bundle.h"
33 #include "content/public/test/test_utils.h"
34 #include "net/cert/x509_certificate.h"
35 #include "net/http/http_status_code.h"
36 #include "net/url_request/test_url_fetcher_factory.h"
37 #include "net/url_request/url_fetcher_delegate.h"
38 #include "net/url_request/url_request_status.h"
39 #include "testing/gmock/include/gmock/gmock.h"
40 #include "testing/gtest/include/gtest/gtest.h"
41 #include "third_party/zlib/google/zip.h"
42 #include "url/gurl.h"
43
44 using ::testing::Assign;
45 using ::testing::ContainerEq;
46 using ::testing::DoAll;
47 using ::testing::ElementsAre;
48 using ::testing::Mock;
49 using ::testing::NotNull;
50 using ::testing::Return;
51 using ::testing::ReturnRef;
52 using ::testing::SaveArg;
53 using ::testing::StrictMock;
54 using ::testing::_;
55 using base::MessageLoop;
56 using content::BrowserThread;
57 namespace safe_browsing {
58 namespace {
59 // A SafeBrowsingDatabaseManager implementation that returns a fixed result for
60 // a given URL.
61 class MockSafeBrowsingDatabaseManager : public SafeBrowsingDatabaseManager {
62 public:
MockSafeBrowsingDatabaseManager(SafeBrowsingService * service)63 explicit MockSafeBrowsingDatabaseManager(SafeBrowsingService* service)
64 : SafeBrowsingDatabaseManager(service) { }
65
66 MOCK_METHOD1(MatchDownloadWhitelistUrl, bool(const GURL&));
67 MOCK_METHOD1(MatchDownloadWhitelistString, bool(const std::string&));
68 MOCK_METHOD2(CheckDownloadUrl, bool(
69 const std::vector<GURL>& url_chain,
70 SafeBrowsingDatabaseManager::Client* client));
71
72 private:
~MockSafeBrowsingDatabaseManager()73 virtual ~MockSafeBrowsingDatabaseManager() {}
74 DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingDatabaseManager);
75 };
76
77 class FakeSafeBrowsingService : public SafeBrowsingService {
78 public:
FakeSafeBrowsingService()79 FakeSafeBrowsingService() { }
80
81 // Returned pointer has the same lifespan as the database_manager_ refcounted
82 // object.
mock_database_manager()83 MockSafeBrowsingDatabaseManager* mock_database_manager() {
84 return mock_database_manager_;
85 }
86
87 protected:
~FakeSafeBrowsingService()88 virtual ~FakeSafeBrowsingService() { }
89
CreateDatabaseManager()90 virtual SafeBrowsingDatabaseManager* CreateDatabaseManager() OVERRIDE {
91 mock_database_manager_ = new MockSafeBrowsingDatabaseManager(this);
92 return mock_database_manager_;
93 }
94
95 private:
96 MockSafeBrowsingDatabaseManager* mock_database_manager_;
97
98 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingService);
99 };
100
101 class MockBinaryFeatureExtractor : public BinaryFeatureExtractor {
102 public:
MockBinaryFeatureExtractor()103 MockBinaryFeatureExtractor() {}
104 MOCK_METHOD2(CheckSignature, void(const base::FilePath&,
105 ClientDownloadRequest_SignatureInfo*));
106 MOCK_METHOD2(ExtractImageHeaders, void(const base::FilePath&,
107 ClientDownloadRequest_ImageHeaders*));
108
109 protected:
~MockBinaryFeatureExtractor()110 virtual ~MockBinaryFeatureExtractor() {}
111
112 private:
113 DISALLOW_COPY_AND_ASSIGN(MockBinaryFeatureExtractor);
114 };
115
116 class TestURLFetcherWatcher : public net::TestURLFetcherDelegateForTests {
117 public:
TestURLFetcherWatcher(net::TestURLFetcherFactory * factory)118 explicit TestURLFetcherWatcher(net::TestURLFetcherFactory* factory)
119 : factory_(factory), fetcher_id_(-1) {
120 factory_->SetDelegateForTests(this);
121 }
~TestURLFetcherWatcher()122 ~TestURLFetcherWatcher() {
123 factory_->SetDelegateForTests(NULL);
124 }
125
126 // TestURLFetcherDelegateForTests impl:
OnRequestStart(int fetcher_id)127 virtual void OnRequestStart(int fetcher_id) OVERRIDE {
128 fetcher_id_ = fetcher_id;
129 run_loop_.Quit();
130 }
OnChunkUpload(int fetcher_id)131 virtual void OnChunkUpload(int fetcher_id) OVERRIDE {}
OnRequestEnd(int fetcher_id)132 virtual void OnRequestEnd(int fetcher_id) OVERRIDE {}
133
WaitForRequest()134 int WaitForRequest() {
135 run_loop_.Run();
136 return fetcher_id_;
137 }
138
139 private:
140 net::TestURLFetcherFactory* factory_;
141 int fetcher_id_;
142 base::RunLoop run_loop_;
143 };
144 } // namespace
145
ACTION_P(SetCertificateContents,contents)146 ACTION_P(SetCertificateContents, contents) {
147 arg1->add_certificate_chain()->add_element()->set_certificate(contents);
148 }
149
ACTION_P(SetDosHeaderContents,contents)150 ACTION_P(SetDosHeaderContents, contents) {
151 arg1->mutable_pe_headers()->set_dos_header(contents);
152 }
153
ACTION_P(TrustSignature,certificate_file)154 ACTION_P(TrustSignature, certificate_file) {
155 arg1->set_trusted(true);
156 // Add a certificate chain. Note that we add the certificate twice so that
157 // it appears as its own issuer.
158 std::string cert_data;
159 ASSERT_TRUE(base::ReadFileToString(certificate_file, &cert_data));
160 ClientDownloadRequest_CertificateChain* chain =
161 arg1->add_certificate_chain();
162 chain->add_element()->set_certificate(cert_data);
163 chain->add_element()->set_certificate(cert_data);
164 }
165
166 // We can't call OnSafeBrowsingResult directly because SafeBrowsingCheck does
167 // not have any copy constructor which means it can't be stored in a callback
168 // easily. Note: check will be deleted automatically when the callback is
169 // deleted.
OnSafeBrowsingResult(SafeBrowsingDatabaseManager::SafeBrowsingCheck * check)170 void OnSafeBrowsingResult(
171 SafeBrowsingDatabaseManager::SafeBrowsingCheck* check) {
172 check->client->OnSafeBrowsingResult(*check);
173 }
174
ACTION_P(CheckDownloadUrlDone,threat_type)175 ACTION_P(CheckDownloadUrlDone, threat_type) {
176 SafeBrowsingDatabaseManager::SafeBrowsingCheck* check =
177 new SafeBrowsingDatabaseManager::SafeBrowsingCheck(
178 arg0,
179 std::vector<SBFullHash>(),
180 arg1,
181 safe_browsing_util::BINURL,
182 std::vector<SBThreatType>(1, SB_THREAT_TYPE_BINARY_MALWARE_URL));
183 for (size_t i = 0; i < check->url_results.size(); ++i)
184 check->url_results[i] = threat_type;
185 BrowserThread::PostTask(BrowserThread::IO,
186 FROM_HERE,
187 base::Bind(&OnSafeBrowsingResult,
188 base::Owned(check)));
189 }
190
191 class DownloadProtectionServiceTest : public testing::Test {
192 protected:
DownloadProtectionServiceTest()193 DownloadProtectionServiceTest()
194 : test_browser_thread_bundle_(
195 content::TestBrowserThreadBundle::IO_MAINLOOP) {
196 }
SetUp()197 virtual void SetUp() {
198 // Start real threads for the IO and File threads so that the DCHECKs
199 // to test that we're on the correct thread work.
200 sb_service_ = new StrictMock<FakeSafeBrowsingService>();
201 sb_service_->Initialize();
202 binary_feature_extractor_ = new StrictMock<MockBinaryFeatureExtractor>();
203 download_service_ = sb_service_->download_protection_service();
204 download_service_->binary_feature_extractor_ = binary_feature_extractor_;
205 download_service_->SetEnabled(true);
206 base::RunLoop().RunUntilIdle();
207 has_result_ = false;
208
209 base::FilePath source_path;
210 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &source_path));
211 testdata_path_ = source_path
212 .AppendASCII("chrome")
213 .AppendASCII("test")
214 .AppendASCII("data")
215 .AppendASCII("safe_browsing")
216 .AppendASCII("download_protection");
217 }
218
TearDown()219 virtual void TearDown() {
220 sb_service_->ShutDown();
221 // Flush all of the thread message loops to ensure that there are no
222 // tasks currently running.
223 FlushThreadMessageLoops();
224 sb_service_ = NULL;
225 }
226
RequestContainsResource(const ClientDownloadRequest & request,ClientDownloadRequest::ResourceType type,const std::string & url,const std::string & referrer)227 bool RequestContainsResource(const ClientDownloadRequest& request,
228 ClientDownloadRequest::ResourceType type,
229 const std::string& url,
230 const std::string& referrer) {
231 for (int i = 0; i < request.resources_size(); ++i) {
232 if (request.resources(i).url() == url &&
233 request.resources(i).type() == type &&
234 (referrer.empty() || request.resources(i).referrer() == referrer)) {
235 return true;
236 }
237 }
238 return false;
239 }
240
241 // At this point we only set the server IP for the download itself.
RequestContainsServerIp(const ClientDownloadRequest & request,const std::string & remote_address)242 bool RequestContainsServerIp(const ClientDownloadRequest& request,
243 const std::string& remote_address) {
244 for (int i = 0; i < request.resources_size(); ++i) {
245 // We want the last DOWNLOAD_URL in the chain.
246 if (request.resources(i).type() == ClientDownloadRequest::DOWNLOAD_URL &&
247 (i + 1 == request.resources_size() ||
248 request.resources(i + 1).type() !=
249 ClientDownloadRequest::DOWNLOAD_URL)) {
250 return remote_address == request.resources(i).remote_ip();
251 }
252 }
253 return false;
254 }
255
256 // Flushes any pending tasks in the message loops of all threads.
FlushThreadMessageLoops()257 void FlushThreadMessageLoops() {
258 BrowserThread::GetBlockingPool()->FlushForTesting();
259 FlushMessageLoop(BrowserThread::IO);
260 base::RunLoop().RunUntilIdle();
261 }
262
263 // Proxy for private method.
GetCertificateWhitelistStrings(const net::X509Certificate & certificate,const net::X509Certificate & issuer,std::vector<std::string> * whitelist_strings)264 static void GetCertificateWhitelistStrings(
265 const net::X509Certificate& certificate,
266 const net::X509Certificate& issuer,
267 std::vector<std::string>* whitelist_strings) {
268 DownloadProtectionService::GetCertificateWhitelistStrings(
269 certificate, issuer, whitelist_strings);
270 }
271
272 // Reads a single PEM-encoded certificate from the testdata directory.
273 // Returns NULL on failure.
ReadTestCertificate(const std::string & filename)274 scoped_refptr<net::X509Certificate> ReadTestCertificate(
275 const std::string& filename) {
276 std::string cert_data;
277 if (!base::ReadFileToString(testdata_path_.AppendASCII(filename),
278 &cert_data)) {
279 return NULL;
280 }
281 net::CertificateList certs =
282 net::X509Certificate::CreateCertificateListFromBytes(
283 cert_data.data(),
284 cert_data.size(),
285 net::X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
286 return certs.empty() ? NULL : certs[0];
287 }
288
289 private:
290 // Helper functions for FlushThreadMessageLoops.
RunAllPendingAndQuitUI()291 void RunAllPendingAndQuitUI() {
292 base::MessageLoop::current()->RunUntilIdle();
293 BrowserThread::PostTask(
294 BrowserThread::UI,
295 FROM_HERE,
296 base::Bind(&DownloadProtectionServiceTest::QuitMessageLoop,
297 base::Unretained(this)));
298 }
299
QuitMessageLoop()300 void QuitMessageLoop() {
301 base::MessageLoop::current()->Quit();
302 }
303
PostRunMessageLoopTask(BrowserThread::ID thread)304 void PostRunMessageLoopTask(BrowserThread::ID thread) {
305 BrowserThread::PostTask(
306 thread,
307 FROM_HERE,
308 base::Bind(&DownloadProtectionServiceTest::RunAllPendingAndQuitUI,
309 base::Unretained(this)));
310 }
311
FlushMessageLoop(BrowserThread::ID thread)312 void FlushMessageLoop(BrowserThread::ID thread) {
313 BrowserThread::PostTask(
314 BrowserThread::UI,
315 FROM_HERE,
316 base::Bind(&DownloadProtectionServiceTest::PostRunMessageLoopTask,
317 base::Unretained(this), thread));
318 MessageLoop::current()->Run();
319 }
320
321 public:
CheckDoneCallback(DownloadProtectionService::DownloadCheckResult result)322 void CheckDoneCallback(
323 DownloadProtectionService::DownloadCheckResult result) {
324 result_ = result;
325 has_result_ = true;
326 MessageLoop::current()->Quit();
327 }
328
SyncCheckDoneCallback(DownloadProtectionService::DownloadCheckResult result)329 void SyncCheckDoneCallback(
330 DownloadProtectionService::DownloadCheckResult result) {
331 result_ = result;
332 has_result_ = true;
333 }
334
SendURLFetchComplete(net::TestURLFetcher * fetcher)335 void SendURLFetchComplete(net::TestURLFetcher* fetcher) {
336 fetcher->delegate()->OnURLFetchComplete(fetcher);
337 }
338
IsResult(DownloadProtectionService::DownloadCheckResult expected)339 testing::AssertionResult IsResult(
340 DownloadProtectionService::DownloadCheckResult expected) {
341 if (!has_result_)
342 return testing::AssertionFailure() << "No result";
343 has_result_ = false;
344 return result_ == expected ?
345 testing::AssertionSuccess() :
346 testing::AssertionFailure() << "Expected " << expected <<
347 ", got " << result_;
348 }
349
350 protected:
351 scoped_refptr<FakeSafeBrowsingService> sb_service_;
352 scoped_refptr<MockBinaryFeatureExtractor> binary_feature_extractor_;
353 DownloadProtectionService* download_service_;
354 DownloadProtectionService::DownloadCheckResult result_;
355 bool has_result_;
356 content::TestBrowserThreadBundle test_browser_thread_bundle_;
357 content::InProcessUtilityThreadHelper in_process_utility_thread_helper_;
358 base::FilePath testdata_path_;
359 };
360
TEST_F(DownloadProtectionServiceTest,CheckClientDownloadInvalidUrl)361 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadInvalidUrl) {
362 base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
363 base::FilePath a_exe(FILE_PATH_LITERAL("a.exe"));
364 std::vector<GURL> url_chain;
365 GURL referrer("http://www.google.com/");
366
367 content::MockDownloadItem item;
368 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
369 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
370 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
371 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
372 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
373 EXPECT_CALL(item, GetTabReferrerUrl())
374 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
375 download_service_->CheckClientDownload(
376 &item,
377 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
378 base::Unretained(this)));
379 MessageLoop::current()->Run();
380 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
381 Mock::VerifyAndClearExpectations(&item);
382
383 url_chain.push_back(GURL("file://www.google.com/"));
384 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
385 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
386 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
387 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
388 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
389 EXPECT_CALL(item, GetTabReferrerUrl())
390 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
391 download_service_->CheckClientDownload(
392 &item,
393 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
394 base::Unretained(this)));
395 MessageLoop::current()->Run();
396 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
397 }
398
TEST_F(DownloadProtectionServiceTest,CheckClientDownloadWhitelistedUrl)399 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadWhitelistedUrl) {
400 // Response to any requests will be DANGEROUS.
401 ClientDownloadResponse response;
402 response.set_verdict(ClientDownloadResponse::DANGEROUS);
403 net::FakeURLFetcherFactory factory(NULL);
404 factory.SetFakeResponse(
405 DownloadProtectionService::GetDownloadRequestUrl(),
406 response.SerializeAsString(),
407 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
408
409 std::string hash = "hash";
410 base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
411 base::FilePath a_exe(FILE_PATH_LITERAL("a.exe"));
412 std::vector<GURL> url_chain;
413 GURL referrer;
414
415 content::MockDownloadItem item;
416 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
417 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
418 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
419 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
420 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
421 EXPECT_CALL(item, GetTabReferrerUrl())
422 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
423 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
424 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
425 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
426 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
427 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(a_tmp, _))
428 .Times(4);
429 EXPECT_CALL(*binary_feature_extractor_.get(), ExtractImageHeaders(a_tmp, _))
430 .Times(4);
431
432 // We should not get whilelist checks for other URLs than specified below.
433 EXPECT_CALL(*sb_service_->mock_database_manager(),
434 MatchDownloadWhitelistUrl(_)).Times(0);
435 EXPECT_CALL(*sb_service_->mock_database_manager(),
436 MatchDownloadWhitelistUrl(GURL("http://www.evil.com/bla.exe")))
437 .WillRepeatedly(Return(false));
438 EXPECT_CALL(*sb_service_->mock_database_manager(),
439 MatchDownloadWhitelistUrl(GURL("http://www.google.com/a.exe")))
440 .WillRepeatedly(Return(true));
441
442 // With no referrer and just the bad url, should be marked DANGEROUS.
443 url_chain.push_back(GURL("http://www.evil.com/bla.exe"));
444 download_service_->CheckClientDownload(
445 &item,
446 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
447 base::Unretained(this)));
448 MessageLoop::current()->Run();
449 #if defined(OS_WIN)
450 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
451 #else
452 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
453 #endif
454
455 // Check that the referrer is not matched against the whitelist.
456 referrer = GURL("http://www.google.com/");
457 download_service_->CheckClientDownload(
458 &item,
459 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
460 base::Unretained(this)));
461 MessageLoop::current()->Run();
462 #if defined(OS_WIN)
463 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
464 #else
465 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
466 #endif
467
468 // Redirect from a site shouldn't be checked either.
469 url_chain.insert(url_chain.begin(), GURL("http://www.google.com/redirect"));
470 download_service_->CheckClientDownload(
471 &item,
472 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
473 base::Unretained(this)));
474 MessageLoop::current()->Run();
475 #if defined(OS_WIN)
476 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
477 #else
478 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
479 #endif
480
481 // Only if the final url is whitelisted should it be SAFE.
482 url_chain.push_back(GURL("http://www.google.com/a.exe"));
483 download_service_->CheckClientDownload(
484 &item,
485 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
486 base::Unretained(this)));
487 MessageLoop::current()->Run();
488 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
489 }
490
TEST_F(DownloadProtectionServiceTest,CheckClientDownloadFetchFailed)491 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadFetchFailed) {
492 net::FakeURLFetcherFactory factory(NULL);
493 // HTTP request will fail.
494 factory.SetFakeResponse(
495 DownloadProtectionService::GetDownloadRequestUrl(), std::string(),
496 net::HTTP_INTERNAL_SERVER_ERROR, net::URLRequestStatus::FAILED);
497
498 base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
499 base::FilePath a_exe(FILE_PATH_LITERAL("a.exe"));
500 std::vector<GURL> url_chain;
501 url_chain.push_back(GURL("http://www.evil.com/a.exe"));
502 GURL referrer("http://www.google.com/");
503 std::string hash = "hash";
504
505 content::MockDownloadItem item;
506 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
507 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
508 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
509 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
510 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
511 EXPECT_CALL(item, GetTabReferrerUrl())
512 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
513 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
514 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
515 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
516 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
517
518 EXPECT_CALL(*sb_service_->mock_database_manager(),
519 MatchDownloadWhitelistUrl(_))
520 .WillRepeatedly(Return(false));
521 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(a_tmp, _));
522 EXPECT_CALL(*binary_feature_extractor_.get(), ExtractImageHeaders(a_tmp, _));
523
524 download_service_->CheckClientDownload(
525 &item,
526 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
527 base::Unretained(this)));
528 MessageLoop::current()->Run();
529 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
530 }
531
TEST_F(DownloadProtectionServiceTest,CheckClientDownloadSuccess)532 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadSuccess) {
533 ClientDownloadResponse response;
534 response.set_verdict(ClientDownloadResponse::SAFE);
535 net::FakeURLFetcherFactory factory(NULL);
536 // Empty response means SAFE.
537 factory.SetFakeResponse(
538 DownloadProtectionService::GetDownloadRequestUrl(),
539 response.SerializeAsString(),
540 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
541
542 base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
543 base::FilePath a_exe(FILE_PATH_LITERAL("a.exe"));
544 std::vector<GURL> url_chain;
545 url_chain.push_back(GURL("http://www.evil.com/a.exe"));
546 GURL referrer("http://www.google.com/");
547 std::string hash = "hash";
548
549 content::MockDownloadItem item;
550 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
551 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
552 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
553 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
554 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
555 EXPECT_CALL(item, GetTabReferrerUrl())
556 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
557 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
558 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
559 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
560 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
561
562 EXPECT_CALL(*sb_service_->mock_database_manager(),
563 MatchDownloadWhitelistUrl(_))
564 .WillRepeatedly(Return(false));
565 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(a_tmp, _))
566 .Times(6);
567 EXPECT_CALL(*binary_feature_extractor_.get(), ExtractImageHeaders(a_tmp, _))
568 .Times(6);
569
570 download_service_->CheckClientDownload(
571 &item,
572 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
573 base::Unretained(this)));
574 MessageLoop::current()->Run();
575 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
576
577 // Invalid response should be safe too.
578 response.Clear();
579 factory.SetFakeResponse(
580 DownloadProtectionService::GetDownloadRequestUrl(),
581 response.SerializePartialAsString(),
582 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
583
584 download_service_->CheckClientDownload(
585 &item,
586 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
587 base::Unretained(this)));
588 MessageLoop::current()->Run();
589 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
590 std::string feedback_ping;
591 std::string feedback_response;
592 EXPECT_FALSE(DownloadFeedbackService::GetPingsForDownloadForTesting(
593 item, &feedback_ping, &feedback_response));
594
595 // If the response is dangerous the result should also be marked as dangerous.
596 response.set_verdict(ClientDownloadResponse::DANGEROUS);
597 factory.SetFakeResponse(
598 DownloadProtectionService::GetDownloadRequestUrl(),
599 response.SerializeAsString(),
600 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
601
602 download_service_->CheckClientDownload(
603 &item,
604 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
605 base::Unretained(this)));
606 MessageLoop::current()->Run();
607 EXPECT_FALSE(DownloadFeedbackService::GetPingsForDownloadForTesting(
608 item, &feedback_ping, &feedback_response));
609 #if defined(OS_WIN)
610 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
611 #else
612 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
613 #endif
614
615 // If the response is uncommon the result should also be marked as uncommon.
616 response.set_verdict(ClientDownloadResponse::UNCOMMON);
617 factory.SetFakeResponse(
618 DownloadProtectionService::GetDownloadRequestUrl(),
619 response.SerializeAsString(),
620 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
621
622 download_service_->CheckClientDownload(
623 &item,
624 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
625 base::Unretained(this)));
626 MessageLoop::current()->Run();
627 #if defined(OS_WIN)
628 EXPECT_TRUE(IsResult(DownloadProtectionService::UNCOMMON));
629 EXPECT_TRUE(DownloadFeedbackService::GetPingsForDownloadForTesting(
630 item, &feedback_ping, &feedback_response));
631 ClientDownloadRequest decoded_request;
632 EXPECT_TRUE(decoded_request.ParseFromString(feedback_ping));
633 EXPECT_EQ(url_chain.back().spec(), decoded_request.url());
634 EXPECT_EQ(response.SerializeAsString(), feedback_response);
635 #else
636 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
637 #endif
638
639 // If the response is dangerous_host the result should also be marked as
640 // dangerous_host.
641 response.set_verdict(ClientDownloadResponse::DANGEROUS_HOST);
642 factory.SetFakeResponse(
643 DownloadProtectionService::GetDownloadRequestUrl(),
644 response.SerializeAsString(),
645 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
646
647 download_service_->CheckClientDownload(
648 &item,
649 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
650 base::Unretained(this)));
651 MessageLoop::current()->Run();
652 #if defined(OS_WIN)
653 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS_HOST));
654 EXPECT_TRUE(DownloadFeedbackService::GetPingsForDownloadForTesting(
655 item, &feedback_ping, &feedback_response));
656 EXPECT_EQ(response.SerializeAsString(), feedback_response);
657 #else
658 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
659 #endif
660
661 // If the response is POTENTIALLY_UNWANTED the result should also be marked as
662 // POTENTIALLY_UNWANTED.
663 response.set_verdict(ClientDownloadResponse::POTENTIALLY_UNWANTED);
664 factory.SetFakeResponse(
665 DownloadProtectionService::GetDownloadRequestUrl(),
666 response.SerializeAsString(),
667 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
668
669 download_service_->CheckClientDownload(
670 &item,
671 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
672 base::Unretained(this)));
673 MessageLoop::current()->Run();
674 #if defined(OS_WIN)
675 EXPECT_TRUE(IsResult(DownloadProtectionService::POTENTIALLY_UNWANTED));
676 #else
677 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
678 #endif
679 }
680
TEST_F(DownloadProtectionServiceTest,CheckClientDownloadHTTPS)681 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadHTTPS) {
682 ClientDownloadResponse response;
683 response.set_verdict(ClientDownloadResponse::DANGEROUS);
684 net::FakeURLFetcherFactory factory(NULL);
685 factory.SetFakeResponse(
686 DownloadProtectionService::GetDownloadRequestUrl(),
687 response.SerializeAsString(),
688 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
689
690 base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
691 base::FilePath a_exe(FILE_PATH_LITERAL("a.exe"));
692 std::vector<GURL> url_chain;
693 url_chain.push_back(GURL("http://www.evil.com/a.exe"));
694 GURL referrer("http://www.google.com/");
695 std::string hash = "hash";
696
697 content::MockDownloadItem item;
698 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
699 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
700 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
701 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
702 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
703 EXPECT_CALL(item, GetTabReferrerUrl())
704 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
705 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
706 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
707 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
708 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
709
710 EXPECT_CALL(*sb_service_->mock_database_manager(),
711 MatchDownloadWhitelistUrl(_))
712 .WillRepeatedly(Return(false));
713 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(a_tmp, _))
714 .Times(1);
715 EXPECT_CALL(*binary_feature_extractor_.get(), ExtractImageHeaders(a_tmp, _))
716 .Times(1);
717
718 download_service_->CheckClientDownload(
719 &item,
720 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
721 base::Unretained(this)));
722 MessageLoop::current()->Run();
723 #if defined(OS_WIN)
724 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
725 #else
726 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
727 #endif
728 }
729
TEST_F(DownloadProtectionServiceTest,CheckClientDownloadZip)730 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadZip) {
731 ClientDownloadResponse response;
732 response.set_verdict(ClientDownloadResponse::SAFE);
733 net::FakeURLFetcherFactory factory(NULL);
734 // Empty response means SAFE.
735 factory.SetFakeResponse(
736 DownloadProtectionService::GetDownloadRequestUrl(),
737 response.SerializeAsString(),
738 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
739
740 base::ScopedTempDir download_dir;
741 ASSERT_TRUE(download_dir.CreateUniqueTempDir());
742
743 base::FilePath a_tmp(download_dir.path().Append(FILE_PATH_LITERAL("a.tmp")));
744 base::FilePath a_zip(FILE_PATH_LITERAL("a.zip"));
745 std::vector<GURL> url_chain;
746 url_chain.push_back(GURL("http://www.evil.com/a.zip"));
747 GURL referrer("http://www.google.com/");
748 std::string hash = "hash";
749
750 content::MockDownloadItem item;
751 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
752 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_zip));
753 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
754 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
755 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
756 EXPECT_CALL(item, GetTabReferrerUrl())
757 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
758 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
759 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
760 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
761 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
762
763 // Write out a zip archive to the temporary file. In this case, it
764 // only contains a text file.
765 base::ScopedTempDir zip_source_dir;
766 ASSERT_TRUE(zip_source_dir.CreateUniqueTempDir());
767 std::string file_contents = "dummy file";
768 ASSERT_EQ(static_cast<int>(file_contents.size()), base::WriteFile(
769 zip_source_dir.path().Append(FILE_PATH_LITERAL("file.txt")),
770 file_contents.data(), file_contents.size()));
771 ASSERT_TRUE(zip::Zip(zip_source_dir.path(), a_tmp, false));
772
773 download_service_->CheckClientDownload(
774 &item,
775 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
776 base::Unretained(this)));
777 MessageLoop::current()->Run();
778 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
779 Mock::VerifyAndClearExpectations(sb_service_.get());
780 Mock::VerifyAndClearExpectations(binary_feature_extractor_.get());
781
782 // Now check with an executable in the zip file as well.
783 ASSERT_EQ(static_cast<int>(file_contents.size()), base::WriteFile(
784 zip_source_dir.path().Append(FILE_PATH_LITERAL("file.exe")),
785 file_contents.data(), file_contents.size()));
786 ASSERT_TRUE(zip::Zip(zip_source_dir.path(), a_tmp, false));
787
788 EXPECT_CALL(*sb_service_->mock_database_manager(),
789 MatchDownloadWhitelistUrl(_))
790 .WillRepeatedly(Return(false));
791
792 download_service_->CheckClientDownload(
793 &item,
794 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
795 base::Unretained(this)));
796 MessageLoop::current()->Run();
797 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
798 Mock::VerifyAndClearExpectations(binary_feature_extractor_.get());
799
800 // If the response is dangerous the result should also be marked as
801 // dangerous.
802 response.set_verdict(ClientDownloadResponse::DANGEROUS);
803 factory.SetFakeResponse(
804 DownloadProtectionService::GetDownloadRequestUrl(),
805 response.SerializeAsString(),
806 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
807
808 download_service_->CheckClientDownload(
809 &item,
810 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
811 base::Unretained(this)));
812 MessageLoop::current()->Run();
813 #if defined(OS_WIN)
814 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
815 #else
816 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
817 #endif
818 Mock::VerifyAndClearExpectations(binary_feature_extractor_.get());
819 }
820
TEST_F(DownloadProtectionServiceTest,CheckClientDownloadCorruptZip)821 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadCorruptZip) {
822 base::ScopedTempDir download_dir;
823 ASSERT_TRUE(download_dir.CreateUniqueTempDir());
824
825 base::FilePath a_tmp(download_dir.path().Append(FILE_PATH_LITERAL("a.tmp")));
826 base::FilePath a_zip(FILE_PATH_LITERAL("a.zip"));
827 std::vector<GURL> url_chain;
828 url_chain.push_back(GURL("http://www.evil.com/a.zip"));
829 GURL referrer("http://www.google.com/");
830 std::string hash = "hash";
831
832 content::MockDownloadItem item;
833 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
834 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_zip));
835 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
836 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
837 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
838 EXPECT_CALL(item, GetTabReferrerUrl())
839 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
840 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
841 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
842 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
843 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
844
845 std::string file_contents = "corrupt zip file";
846 ASSERT_EQ(static_cast<int>(file_contents.size()), base::WriteFile(
847 a_tmp, file_contents.data(), file_contents.size()));
848
849 download_service_->CheckClientDownload(
850 &item,
851 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
852 base::Unretained(this)));
853 MessageLoop::current()->Run();
854 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
855 Mock::VerifyAndClearExpectations(sb_service_.get());
856 Mock::VerifyAndClearExpectations(binary_feature_extractor_.get());
857 }
858
TEST_F(DownloadProtectionServiceTest,CheckClientCrxDownloadSuccess)859 TEST_F(DownloadProtectionServiceTest, CheckClientCrxDownloadSuccess) {
860 ClientDownloadResponse response;
861 // Even if the server verdict is dangerous we should return SAFE because
862 // DownloadProtectionService::IsSupportedDownload() will return false
863 // for crx downloads.
864 response.set_verdict(ClientDownloadResponse::DANGEROUS);
865 net::FakeURLFetcherFactory factory(NULL);
866 // Empty response means SAFE.
867 factory.SetFakeResponse(
868 DownloadProtectionService::GetDownloadRequestUrl(),
869 response.SerializeAsString(),
870 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
871
872 base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
873 base::FilePath a_crx(FILE_PATH_LITERAL("a.crx"));
874 std::vector<GURL> url_chain;
875 url_chain.push_back(GURL("http://www.evil.com/a.crx"));
876 GURL referrer("http://www.google.com/");
877 std::string hash = "hash";
878
879 content::MockDownloadItem item;
880 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
881 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_crx));
882 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
883 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
884 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
885 EXPECT_CALL(item, GetTabReferrerUrl())
886 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
887 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
888 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
889 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
890 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
891
892 EXPECT_CALL(*sb_service_->mock_database_manager(),
893 MatchDownloadWhitelistUrl(_))
894 .WillRepeatedly(Return(false));
895 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(a_tmp, _))
896 .Times(1);
897 EXPECT_CALL(*binary_feature_extractor_.get(), ExtractImageHeaders(a_tmp, _))
898 .Times(1);
899
900 EXPECT_FALSE(download_service_->IsSupportedDownload(item, a_crx));
901 download_service_->CheckClientDownload(
902 &item,
903 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
904 base::Unretained(this)));
905 MessageLoop::current()->Run();
906 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
907 }
908
TEST_F(DownloadProtectionServiceTest,CheckClientDownloadValidateRequest)909 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadValidateRequest) {
910 net::TestURLFetcherFactory factory;
911
912 base::FilePath tmp_path(FILE_PATH_LITERAL("bla.tmp"));
913 base::FilePath final_path(FILE_PATH_LITERAL("bla.exe"));
914 std::vector<GURL> url_chain;
915 url_chain.push_back(GURL("http://www.google.com/"));
916 url_chain.push_back(GURL("http://www.google.com/bla.exe"));
917 GURL referrer("http://www.google.com/");
918 std::string hash = "hash";
919 std::string remote_address = "10.11.12.13";
920
921 content::MockDownloadItem item;
922 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path));
923 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path));
924 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
925 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
926 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
927 EXPECT_CALL(item, GetTabReferrerUrl())
928 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
929 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
930 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
931 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
932 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(remote_address));
933
934 EXPECT_CALL(*sb_service_->mock_database_manager(),
935 MatchDownloadWhitelistUrl(_))
936 .WillRepeatedly(Return(false));
937 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path, _))
938 .WillOnce(SetCertificateContents("dummy cert data"));
939 EXPECT_CALL(*binary_feature_extractor_.get(),
940 ExtractImageHeaders(tmp_path, _))
941 .WillOnce(SetDosHeaderContents("dummy dos header"));
942 download_service_->CheckClientDownload(
943 &item,
944 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
945 base::Unretained(this)));
946
947 #if !defined(OS_WIN)
948 // SendRequest is not called. Wait for FinishRequest to call our callback.
949 MessageLoop::current()->Run();
950 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
951 EXPECT_EQ(NULL, fetcher);
952 #else
953 // Run the message loop(s) until SendRequest is called.
954 FlushThreadMessageLoops();
955 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
956 ASSERT_TRUE(fetcher);
957 ClientDownloadRequest request;
958 EXPECT_TRUE(request.ParseFromString(fetcher->upload_data()));
959 EXPECT_EQ("http://www.google.com/bla.exe", request.url());
960 EXPECT_EQ(hash, request.digests().sha256());
961 EXPECT_EQ(item.GetReceivedBytes(), request.length());
962 EXPECT_EQ(item.HasUserGesture(), request.user_initiated());
963 EXPECT_TRUE(RequestContainsServerIp(request, remote_address));
964 EXPECT_EQ(2, request.resources_size());
965 EXPECT_TRUE(RequestContainsResource(request,
966 ClientDownloadRequest::DOWNLOAD_REDIRECT,
967 "http://www.google.com/", ""));
968 EXPECT_TRUE(RequestContainsResource(request,
969 ClientDownloadRequest::DOWNLOAD_URL,
970 "http://www.google.com/bla.exe",
971 referrer.spec()));
972 EXPECT_TRUE(request.has_signature());
973 ASSERT_EQ(1, request.signature().certificate_chain_size());
974 const ClientDownloadRequest_CertificateChain& chain =
975 request.signature().certificate_chain(0);
976 ASSERT_EQ(1, chain.element_size());
977 EXPECT_EQ("dummy cert data", chain.element(0).certificate());
978 EXPECT_TRUE(request.has_image_headers());
979 const ClientDownloadRequest_ImageHeaders& headers =
980 request.image_headers();
981 EXPECT_TRUE(headers.has_pe_headers());
982 EXPECT_TRUE(headers.pe_headers().has_dos_header());
983 EXPECT_EQ("dummy dos header", headers.pe_headers().dos_header());
984
985 // Simulate the request finishing.
986 base::MessageLoop::current()->PostTask(
987 FROM_HERE,
988 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete,
989 base::Unretained(this), fetcher));
990 MessageLoop::current()->Run();
991 #endif
992 }
993
994 // Similar to above, but with an unsigned binary.
TEST_F(DownloadProtectionServiceTest,CheckClientDownloadValidateRequestNoSignature)995 TEST_F(DownloadProtectionServiceTest,
996 CheckClientDownloadValidateRequestNoSignature) {
997 net::TestURLFetcherFactory factory;
998
999 base::FilePath tmp_path(FILE_PATH_LITERAL("bla.tmp"));
1000 base::FilePath final_path(FILE_PATH_LITERAL("bla.exe"));
1001 std::vector<GURL> url_chain;
1002 url_chain.push_back(GURL("http://www.google.com/"));
1003 url_chain.push_back(GURL("ftp://www.google.com/bla.exe"));
1004 GURL referrer("http://www.google.com/");
1005 std::string hash = "hash";
1006 std::string remote_address = "10.11.12.13";
1007
1008 content::MockDownloadItem item;
1009 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path));
1010 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path));
1011 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
1012 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
1013 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1014 EXPECT_CALL(item, GetTabReferrerUrl())
1015 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1016 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
1017 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
1018 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
1019 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(remote_address));
1020
1021 EXPECT_CALL(*sb_service_->mock_database_manager(),
1022 MatchDownloadWhitelistUrl(_))
1023 .WillRepeatedly(Return(false));
1024 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path, _));
1025 EXPECT_CALL(*binary_feature_extractor_.get(),
1026 ExtractImageHeaders(tmp_path, _));
1027 download_service_->CheckClientDownload(
1028 &item,
1029 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
1030 base::Unretained(this)));
1031
1032 #if !defined(OS_WIN)
1033 // SendRequest is not called. Wait for FinishRequest to call our callback.
1034 MessageLoop::current()->Run();
1035 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
1036 EXPECT_EQ(NULL, fetcher);
1037 #else
1038 // Run the message loop(s) until SendRequest is called.
1039 FlushThreadMessageLoops();
1040 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
1041 ASSERT_TRUE(fetcher);
1042 ClientDownloadRequest request;
1043 EXPECT_TRUE(request.ParseFromString(fetcher->upload_data()));
1044 EXPECT_EQ("ftp://www.google.com/bla.exe", request.url());
1045 EXPECT_EQ(hash, request.digests().sha256());
1046 EXPECT_EQ(item.GetReceivedBytes(), request.length());
1047 EXPECT_EQ(item.HasUserGesture(), request.user_initiated());
1048 EXPECT_EQ(2, request.resources_size());
1049 EXPECT_TRUE(RequestContainsResource(request,
1050 ClientDownloadRequest::DOWNLOAD_REDIRECT,
1051 "http://www.google.com/", ""));
1052 EXPECT_TRUE(RequestContainsResource(request,
1053 ClientDownloadRequest::DOWNLOAD_URL,
1054 "ftp://www.google.com/bla.exe",
1055 referrer.spec()));
1056 EXPECT_TRUE(request.has_signature());
1057 EXPECT_EQ(0, request.signature().certificate_chain_size());
1058
1059 // Simulate the request finishing.
1060 base::MessageLoop::current()->PostTask(
1061 FROM_HERE,
1062 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete,
1063 base::Unretained(this), fetcher));
1064 MessageLoop::current()->Run();
1065 #endif
1066 }
1067
1068 // Similar to above, but with tab history.
TEST_F(DownloadProtectionServiceTest,CheckClientDownloadValidateRequestTabHistory)1069 TEST_F(DownloadProtectionServiceTest,
1070 CheckClientDownloadValidateRequestTabHistory) {
1071 net::TestURLFetcherFactory factory;
1072
1073 base::ScopedTempDir profile_dir;
1074 ASSERT_TRUE(profile_dir.CreateUniqueTempDir());
1075 TestingProfile profile(profile_dir.path());
1076 ASSERT_TRUE(
1077 profile.CreateHistoryService(true /* delete_file */, false /* no_db */));
1078
1079 base::FilePath tmp_path(FILE_PATH_LITERAL("bla.tmp"));
1080 base::FilePath final_path(FILE_PATH_LITERAL("bla.exe"));
1081 std::vector<GURL> url_chain;
1082 url_chain.push_back(GURL("http://www.google.com/"));
1083 url_chain.push_back(GURL("http://www.google.com/bla.exe"));
1084 GURL referrer("http://www.google.com/");
1085 GURL tab_url("http://tab.com/final");
1086 GURL tab_referrer("http://tab.com/referrer");
1087 std::string hash = "hash";
1088 std::string remote_address = "10.11.12.13";
1089
1090 content::MockDownloadItem item;
1091 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path));
1092 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path));
1093 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
1094 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
1095 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(tab_url));
1096 EXPECT_CALL(item, GetTabReferrerUrl())
1097 .WillRepeatedly(ReturnRef(tab_referrer));
1098 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
1099 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
1100 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
1101 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(remote_address));
1102 EXPECT_CALL(item, GetBrowserContext()).WillRepeatedly(Return(&profile));
1103 EXPECT_CALL(*sb_service_->mock_database_manager(),
1104 MatchDownloadWhitelistUrl(_))
1105 .WillRepeatedly(Return(false));
1106 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path, _))
1107 .WillRepeatedly(SetCertificateContents("dummy cert data"));
1108 EXPECT_CALL(*binary_feature_extractor_.get(),
1109 ExtractImageHeaders(tmp_path, _))
1110 .WillRepeatedly(SetDosHeaderContents("dummy dos header"));
1111
1112 // First test with no history match for the tab URL.
1113 {
1114 TestURLFetcherWatcher fetcher_watcher(&factory);
1115 download_service_->CheckClientDownload(
1116 &item,
1117 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
1118 base::Unretained(this)));
1119
1120 #if !defined(OS_WIN)
1121 // SendRequest is not called. Wait for FinishRequest to call our callback.
1122 MessageLoop::current()->Run();
1123 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
1124 EXPECT_EQ(NULL, fetcher);
1125 #else
1126 EXPECT_EQ(0, fetcher_watcher.WaitForRequest());
1127 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
1128 ASSERT_TRUE(fetcher);
1129 ClientDownloadRequest request;
1130 EXPECT_TRUE(request.ParseFromString(fetcher->upload_data()));
1131 EXPECT_EQ("http://www.google.com/bla.exe", request.url());
1132 EXPECT_EQ(hash, request.digests().sha256());
1133 EXPECT_EQ(item.GetReceivedBytes(), request.length());
1134 EXPECT_EQ(item.HasUserGesture(), request.user_initiated());
1135 EXPECT_TRUE(RequestContainsServerIp(request, remote_address));
1136 EXPECT_EQ(3, request.resources_size());
1137 EXPECT_TRUE(
1138 RequestContainsResource(request,
1139 ClientDownloadRequest::DOWNLOAD_REDIRECT,
1140 "http://www.google.com/",
1141 ""));
1142 EXPECT_TRUE(RequestContainsResource(request,
1143 ClientDownloadRequest::DOWNLOAD_URL,
1144 "http://www.google.com/bla.exe",
1145 referrer.spec()));
1146 EXPECT_TRUE(RequestContainsResource(request,
1147 ClientDownloadRequest::TAB_URL,
1148 tab_url.spec(),
1149 tab_referrer.spec()));
1150 EXPECT_TRUE(request.has_signature());
1151 ASSERT_EQ(1, request.signature().certificate_chain_size());
1152 const ClientDownloadRequest_CertificateChain& chain =
1153 request.signature().certificate_chain(0);
1154 ASSERT_EQ(1, chain.element_size());
1155 EXPECT_EQ("dummy cert data", chain.element(0).certificate());
1156 EXPECT_TRUE(request.has_image_headers());
1157 const ClientDownloadRequest_ImageHeaders& headers =
1158 request.image_headers();
1159 EXPECT_TRUE(headers.has_pe_headers());
1160 EXPECT_TRUE(headers.pe_headers().has_dos_header());
1161 EXPECT_EQ("dummy dos header", headers.pe_headers().dos_header());
1162
1163 // Simulate the request finishing.
1164 base::MessageLoop::current()->PostTask(
1165 FROM_HERE,
1166 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete,
1167 base::Unretained(this),
1168 fetcher));
1169 MessageLoop::current()->Run();
1170 #endif
1171 }
1172
1173 // Now try with a history match.
1174 {
1175 history::RedirectList redirects;
1176 redirects.push_back(GURL("http://tab.com/ref1"));
1177 redirects.push_back(GURL("http://tab.com/ref2"));
1178 redirects.push_back(tab_url);
1179 HistoryServiceFactory::GetForProfile(&profile, Profile::EXPLICIT_ACCESS)
1180 ->AddPage(tab_url,
1181 base::Time::Now(),
1182 static_cast<void*>(this),
1183 0,
1184 GURL(),
1185 redirects,
1186 content::PAGE_TRANSITION_TYPED,
1187 history::SOURCE_BROWSED,
1188 false);
1189
1190 TestURLFetcherWatcher fetcher_watcher(&factory);
1191 download_service_->CheckClientDownload(
1192 &item,
1193 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
1194 base::Unretained(this)));
1195 #if !defined(OS_WIN)
1196 // SendRequest is not called. Wait for FinishRequest to call our callback.
1197 MessageLoop::current()->Run();
1198 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
1199 EXPECT_EQ(NULL, fetcher);
1200 #else
1201 EXPECT_EQ(0, fetcher_watcher.WaitForRequest());
1202 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
1203 ASSERT_TRUE(fetcher);
1204 ClientDownloadRequest request;
1205 EXPECT_TRUE(request.ParseFromString(fetcher->upload_data()));
1206 EXPECT_EQ("http://www.google.com/bla.exe", request.url());
1207 EXPECT_EQ(hash, request.digests().sha256());
1208 EXPECT_EQ(item.GetReceivedBytes(), request.length());
1209 EXPECT_EQ(item.HasUserGesture(), request.user_initiated());
1210 EXPECT_TRUE(RequestContainsServerIp(request, remote_address));
1211 EXPECT_EQ(5, request.resources_size());
1212 EXPECT_TRUE(
1213 RequestContainsResource(request,
1214 ClientDownloadRequest::DOWNLOAD_REDIRECT,
1215 "http://www.google.com/",
1216 ""));
1217 EXPECT_TRUE(RequestContainsResource(request,
1218 ClientDownloadRequest::DOWNLOAD_URL,
1219 "http://www.google.com/bla.exe",
1220 referrer.spec()));
1221 EXPECT_TRUE(RequestContainsResource(request,
1222 ClientDownloadRequest::TAB_REDIRECT,
1223 "http://tab.com/ref1",
1224 ""));
1225 EXPECT_TRUE(RequestContainsResource(request,
1226 ClientDownloadRequest::TAB_REDIRECT,
1227 "http://tab.com/ref2",
1228 ""));
1229 EXPECT_TRUE(RequestContainsResource(request,
1230 ClientDownloadRequest::TAB_URL,
1231 tab_url.spec(),
1232 tab_referrer.spec()));
1233 EXPECT_TRUE(request.has_signature());
1234 ASSERT_EQ(1, request.signature().certificate_chain_size());
1235 const ClientDownloadRequest_CertificateChain& chain =
1236 request.signature().certificate_chain(0);
1237 ASSERT_EQ(1, chain.element_size());
1238 EXPECT_EQ("dummy cert data", chain.element(0).certificate());
1239
1240 // Simulate the request finishing.
1241 base::MessageLoop::current()->PostTask(
1242 FROM_HERE,
1243 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete,
1244 base::Unretained(this),
1245 fetcher));
1246 MessageLoop::current()->Run();
1247 #endif
1248 }
1249 }
1250
TEST_F(DownloadProtectionServiceTest,TestCheckDownloadUrl)1251 TEST_F(DownloadProtectionServiceTest, TestCheckDownloadUrl) {
1252 std::vector<GURL> url_chain;
1253 url_chain.push_back(GURL("http://www.google.com/"));
1254 url_chain.push_back(GURL("http://www.google.com/bla.exe"));
1255 GURL referrer("http://www.google.com/");
1256 std::string hash = "hash";
1257
1258 content::MockDownloadItem item;
1259 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
1260 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
1261 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
1262
1263 // CheckDownloadURL returns immediately which means the client object callback
1264 // will never be called. Nevertheless the callback provided to
1265 // CheckClientDownload must still be called.
1266 EXPECT_CALL(*sb_service_->mock_database_manager(),
1267 CheckDownloadUrl(ContainerEq(url_chain), NotNull()))
1268 .WillOnce(Return(true));
1269 download_service_->CheckDownloadUrl(
1270 item,
1271 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
1272 base::Unretained(this)));
1273 MessageLoop::current()->Run();
1274 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
1275 Mock::VerifyAndClearExpectations(sb_service_.get());
1276
1277 EXPECT_CALL(*sb_service_->mock_database_manager(),
1278 CheckDownloadUrl(ContainerEq(url_chain), NotNull()))
1279 .WillOnce(DoAll(CheckDownloadUrlDone(SB_THREAT_TYPE_SAFE),
1280 Return(false)));
1281 download_service_->CheckDownloadUrl(
1282 item,
1283 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
1284 base::Unretained(this)));
1285 MessageLoop::current()->Run();
1286 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
1287 Mock::VerifyAndClearExpectations(sb_service_.get());
1288
1289 EXPECT_CALL(*sb_service_->mock_database_manager(),
1290 CheckDownloadUrl(ContainerEq(url_chain), NotNull()))
1291 .WillOnce(DoAll(
1292 CheckDownloadUrlDone(SB_THREAT_TYPE_URL_MALWARE),
1293 Return(false)));
1294 download_service_->CheckDownloadUrl(
1295 item,
1296 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
1297 base::Unretained(this)));
1298 MessageLoop::current()->Run();
1299 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
1300 Mock::VerifyAndClearExpectations(sb_service_.get());
1301
1302 EXPECT_CALL(*sb_service_->mock_database_manager(),
1303 CheckDownloadUrl(ContainerEq(url_chain),
1304 NotNull()))
1305 .WillOnce(DoAll(
1306 CheckDownloadUrlDone(SB_THREAT_TYPE_BINARY_MALWARE_URL),
1307 Return(false)));
1308 download_service_->CheckDownloadUrl(
1309 item,
1310 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
1311 base::Unretained(this)));
1312 MessageLoop::current()->Run();
1313 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
1314 }
1315
TEST_F(DownloadProtectionServiceTest,TestDownloadRequestTimeout)1316 TEST_F(DownloadProtectionServiceTest, TestDownloadRequestTimeout) {
1317 net::TestURLFetcherFactory factory;
1318
1319 std::vector<GURL> url_chain;
1320 url_chain.push_back(GURL("http://www.evil.com/bla.exe"));
1321 GURL referrer("http://www.google.com/");
1322 base::FilePath tmp_path(FILE_PATH_LITERAL("a.tmp"));
1323 base::FilePath final_path(FILE_PATH_LITERAL("a.exe"));
1324 std::string hash = "hash";
1325
1326 content::MockDownloadItem item;
1327 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path));
1328 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path));
1329 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
1330 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
1331 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1332 EXPECT_CALL(item, GetTabReferrerUrl())
1333 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1334 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
1335 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
1336 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
1337 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
1338
1339 EXPECT_CALL(*sb_service_->mock_database_manager(),
1340 MatchDownloadWhitelistUrl(_))
1341 .WillRepeatedly(Return(false));
1342 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path, _));
1343 EXPECT_CALL(*binary_feature_extractor_.get(),
1344 ExtractImageHeaders(tmp_path, _));
1345
1346 download_service_->download_request_timeout_ms_ = 10;
1347 download_service_->CheckClientDownload(
1348 &item,
1349 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
1350 base::Unretained(this)));
1351
1352 // The request should time out because the HTTP request hasn't returned
1353 // anything yet.
1354 MessageLoop::current()->Run();
1355 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
1356 }
1357
TEST_F(DownloadProtectionServiceTest,TestDownloadItemDestroyed)1358 TEST_F(DownloadProtectionServiceTest, TestDownloadItemDestroyed) {
1359 net::TestURLFetcherFactory factory;
1360
1361 std::vector<GURL> url_chain;
1362 url_chain.push_back(GURL("http://www.evil.com/bla.exe"));
1363 GURL referrer("http://www.google.com/");
1364 base::FilePath tmp_path(FILE_PATH_LITERAL("a.tmp"));
1365 base::FilePath final_path(FILE_PATH_LITERAL("a.exe"));
1366 std::string hash = "hash";
1367
1368 {
1369 content::MockDownloadItem item;
1370 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path));
1371 EXPECT_CALL(item, GetTargetFilePath())
1372 .WillRepeatedly(ReturnRef(final_path));
1373 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
1374 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
1375 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1376 EXPECT_CALL(item, GetTabReferrerUrl())
1377 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1378 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
1379 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
1380 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
1381 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
1382
1383 EXPECT_CALL(*sb_service_->mock_database_manager(),
1384 MatchDownloadWhitelistUrl(_))
1385 .WillRepeatedly(Return(false));
1386 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path, _));
1387 EXPECT_CALL(*binary_feature_extractor_.get(),
1388 ExtractImageHeaders(tmp_path, _));
1389
1390 download_service_->CheckClientDownload(
1391 &item,
1392 base::Bind(&DownloadProtectionServiceTest::SyncCheckDoneCallback,
1393 base::Unretained(this)));
1394 // MockDownloadItem going out of scope triggers the OnDownloadDestroyed
1395 // notification.
1396 }
1397
1398 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
1399 }
1400
TEST_F(DownloadProtectionServiceTest,GetCertificateWhitelistStrings)1401 TEST_F(DownloadProtectionServiceTest, GetCertificateWhitelistStrings) {
1402 // We'll pass this cert in as the "issuer", even though it isn't really
1403 // used to sign the certs below. GetCertificateWhitelistStirngs doesn't care
1404 // about this.
1405 scoped_refptr<net::X509Certificate> issuer_cert(
1406 ReadTestCertificate("issuer.pem"));
1407 ASSERT_TRUE(issuer_cert.get());
1408 std::string cert_base = "cert/" + base::HexEncode(
1409 issuer_cert->fingerprint().data,
1410 sizeof(issuer_cert->fingerprint().data));
1411
1412 scoped_refptr<net::X509Certificate> cert(ReadTestCertificate("test_cn.pem"));
1413 ASSERT_TRUE(cert.get());
1414 std::vector<std::string> whitelist_strings;
1415 GetCertificateWhitelistStrings(
1416 *cert.get(), *issuer_cert.get(), &whitelist_strings);
1417 // This also tests escaping of characters in the certificate attributes.
1418 EXPECT_THAT(whitelist_strings, ElementsAre(
1419 cert_base + "/CN=subject%2F%251"));
1420
1421 cert = ReadTestCertificate("test_cn_o.pem");
1422 ASSERT_TRUE(cert.get());
1423 whitelist_strings.clear();
1424 GetCertificateWhitelistStrings(
1425 *cert.get(), *issuer_cert.get(), &whitelist_strings);
1426 EXPECT_THAT(whitelist_strings,
1427 ElementsAre(cert_base + "/CN=subject",
1428 cert_base + "/CN=subject/O=org",
1429 cert_base + "/O=org"));
1430
1431 cert = ReadTestCertificate("test_cn_o_ou.pem");
1432 ASSERT_TRUE(cert.get());
1433 whitelist_strings.clear();
1434 GetCertificateWhitelistStrings(
1435 *cert.get(), *issuer_cert.get(), &whitelist_strings);
1436 EXPECT_THAT(whitelist_strings,
1437 ElementsAre(cert_base + "/CN=subject",
1438 cert_base + "/CN=subject/O=org",
1439 cert_base + "/CN=subject/O=org/OU=unit",
1440 cert_base + "/CN=subject/OU=unit",
1441 cert_base + "/O=org",
1442 cert_base + "/O=org/OU=unit",
1443 cert_base + "/OU=unit"));
1444
1445 cert = ReadTestCertificate("test_cn_ou.pem");
1446 ASSERT_TRUE(cert.get());
1447 whitelist_strings.clear();
1448 GetCertificateWhitelistStrings(
1449 *cert.get(), *issuer_cert.get(), &whitelist_strings);
1450 EXPECT_THAT(whitelist_strings,
1451 ElementsAre(cert_base + "/CN=subject",
1452 cert_base + "/CN=subject/OU=unit",
1453 cert_base + "/OU=unit"));
1454
1455 cert = ReadTestCertificate("test_o.pem");
1456 ASSERT_TRUE(cert.get());
1457 whitelist_strings.clear();
1458 GetCertificateWhitelistStrings(
1459 *cert.get(), *issuer_cert.get(), &whitelist_strings);
1460 EXPECT_THAT(whitelist_strings, ElementsAre(cert_base + "/O=org"));
1461
1462 cert = ReadTestCertificate("test_o_ou.pem");
1463 ASSERT_TRUE(cert.get());
1464 whitelist_strings.clear();
1465 GetCertificateWhitelistStrings(
1466 *cert.get(), *issuer_cert.get(), &whitelist_strings);
1467 EXPECT_THAT(whitelist_strings,
1468 ElementsAre(cert_base + "/O=org",
1469 cert_base + "/O=org/OU=unit",
1470 cert_base + "/OU=unit"));
1471
1472 cert = ReadTestCertificate("test_ou.pem");
1473 ASSERT_TRUE(cert.get());
1474 whitelist_strings.clear();
1475 GetCertificateWhitelistStrings(
1476 *cert.get(), *issuer_cert.get(), &whitelist_strings);
1477 EXPECT_THAT(whitelist_strings, ElementsAre(cert_base + "/OU=unit"));
1478
1479 cert = ReadTestCertificate("test_c.pem");
1480 ASSERT_TRUE(cert.get());
1481 whitelist_strings.clear();
1482 GetCertificateWhitelistStrings(
1483 *cert.get(), *issuer_cert.get(), &whitelist_strings);
1484 EXPECT_THAT(whitelist_strings, ElementsAre());
1485 }
1486 } // namespace safe_browsing
1487