| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 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/browser/ui/browser.h" | 5 #include "chrome/browser/ui/browser.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <memory> | 10 #include <memory> |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 #include "content/public/browser/interstitial_page.h" | 82 #include "content/public/browser/interstitial_page.h" |
| 83 #include "content/public/browser/interstitial_page_delegate.h" | 83 #include "content/public/browser/interstitial_page_delegate.h" |
| 84 #include "content/public/browser/navigation_entry.h" | 84 #include "content/public/browser/navigation_entry.h" |
| 85 #include "content/public/browser/notification_service.h" | 85 #include "content/public/browser/notification_service.h" |
| 86 #include "content/public/browser/render_frame_host.h" | 86 #include "content/public/browser/render_frame_host.h" |
| 87 #include "content/public/browser/render_process_host.h" | 87 #include "content/public/browser/render_process_host.h" |
| 88 #include "content/public/browser/render_view_host.h" | 88 #include "content/public/browser/render_view_host.h" |
| 89 #include "content/public/browser/render_widget_host.h" | 89 #include "content/public/browser/render_widget_host.h" |
| 90 #include "content/public/browser/render_widget_host_view.h" | 90 #include "content/public/browser/render_widget_host_view.h" |
| 91 #include "content/public/browser/resource_context.h" | 91 #include "content/public/browser/resource_context.h" |
| 92 #include "content/public/browser/security_style_explanation.h" | |
| 93 #include "content/public/browser/security_style_explanations.h" | |
| 94 #include "content/public/browser/web_contents.h" | 92 #include "content/public/browser/web_contents.h" |
| 95 #include "content/public/browser/web_contents_observer.h" | 93 #include "content/public/browser/web_contents_observer.h" |
| 96 #include "content/public/common/frame_navigate_params.h" | 94 #include "content/public/common/frame_navigate_params.h" |
| 97 #include "content/public/common/renderer_preferences.h" | 95 #include "content/public/common/renderer_preferences.h" |
| 98 #include "content/public/common/ssl_status.h" | 96 #include "content/public/common/ssl_status.h" |
| 99 #include "content/public/common/url_constants.h" | 97 #include "content/public/common/url_constants.h" |
| 100 #include "content/public/test/browser_test_utils.h" | 98 #include "content/public/test/browser_test_utils.h" |
| 101 #include "content/public/test/test_navigation_observer.h" | 99 #include "content/public/test/test_navigation_observer.h" |
| 102 #include "extensions/browser/extension_registry.h" | 100 #include "extensions/browser/extension_registry.h" |
| 103 #include "extensions/browser/extension_system.h" | 101 #include "extensions/browser/extension_system.h" |
| 104 #include "extensions/browser/uninstall_reason.h" | 102 #include "extensions/browser/uninstall_reason.h" |
| 105 #include "extensions/common/constants.h" | 103 #include "extensions/common/constants.h" |
| 106 #include "extensions/common/extension.h" | 104 #include "extensions/common/extension.h" |
| 107 #include "extensions/common/extension_set.h" | 105 #include "extensions/common/extension_set.h" |
| 108 #include "net/base/net_errors.h" | |
| 109 #include "net/base/test_data_directory.h" | |
| 110 #include "net/cert/x509_certificate.h" | |
| 111 #include "net/dns/mock_host_resolver.h" | 106 #include "net/dns/mock_host_resolver.h" |
| 112 #include "net/ssl/ssl_cipher_suite_names.h" | |
| 113 #include "net/ssl/ssl_connection_status_flags.h" | |
| 114 #include "net/test/cert_test_util.h" | |
| 115 #include "net/test/embedded_test_server/embedded_test_server.h" | 107 #include "net/test/embedded_test_server/embedded_test_server.h" |
| 116 #include "net/test/embedded_test_server/request_handler_util.h" | 108 #include "net/test/embedded_test_server/request_handler_util.h" |
| 117 #include "net/test/spawned_test_server/spawned_test_server.h" | 109 #include "net/test/spawned_test_server/spawned_test_server.h" |
| 118 #include "net/test/url_request/url_request_mock_http_job.h" | |
| 119 #include "net/url_request/url_request_filter.h" | |
| 120 #include "net/url_request/url_request_test_util.h" | |
| 121 #include "ui/base/l10n/l10n_util.h" | 110 #include "ui/base/l10n/l10n_util.h" |
| 122 #include "ui/base/page_transition_types.h" | 111 #include "ui/base/page_transition_types.h" |
| 123 | 112 |
| 124 #if defined(OS_MACOSX) | 113 #if defined(OS_MACOSX) |
| 125 #include "base/mac/scoped_nsautorelease_pool.h" | 114 #include "base/mac/scoped_nsautorelease_pool.h" |
| 126 #include "chrome/browser/ui/cocoa/run_loop_testing.h" | 115 #include "chrome/browser/ui/cocoa/run_loop_testing.h" |
| 127 #endif | 116 #endif |
| 128 | 117 |
| 129 #if defined(OS_WIN) | 118 #if defined(OS_WIN) |
| 130 #include "base/i18n/rtl.h" | 119 #include "base/i18n/rtl.h" |
| 131 #include "chrome/browser/browser_process.h" | 120 #include "chrome/browser/browser_process.h" |
| 132 #endif | 121 #endif |
| 133 | 122 |
| 134 using app_modal::AppModalDialog; | 123 using app_modal::AppModalDialog; |
| 135 using app_modal::AppModalDialogQueue; | 124 using app_modal::AppModalDialogQueue; |
| 136 using app_modal::JavaScriptAppModalDialog; | 125 using app_modal::JavaScriptAppModalDialog; |
| 137 using base::ASCIIToUTF16; | 126 using base::ASCIIToUTF16; |
| 138 using content::InterstitialPage; | 127 using content::InterstitialPage; |
| 139 using content::HostZoomMap; | 128 using content::HostZoomMap; |
| 140 using content::NavigationController; | 129 using content::NavigationController; |
| 141 using content::NavigationEntry; | 130 using content::NavigationEntry; |
| 142 using content::OpenURLParams; | 131 using content::OpenURLParams; |
| 143 using content::Referrer; | 132 using content::Referrer; |
| 144 using content::WebContents; | 133 using content::WebContents; |
| 145 using content::WebContentsObserver; | 134 using content::WebContentsObserver; |
| 146 using extensions::Extension; | 135 using extensions::Extension; |
| 147 | 136 |
| 148 namespace { | 137 namespace { |
| 149 | 138 |
| 150 enum CertificateStatus { VALID_CERTIFICATE, INVALID_CERTIFICATE }; | |
| 151 | |
| 152 const char* kBeforeUnloadHTML = | 139 const char* kBeforeUnloadHTML = |
| 153 "<html><head><title>beforeunload</title></head><body>" | 140 "<html><head><title>beforeunload</title></head><body>" |
| 154 "<script>window.onbeforeunload=function(e){return 'foo'}</script>" | 141 "<script>window.onbeforeunload=function(e){return 'foo'}</script>" |
| 155 "</body></html>"; | 142 "</body></html>"; |
| 156 | 143 |
| 157 const char* kOpenNewBeforeUnloadPage = | 144 const char* kOpenNewBeforeUnloadPage = |
| 158 "w=window.open(); w.onbeforeunload=function(e){return 'foo'};"; | 145 "w=window.open(); w.onbeforeunload=function(e){return 'foo'};"; |
| 159 | 146 |
| 160 const base::FilePath::CharType* kBeforeUnloadFile = | 147 const base::FilePath::CharType* kBeforeUnloadFile = |
| 161 FILE_PATH_LITERAL("beforeunload.html"); | 148 FILE_PATH_LITERAL("beforeunload.html"); |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 typedef std::map<content::RenderViewHost*, Sizes> RenderViewSizes; | 324 typedef std::map<content::RenderViewHost*, Sizes> RenderViewSizes; |
| 338 RenderViewSizes render_view_sizes_; | 325 RenderViewSizes render_view_sizes_; |
| 339 // Enlarge WebContentsView by this size insets in | 326 // Enlarge WebContentsView by this size insets in |
| 340 // DidStartNavigationToPendingEntry. | 327 // DidStartNavigationToPendingEntry. |
| 341 gfx::Size wcv_resize_insets_; | 328 gfx::Size wcv_resize_insets_; |
| 342 BrowserWindow* browser_window_; // Weak ptr. | 329 BrowserWindow* browser_window_; // Weak ptr. |
| 343 | 330 |
| 344 DISALLOW_COPY_AND_ASSIGN(RenderViewSizeObserver); | 331 DISALLOW_COPY_AND_ASSIGN(RenderViewSizeObserver); |
| 345 }; | 332 }; |
| 346 | 333 |
| 347 void ProceedThroughInterstitial(content::WebContents* web_contents) { | |
| 348 InterstitialPage* interstitial_page = web_contents->GetInterstitialPage(); | |
| 349 ASSERT_TRUE(interstitial_page); | |
| 350 | |
| 351 content::WindowedNotificationObserver observer( | |
| 352 content::NOTIFICATION_LOAD_STOP, | |
| 353 content::Source<NavigationController>(&web_contents->GetController())); | |
| 354 interstitial_page->Proceed(); | |
| 355 observer.Wait(); | |
| 356 } | |
| 357 | |
| 358 void GetFilePathWithHostAndPortReplacement( | |
| 359 const std::string& original_file_path, | |
| 360 const net::HostPortPair& host_port_pair, | |
| 361 std::string* replacement_path) { | |
| 362 base::StringPairs replacement_text; | |
| 363 replacement_text.push_back( | |
| 364 make_pair("REPLACE_WITH_HOST_AND_PORT", host_port_pair.ToString())); | |
| 365 net::test_server::GetFilePathWithReplacements( | |
| 366 original_file_path, replacement_text, replacement_path); | |
| 367 } | |
| 368 | |
| 369 // A WebContentsObserver useful for testing the SecurityStyleChanged() | |
| 370 // method: it keeps track of the latest security style and explanation | |
| 371 // that was fired. | |
| 372 class SecurityStyleTestObserver : public WebContentsObserver { | |
| 373 public: | |
| 374 explicit SecurityStyleTestObserver(content::WebContents* web_contents) | |
| 375 : content::WebContentsObserver(web_contents), | |
| 376 latest_security_style_(content::SECURITY_STYLE_UNKNOWN) {} | |
| 377 ~SecurityStyleTestObserver() override {} | |
| 378 | |
| 379 void SecurityStyleChanged(content::SecurityStyle security_style, | |
| 380 const content::SecurityStyleExplanations& | |
| 381 security_style_explanations) override { | |
| 382 latest_security_style_ = security_style; | |
| 383 latest_explanations_ = security_style_explanations; | |
| 384 } | |
| 385 | |
| 386 content::SecurityStyle latest_security_style() const { | |
| 387 return latest_security_style_; | |
| 388 } | |
| 389 | |
| 390 const content::SecurityStyleExplanations& latest_explanations() const { | |
| 391 return latest_explanations_; | |
| 392 } | |
| 393 | |
| 394 void ClearLatestSecurityStyleAndExplanations() { | |
| 395 latest_security_style_ = content::SECURITY_STYLE_UNKNOWN; | |
| 396 latest_explanations_ = content::SecurityStyleExplanations(); | |
| 397 } | |
| 398 | |
| 399 private: | |
| 400 content::SecurityStyle latest_security_style_; | |
| 401 content::SecurityStyleExplanations latest_explanations_; | |
| 402 | |
| 403 DISALLOW_COPY_AND_ASSIGN(SecurityStyleTestObserver); | |
| 404 }; | |
| 405 | |
| 406 // Check that |observer|'s latest event was for an expired certificate | |
| 407 // and that it saw the proper SecurityStyle and explanations. | |
| 408 void CheckBrokenSecurityStyle(const SecurityStyleTestObserver& observer, | |
| 409 int error, | |
| 410 Browser* browser) { | |
| 411 EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATION_BROKEN, | |
| 412 observer.latest_security_style()); | |
| 413 | |
| 414 const content::SecurityStyleExplanations& expired_explanation = | |
| 415 observer.latest_explanations(); | |
| 416 EXPECT_EQ(0u, expired_explanation.unauthenticated_explanations.size()); | |
| 417 ASSERT_EQ(1u, expired_explanation.broken_explanations.size()); | |
| 418 | |
| 419 // Check that the summary and description are as expected. | |
| 420 EXPECT_EQ(l10n_util::GetStringUTF8(IDS_CERTIFICATE_CHAIN_ERROR), | |
| 421 expired_explanation.broken_explanations[0].summary); | |
| 422 | |
| 423 base::string16 error_string = base::UTF8ToUTF16(net::ErrorToString(error)); | |
| 424 EXPECT_EQ(l10n_util::GetStringFUTF8( | |
| 425 IDS_CERTIFICATE_CHAIN_ERROR_DESCRIPTION_FORMAT, error_string), | |
| 426 expired_explanation.broken_explanations[0].description); | |
| 427 | |
| 428 // Check the associated certificate id. | |
| 429 int cert_id = browser->tab_strip_model()->GetActiveWebContents()-> | |
| 430 GetController().GetActiveEntry()->GetSSL().cert_id; | |
| 431 EXPECT_EQ(cert_id, | |
| 432 expired_explanation.broken_explanations[0].cert_id); | |
| 433 } | |
| 434 | |
| 435 // Checks that the given |secure_explanations| contains appropriate | |
| 436 // an appropriate explanation if the certificate status is valid. | |
| 437 void CheckSecureExplanations( | |
| 438 const std::vector<content::SecurityStyleExplanation>& secure_explanations, | |
| 439 CertificateStatus cert_status, | |
| 440 Browser* browser) { | |
| 441 ASSERT_EQ(cert_status == VALID_CERTIFICATE ? 2u : 1u, | |
| 442 secure_explanations.size()); | |
| 443 if (cert_status == VALID_CERTIFICATE) { | |
| 444 EXPECT_EQ(l10n_util::GetStringUTF8(IDS_VALID_SERVER_CERTIFICATE), | |
| 445 secure_explanations[0].summary); | |
| 446 EXPECT_EQ( | |
| 447 l10n_util::GetStringUTF8(IDS_VALID_SERVER_CERTIFICATE_DESCRIPTION), | |
| 448 secure_explanations[0].description); | |
| 449 int cert_id = browser->tab_strip_model() | |
| 450 ->GetActiveWebContents() | |
| 451 ->GetController() | |
| 452 .GetActiveEntry() | |
| 453 ->GetSSL() | |
| 454 .cert_id; | |
| 455 EXPECT_EQ(cert_id, secure_explanations[0].cert_id); | |
| 456 } | |
| 457 | |
| 458 EXPECT_EQ(l10n_util::GetStringUTF8(IDS_SECURE_PROTOCOL_AND_CIPHERSUITE), | |
| 459 secure_explanations.back().summary); | |
| 460 EXPECT_EQ( | |
| 461 l10n_util::GetStringUTF8(IDS_SECURE_PROTOCOL_AND_CIPHERSUITE_DESCRIPTION), | |
| 462 secure_explanations.back().description); | |
| 463 } | |
| 464 | |
| 465 } // namespace | 334 } // namespace |
| 466 | 335 |
| 467 class BrowserTest : public ExtensionBrowserTest { | 336 class BrowserTest : public ExtensionBrowserTest { |
| 468 protected: | 337 protected: |
| 469 // In RTL locales wrap the page title with RTL embedding characters so that it | 338 // In RTL locales wrap the page title with RTL embedding characters so that it |
| 470 // matches the value returned by GetWindowTitle(). | 339 // matches the value returned by GetWindowTitle(). |
| 471 base::string16 LocaleWindowCaptionFromPageTitle( | 340 base::string16 LocaleWindowCaptionFromPageTitle( |
| 472 const base::string16& expected_title) { | 341 const base::string16& expected_title) { |
| 473 base::string16 page_title = WindowCaptionFromPageTitle(expected_title); | 342 base::string16 page_title = WindowCaptionFromPageTitle(expected_title); |
| 474 #if defined(OS_WIN) | 343 #if defined(OS_WIN) |
| (...skipping 2345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2820 // destroy |contents|. | 2689 // destroy |contents|. |
| 2821 interstitial->DontProceed(); | 2690 interstitial->DontProceed(); |
| 2822 content::WaitForInterstitialDetach(web_contents); | 2691 content::WaitForInterstitialDetach(web_contents); |
| 2823 // interstitial is deleted now. | 2692 // interstitial is deleted now. |
| 2824 | 2693 |
| 2825 EXPECT_TRUE(chrome::CanDuplicateTab(browser())); | 2694 EXPECT_TRUE(chrome::CanDuplicateTab(browser())); |
| 2826 EXPECT_TRUE(chrome::CanDuplicateTabAt(browser(), 0)); | 2695 EXPECT_TRUE(chrome::CanDuplicateTabAt(browser(), 0)); |
| 2827 EXPECT_TRUE(chrome::CanDuplicateTabAt(browser(), 1)); | 2696 EXPECT_TRUE(chrome::CanDuplicateTabAt(browser(), 1)); |
| 2828 } | 2697 } |
| 2829 | 2698 |
| 2830 // Tests that the WebContentsObserver::SecurityStyleChanged event fires | |
| 2831 // with the current style on HTTP, broken HTTPS, and valid HTTPS pages. | |
| 2832 IN_PROC_BROWSER_TEST_F(BrowserTest, SecurityStyleChangedObserver) { | |
| 2833 net::EmbeddedTestServer https_test_server( | |
| 2834 net::EmbeddedTestServer::TYPE_HTTPS); | |
| 2835 https_test_server.ServeFilesFromSourceDirectory(base::FilePath(kDocRoot)); | |
| 2836 ASSERT_TRUE(https_test_server.Start()); | |
| 2837 | |
| 2838 net::EmbeddedTestServer https_test_server_expired( | |
| 2839 net::EmbeddedTestServer::TYPE_HTTPS); | |
| 2840 https_test_server_expired.SetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED); | |
| 2841 https_test_server_expired.ServeFilesFromSourceDirectory( | |
| 2842 base::FilePath(kDocRoot)); | |
| 2843 ASSERT_TRUE(https_test_server_expired.Start()); | |
| 2844 ASSERT_TRUE(embedded_test_server()->Start()); | |
| 2845 | |
| 2846 content::WebContents* web_contents = | |
| 2847 browser()->tab_strip_model()->GetActiveWebContents(); | |
| 2848 SecurityStyleTestObserver observer(web_contents); | |
| 2849 | |
| 2850 // Visit an HTTP url. | |
| 2851 GURL http_url(embedded_test_server()->GetURL("/")); | |
| 2852 ui_test_utils::NavigateToURL(browser(), http_url); | |
| 2853 EXPECT_EQ(content::SECURITY_STYLE_UNAUTHENTICATED, | |
| 2854 observer.latest_security_style()); | |
| 2855 EXPECT_EQ(0u, | |
| 2856 observer.latest_explanations().unauthenticated_explanations.size()); | |
| 2857 EXPECT_EQ(0u, observer.latest_explanations().broken_explanations.size()); | |
| 2858 EXPECT_EQ(0u, observer.latest_explanations().secure_explanations.size()); | |
| 2859 EXPECT_FALSE(observer.latest_explanations().scheme_is_cryptographic); | |
| 2860 EXPECT_FALSE(observer.latest_explanations().ran_insecure_content); | |
| 2861 EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content); | |
| 2862 | |
| 2863 // Visit an (otherwise valid) HTTPS page that displays mixed content. | |
| 2864 std::string replacement_path; | |
| 2865 GetFilePathWithHostAndPortReplacement( | |
| 2866 "/ssl/page_displays_insecure_content.html", | |
| 2867 embedded_test_server()->host_port_pair(), &replacement_path); | |
| 2868 | |
| 2869 GURL mixed_content_url(https_test_server.GetURL(replacement_path)); | |
| 2870 ui_test_utils::NavigateToURL(browser(), mixed_content_url); | |
| 2871 EXPECT_EQ(content::SECURITY_STYLE_UNAUTHENTICATED, | |
| 2872 observer.latest_security_style()); | |
| 2873 | |
| 2874 const content::SecurityStyleExplanations& mixed_content_explanation = | |
| 2875 observer.latest_explanations(); | |
| 2876 ASSERT_EQ(0u, mixed_content_explanation.unauthenticated_explanations.size()); | |
| 2877 ASSERT_EQ(0u, mixed_content_explanation.broken_explanations.size()); | |
| 2878 CheckSecureExplanations(mixed_content_explanation.secure_explanations, | |
| 2879 VALID_CERTIFICATE, browser()); | |
| 2880 EXPECT_TRUE(mixed_content_explanation.scheme_is_cryptographic); | |
| 2881 EXPECT_TRUE(mixed_content_explanation.displayed_insecure_content); | |
| 2882 EXPECT_FALSE(mixed_content_explanation.ran_insecure_content); | |
| 2883 EXPECT_EQ(content::SECURITY_STYLE_UNAUTHENTICATED, | |
| 2884 mixed_content_explanation.displayed_insecure_content_style); | |
| 2885 EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATION_BROKEN, | |
| 2886 mixed_content_explanation.ran_insecure_content_style); | |
| 2887 | |
| 2888 // Visit a broken HTTPS url. | |
| 2889 GURL expired_url(https_test_server_expired.GetURL(std::string("/"))); | |
| 2890 ui_test_utils::NavigateToURL(browser(), expired_url); | |
| 2891 | |
| 2892 // An interstitial should show, and an event for the lock icon on the | |
| 2893 // interstitial should fire. | |
| 2894 content::WaitForInterstitialAttach(web_contents); | |
| 2895 EXPECT_TRUE(web_contents->ShowingInterstitialPage()); | |
| 2896 CheckBrokenSecurityStyle(observer, net::ERR_CERT_DATE_INVALID, browser()); | |
| 2897 CheckSecureExplanations(observer.latest_explanations().secure_explanations, | |
| 2898 INVALID_CERTIFICATE, browser()); | |
| 2899 EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic); | |
| 2900 EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content); | |
| 2901 EXPECT_FALSE(observer.latest_explanations().ran_insecure_content); | |
| 2902 | |
| 2903 // Before clicking through, navigate to a different page, and then go | |
| 2904 // back to the interstitial. | |
| 2905 GURL valid_https_url(https_test_server.GetURL(std::string("/"))); | |
| 2906 ui_test_utils::NavigateToURL(browser(), valid_https_url); | |
| 2907 EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATED, | |
| 2908 observer.latest_security_style()); | |
| 2909 EXPECT_EQ(0u, | |
| 2910 observer.latest_explanations().unauthenticated_explanations.size()); | |
| 2911 EXPECT_EQ(0u, observer.latest_explanations().broken_explanations.size()); | |
| 2912 CheckSecureExplanations(observer.latest_explanations().secure_explanations, | |
| 2913 VALID_CERTIFICATE, browser()); | |
| 2914 EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic); | |
| 2915 EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content); | |
| 2916 EXPECT_FALSE(observer.latest_explanations().ran_insecure_content); | |
| 2917 | |
| 2918 // After going back to the interstitial, an event for a broken lock | |
| 2919 // icon should fire again. | |
| 2920 ui_test_utils::NavigateToURL(browser(), expired_url); | |
| 2921 content::WaitForInterstitialAttach(web_contents); | |
| 2922 EXPECT_TRUE(web_contents->ShowingInterstitialPage()); | |
| 2923 CheckBrokenSecurityStyle(observer, net::ERR_CERT_DATE_INVALID, browser()); | |
| 2924 CheckSecureExplanations(observer.latest_explanations().secure_explanations, | |
| 2925 INVALID_CERTIFICATE, browser()); | |
| 2926 EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic); | |
| 2927 EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content); | |
| 2928 EXPECT_FALSE(observer.latest_explanations().ran_insecure_content); | |
| 2929 | |
| 2930 // Since the next expected style is the same as the previous, clear | |
| 2931 // the observer (to make sure that the event fires twice and we don't | |
| 2932 // just see the previous event's style). | |
| 2933 observer.ClearLatestSecurityStyleAndExplanations(); | |
| 2934 | |
| 2935 // Other conditions cannot be tested on this host after clicking | |
| 2936 // through because once the interstitial is clicked through, all URLs | |
| 2937 // for this host will remain in a broken state. | |
| 2938 ProceedThroughInterstitial(web_contents); | |
| 2939 CheckBrokenSecurityStyle(observer, net::ERR_CERT_DATE_INVALID, browser()); | |
| 2940 CheckSecureExplanations(observer.latest_explanations().secure_explanations, | |
| 2941 INVALID_CERTIFICATE, browser()); | |
| 2942 EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic); | |
| 2943 EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content); | |
| 2944 EXPECT_FALSE(observer.latest_explanations().ran_insecure_content); | |
| 2945 } | |
| 2946 | |
| 2947 // Visit a valid HTTPS page, then a broken HTTPS page, and then go back, | |
| 2948 // and test that the observed security style matches. | |
| 2949 IN_PROC_BROWSER_TEST_F(BrowserTest, SecurityStyleChangedObserverGoBack) { | |
| 2950 net::EmbeddedTestServer https_test_server( | |
| 2951 net::EmbeddedTestServer::TYPE_HTTPS); | |
| 2952 https_test_server.ServeFilesFromSourceDirectory(base::FilePath(kDocRoot)); | |
| 2953 ASSERT_TRUE(https_test_server.Start()); | |
| 2954 | |
| 2955 net::EmbeddedTestServer https_test_server_expired( | |
| 2956 net::EmbeddedTestServer::TYPE_HTTPS); | |
| 2957 https_test_server_expired.SetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED); | |
| 2958 https_test_server_expired.ServeFilesFromSourceDirectory( | |
| 2959 base::FilePath(kDocRoot)); | |
| 2960 ASSERT_TRUE(https_test_server_expired.Start()); | |
| 2961 | |
| 2962 content::WebContents* web_contents = | |
| 2963 browser()->tab_strip_model()->GetActiveWebContents(); | |
| 2964 SecurityStyleTestObserver observer(web_contents); | |
| 2965 | |
| 2966 // Visit a valid HTTPS url. | |
| 2967 GURL valid_https_url(https_test_server.GetURL(std::string("/"))); | |
| 2968 ui_test_utils::NavigateToURL(browser(), valid_https_url); | |
| 2969 EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATED, | |
| 2970 observer.latest_security_style()); | |
| 2971 EXPECT_EQ(0u, | |
| 2972 observer.latest_explanations().unauthenticated_explanations.size()); | |
| 2973 EXPECT_EQ(0u, observer.latest_explanations().broken_explanations.size()); | |
| 2974 CheckSecureExplanations(observer.latest_explanations().secure_explanations, | |
| 2975 VALID_CERTIFICATE, browser()); | |
| 2976 EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic); | |
| 2977 EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content); | |
| 2978 EXPECT_FALSE(observer.latest_explanations().ran_insecure_content); | |
| 2979 | |
| 2980 // Navigate to a bad HTTPS page on a different host, and then click | |
| 2981 // Back to verify that the previous good security style is seen again. | |
| 2982 GURL expired_https_url(https_test_server_expired.GetURL(std::string("/"))); | |
| 2983 host_resolver()->AddRule("www.example_broken.test", "127.0.0.1"); | |
| 2984 GURL::Replacements replace_host; | |
| 2985 replace_host.SetHostStr("www.example_broken.test"); | |
| 2986 GURL https_url_different_host = | |
| 2987 expired_https_url.ReplaceComponents(replace_host); | |
| 2988 | |
| 2989 ui_test_utils::NavigateToURL(browser(), https_url_different_host); | |
| 2990 | |
| 2991 content::WaitForInterstitialAttach(web_contents); | |
| 2992 EXPECT_TRUE(web_contents->ShowingInterstitialPage()); | |
| 2993 CheckBrokenSecurityStyle(observer, net::ERR_CERT_COMMON_NAME_INVALID, | |
| 2994 browser()); | |
| 2995 ProceedThroughInterstitial(web_contents); | |
| 2996 CheckBrokenSecurityStyle(observer, net::ERR_CERT_COMMON_NAME_INVALID, | |
| 2997 browser()); | |
| 2998 CheckSecureExplanations(observer.latest_explanations().secure_explanations, | |
| 2999 INVALID_CERTIFICATE, browser()); | |
| 3000 EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic); | |
| 3001 EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content); | |
| 3002 EXPECT_FALSE(observer.latest_explanations().ran_insecure_content); | |
| 3003 | |
| 3004 content::WindowedNotificationObserver back_nav_load_observer( | |
| 3005 content::NOTIFICATION_LOAD_STOP, | |
| 3006 content::Source<NavigationController>(&web_contents->GetController())); | |
| 3007 chrome::GoBack(browser(), CURRENT_TAB); | |
| 3008 back_nav_load_observer.Wait(); | |
| 3009 | |
| 3010 EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATED, | |
| 3011 observer.latest_security_style()); | |
| 3012 EXPECT_EQ(0u, | |
| 3013 observer.latest_explanations().unauthenticated_explanations.size()); | |
| 3014 EXPECT_EQ(0u, observer.latest_explanations().broken_explanations.size()); | |
| 3015 CheckSecureExplanations(observer.latest_explanations().secure_explanations, | |
| 3016 VALID_CERTIFICATE, browser()); | |
| 3017 EXPECT_TRUE(observer.latest_explanations().scheme_is_cryptographic); | |
| 3018 EXPECT_FALSE(observer.latest_explanations().displayed_insecure_content); | |
| 3019 EXPECT_FALSE(observer.latest_explanations().ran_insecure_content); | |
| 3020 } | |
| 3021 | |
| 3022 namespace { | |
| 3023 | |
| 3024 // After AddNonsecureUrlHandler() is called, requests to this hostname | |
| 3025 // will use obsolete TLS settings. | |
| 3026 const char kMockNonsecureHostname[] = "example-nonsecure.test"; | |
| 3027 | |
| 3028 // A URLRequestMockHTTPJob that mocks a TLS connection with an obsolete | |
| 3029 // protocol version. | |
| 3030 class URLRequestObsoleteTLSJob : public net::URLRequestMockHTTPJob { | |
| 3031 public: | |
| 3032 URLRequestObsoleteTLSJob(net::URLRequest* request, | |
| 3033 net::NetworkDelegate* network_delegate, | |
| 3034 const base::FilePath& file_path, | |
| 3035 scoped_refptr<net::X509Certificate> cert, | |
| 3036 scoped_refptr<base::TaskRunner> task_runner) | |
| 3037 : net::URLRequestMockHTTPJob(request, | |
| 3038 network_delegate, | |
| 3039 file_path, | |
| 3040 task_runner), | |
| 3041 cert_(std::move(cert)) {} | |
| 3042 | |
| 3043 void GetResponseInfo(net::HttpResponseInfo* info) override { | |
| 3044 net::URLRequestMockHTTPJob::GetResponseInfo(info); | |
| 3045 net::SSLConnectionStatusSetVersion(net::SSL_CONNECTION_VERSION_TLS1_1, | |
| 3046 &info->ssl_info.connection_status); | |
| 3047 const uint16_t kTlsEcdheRsaWithAes128CbcSha = 0xc013; | |
| 3048 net::SSLConnectionStatusSetCipherSuite(kTlsEcdheRsaWithAes128CbcSha, | |
| 3049 &info->ssl_info.connection_status); | |
| 3050 info->ssl_info.cert = cert_; | |
| 3051 } | |
| 3052 | |
| 3053 protected: | |
| 3054 ~URLRequestObsoleteTLSJob() override {} | |
| 3055 | |
| 3056 private: | |
| 3057 const scoped_refptr<net::X509Certificate> cert_; | |
| 3058 | |
| 3059 DISALLOW_COPY_AND_ASSIGN(URLRequestObsoleteTLSJob); | |
| 3060 }; | |
| 3061 | |
| 3062 // A URLRequestInterceptor that handles requests with | |
| 3063 // URLRequestObsoleteTLSJob jobs. | |
| 3064 class URLRequestNonsecureInterceptor : public net::URLRequestInterceptor { | |
| 3065 public: | |
| 3066 URLRequestNonsecureInterceptor( | |
| 3067 const base::FilePath& base_path, | |
| 3068 scoped_refptr<base::SequencedWorkerPool> worker_pool, | |
| 3069 scoped_refptr<net::X509Certificate> cert) | |
| 3070 : base_path_(base_path), | |
| 3071 worker_pool_(std::move(worker_pool)), | |
| 3072 cert_(std::move(cert)) {} | |
| 3073 | |
| 3074 ~URLRequestNonsecureInterceptor() override {} | |
| 3075 | |
| 3076 // net::URLRequestInterceptor: | |
| 3077 net::URLRequestJob* MaybeInterceptRequest( | |
| 3078 net::URLRequest* request, | |
| 3079 net::NetworkDelegate* network_delegate) const override { | |
| 3080 return new URLRequestObsoleteTLSJob( | |
| 3081 request, network_delegate, base_path_, cert_, | |
| 3082 worker_pool_->GetTaskRunnerWithShutdownBehavior( | |
| 3083 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)); | |
| 3084 } | |
| 3085 | |
| 3086 private: | |
| 3087 const base::FilePath base_path_; | |
| 3088 const scoped_refptr<base::SequencedWorkerPool> worker_pool_; | |
| 3089 const scoped_refptr<net::X509Certificate> cert_; | |
| 3090 | |
| 3091 DISALLOW_COPY_AND_ASSIGN(URLRequestNonsecureInterceptor); | |
| 3092 }; | |
| 3093 | |
| 3094 // Installs a handler to serve HTTPS requests to | |
| 3095 // |kMockNonsecureHostname| with connections that have obsolete TLS | |
| 3096 // settings. | |
| 3097 void AddNonsecureUrlHandler( | |
| 3098 const base::FilePath& base_path, | |
| 3099 scoped_refptr<net::X509Certificate> cert, | |
| 3100 scoped_refptr<base::SequencedWorkerPool> worker_pool) { | |
| 3101 net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance(); | |
| 3102 filter->AddHostnameInterceptor( | |
| 3103 "https", kMockNonsecureHostname, | |
| 3104 std::unique_ptr<net::URLRequestInterceptor>( | |
| 3105 new URLRequestNonsecureInterceptor(base_path, worker_pool, cert))); | |
| 3106 } | |
| 3107 | |
| 3108 class BrowserTestNonsecureURLRequest : public BrowserTest { | |
| 3109 public: | |
| 3110 BrowserTestNonsecureURLRequest() : BrowserTest(), cert_(nullptr) {} | |
| 3111 | |
| 3112 void SetUpInProcessBrowserTestFixture() override { | |
| 3113 cert_ = | |
| 3114 net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem"); | |
| 3115 ASSERT_TRUE(cert_); | |
| 3116 } | |
| 3117 | |
| 3118 void SetUpOnMainThread() override { | |
| 3119 base::FilePath serve_file; | |
| 3120 PathService::Get(chrome::DIR_TEST_DATA, &serve_file); | |
| 3121 serve_file = serve_file.Append(FILE_PATH_LITERAL("title1.html")); | |
| 3122 content::BrowserThread::PostTask( | |
| 3123 content::BrowserThread::IO, FROM_HERE, | |
| 3124 base::Bind( | |
| 3125 &AddNonsecureUrlHandler, serve_file, cert_, | |
| 3126 make_scoped_refptr(content::BrowserThread::GetBlockingPool()))); | |
| 3127 } | |
| 3128 | |
| 3129 private: | |
| 3130 scoped_refptr<net::X509Certificate> cert_; | |
| 3131 | |
| 3132 DISALLOW_COPY_AND_ASSIGN(BrowserTestNonsecureURLRequest); | |
| 3133 }; | |
| 3134 | |
| 3135 } // namespace | |
| 3136 | |
| 3137 // Tests that a connection with obsolete TLS settings does not get a | |
| 3138 // secure connection explanation. | |
| 3139 IN_PROC_BROWSER_TEST_F(BrowserTestNonsecureURLRequest, | |
| 3140 SecurityStyleChangedObserverNonsecureConnection) { | |
| 3141 content::WebContents* web_contents = | |
| 3142 browser()->tab_strip_model()->GetActiveWebContents(); | |
| 3143 SecurityStyleTestObserver observer(web_contents); | |
| 3144 | |
| 3145 ui_test_utils::NavigateToURL( | |
| 3146 browser(), GURL(std::string("https://") + kMockNonsecureHostname)); | |
| 3147 | |
| 3148 // The security style of the page doesn't get downgraded for obsolete | |
| 3149 // TLS settings, so it should remain at SECURITY_STYLE_AUTHENTICATED. | |
| 3150 EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATED, | |
| 3151 observer.latest_security_style()); | |
| 3152 | |
| 3153 // The messages explaining the security style do, however, get | |
| 3154 // downgraded: SECURE_PROTOCOL_AND_CIPHERSUITE should not show up when | |
| 3155 // the TLS settings are obsolete. | |
| 3156 for (const auto& explanation : | |
| 3157 observer.latest_explanations().secure_explanations) { | |
| 3158 EXPECT_NE(l10n_util::GetStringUTF8(IDS_SECURE_PROTOCOL_AND_CIPHERSUITE), | |
| 3159 explanation.summary); | |
| 3160 } | |
| 3161 } | |
| 3162 | |
| 3163 namespace { | 2699 namespace { |
| 3164 class JSBooleanResultGetter { | 2700 class JSBooleanResultGetter { |
| 3165 public: | 2701 public: |
| 3166 JSBooleanResultGetter() = default; | 2702 JSBooleanResultGetter() = default; |
| 3167 void OnJsExecutionDone(base::Closure callback, const base::Value* value) { | 2703 void OnJsExecutionDone(base::Closure callback, const base::Value* value) { |
| 3168 js_result_.reset(value->DeepCopy()); | 2704 js_result_.reset(value->DeepCopy()); |
| 3169 callback.Run(); | 2705 callback.Run(); |
| 3170 } | 2706 } |
| 3171 bool GetResult() const { | 2707 bool GetResult() const { |
| 3172 bool res; | 2708 bool res; |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3308 Browser* browser = new Browser(params); | 2844 Browser* browser = new Browser(params); |
| 3309 gfx::Rect bounds = browser->window()->GetBounds(); | 2845 gfx::Rect bounds = browser->window()->GetBounds(); |
| 3310 | 2846 |
| 3311 // Should be EXPECT_EQ, but this width is inconsistent across platforms. | 2847 // Should be EXPECT_EQ, but this width is inconsistent across platforms. |
| 3312 // See https://crbug.com/567925. | 2848 // See https://crbug.com/567925. |
| 3313 EXPECT_GE(bounds.width(), 100); | 2849 EXPECT_GE(bounds.width(), 100); |
| 3314 EXPECT_EQ(122, bounds.height()); | 2850 EXPECT_EQ(122, bounds.height()); |
| 3315 browser->window()->Close(); | 2851 browser->window()->Close(); |
| 3316 } | 2852 } |
| 3317 } | 2853 } |
| OLD | NEW |