| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "chrome/renderer/safe_browsing/phishing_classifier_delegate.h" | 5 #include "chrome/renderer/safe_browsing/phishing_classifier_delegate.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "base/run_loop.h" | 9 #include "base/run_loop.h" |
| 10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 namespace safe_browsing { | 48 namespace safe_browsing { |
| 49 | 49 |
| 50 namespace { | 50 namespace { |
| 51 class MockPhishingClassifier : public PhishingClassifier { | 51 class MockPhishingClassifier : public PhishingClassifier { |
| 52 public: | 52 public: |
| 53 explicit MockPhishingClassifier(content::RenderView* render_view) | 53 explicit MockPhishingClassifier(content::RenderView* render_view) |
| 54 : PhishingClassifier(render_view, NULL /* clock */) {} | 54 : PhishingClassifier(render_view, NULL /* clock */) {} |
| 55 | 55 |
| 56 virtual ~MockPhishingClassifier() {} | 56 virtual ~MockPhishingClassifier() {} |
| 57 | 57 |
| 58 MOCK_METHOD2(BeginClassification, void(const string16*, const DoneCallback&)); | 58 MOCK_METHOD2(BeginClassification, |
| 59 void(const base::string16*, const DoneCallback&)); |
| 59 MOCK_METHOD0(CancelPendingClassification, void()); | 60 MOCK_METHOD0(CancelPendingClassification, void()); |
| 60 | 61 |
| 61 private: | 62 private: |
| 62 DISALLOW_COPY_AND_ASSIGN(MockPhishingClassifier); | 63 DISALLOW_COPY_AND_ASSIGN(MockPhishingClassifier); |
| 63 }; | 64 }; |
| 64 | 65 |
| 65 class MockScorer : public Scorer { | 66 class MockScorer : public Scorer { |
| 66 public: | 67 public: |
| 67 MockScorer() : Scorer() {} | 68 MockScorer() : Scorer() {} |
| 68 virtual ~MockScorer() {} | 69 virtual ~MockScorer() {} |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 167 verdict)); | 168 verdict)); |
| 168 intercepting_filter_->RunUntilVerdictReceived(); | 169 intercepting_filter_->RunUntilVerdictReceived(); |
| 169 } | 170 } |
| 170 | 171 |
| 171 void OnStartPhishingDetection(const GURL& url) { | 172 void OnStartPhishingDetection(const GURL& url) { |
| 172 PostTaskToInProcessRendererAndWait( | 173 PostTaskToInProcessRendererAndWait( |
| 173 base::Bind(&PhishingClassifierDelegate::OnStartPhishingDetection, | 174 base::Bind(&PhishingClassifierDelegate::OnStartPhishingDetection, |
| 174 base::Unretained(delegate_), url)); | 175 base::Unretained(delegate_), url)); |
| 175 } | 176 } |
| 176 | 177 |
| 177 void PageCaptured(string16* page_text, bool preliminary_capture) { | 178 void PageCaptured(base::string16* page_text, bool preliminary_capture) { |
| 178 PostTaskToInProcessRendererAndWait( | 179 PostTaskToInProcessRendererAndWait( |
| 179 base::Bind(&PhishingClassifierDelegate::PageCaptured, | 180 base::Bind(&PhishingClassifierDelegate::PageCaptured, |
| 180 base::Unretained(delegate_), page_text, | 181 base::Unretained(delegate_), page_text, |
| 181 preliminary_capture)); | 182 preliminary_capture)); |
| 182 } | 183 } |
| 183 | 184 |
| 184 bool StartTestServer() { | 185 bool StartTestServer() { |
| 185 CHECK(!embedded_test_server_); | 186 CHECK(!embedded_test_server_); |
| 186 embedded_test_server_.reset(new net::test_server::EmbeddedTestServer()); | 187 embedded_test_server_.reset(new net::test_server::EmbeddedTestServer()); |
| 187 embedded_test_server_->RegisterRequestHandler( | 188 embedded_test_server_->RegisterRequestHandler( |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 | 265 |
| 265 // Test an initial load. We expect classification to happen normally. | 266 // Test an initial load. We expect classification to happen normally. |
| 266 EXPECT_CALL(*classifier_, CancelPendingClassification()).Times(2); | 267 EXPECT_CALL(*classifier_, CancelPendingClassification()).Times(2); |
| 267 std::string port = base::IntToString(embedded_test_server_->port()); | 268 std::string port = base::IntToString(embedded_test_server_->port()); |
| 268 std::string html = "<html><body><iframe src=\"http://sub1.com:"; | 269 std::string html = "<html><body><iframe src=\"http://sub1.com:"; |
| 269 html += port; | 270 html += port; |
| 270 html += "/\"></iframe></body></html>"; | 271 html += "/\"></iframe></body></html>"; |
| 271 GURL url = LoadHtml("host.com", html); | 272 GURL url = LoadHtml("host.com", html); |
| 272 Mock::VerifyAndClearExpectations(classifier_); | 273 Mock::VerifyAndClearExpectations(classifier_); |
| 273 OnStartPhishingDetection(url); | 274 OnStartPhishingDetection(url); |
| 274 string16 page_text = ASCIIToUTF16("dummy"); | 275 base::string16 page_text = ASCIIToUTF16("dummy"); |
| 275 { | 276 { |
| 276 InSequence s; | 277 InSequence s; |
| 277 EXPECT_CALL(*classifier_, CancelPendingClassification()); | 278 EXPECT_CALL(*classifier_, CancelPendingClassification()); |
| 278 EXPECT_CALL(*classifier_, BeginClassification(Pointee(page_text), _)); | 279 EXPECT_CALL(*classifier_, BeginClassification(Pointee(page_text), _)); |
| 279 PageCaptured(&page_text, false); | 280 PageCaptured(&page_text, false); |
| 280 Mock::VerifyAndClearExpectations(classifier_); | 281 Mock::VerifyAndClearExpectations(classifier_); |
| 281 } | 282 } |
| 282 | 283 |
| 283 // Reloading the same page should not trigger a reclassification. | 284 // Reloading the same page should not trigger a reclassification. |
| 284 // However, it will cancel any pending classification since the | 285 // However, it will cancel any pending classification since the |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 398 // The delegate will cancel pending classification on destruction. | 399 // The delegate will cancel pending classification on destruction. |
| 399 EXPECT_CALL(*classifier_, CancelPendingClassification()); | 400 EXPECT_CALL(*classifier_, CancelPendingClassification()); |
| 400 } | 401 } |
| 401 | 402 |
| 402 IN_PROC_BROWSER_TEST_F(PhishingClassifierDelegateTest, NoScorer) { | 403 IN_PROC_BROWSER_TEST_F(PhishingClassifierDelegateTest, NoScorer) { |
| 403 // For this test, we'll create the delegate with no scorer available yet. | 404 // For this test, we'll create the delegate with no scorer available yet. |
| 404 ASSERT_FALSE(classifier_->is_ready()); | 405 ASSERT_FALSE(classifier_->is_ready()); |
| 405 | 406 |
| 406 // Queue up a pending classification, cancel it, then queue up another one. | 407 // Queue up a pending classification, cancel it, then queue up another one. |
| 407 GURL url = LoadHtml("host.com", "dummy"); | 408 GURL url = LoadHtml("host.com", "dummy"); |
| 408 string16 page_text = ASCIIToUTF16("dummy"); | 409 base::string16 page_text = ASCIIToUTF16("dummy"); |
| 409 OnStartPhishingDetection(url); | 410 OnStartPhishingDetection(url); |
| 410 PageCaptured(&page_text, false); | 411 PageCaptured(&page_text, false); |
| 411 | 412 |
| 412 url = LoadHtml("host2.com", "dummy2"); | 413 url = LoadHtml("host2.com", "dummy2"); |
| 413 page_text = ASCIIToUTF16("dummy2"); | 414 page_text = ASCIIToUTF16("dummy2"); |
| 414 OnStartPhishingDetection(url); | 415 OnStartPhishingDetection(url); |
| 415 PageCaptured(&page_text, false); | 416 PageCaptured(&page_text, false); |
| 416 | 417 |
| 417 // Now set a scorer, which should cause a classifier to be created and | 418 // Now set a scorer, which should cause a classifier to be created and |
| 418 // the classification to proceed. | 419 // the classification to proceed. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 432 EXPECT_CALL(*classifier_, CancelPendingClassification()); | 433 EXPECT_CALL(*classifier_, CancelPendingClassification()); |
| 433 } | 434 } |
| 434 | 435 |
| 435 IN_PROC_BROWSER_TEST_F(PhishingClassifierDelegateTest, NoScorer_Ref) { | 436 IN_PROC_BROWSER_TEST_F(PhishingClassifierDelegateTest, NoScorer_Ref) { |
| 436 // Similar to the last test, but navigates within the page before | 437 // Similar to the last test, but navigates within the page before |
| 437 // setting the scorer. | 438 // setting the scorer. |
| 438 ASSERT_FALSE(classifier_->is_ready()); | 439 ASSERT_FALSE(classifier_->is_ready()); |
| 439 | 440 |
| 440 // Queue up a pending classification, cancel it, then queue up another one. | 441 // Queue up a pending classification, cancel it, then queue up another one. |
| 441 GURL url = LoadHtml("host.com", "dummy"); | 442 GURL url = LoadHtml("host.com", "dummy"); |
| 442 string16 page_text = ASCIIToUTF16("dummy"); | 443 base::string16 page_text = ASCIIToUTF16("dummy"); |
| 443 OnStartPhishingDetection(url); | 444 OnStartPhishingDetection(url); |
| 444 PageCaptured(&page_text, false); | 445 PageCaptured(&page_text, false); |
| 445 | 446 |
| 446 OnStartPhishingDetection(url); | 447 OnStartPhishingDetection(url); |
| 447 page_text = ASCIIToUTF16("dummy"); | 448 page_text = ASCIIToUTF16("dummy"); |
| 448 PageCaptured(&page_text, false); | 449 PageCaptured(&page_text, false); |
| 449 | 450 |
| 450 // Now set a scorer, which should cause a classifier to be created and | 451 // Now set a scorer, which should cause a classifier to be created and |
| 451 // the classification to proceed. | 452 // the classification to proceed. |
| 452 page_text = ASCIIToUTF16("dummy"); | 453 page_text = ASCIIToUTF16("dummy"); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 463 NoStartPhishingDetection) { | 464 NoStartPhishingDetection) { |
| 464 // Tests the behavior when OnStartPhishingDetection has not yet been called | 465 // Tests the behavior when OnStartPhishingDetection has not yet been called |
| 465 // when the page load finishes. | 466 // when the page load finishes. |
| 466 MockScorer scorer; | 467 MockScorer scorer; |
| 467 delegate_->SetPhishingScorer(&scorer); | 468 delegate_->SetPhishingScorer(&scorer); |
| 468 ASSERT_TRUE(classifier_->is_ready()); | 469 ASSERT_TRUE(classifier_->is_ready()); |
| 469 | 470 |
| 470 EXPECT_CALL(*classifier_, CancelPendingClassification()); | 471 EXPECT_CALL(*classifier_, CancelPendingClassification()); |
| 471 GURL url = LoadHtml("host.com", "<html><body>phish</body></html>"); | 472 GURL url = LoadHtml("host.com", "<html><body>phish</body></html>"); |
| 472 Mock::VerifyAndClearExpectations(classifier_); | 473 Mock::VerifyAndClearExpectations(classifier_); |
| 473 string16 page_text = ASCIIToUTF16("phish"); | 474 base::string16 page_text = ASCIIToUTF16("phish"); |
| 474 EXPECT_CALL(*classifier_, CancelPendingClassification()); | 475 EXPECT_CALL(*classifier_, CancelPendingClassification()); |
| 475 PageCaptured(&page_text, false); | 476 PageCaptured(&page_text, false); |
| 476 Mock::VerifyAndClearExpectations(classifier_); | 477 Mock::VerifyAndClearExpectations(classifier_); |
| 477 // Now simulate the StartPhishingDetection IPC. We expect classification | 478 // Now simulate the StartPhishingDetection IPC. We expect classification |
| 478 // to begin. | 479 // to begin. |
| 479 page_text = ASCIIToUTF16("phish"); | 480 page_text = ASCIIToUTF16("phish"); |
| 480 EXPECT_CALL(*classifier_, BeginClassification(Pointee(page_text), _)); | 481 EXPECT_CALL(*classifier_, BeginClassification(Pointee(page_text), _)); |
| 481 OnStartPhishingDetection(url); | 482 OnStartPhishingDetection(url); |
| 482 Mock::VerifyAndClearExpectations(classifier_); | 483 Mock::VerifyAndClearExpectations(classifier_); |
| 483 | 484 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 535 IgnorePreliminaryCapture) { | 536 IgnorePreliminaryCapture) { |
| 536 // Tests that preliminary PageCaptured notifications are ignored. | 537 // Tests that preliminary PageCaptured notifications are ignored. |
| 537 MockScorer scorer; | 538 MockScorer scorer; |
| 538 delegate_->SetPhishingScorer(&scorer); | 539 delegate_->SetPhishingScorer(&scorer); |
| 539 ASSERT_TRUE(classifier_->is_ready()); | 540 ASSERT_TRUE(classifier_->is_ready()); |
| 540 | 541 |
| 541 EXPECT_CALL(*classifier_, CancelPendingClassification()); | 542 EXPECT_CALL(*classifier_, CancelPendingClassification()); |
| 542 GURL url = LoadHtml("host.com", "<html><body>phish</body></html>"); | 543 GURL url = LoadHtml("host.com", "<html><body>phish</body></html>"); |
| 543 Mock::VerifyAndClearExpectations(classifier_); | 544 Mock::VerifyAndClearExpectations(classifier_); |
| 544 OnStartPhishingDetection(url); | 545 OnStartPhishingDetection(url); |
| 545 string16 page_text = ASCIIToUTF16("phish"); | 546 base::string16 page_text = ASCIIToUTF16("phish"); |
| 546 PageCaptured(&page_text, true); | 547 PageCaptured(&page_text, true); |
| 547 | 548 |
| 548 // Once the non-preliminary capture happens, classification should begin. | 549 // Once the non-preliminary capture happens, classification should begin. |
| 549 page_text = ASCIIToUTF16("phish"); | 550 page_text = ASCIIToUTF16("phish"); |
| 550 { | 551 { |
| 551 InSequence s; | 552 InSequence s; |
| 552 EXPECT_CALL(*classifier_, CancelPendingClassification()); | 553 EXPECT_CALL(*classifier_, CancelPendingClassification()); |
| 553 EXPECT_CALL(*classifier_, BeginClassification(Pointee(page_text), _)); | 554 EXPECT_CALL(*classifier_, BeginClassification(Pointee(page_text), _)); |
| 554 PageCaptured(&page_text, false); | 555 PageCaptured(&page_text, false); |
| 555 Mock::VerifyAndClearExpectations(classifier_); | 556 Mock::VerifyAndClearExpectations(classifier_); |
| 556 } | 557 } |
| 557 | 558 |
| 558 // The delegate will cancel pending classification on destruction. | 559 // The delegate will cancel pending classification on destruction. |
| 559 EXPECT_CALL(*classifier_, CancelPendingClassification()); | 560 EXPECT_CALL(*classifier_, CancelPendingClassification()); |
| 560 } | 561 } |
| 561 | 562 |
| 562 IN_PROC_BROWSER_TEST_F(PhishingClassifierDelegateTest, DuplicatePageCapture) { | 563 IN_PROC_BROWSER_TEST_F(PhishingClassifierDelegateTest, DuplicatePageCapture) { |
| 563 // Tests that a second PageCaptured notification causes classification to | 564 // Tests that a second PageCaptured notification causes classification to |
| 564 // be cancelled. | 565 // be cancelled. |
| 565 MockScorer scorer; | 566 MockScorer scorer; |
| 566 delegate_->SetPhishingScorer(&scorer); | 567 delegate_->SetPhishingScorer(&scorer); |
| 567 ASSERT_TRUE(classifier_->is_ready()); | 568 ASSERT_TRUE(classifier_->is_ready()); |
| 568 | 569 |
| 569 EXPECT_CALL(*classifier_, CancelPendingClassification()); | 570 EXPECT_CALL(*classifier_, CancelPendingClassification()); |
| 570 GURL url = LoadHtml("host.com", "<html><body>phish</body></html>"); | 571 GURL url = LoadHtml("host.com", "<html><body>phish</body></html>"); |
| 571 Mock::VerifyAndClearExpectations(classifier_); | 572 Mock::VerifyAndClearExpectations(classifier_); |
| 572 OnStartPhishingDetection(url); | 573 OnStartPhishingDetection(url); |
| 573 string16 page_text = ASCIIToUTF16("phish"); | 574 base::string16 page_text = ASCIIToUTF16("phish"); |
| 574 { | 575 { |
| 575 InSequence s; | 576 InSequence s; |
| 576 EXPECT_CALL(*classifier_, CancelPendingClassification()); | 577 EXPECT_CALL(*classifier_, CancelPendingClassification()); |
| 577 EXPECT_CALL(*classifier_, BeginClassification(Pointee(page_text), _)); | 578 EXPECT_CALL(*classifier_, BeginClassification(Pointee(page_text), _)); |
| 578 PageCaptured(&page_text, false); | 579 PageCaptured(&page_text, false); |
| 579 Mock::VerifyAndClearExpectations(classifier_); | 580 Mock::VerifyAndClearExpectations(classifier_); |
| 580 } | 581 } |
| 581 | 582 |
| 582 page_text = ASCIIToUTF16("phish"); | 583 page_text = ASCIIToUTF16("phish"); |
| 583 EXPECT_CALL(*classifier_, CancelPendingClassification()); | 584 EXPECT_CALL(*classifier_, CancelPendingClassification()); |
| 584 PageCaptured(&page_text, false); | 585 PageCaptured(&page_text, false); |
| 585 Mock::VerifyAndClearExpectations(classifier_); | 586 Mock::VerifyAndClearExpectations(classifier_); |
| 586 | 587 |
| 587 // The delegate will cancel pending classification on destruction. | 588 // The delegate will cancel pending classification on destruction. |
| 588 EXPECT_CALL(*classifier_, CancelPendingClassification()); | 589 EXPECT_CALL(*classifier_, CancelPendingClassification()); |
| 589 } | 590 } |
| 590 | 591 |
| 591 IN_PROC_BROWSER_TEST_F(PhishingClassifierDelegateTest, PhishingDetectionDone) { | 592 IN_PROC_BROWSER_TEST_F(PhishingClassifierDelegateTest, PhishingDetectionDone) { |
| 592 // Tests that a PhishingDetectionDone IPC is sent to the browser | 593 // Tests that a PhishingDetectionDone IPC is sent to the browser |
| 593 // whenever we finish classification. | 594 // whenever we finish classification. |
| 594 MockScorer scorer; | 595 MockScorer scorer; |
| 595 delegate_->SetPhishingScorer(&scorer); | 596 delegate_->SetPhishingScorer(&scorer); |
| 596 ASSERT_TRUE(classifier_->is_ready()); | 597 ASSERT_TRUE(classifier_->is_ready()); |
| 597 | 598 |
| 598 // Start by loading a page to populate the delegate's state. | 599 // Start by loading a page to populate the delegate's state. |
| 599 EXPECT_CALL(*classifier_, CancelPendingClassification()); | 600 EXPECT_CALL(*classifier_, CancelPendingClassification()); |
| 600 GURL url = LoadHtml("host.com", "<html><body>phish</body></html>"); | 601 GURL url = LoadHtml("host.com", "<html><body>phish</body></html>"); |
| 601 Mock::VerifyAndClearExpectations(classifier_); | 602 Mock::VerifyAndClearExpectations(classifier_); |
| 602 string16 page_text = ASCIIToUTF16("phish"); | 603 base::string16 page_text = ASCIIToUTF16("phish"); |
| 603 OnStartPhishingDetection(url); | 604 OnStartPhishingDetection(url); |
| 604 { | 605 { |
| 605 InSequence s; | 606 InSequence s; |
| 606 EXPECT_CALL(*classifier_, CancelPendingClassification()); | 607 EXPECT_CALL(*classifier_, CancelPendingClassification()); |
| 607 EXPECT_CALL(*classifier_, BeginClassification(Pointee(page_text), _)); | 608 EXPECT_CALL(*classifier_, BeginClassification(Pointee(page_text), _)); |
| 608 PageCaptured(&page_text, false); | 609 PageCaptured(&page_text, false); |
| 609 Mock::VerifyAndClearExpectations(classifier_); | 610 Mock::VerifyAndClearExpectations(classifier_); |
| 610 } | 611 } |
| 611 | 612 |
| 612 // Now run the callback to simulate the classifier finishing. | 613 // Now run the callback to simulate the classifier finishing. |
| 613 ClientPhishingRequest verdict; | 614 ClientPhishingRequest verdict; |
| 614 verdict.set_url(url.spec()); | 615 verdict.set_url(url.spec()); |
| 615 verdict.set_client_score(0.8f); | 616 verdict.set_client_score(0.8f); |
| 616 verdict.set_is_phishing(false); // Send IPC even if site is not phishing. | 617 verdict.set_is_phishing(false); // Send IPC even if site is not phishing. |
| 617 RunClassificationDone(verdict); | 618 RunClassificationDone(verdict); |
| 618 ASSERT_TRUE(intercepting_filter_->verdict()); | 619 ASSERT_TRUE(intercepting_filter_->verdict()); |
| 619 EXPECT_EQ(verdict.SerializeAsString(), | 620 EXPECT_EQ(verdict.SerializeAsString(), |
| 620 intercepting_filter_->verdict()->SerializeAsString()); | 621 intercepting_filter_->verdict()->SerializeAsString()); |
| 621 | 622 |
| 622 // The delegate will cancel pending classification on destruction. | 623 // The delegate will cancel pending classification on destruction. |
| 623 EXPECT_CALL(*classifier_, CancelPendingClassification()); | 624 EXPECT_CALL(*classifier_, CancelPendingClassification()); |
| 624 } | 625 } |
| 625 | 626 |
| 626 } // namespace safe_browsing | 627 } // namespace safe_browsing |
| OLD | NEW |