| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/command_line.h" | 5 #include "base/command_line.h" |
| 6 #include "base/file_path.h" | 6 #include "base/file_path.h" |
| 7 #include "base/memory/ref_counted.h" | 7 #include "base/memory/ref_counted.h" |
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "base/scoped_temp_dir.h" | 9 #include "base/scoped_temp_dir.h" |
| 10 #include "base/task.h" | 10 #include "base/task.h" |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 | 66 |
| 67 private: | 67 private: |
| 68 DISALLOW_COPY_AND_ASSIGN(MockClientSideDetectionService); | 68 DISALLOW_COPY_AND_ASSIGN(MockClientSideDetectionService); |
| 69 }; | 69 }; |
| 70 | 70 |
| 71 class MockSafeBrowsingService : public SafeBrowsingService { | 71 class MockSafeBrowsingService : public SafeBrowsingService { |
| 72 public: | 72 public: |
| 73 MockSafeBrowsingService() {} | 73 MockSafeBrowsingService() {} |
| 74 virtual ~MockSafeBrowsingService() {} | 74 virtual ~MockSafeBrowsingService() {} |
| 75 | 75 |
| 76 MOCK_METHOD8(DisplayBlockingPage, | 76 MOCK_METHOD1(DoDisplayBlockingPage, void(const UnsafeResource& resource)); |
| 77 void(const GURL&, const GURL&, const std::vector<GURL>&, | |
| 78 ResourceType::Type, UrlCheckResult, Client*, int, int)); | |
| 79 MOCK_METHOD1(MatchCsdWhitelistUrl, bool(const GURL&)); | 77 MOCK_METHOD1(MatchCsdWhitelistUrl, bool(const GURL&)); |
| 80 | 78 |
| 81 // Helper function which calls OnBlockingPageComplete for this client | 79 // Helper function which calls OnBlockingPageComplete for this client |
| 82 // object. | 80 // object. |
| 83 void InvokeOnBlockingPageComplete(SafeBrowsingService::Client* client) { | 81 void InvokeOnBlockingPageComplete(SafeBrowsingService::Client* client) { |
| 84 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 82 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 85 DCHECK(client); | 83 DCHECK(client); |
| 86 // Note: this will delete the client object in the case of the CsdClient | 84 // Note: this will delete the client object in the case of the CsdClient |
| 87 // implementation. | 85 // implementation. |
| 88 client->OnBlockingPageComplete(false); | 86 client->OnBlockingPageComplete(false); |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 verdict.set_client_score(1.0f); | 233 verdict.set_client_score(1.0f); |
| 236 verdict.set_is_phishing(true); | 234 verdict.set_is_phishing(true); |
| 237 | 235 |
| 238 EXPECT_CALL(*csd_service_, | 236 EXPECT_CALL(*csd_service_, |
| 239 SendClientReportPhishingRequest(Pointee(EqualsProto(verdict)), _)) | 237 SendClientReportPhishingRequest(Pointee(EqualsProto(verdict)), _)) |
| 240 .WillOnce(DoAll(DeleteArg<0>(), SaveArg<1>(&cb))); | 238 .WillOnce(DoAll(DeleteArg<0>(), SaveArg<1>(&cb))); |
| 241 OnDetectedPhishingSite(verdict.SerializeAsString()); | 239 OnDetectedPhishingSite(verdict.SerializeAsString()); |
| 242 EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get())); | 240 EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get())); |
| 243 ASSERT_TRUE(cb); | 241 ASSERT_TRUE(cb); |
| 244 | 242 |
| 245 // Make sure DisplayBlockingPage is not going to be called. | 243 // Make sure DoDisplayBlockingPage is not going to be called. |
| 246 EXPECT_CALL(*sb_service_, | 244 EXPECT_CALL(*sb_service_, DoDisplayBlockingPage(_)).Times(0); |
| 247 DisplayBlockingPage(_, _, _, _, _, _, _, _)).Times(0); | |
| 248 cb->Run(GURL(verdict.url()), false); | 245 cb->Run(GURL(verdict.url()), false); |
| 249 delete cb; | 246 delete cb; |
| 250 // If there was a message posted on the IO thread to display the | 247 MessageLoop::current()->RunAllPending(); |
| 251 // interstitial page we know that it would have been posted before | |
| 252 // we put the quit message there. | |
| 253 BrowserThread::PostTask(BrowserThread::IO, | |
| 254 FROM_HERE, | |
| 255 NewRunnableFunction(&QuitUIMessageLoop)); | |
| 256 MessageLoop::current()->Run(); | |
| 257 EXPECT_TRUE(Mock::VerifyAndClear(sb_service_.get())); | 248 EXPECT_TRUE(Mock::VerifyAndClear(sb_service_.get())); |
| 258 } | 249 } |
| 259 | 250 |
| 260 TEST_F(ClientSideDetectionHostTest, OnDetectedPhishingSiteDisabled) { | 251 TEST_F(ClientSideDetectionHostTest, OnDetectedPhishingSiteDisabled) { |
| 261 // Case 2: client thinks the page is phishing and so does the server but | 252 // Case 2: client thinks the page is phishing and so does the server but |
| 262 // showing the interstitial is disabled => no interstitial is shown. | 253 // showing the interstitial is disabled => no interstitial is shown. |
| 263 ClientSideDetectionService::ClientReportPhishingRequestCallback* cb; | 254 ClientSideDetectionService::ClientReportPhishingRequestCallback* cb; |
| 264 ClientPhishingRequest verdict; | 255 ClientPhishingRequest verdict; |
| 265 verdict.set_url("http://phishingurl.com/"); | 256 verdict.set_url("http://phishingurl.com/"); |
| 266 verdict.set_client_score(1.0f); | 257 verdict.set_client_score(1.0f); |
| 267 verdict.set_is_phishing(true); | 258 verdict.set_is_phishing(true); |
| 268 | 259 |
| 269 EXPECT_CALL(*csd_service_, | 260 EXPECT_CALL(*csd_service_, |
| 270 SendClientReportPhishingRequest(Pointee(EqualsProto(verdict)), _)) | 261 SendClientReportPhishingRequest(Pointee(EqualsProto(verdict)), _)) |
| 271 .WillOnce(DoAll(DeleteArg<0>(), SaveArg<1>(&cb))); | 262 .WillOnce(DoAll(DeleteArg<0>(), SaveArg<1>(&cb))); |
| 272 OnDetectedPhishingSite(verdict.SerializeAsString()); | 263 OnDetectedPhishingSite(verdict.SerializeAsString()); |
| 273 EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get())); | 264 EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get())); |
| 274 ASSERT_TRUE(cb); | 265 ASSERT_TRUE(cb); |
| 275 | 266 |
| 276 // Make sure DisplayBlockingPage is not going to be called. | 267 // Make sure DoDisplayBlockingPage is not going to be called. |
| 277 EXPECT_CALL(*sb_service_, | 268 EXPECT_CALL(*sb_service_, DoDisplayBlockingPage(_)).Times(0); |
| 278 DisplayBlockingPage(_, _, _, _, _, _, _, _)).Times(0); | |
| 279 cb->Run(GURL(verdict.url()), false); | 269 cb->Run(GURL(verdict.url()), false); |
| 280 delete cb; | 270 delete cb; |
| 281 | 271 MessageLoop::current()->RunAllPending(); |
| 282 FlushIOMessageLoop(); | |
| 283 EXPECT_TRUE(Mock::VerifyAndClear(sb_service_.get())); | 272 EXPECT_TRUE(Mock::VerifyAndClear(sb_service_.get())); |
| 284 } | 273 } |
| 285 | 274 |
| 286 TEST_F(ClientSideDetectionHostTest, OnDetectedPhishingSiteShowInterstitial) { | 275 TEST_F(ClientSideDetectionHostTest, OnDetectedPhishingSiteShowInterstitial) { |
| 287 // Case 3: client thinks the page is phishing and so does the server. | 276 // Case 3: client thinks the page is phishing and so does the server. |
| 288 // We show an interstitial. | 277 // We show an interstitial. |
| 289 ClientSideDetectionService::ClientReportPhishingRequestCallback* cb; | 278 ClientSideDetectionService::ClientReportPhishingRequestCallback* cb; |
| 290 GURL phishing_url("http://phishingurl.com/"); | 279 GURL phishing_url("http://phishingurl.com/"); |
| 291 ClientPhishingRequest verdict; | 280 ClientPhishingRequest verdict; |
| 292 verdict.set_url(phishing_url.spec()); | 281 verdict.set_url(phishing_url.spec()); |
| 293 verdict.set_client_score(1.0f); | 282 verdict.set_client_score(1.0f); |
| 294 verdict.set_is_phishing(true); | 283 verdict.set_is_phishing(true); |
| 295 | 284 |
| 296 CommandLine::ForCurrentProcess()->AppendSwitch( | 285 CommandLine::ForCurrentProcess()->AppendSwitch( |
| 297 switches::kEnableClientSidePhishingInterstitial); | 286 switches::kEnableClientSidePhishingInterstitial); |
| 298 | 287 |
| 299 EXPECT_CALL(*csd_service_, | 288 EXPECT_CALL(*csd_service_, |
| 300 SendClientReportPhishingRequest(Pointee(EqualsProto(verdict)), _)) | 289 SendClientReportPhishingRequest(Pointee(EqualsProto(verdict)), _)) |
| 301 .WillOnce(DoAll(DeleteArg<0>(), SaveArg<1>(&cb))); | 290 .WillOnce(DoAll(DeleteArg<0>(), SaveArg<1>(&cb))); |
| 302 OnDetectedPhishingSite(verdict.SerializeAsString()); | 291 OnDetectedPhishingSite(verdict.SerializeAsString()); |
| 303 EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get())); | 292 EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get())); |
| 304 ASSERT_TRUE(cb); | 293 ASSERT_TRUE(cb); |
| 305 | 294 |
| 306 SafeBrowsingService::Client* client; | 295 SafeBrowsingService::UnsafeResource resource; |
| 307 EXPECT_CALL(*sb_service_, | 296 EXPECT_CALL(*sb_service_, DoDisplayBlockingPage(_)) |
| 308 DisplayBlockingPage( | 297 .WillOnce(SaveArg<0>(&resource)); |
| 309 phishing_url, | |
| 310 phishing_url, | |
| 311 _, | |
| 312 ResourceType::MAIN_FRAME, | |
| 313 SafeBrowsingService::CLIENT_SIDE_PHISHING_URL, | |
| 314 _ /* a CsdClient object */, | |
| 315 contents()->GetRenderProcessHost()->id(), | |
| 316 contents()->render_view_host()->routing_id())) | |
| 317 .WillOnce(SaveArg<5>(&client)); | |
| 318 | |
| 319 cb->Run(phishing_url, true); | 298 cb->Run(phishing_url, true); |
| 320 delete cb; | 299 delete cb; |
| 321 | 300 |
| 322 FlushIOMessageLoop(); | 301 MessageLoop::current()->RunAllPending(); |
| 323 EXPECT_TRUE(Mock::VerifyAndClear(sb_service_.get())); | 302 EXPECT_TRUE(Mock::VerifyAndClear(sb_service_.get())); |
| 303 EXPECT_EQ(phishing_url, resource.url); |
| 304 EXPECT_EQ(phishing_url, resource.original_url); |
| 305 EXPECT_EQ(ResourceType::MAIN_FRAME, resource.resource_type); |
| 306 EXPECT_EQ(SafeBrowsingService::CLIENT_SIDE_PHISHING_URL, |
| 307 resource.threat_type); |
| 308 EXPECT_EQ(contents()->GetRenderProcessHost()->id(), |
| 309 resource.render_process_host_id); |
| 310 EXPECT_EQ(contents()->render_view_host()->routing_id(), |
| 311 resource.render_view_id); |
| 324 | 312 |
| 325 // Make sure the client object will be deleted. | 313 // Make sure the client object will be deleted. |
| 326 BrowserThread::PostTask( | 314 BrowserThread::PostTask( |
| 327 BrowserThread::IO, | 315 BrowserThread::IO, |
| 328 FROM_HERE, | 316 FROM_HERE, |
| 329 NewRunnableMethod( | 317 NewRunnableMethod( |
| 330 sb_service_.get(), | 318 sb_service_.get(), |
| 331 &MockSafeBrowsingService::InvokeOnBlockingPageComplete, | 319 &MockSafeBrowsingService::InvokeOnBlockingPageComplete, |
| 332 client)); | 320 resource.client)); |
| 333 // Since the CsdClient object will be deleted on the UI thread I need | 321 // Since the CsdClient object will be deleted on the UI thread I need |
| 334 // to run the UI message loop. Post a task to stop the UI message loop | 322 // to run the UI message loop. Post a task to stop the UI message loop |
| 335 // after the client object destructor is called. | 323 // after the client object destructor is called. |
| 336 FlushIOMessageLoop(); | 324 FlushIOMessageLoop(); |
| 337 } | 325 } |
| 338 | 326 |
| 339 TEST_F(ClientSideDetectionHostTest, OnDetectedPhishingSiteMultiplePings) { | 327 TEST_F(ClientSideDetectionHostTest, OnDetectedPhishingSiteMultiplePings) { |
| 340 // Case 4 & 5: client thinks a page is phishing then navigates to | 328 // Case 4 & 5: client thinks a page is phishing then navigates to |
| 341 // another page which is also considered phishing by the client | 329 // another page which is also considered phishing by the client |
| 342 // before the server responds with a verdict. After a while the | 330 // before the server responds with a verdict. After a while the |
| (...skipping 28 matching lines...) Expand all Loading... |
| 371 verdict.set_client_score(0.8f); | 359 verdict.set_client_score(0.8f); |
| 372 EXPECT_CALL(*csd_service_, | 360 EXPECT_CALL(*csd_service_, |
| 373 SendClientReportPhishingRequest(Pointee(EqualsProto(verdict)), _)) | 361 SendClientReportPhishingRequest(Pointee(EqualsProto(verdict)), _)) |
| 374 .WillOnce(DoAll(DeleteArg<0>(), SaveArg<1>(&cb_other))); | 362 .WillOnce(DoAll(DeleteArg<0>(), SaveArg<1>(&cb_other))); |
| 375 OnDetectedPhishingSite(verdict.SerializeAsString()); | 363 OnDetectedPhishingSite(verdict.SerializeAsString()); |
| 376 EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get())); | 364 EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get())); |
| 377 ASSERT_TRUE(cb_other); | 365 ASSERT_TRUE(cb_other); |
| 378 | 366 |
| 379 // We expect that the interstitial is shown for the second phishing URL and | 367 // We expect that the interstitial is shown for the second phishing URL and |
| 380 // not for the first phishing URL. | 368 // not for the first phishing URL. |
| 381 EXPECT_CALL(*sb_service_, | 369 SafeBrowsingService::UnsafeResource resource; |
| 382 DisplayBlockingPage(phishing_url, phishing_url,_, _, _, _, _, _)) | 370 EXPECT_CALL(*sb_service_, DoDisplayBlockingPage(_)) |
| 383 .Times(0); | 371 .WillOnce(SaveArg<0>(&resource)); |
| 384 SafeBrowsingService::Client* client; | |
| 385 EXPECT_CALL(*sb_service_, | |
| 386 DisplayBlockingPage( | |
| 387 other_phishing_url, | |
| 388 other_phishing_url, | |
| 389 _, | |
| 390 ResourceType::MAIN_FRAME, | |
| 391 SafeBrowsingService::CLIENT_SIDE_PHISHING_URL, | |
| 392 _ /* a CsdClient object */, | |
| 393 contents()->GetRenderProcessHost()->id(), | |
| 394 contents()->render_view_host()->routing_id())) | |
| 395 .WillOnce(SaveArg<5>(&client)); | |
| 396 | |
| 397 cb->Run(phishing_url, true); // Should have no effect. | 372 cb->Run(phishing_url, true); // Should have no effect. |
| 398 delete cb; | 373 delete cb; |
| 399 cb_other->Run(other_phishing_url, true); // Should show interstitial. | 374 cb_other->Run(other_phishing_url, true); // Should show interstitial. |
| 400 delete cb_other; | 375 delete cb_other; |
| 401 | 376 |
| 402 FlushIOMessageLoop(); | 377 MessageLoop::current()->RunAllPending(); |
| 403 EXPECT_TRUE(Mock::VerifyAndClear(sb_service_.get())); | 378 EXPECT_TRUE(Mock::VerifyAndClear(sb_service_.get())); |
| 379 EXPECT_EQ(other_phishing_url, resource.url); |
| 380 EXPECT_EQ(other_phishing_url, resource.original_url); |
| 381 EXPECT_EQ(ResourceType::MAIN_FRAME, resource.resource_type); |
| 382 EXPECT_EQ(SafeBrowsingService::CLIENT_SIDE_PHISHING_URL, |
| 383 resource.threat_type); |
| 384 EXPECT_EQ(contents()->GetRenderProcessHost()->id(), |
| 385 resource.render_process_host_id); |
| 386 EXPECT_EQ(contents()->render_view_host()->routing_id(), |
| 387 resource.render_view_id); |
| 404 | 388 |
| 405 // Make sure the client object will be deleted. | 389 // Make sure the client object will be deleted. |
| 406 BrowserThread::PostTask( | 390 BrowserThread::PostTask( |
| 407 BrowserThread::IO, | 391 BrowserThread::IO, |
| 408 FROM_HERE, | 392 FROM_HERE, |
| 409 NewRunnableMethod( | 393 NewRunnableMethod( |
| 410 sb_service_.get(), | 394 sb_service_.get(), |
| 411 &MockSafeBrowsingService::InvokeOnBlockingPageComplete, | 395 &MockSafeBrowsingService::InvokeOnBlockingPageComplete, |
| 412 client)); | 396 resource.client)); |
| 413 // Since the CsdClient object will be deleted on the UI thread I need | 397 // Since the CsdClient object will be deleted on the UI thread I need |
| 414 // to run the UI message loop. Post a task to stop the UI message loop | 398 // to run the UI message loop. Post a task to stop the UI message loop |
| 415 // after the client object destructor is called. | 399 // after the client object destructor is called. |
| 416 FlushIOMessageLoop(); | 400 FlushIOMessageLoop(); |
| 417 } | 401 } |
| 418 | 402 |
| 419 TEST_F(ClientSideDetectionHostTest, NavigationCancelsShouldClassifyUrl) { | 403 TEST_F(ClientSideDetectionHostTest, NavigationCancelsShouldClassifyUrl) { |
| 420 // Test that canceling pending should classify requests works as expected. | 404 // Test that canceling pending should classify requests works as expected. |
| 421 | 405 |
| 422 GURL first_url("http://first.phishy.url.com"); | 406 GURL first_url("http://first.phishy.url.com"); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 576 SafeBrowsingMsg_StartPhishingDetection::ID); | 560 SafeBrowsingMsg_StartPhishingDetection::ID); |
| 577 ASSERT_FALSE(msg); | 561 ASSERT_FALSE(msg); |
| 578 | 562 |
| 579 // If result is cached, we will try and display the blocking page directly | 563 // If result is cached, we will try and display the blocking page directly |
| 580 // with no start classification message. | 564 // with no start classification message. |
| 581 CommandLine::ForCurrentProcess()->AppendSwitch( | 565 CommandLine::ForCurrentProcess()->AppendSwitch( |
| 582 switches::kEnableClientSidePhishingInterstitial); | 566 switches::kEnableClientSidePhishingInterstitial); |
| 583 url = GURL("http://host8.com/"); | 567 url = GURL("http://host8.com/"); |
| 584 ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kTrue, NULL, | 568 ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kTrue, NULL, |
| 585 NULL); | 569 NULL); |
| 586 EXPECT_CALL(*sb_service_, | 570 |
| 587 DisplayBlockingPage(Eq(url), Eq(url), _, _, _, _, _, _)) | 571 SafeBrowsingService::UnsafeResource resource; |
| 588 .WillOnce(DeleteArg<5>()); | 572 EXPECT_CALL(*sb_service_, DoDisplayBlockingPage(_)) |
| 573 .WillOnce(SaveArg<0>(&resource)); |
| 574 |
| 589 NavigateAndCommit(url); | 575 NavigateAndCommit(url); |
| 590 // Wait for CheckCsdWhitelist to be called on the IO thread. | 576 // Wait for CheckCsdWhitelist to be called on the IO thread. |
| 591 FlushIOMessageLoop(); | 577 FlushIOMessageLoop(); |
| 592 // Wait for CheckCache() to be called on the UI thread. | 578 // Wait for CheckCache() to be called on the UI thread. |
| 593 MessageLoop::current()->RunAllPending(); | 579 MessageLoop::current()->RunAllPending(); |
| 594 // Wait for DisplayBlockingPage to be called on the IO thread. | |
| 595 FlushIOMessageLoop(); | |
| 596 // Now we check that all expected functions were indeed called on the two | 580 // Now we check that all expected functions were indeed called on the two |
| 597 // service objects. | 581 // service objects. |
| 598 EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get())); | 582 EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get())); |
| 599 EXPECT_TRUE(Mock::VerifyAndClear(sb_service_.get())); | 583 EXPECT_TRUE(Mock::VerifyAndClear(sb_service_.get())); |
| 584 EXPECT_EQ(url, resource.url); |
| 585 EXPECT_EQ(url, resource.original_url); |
| 586 delete resource.client; |
| 600 msg = process()->sink().GetFirstMessageMatching( | 587 msg = process()->sink().GetFirstMessageMatching( |
| 601 SafeBrowsingMsg_StartPhishingDetection::ID); | 588 SafeBrowsingMsg_StartPhishingDetection::ID); |
| 602 ASSERT_FALSE(msg); | 589 ASSERT_FALSE(msg); |
| 603 } | 590 } |
| 604 | 591 |
| 605 } // namespace safe_browsing | 592 } // namespace safe_browsing |
| OLD | NEW |