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 "base/command_line.h" 6 #include "base/path_service.h" 7 #include "base/prefs/pref_service.h" 8 #include "base/strings/string_util.h" 9 #include "base/strings/stringprintf.h" 10 #include "base/strings/utf_string_conversions.h" 11 #include "base/time/time.h" 12 #include "chrome/app/chrome_command_ids.h" 13 #include "chrome/browser/chrome_notification_types.h" 14 #include "chrome/browser/content_settings/host_content_settings_map.h" 15 #include "chrome/browser/profiles/profile.h" 16 #include "chrome/browser/ssl/ssl_blocking_page.h" 17 #include "chrome/browser/ui/browser.h" 18 #include "chrome/browser/ui/browser_commands.h" 19 #include "chrome/browser/ui/browser_navigator.h" 20 #include "chrome/browser/ui/browser_tabstrip.h" 21 #include "chrome/browser/ui/tabs/tab_strip_model.h" 22 #include "chrome/common/chrome_paths.h" 23 #include "chrome/common/chrome_switches.h" 24 #include "chrome/common/pref_names.h" 25 #include "chrome/test/base/in_process_browser_test.h" 26 #include "chrome/test/base/ui_test_utils.h" 27 #include "components/web_modal/web_contents_modal_dialog_manager.h" 28 #include "content/public/browser/browser_context.h" 29 #include "content/public/browser/interstitial_page.h" 30 #include "content/public/browser/navigation_controller.h" 31 #include "content/public/browser/navigation_entry.h" 32 #include "content/public/browser/notification_service.h" 33 #include "content/public/browser/render_view_host.h" 34 #include "content/public/browser/render_widget_host_view.h" 35 #include "content/public/browser/web_contents.h" 36 #include "content/public/browser/web_contents_observer.h" 37 #include "content/public/common/security_style.h" 38 #include "content/public/common/ssl_status.h" 39 #include "content/public/test/browser_test_utils.h" 40 #include "content/public/test/download_test_observer.h" 41 #include "content/public/test/test_renderer_host.h" 42 #include "crypto/nss_util.h" 43 #include "net/base/crypto_module.h" 44 #include "net/base/net_errors.h" 45 #include "net/base/test_data_directory.h" 46 #include "net/cert/cert_status_flags.h" 47 #include "net/test/spawned_test_server/spawned_test_server.h" 48 49 #if defined(USE_NSS) 50 #include "net/cert/nss_cert_database.h" 51 #endif // defined(USE_NSS) 52 53 using base::ASCIIToUTF16; 54 using content::InterstitialPage; 55 using content::NavigationController; 56 using content::NavigationEntry; 57 using content::SSLStatus; 58 using content::WebContents; 59 using web_modal::WebContentsModalDialogManager; 60 61 const base::FilePath::CharType kDocRoot[] = 62 FILE_PATH_LITERAL("chrome/test/data"); 63 64 namespace { 65 66 class ProvisionalLoadWaiter : public content::WebContentsObserver { 67 public: 68 explicit ProvisionalLoadWaiter(WebContents* tab) 69 : WebContentsObserver(tab), waiting_(false), seen_(false) {} 70 71 void Wait() { 72 if (seen_) 73 return; 74 75 waiting_ = true; 76 content::RunMessageLoop(); 77 } 78 79 virtual void DidFailProvisionalLoad( 80 int64 frame_id, 81 const base::string16& frame_unique_name, 82 bool is_main_frame, 83 const GURL& validated_url, 84 int error_code, 85 const base::string16& error_description, 86 content::RenderViewHost* render_view_host) OVERRIDE { 87 seen_ = true; 88 if (waiting_) 89 base::MessageLoopForUI::current()->Quit(); 90 } 91 92 private: 93 bool waiting_; 94 bool seen_; 95 }; 96 97 namespace AuthState { 98 99 enum AuthStateFlags { 100 NONE = 0, 101 DISPLAYED_INSECURE_CONTENT = 1 << 0, 102 RAN_INSECURE_CONTENT = 1 << 1, 103 SHOWING_INTERSTITIAL = 1 << 2 104 }; 105 106 void Check(const NavigationEntry& entry, int expected_authentication_state) { 107 EXPECT_EQ(!!(expected_authentication_state & AuthState::SHOWING_INTERSTITIAL) 108 ? content::PAGE_TYPE_INTERSTITIAL 109 : content::PAGE_TYPE_NORMAL, 110 entry.GetPageType()); 111 112 bool displayed_insecure_content = 113 !!(entry.GetSSL().content_status & SSLStatus::DISPLAYED_INSECURE_CONTENT); 114 EXPECT_EQ( 115 !!(expected_authentication_state & AuthState::DISPLAYED_INSECURE_CONTENT), 116 displayed_insecure_content); 117 118 bool ran_insecure_content = 119 !!(entry.GetSSL().content_status & SSLStatus::RAN_INSECURE_CONTENT); 120 EXPECT_EQ(!!(expected_authentication_state & AuthState::RAN_INSECURE_CONTENT), 121 ran_insecure_content); 122 } 123 124 } // namespace AuthState 125 126 namespace SecurityStyle { 127 128 void Check(const NavigationEntry& entry, 129 content::SecurityStyle expected_security_style) { 130 EXPECT_EQ(expected_security_style, entry.GetSSL().security_style); 131 } 132 133 } // namespace SecurityStyle 134 135 namespace CertError { 136 137 enum CertErrorFlags { 138 NONE = 0 139 }; 140 141 void Check(const NavigationEntry& entry, net::CertStatus error) { 142 if (error) { 143 EXPECT_EQ(error, entry.GetSSL().cert_status & error); 144 net::CertStatus extra_cert_errors = 145 error ^ (entry.GetSSL().cert_status & net::CERT_STATUS_ALL_ERRORS); 146 if (extra_cert_errors) 147 LOG(WARNING) << "Got unexpected cert error: " << extra_cert_errors; 148 } else { 149 EXPECT_EQ(0U, entry.GetSSL().cert_status & net::CERT_STATUS_ALL_ERRORS); 150 } 151 } 152 153 } // namespace CertError 154 155 void CheckSecurityState(WebContents* tab, 156 net::CertStatus error, 157 content::SecurityStyle expected_security_style, 158 int expected_authentication_state) { 159 ASSERT_FALSE(tab->IsCrashed()); 160 NavigationEntry* entry = tab->GetController().GetActiveEntry(); 161 ASSERT_TRUE(entry); 162 CertError::Check(*entry, error); 163 SecurityStyle::Check(*entry, expected_security_style); 164 AuthState::Check(*entry, expected_authentication_state); 165 } 166 167 } // namespace 168 169 class SSLUITest : public InProcessBrowserTest { 170 public: 171 SSLUITest() 172 : https_server_(net::SpawnedTestServer::TYPE_HTTPS, 173 SSLOptions(SSLOptions::CERT_OK), 174 base::FilePath(kDocRoot)), 175 https_server_expired_(net::SpawnedTestServer::TYPE_HTTPS, 176 SSLOptions(SSLOptions::CERT_EXPIRED), 177 base::FilePath(kDocRoot)), 178 https_server_mismatched_(net::SpawnedTestServer::TYPE_HTTPS, 179 SSLOptions(SSLOptions::CERT_MISMATCHED_NAME), 180 base::FilePath(kDocRoot)), 181 wss_server_expired_(net::SpawnedTestServer::TYPE_WSS, 182 SSLOptions(SSLOptions::CERT_EXPIRED), 183 net::GetWebSocketTestDataDirectory()) {} 184 185 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 186 // Browser will both run and display insecure content. 187 command_line->AppendSwitch(switches::kAllowRunningInsecureContent); 188 // Use process-per-site so that navigating to a same-site page in a 189 // new tab will use the same process. 190 command_line->AppendSwitch(switches::kProcessPerSite); 191 } 192 193 void CheckAuthenticatedState(WebContents* tab, 194 int expected_authentication_state) { 195 CheckSecurityState(tab, 196 CertError::NONE, 197 content::SECURITY_STYLE_AUTHENTICATED, 198 expected_authentication_state); 199 } 200 201 void CheckUnauthenticatedState(WebContents* tab) { 202 CheckSecurityState(tab, 203 CertError::NONE, 204 content::SECURITY_STYLE_UNAUTHENTICATED, 205 AuthState::NONE); 206 } 207 208 void CheckAuthenticationBrokenState(WebContents* tab, 209 net::CertStatus error, 210 int expected_authentication_state) { 211 CheckSecurityState(tab, 212 error, 213 content::SECURITY_STYLE_AUTHENTICATION_BROKEN, 214 expected_authentication_state); 215 // CERT_STATUS_UNABLE_TO_CHECK_REVOCATION doesn't lower the security style 216 // to SECURITY_STYLE_AUTHENTICATION_BROKEN. 217 ASSERT_NE(net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION, error); 218 } 219 220 void CheckWorkerLoadResult(WebContents* tab, bool expected_load) { 221 // Workers are async and we don't have notifications for them passing 222 // messages since they do it between renderer and worker processes. 223 // So have a polling loop, check every 200ms, timeout at 30s. 224 const int kTimeoutMS = 200; 225 base::Time time_to_quit = base::Time::Now() + 226 base::TimeDelta::FromMilliseconds(30000); 227 228 while (base::Time::Now() < time_to_quit) { 229 bool worker_finished = false; 230 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 231 tab, 232 "window.domAutomationController.send(IsWorkerFinished());", 233 &worker_finished)); 234 235 if (worker_finished) 236 break; 237 238 // Wait a bit. 239 base::MessageLoop::current()->PostDelayedTask( 240 FROM_HERE, 241 base::MessageLoop::QuitClosure(), 242 base::TimeDelta::FromMilliseconds(kTimeoutMS)); 243 content::RunMessageLoop(); 244 } 245 246 bool actually_loaded_content = false; 247 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 248 tab, 249 "window.domAutomationController.send(IsContentLoaded());", 250 &actually_loaded_content)); 251 EXPECT_EQ(expected_load, actually_loaded_content); 252 } 253 254 void ProceedThroughInterstitial(WebContents* tab) { 255 InterstitialPage* interstitial_page = tab->GetInterstitialPage(); 256 ASSERT_TRUE(interstitial_page); 257 content::WindowedNotificationObserver observer( 258 content::NOTIFICATION_LOAD_STOP, 259 content::Source<NavigationController>(&tab->GetController())); 260 interstitial_page->Proceed(); 261 observer.Wait(); 262 } 263 264 bool IsShowingWebContentsModalDialog() const { 265 return WebContentsModalDialogManager::FromWebContents( 266 browser()->tab_strip_model()->GetActiveWebContents())-> 267 IsDialogActive(); 268 } 269 270 static bool GetFilePathWithHostAndPortReplacement( 271 const std::string& original_file_path, 272 const net::HostPortPair& host_port_pair, 273 std::string* replacement_path) { 274 std::vector<net::SpawnedTestServer::StringPair> replacement_text; 275 replacement_text.push_back( 276 make_pair("REPLACE_WITH_HOST_AND_PORT", host_port_pair.ToString())); 277 return net::SpawnedTestServer::GetFilePathWithReplacements( 278 original_file_path, replacement_text, replacement_path); 279 } 280 281 static bool GetTopFramePath(const net::SpawnedTestServer& http_server, 282 const net::SpawnedTestServer& good_https_server, 283 const net::SpawnedTestServer& bad_https_server, 284 std::string* top_frame_path) { 285 // The "frame_left.html" page contained in the top_frame.html page contains 286 // <a href>'s to three different servers. This sets up all of the 287 // replacement text to work with test servers which listen on ephemeral 288 // ports. 289 GURL http_url = http_server.GetURL("files/ssl/google.html"); 290 GURL good_https_url = good_https_server.GetURL("files/ssl/google.html"); 291 GURL bad_https_url = bad_https_server.GetURL( 292 "files/ssl/bad_iframe.html"); 293 294 std::vector<net::SpawnedTestServer::StringPair> replacement_text_frame_left; 295 replacement_text_frame_left.push_back( 296 make_pair("REPLACE_WITH_HTTP_PAGE", http_url.spec())); 297 replacement_text_frame_left.push_back( 298 make_pair("REPLACE_WITH_GOOD_HTTPS_PAGE", good_https_url.spec())); 299 replacement_text_frame_left.push_back( 300 make_pair("REPLACE_WITH_BAD_HTTPS_PAGE", bad_https_url.spec())); 301 std::string frame_left_path; 302 if (!net::SpawnedTestServer::GetFilePathWithReplacements( 303 "frame_left.html", 304 replacement_text_frame_left, 305 &frame_left_path)) 306 return false; 307 308 // Substitute the generated frame_left URL into the top_frame page. 309 std::vector<net::SpawnedTestServer::StringPair> replacement_text_top_frame; 310 replacement_text_top_frame.push_back( 311 make_pair("REPLACE_WITH_FRAME_LEFT_PATH", frame_left_path)); 312 return net::SpawnedTestServer::GetFilePathWithReplacements( 313 "files/ssl/top_frame.html", 314 replacement_text_top_frame, 315 top_frame_path); 316 } 317 318 static bool GetPageWithUnsafeWorkerPath( 319 const net::SpawnedTestServer& expired_https_server, 320 std::string* page_with_unsafe_worker_path) { 321 // Get the "imported.js" URL from the expired https server and 322 // substitute it into the unsafe_worker.js file. 323 GURL imported_js_url = expired_https_server.GetURL("files/ssl/imported.js"); 324 std::vector<net::SpawnedTestServer::StringPair> 325 replacement_text_for_unsafe_worker; 326 replacement_text_for_unsafe_worker.push_back( 327 make_pair("REPLACE_WITH_IMPORTED_JS_URL", imported_js_url.spec())); 328 std::string unsafe_worker_path; 329 if (!net::SpawnedTestServer::GetFilePathWithReplacements( 330 "unsafe_worker.js", 331 replacement_text_for_unsafe_worker, 332 &unsafe_worker_path)) 333 return false; 334 335 // Now, substitute this into the page with unsafe worker. 336 std::vector<net::SpawnedTestServer::StringPair> 337 replacement_text_for_page_with_unsafe_worker; 338 replacement_text_for_page_with_unsafe_worker.push_back( 339 make_pair("REPLACE_WITH_UNSAFE_WORKER_PATH", unsafe_worker_path)); 340 return net::SpawnedTestServer::GetFilePathWithReplacements( 341 "files/ssl/page_with_unsafe_worker.html", 342 replacement_text_for_page_with_unsafe_worker, 343 page_with_unsafe_worker_path); 344 } 345 346 net::SpawnedTestServer https_server_; 347 net::SpawnedTestServer https_server_expired_; 348 net::SpawnedTestServer https_server_mismatched_; 349 net::SpawnedTestServer wss_server_expired_; 350 351 private: 352 typedef net::SpawnedTestServer::SSLOptions SSLOptions; 353 354 DISALLOW_COPY_AND_ASSIGN(SSLUITest); 355 }; 356 357 class SSLUITestBlock : public SSLUITest { 358 public: 359 SSLUITestBlock() : SSLUITest() {} 360 361 // Browser will neither run nor display insecure content. 362 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 363 command_line->AppendSwitch(switches::kNoDisplayingInsecureContent); 364 } 365 }; 366 367 class SSLUITestIgnoreCertErrors : public SSLUITest { 368 public: 369 SSLUITestIgnoreCertErrors() : SSLUITest() {} 370 371 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 372 // Browser will ignore certificate errors. 373 command_line->AppendSwitch(switches::kIgnoreCertificateErrors); 374 } 375 }; 376 377 // Visits a regular page over http. 378 IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTP) { 379 ASSERT_TRUE(test_server()->Start()); 380 381 ui_test_utils::NavigateToURL(browser(), 382 test_server()->GetURL("files/ssl/google.html")); 383 384 CheckUnauthenticatedState( 385 browser()->tab_strip_model()->GetActiveWebContents()); 386 } 387 388 // Visits a page over http which includes broken https resources (status should 389 // be OK). 390 // TODO(jcampan): test that bad HTTPS content is blocked (otherwise we'll give 391 // the secure cookies away!). 392 IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTPWithBrokenHTTPSResource) { 393 ASSERT_TRUE(test_server()->Start()); 394 ASSERT_TRUE(https_server_expired_.Start()); 395 396 std::string replacement_path; 397 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( 398 "files/ssl/page_with_unsafe_contents.html", 399 https_server_expired_.host_port_pair(), 400 &replacement_path)); 401 402 ui_test_utils::NavigateToURL( 403 browser(), test_server()->GetURL(replacement_path)); 404 405 CheckUnauthenticatedState( 406 browser()->tab_strip_model()->GetActiveWebContents()); 407 } 408 409 IN_PROC_BROWSER_TEST_F(SSLUITest, TestBrokenHTTPSWithInsecureContent) { 410 ASSERT_TRUE(test_server()->Start()); 411 ASSERT_TRUE(https_server_expired_.Start()); 412 413 std::string replacement_path; 414 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( 415 "files/ssl/page_displays_insecure_content.html", 416 test_server()->host_port_pair(), 417 &replacement_path)); 418 419 ui_test_utils::NavigateToURL(browser(), 420 https_server_expired_.GetURL(replacement_path)); 421 422 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 423 CheckAuthenticationBrokenState( 424 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL); 425 426 ProceedThroughInterstitial(tab); 427 428 CheckAuthenticationBrokenState(tab, 429 net::CERT_STATUS_DATE_INVALID, 430 AuthState::DISPLAYED_INSECURE_CONTENT); 431 } 432 433 // http://crbug.com/91745 434 #if defined(OS_CHROMEOS) 435 #define MAYBE_TestOKHTTPS DISABLED_TestOKHTTPS 436 #else 437 #define MAYBE_TestOKHTTPS TestOKHTTPS 438 #endif 439 440 // Visits a page over OK https: 441 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestOKHTTPS) { 442 ASSERT_TRUE(https_server_.Start()); 443 444 ui_test_utils::NavigateToURL(browser(), 445 https_server_.GetURL("files/ssl/google.html")); 446 447 CheckAuthenticatedState(browser()->tab_strip_model()->GetActiveWebContents(), 448 AuthState::NONE); 449 } 450 451 // Visits a page with https error and proceed: 452 IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTPSExpiredCertAndProceed) { 453 ASSERT_TRUE(https_server_expired_.Start()); 454 455 ui_test_utils::NavigateToURL(browser(), 456 https_server_expired_.GetURL("files/ssl/google.html")); 457 458 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 459 CheckAuthenticationBrokenState( 460 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL); 461 462 ProceedThroughInterstitial(tab); 463 464 CheckAuthenticationBrokenState( 465 tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE); 466 } 467 468 #ifndef NEDBUG 469 // Flaky on Windows debug (http://crbug.com/280537). 470 #define MAYBE_TestHTTPSExpiredCertAndDontProceed \ 471 DISABLED_TestHTTPSExpiredCertAndDontProceed 472 #else 473 #define MAYBE_TestHTTPSExpiredCertAndDontProceed \ 474 TestHTTPSExpiredCertAndDontProceed 475 #endif 476 477 // Visits a page with https error and don't proceed (and ensure we can still 478 // navigate at that point): 479 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestHTTPSExpiredCertAndDontProceed) { 480 ASSERT_TRUE(test_server()->Start()); 481 ASSERT_TRUE(https_server_.Start()); 482 ASSERT_TRUE(https_server_expired_.Start()); 483 484 // First navigate to an OK page. 485 ui_test_utils::NavigateToURL(browser(), 486 https_server_.GetURL("files/ssl/google.html")); 487 488 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 489 NavigationEntry* entry = tab->GetController().GetActiveEntry(); 490 ASSERT_TRUE(entry); 491 492 GURL cross_site_url = 493 https_server_expired_.GetURL("files/ssl/google.html"); 494 // Change the host name from 127.0.0.1 to localhost so it triggers a 495 // cross-site navigation so we can test http://crbug.com/5800 is gone. 496 ASSERT_EQ("127.0.0.1", cross_site_url.host()); 497 GURL::Replacements replacements; 498 std::string new_host("localhost"); 499 replacements.SetHostStr(new_host); 500 cross_site_url = cross_site_url.ReplaceComponents(replacements); 501 502 // Now go to a bad HTTPS page. 503 ui_test_utils::NavigateToURL(browser(), cross_site_url); 504 505 // An interstitial should be showing. 506 CheckAuthenticationBrokenState(tab, 507 net::CERT_STATUS_COMMON_NAME_INVALID, 508 AuthState::SHOWING_INTERSTITIAL); 509 510 // Simulate user clicking "Take me back". 511 InterstitialPage* interstitial_page = tab->GetInterstitialPage(); 512 ASSERT_TRUE(interstitial_page); 513 interstitial_page->DontProceed(); 514 515 // We should be back to the original good page. 516 CheckAuthenticatedState(tab, AuthState::NONE); 517 518 // Try to navigate to a new page. (to make sure bug 5800 is fixed). 519 ui_test_utils::NavigateToURL(browser(), 520 test_server()->GetURL("files/ssl/google.html")); 521 CheckUnauthenticatedState(tab); 522 } 523 524 // Visits a page with https error and then goes back using Browser::GoBack. 525 IN_PROC_BROWSER_TEST_F(SSLUITest, 526 TestHTTPSExpiredCertAndGoBackViaButton) { 527 ASSERT_TRUE(test_server()->Start()); 528 ASSERT_TRUE(https_server_expired_.Start()); 529 530 // First navigate to an HTTP page. 531 ui_test_utils::NavigateToURL(browser(), 532 test_server()->GetURL("files/ssl/google.html")); 533 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 534 NavigationEntry* entry = tab->GetController().GetActiveEntry(); 535 ASSERT_TRUE(entry); 536 537 // Now go to a bad HTTPS page that shows an interstitial. 538 ui_test_utils::NavigateToURL(browser(), 539 https_server_expired_.GetURL("files/ssl/google.html")); 540 CheckAuthenticationBrokenState( 541 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL); 542 543 ProvisionalLoadWaiter load_failed_observer(tab); 544 545 // Simulate user clicking on back button (crbug.com/39248). 546 chrome::GoBack(browser(), CURRENT_TAB); 547 548 // Wait until we hear the load failure, and make sure we haven't swapped out 549 // the previous page. Prevents regression of http://crbug.com/82667. 550 load_failed_observer.Wait(); 551 EXPECT_FALSE(content::RenderViewHostTester::IsRenderViewHostSwappedOut( 552 tab->GetRenderViewHost())); 553 554 // We should be back at the original good page. 555 EXPECT_FALSE(browser()->tab_strip_model()->GetActiveWebContents()-> 556 GetInterstitialPage()); 557 CheckUnauthenticatedState(tab); 558 } 559 560 // Visits a page with https error and then goes back using GoToOffset. 561 // Disabled because its flaky: http://crbug.com/40932, http://crbug.com/43575. 562 IN_PROC_BROWSER_TEST_F(SSLUITest, 563 TestHTTPSExpiredCertAndGoBackViaMenu) { 564 ASSERT_TRUE(test_server()->Start()); 565 ASSERT_TRUE(https_server_expired_.Start()); 566 567 // First navigate to an HTTP page. 568 ui_test_utils::NavigateToURL(browser(), 569 test_server()->GetURL("files/ssl/google.html")); 570 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 571 NavigationEntry* entry = tab->GetController().GetActiveEntry(); 572 ASSERT_TRUE(entry); 573 574 // Now go to a bad HTTPS page that shows an interstitial. 575 ui_test_utils::NavigateToURL(browser(), 576 https_server_expired_.GetURL("files/ssl/google.html")); 577 CheckAuthenticationBrokenState( 578 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL); 579 580 // Simulate user clicking and holding on back button (crbug.com/37215). 581 tab->GetController().GoToOffset(-1); 582 583 // We should be back at the original good page. 584 EXPECT_FALSE(browser()->tab_strip_model()->GetActiveWebContents()-> 585 GetInterstitialPage()); 586 CheckUnauthenticatedState(tab); 587 } 588 589 // Visits a page with https error and then goes forward using GoToOffset. 590 IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTPSExpiredCertAndGoForward) { 591 ASSERT_TRUE(test_server()->Start()); 592 ASSERT_TRUE(https_server_expired_.Start()); 593 594 // First navigate to two HTTP pages. 595 ui_test_utils::NavigateToURL(browser(), 596 test_server()->GetURL("files/ssl/google.html")); 597 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 598 NavigationEntry* entry1 = tab->GetController().GetActiveEntry(); 599 ASSERT_TRUE(entry1); 600 ui_test_utils::NavigateToURL(browser(), 601 test_server()->GetURL("files/ssl/blank_page.html")); 602 NavigationEntry* entry2 = tab->GetController().GetActiveEntry(); 603 ASSERT_TRUE(entry2); 604 605 // Now go back so that a page is in the forward history. 606 { 607 content::WindowedNotificationObserver observer( 608 content::NOTIFICATION_LOAD_STOP, 609 content::Source<NavigationController>(&tab->GetController())); 610 tab->GetController().GoBack(); 611 observer.Wait(); 612 } 613 ASSERT_TRUE(tab->GetController().CanGoForward()); 614 NavigationEntry* entry3 = tab->GetController().GetActiveEntry(); 615 ASSERT_TRUE(entry1 == entry3); 616 617 // Now go to a bad HTTPS page that shows an interstitial. 618 ui_test_utils::NavigateToURL(browser(), 619 https_server_expired_.GetURL("files/ssl/google.html")); 620 CheckAuthenticationBrokenState( 621 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL); 622 623 // Simulate user clicking and holding on forward button. 624 { 625 content::WindowedNotificationObserver observer( 626 content::NOTIFICATION_LOAD_STOP, 627 content::Source<NavigationController>(&tab->GetController())); 628 tab->GetController().GoToOffset(1); 629 observer.Wait(); 630 } 631 632 // We should be showing the second good page. 633 EXPECT_FALSE(browser()->tab_strip_model()->GetActiveWebContents()-> 634 GetInterstitialPage()); 635 CheckUnauthenticatedState(tab); 636 EXPECT_FALSE(tab->GetController().CanGoForward()); 637 NavigationEntry* entry4 = tab->GetController().GetActiveEntry(); 638 EXPECT_TRUE(entry2 == entry4); 639 } 640 641 // Visit a HTTP page which request WSS connection to a server providing invalid 642 // certificate. Close the page while WSS connection waits for SSLManager's 643 // response from UI thread. 644 // Disabled on Windows because it was flaking on XP Tests (1). crbug.com/165258 645 // Disabled under LeakSanitizer due to memory leaks. http://crbug.com/317363 646 #if defined(OS_WIN) || defined(LEAK_SANITIZER) 647 #define MAYBE_TestWSSInvalidCertAndClose DISABLED_TestWSSInvalidCertAndClose 648 #else 649 #define MAYBE_TestWSSInvalidCertAndClose TestWSSInvalidCertAndClose 650 #endif 651 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestWSSInvalidCertAndClose) { 652 ASSERT_TRUE(test_server()->Start()); 653 ASSERT_TRUE(wss_server_expired_.Start()); 654 655 // Setup page title observer. 656 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 657 content::TitleWatcher watcher(tab, ASCIIToUTF16("PASS")); 658 watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL")); 659 660 // Create GURLs to test pages. 661 std::string master_url_path = base::StringPrintf("%s?%d", 662 test_server()->GetURL("files/ssl/wss_close.html").spec().c_str(), 663 wss_server_expired_.host_port_pair().port()); 664 GURL master_url(master_url_path); 665 std::string slave_url_path = base::StringPrintf("%s?%d", 666 test_server()->GetURL("files/ssl/wss_close_slave.html").spec().c_str(), 667 wss_server_expired_.host_port_pair().port()); 668 GURL slave_url(slave_url_path); 669 670 // Create tabs and visit pages which keep on creating wss connections. 671 WebContents* tabs[16]; 672 for (int i = 0; i < 16; ++i) { 673 tabs[i] = chrome::AddSelectedTabWithURL(browser(), slave_url, 674 content::PAGE_TRANSITION_LINK); 675 } 676 chrome::SelectNextTab(browser()); 677 678 // Visit a page which waits for one TLS handshake failure. 679 // The title will be changed to 'PASS'. 680 ui_test_utils::NavigateToURL(browser(), master_url); 681 const base::string16 result = watcher.WaitAndGetTitle(); 682 EXPECT_TRUE(LowerCaseEqualsASCII(result, "pass")); 683 684 // Close tabs which contains the test page. 685 for (int i = 0; i < 16; ++i) 686 chrome::CloseWebContents(browser(), tabs[i], false); 687 chrome::CloseWebContents(browser(), tab, false); 688 } 689 690 // Visit a HTTPS page and proceeds despite an invalid certificate. The page 691 // requests WSS connection to the same origin host to check if WSS connection 692 // share certificates policy with HTTPS correcly. 693 IN_PROC_BROWSER_TEST_F(SSLUITest, TestWSSInvalidCertAndGoForward) { 694 ASSERT_TRUE(test_server()->Start()); 695 ASSERT_TRUE(wss_server_expired_.Start()); 696 697 // Setup page title observer. 698 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 699 content::TitleWatcher watcher(tab, ASCIIToUTF16("PASS")); 700 watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL")); 701 702 // Visit bad HTTPS page. 703 std::string scheme("https"); 704 GURL::Replacements replacements; 705 replacements.SetSchemeStr(scheme); 706 ui_test_utils::NavigateToURL( 707 browser(), 708 wss_server_expired_.GetURL( 709 "connect_check.html").ReplaceComponents(replacements)); 710 CheckAuthenticationBrokenState( 711 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL); 712 713 // Proceed anyway. 714 ProceedThroughInterstitial(tab); 715 716 // Test page run a WebSocket wss connection test. The result will be shown 717 // as page title. 718 const base::string16 result = watcher.WaitAndGetTitle(); 719 EXPECT_TRUE(LowerCaseEqualsASCII(result, "pass")); 720 } 721 722 #if defined(USE_NSS) 723 // SSL client certificate tests are only enabled when using NSS for private key 724 // storage, as only NSS can avoid modifying global machine state when testing. 725 // See http://crbug.com/51132 726 727 // Visit a HTTPS page which requires client cert authentication. The client 728 // cert will be selected automatically, then a test which uses WebSocket runs. 729 // Disabled: http://crbug.com/159985 730 IN_PROC_BROWSER_TEST_F(SSLUITest, DISABLED_TestWSSClientCert) { 731 // Open a temporary NSS DB for testing. 732 crypto::ScopedTestNSSDB test_nssdb; 733 ASSERT_TRUE(test_nssdb.is_open()); 734 735 // Import client cert for test. These interfaces require NSS. 736 net::NSSCertDatabase* cert_db = net::NSSCertDatabase::GetInstance(); 737 scoped_refptr<net::CryptoModule> crypt_module = cert_db->GetPublicModule(); 738 std::string pkcs12_data; 739 base::FilePath cert_path = net::GetTestCertsDirectory().Append( 740 FILE_PATH_LITERAL("websocket_client_cert.p12")); 741 EXPECT_TRUE(base::ReadFileToString(cert_path, &pkcs12_data)); 742 EXPECT_EQ(net::OK, 743 cert_db->ImportFromPKCS12( 744 crypt_module.get(), pkcs12_data, base::string16(), true, NULL)); 745 746 // Start WebSocket test server with TLS and client cert authentication. 747 net::SpawnedTestServer::SSLOptions options( 748 net::SpawnedTestServer::SSLOptions::CERT_OK); 749 options.request_client_certificate = true; 750 base::FilePath ca_path = net::GetTestCertsDirectory().Append( 751 FILE_PATH_LITERAL("websocket_cacert.pem")); 752 options.client_authorities.push_back(ca_path); 753 net::SpawnedTestServer wss_server(net::SpawnedTestServer::TYPE_WSS, 754 options, 755 net::GetWebSocketTestDataDirectory()); 756 ASSERT_TRUE(wss_server.Start()); 757 std::string scheme("https"); 758 GURL::Replacements replacements; 759 replacements.SetSchemeStr(scheme); 760 GURL url = wss_server.GetURL("connect_check.html").ReplaceComponents( 761 replacements); 762 763 // Setup page title observer. 764 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 765 content::TitleWatcher watcher(tab, ASCIIToUTF16("PASS")); 766 watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL")); 767 768 // Add an entry into AutoSelectCertificateForUrls policy for automatic client 769 // cert selection. 770 Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext()); 771 DCHECK(profile); 772 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); 773 dict->SetString("ISSUER.CN", "pywebsocket"); 774 profile->GetHostContentSettingsMap()->SetWebsiteSetting( 775 ContentSettingsPattern::FromURL(url), 776 ContentSettingsPattern::FromURL(url), 777 CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE, 778 std::string(), 779 dict.release()); 780 781 // Visit a HTTPS page which requires client certs. 782 ui_test_utils::NavigateToURL(browser(), url); 783 CheckAuthenticatedState(tab, AuthState::NONE); 784 785 // Test page runs a WebSocket wss connection test. The result will be shown 786 // as page title. 787 const base::string16 result = watcher.WaitAndGetTitle(); 788 EXPECT_TRUE(LowerCaseEqualsASCII(result, "pass")); 789 } 790 #endif // defined(USE_NSS) 791 792 // Flaky on CrOS http://crbug.com/92292 793 #if defined(OS_CHROMEOS) 794 #define MAYBE_TestHTTPSErrorWithNoNavEntry \ 795 DISABLED_TestHTTPSErrorWithNoNavEntry 796 #else 797 #define MAYBE_TestHTTPSErrorWithNoNavEntry TestHTTPSErrorWithNoNavEntry 798 #endif // defined(OS_CHROMEOS) 799 800 // Open a page with a HTTPS error in a tab with no prior navigation (through a 801 // link with a blank target). This is to test that the lack of navigation entry 802 // does not cause any problems (it was causing a crasher, see 803 // http://crbug.com/19941). 804 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestHTTPSErrorWithNoNavEntry) { 805 ASSERT_TRUE(https_server_expired_.Start()); 806 807 GURL url = https_server_expired_.GetURL("files/ssl/google.htm"); 808 WebContents* tab2 = chrome::AddSelectedTabWithURL( 809 browser(), url, content::PAGE_TRANSITION_TYPED); 810 content::WaitForLoadStop(tab2); 811 812 // Verify our assumption that there was no prior navigation. 813 EXPECT_FALSE(chrome::CanGoBack(browser())); 814 815 // We should have an interstitial page showing. 816 ASSERT_TRUE(tab2->GetInterstitialPage()); 817 } 818 819 IN_PROC_BROWSER_TEST_F(SSLUITest, TestBadHTTPSDownload) { 820 ASSERT_TRUE(test_server()->Start()); 821 ASSERT_TRUE(https_server_expired_.Start()); 822 GURL url_non_dangerous = test_server()->GetURL(std::string()); 823 GURL url_dangerous = 824 https_server_expired_.GetURL("files/downloads/dangerous/dangerous.exe"); 825 base::ScopedTempDir downloads_directory_; 826 827 // Need empty temp dir to avoid having Chrome ask us for a new filename 828 // when we've downloaded dangerous.exe one hundred times. 829 ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir()); 830 831 browser()->profile()->GetPrefs()->SetFilePath( 832 prefs::kDownloadDefaultDirectory, 833 downloads_directory_.path()); 834 835 // Visit a non-dangerous page. 836 ui_test_utils::NavigateToURL(browser(), url_non_dangerous); 837 838 // Now, start a transition to dangerous download. 839 { 840 content::WindowedNotificationObserver observer( 841 content::NOTIFICATION_LOAD_STOP, 842 content::NotificationService::AllSources()); 843 chrome::NavigateParams navigate_params(browser(), url_dangerous, 844 content::PAGE_TRANSITION_TYPED); 845 chrome::Navigate(&navigate_params); 846 observer.Wait(); 847 } 848 849 // To exit the browser cleanly (and this test) we need to complete the 850 // download after completing this test. 851 content::DownloadTestObserverTerminal dangerous_download_observer( 852 content::BrowserContext::GetDownloadManager(browser()->profile()), 853 1, 854 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_ACCEPT); 855 856 // Proceed through the SSL interstitial. This doesn't use 857 // |ProceedThroughInterstitial| since no page load will commit. 858 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 859 ASSERT_TRUE(tab != NULL); 860 ASSERT_TRUE(tab->GetInterstitialPage() != NULL); 861 { 862 content::WindowedNotificationObserver observer( 863 chrome::NOTIFICATION_DOWNLOAD_INITIATED, 864 content::NotificationService::AllSources()); 865 tab->GetInterstitialPage()->Proceed(); 866 observer.Wait(); 867 } 868 869 // There should still be an interstitial at this point. Press the 870 // back button on the browser. Note that this doesn't wait for a 871 // NAV_ENTRY_COMMITTED notification because going back with an 872 // active interstitial simply hides the interstitial. 873 ASSERT_TRUE(tab->GetInterstitialPage() != NULL); 874 EXPECT_TRUE(chrome::CanGoBack(browser())); 875 chrome::GoBack(browser(), CURRENT_TAB); 876 877 dangerous_download_observer.WaitForFinished(); 878 } 879 880 // 881 // Insecure content 882 // 883 884 #if defined(OS_WIN) 885 // http://crbug.com/152940 Flaky on win. 886 #define MAYBE_TestDisplaysInsecureContent DISABLED_TestDisplaysInsecureContent 887 #else 888 #define MAYBE_TestDisplaysInsecureContent TestDisplaysInsecureContent 889 #endif 890 891 // Visits a page that displays insecure content. 892 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestDisplaysInsecureContent) { 893 ASSERT_TRUE(test_server()->Start()); 894 ASSERT_TRUE(https_server_.Start()); 895 896 std::string replacement_path; 897 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( 898 "files/ssl/page_displays_insecure_content.html", 899 test_server()->host_port_pair(), 900 &replacement_path)); 901 902 // Load a page that displays insecure content. 903 ui_test_utils::NavigateToURL(browser(), 904 https_server_.GetURL(replacement_path)); 905 906 CheckAuthenticatedState(browser()->tab_strip_model()->GetActiveWebContents(), 907 AuthState::DISPLAYED_INSECURE_CONTENT); 908 } 909 910 // Visits a page that runs insecure content and tries to suppress the insecure 911 // content warnings by randomizing location.hash. 912 // Based on http://crbug.com/8706 913 IN_PROC_BROWSER_TEST_F(SSLUITest, 914 TestRunsInsecuredContentRandomizeHash) { 915 ASSERT_TRUE(test_server()->Start()); 916 ASSERT_TRUE(https_server_.Start()); 917 918 ui_test_utils::NavigateToURL(browser(), https_server_.GetURL( 919 "files/ssl/page_runs_insecure_content.html")); 920 921 CheckAuthenticationBrokenState( 922 browser()->tab_strip_model()->GetActiveWebContents(), 923 CertError::NONE, 924 AuthState::DISPLAYED_INSECURE_CONTENT | AuthState::RAN_INSECURE_CONTENT); 925 } 926 927 // Visits a page with unsafe content and make sure that: 928 // - frames content is replaced with warning 929 // - images and scripts are filtered out entirely 930 IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContents) { 931 ASSERT_TRUE(https_server_.Start()); 932 ASSERT_TRUE(https_server_expired_.Start()); 933 934 std::string replacement_path; 935 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( 936 "files/ssl/page_with_unsafe_contents.html", 937 https_server_expired_.host_port_pair(), 938 &replacement_path)); 939 ui_test_utils::NavigateToURL(browser(), 940 https_server_.GetURL(replacement_path)); 941 942 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 943 // When the bad content is filtered, the state is expected to be 944 // authenticated. 945 CheckAuthenticatedState(tab, AuthState::NONE); 946 947 // Because of cross-frame scripting restrictions, we cannot access the iframe 948 // content. So to know if the frame was loaded, we just check if a popup was 949 // opened (the iframe content opens one). 950 // Note: because of bug 1115868, no web contents modal dialog is opened right 951 // now. Once the bug is fixed, this will do the real check. 952 EXPECT_FALSE(IsShowingWebContentsModalDialog()); 953 954 int img_width; 955 EXPECT_TRUE(content::ExecuteScriptAndExtractInt( 956 tab, 957 "window.domAutomationController.send(ImageWidth());", 958 &img_width)); 959 // In order to check that the image was not loaded, we check its width. 960 // The actual image (Google logo) is 114 pixels wide, we assume the broken 961 // image is less than 100. 962 EXPECT_LT(img_width, 100); 963 964 bool js_result = false; 965 EXPECT_TRUE(content::ExecuteScriptAndExtractBool( 966 tab, 967 "window.domAutomationController.send(IsFooSet());", 968 &js_result)); 969 EXPECT_FALSE(js_result); 970 } 971 972 // Visits a page with insecure content loaded by JS (after the initial page 973 // load). 974 IN_PROC_BROWSER_TEST_F(SSLUITest, TestDisplaysInsecureContentLoadedFromJS) { 975 ASSERT_TRUE(test_server()->Start()); 976 ASSERT_TRUE(https_server_.Start()); 977 978 std::string replacement_path; 979 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( 980 "files/ssl/page_with_dynamic_insecure_content.html", 981 test_server()->host_port_pair(), 982 &replacement_path)); 983 ui_test_utils::NavigateToURL(browser(), https_server_.GetURL( 984 replacement_path)); 985 986 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 987 CheckAuthenticatedState(tab, AuthState::NONE); 988 989 // Load the insecure image. 990 bool js_result = false; 991 EXPECT_TRUE(content::ExecuteScriptAndExtractBool( 992 tab, 993 "loadBadImage();", 994 &js_result)); 995 EXPECT_TRUE(js_result); 996 997 // We should now have insecure content. 998 CheckAuthenticatedState(tab, AuthState::DISPLAYED_INSECURE_CONTENT); 999 } 1000 1001 // Visits two pages from the same origin: one that displays insecure content and 1002 // one that doesn't. The test checks that we do not propagate the insecure 1003 // content state from one to the other. 1004 IN_PROC_BROWSER_TEST_F(SSLUITest, TestDisplaysInsecureContentTwoTabs) { 1005 ASSERT_TRUE(test_server()->Start()); 1006 ASSERT_TRUE(https_server_.Start()); 1007 1008 ui_test_utils::NavigateToURL(browser(), 1009 https_server_.GetURL("files/ssl/blank_page.html")); 1010 1011 WebContents* tab1 = browser()->tab_strip_model()->GetActiveWebContents(); 1012 1013 // This tab should be fine. 1014 CheckAuthenticatedState(tab1, AuthState::NONE); 1015 1016 // Create a new tab. 1017 std::string replacement_path; 1018 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( 1019 "files/ssl/page_displays_insecure_content.html", 1020 test_server()->host_port_pair(), 1021 &replacement_path)); 1022 1023 GURL url = https_server_.GetURL(replacement_path); 1024 chrome::NavigateParams params(browser(), url, content::PAGE_TRANSITION_TYPED); 1025 params.disposition = NEW_FOREGROUND_TAB; 1026 params.tabstrip_index = 0; 1027 params.source_contents = tab1; 1028 content::WindowedNotificationObserver observer( 1029 content::NOTIFICATION_LOAD_STOP, 1030 content::NotificationService::AllSources()); 1031 chrome::Navigate(¶ms); 1032 WebContents* tab2 = params.target_contents; 1033 observer.Wait(); 1034 1035 // The new tab has insecure content. 1036 CheckAuthenticatedState(tab2, AuthState::DISPLAYED_INSECURE_CONTENT); 1037 1038 // The original tab should not be contaminated. 1039 CheckAuthenticatedState(tab1, AuthState::NONE); 1040 } 1041 1042 // Visits two pages from the same origin: one that runs insecure content and one 1043 // that doesn't. The test checks that we propagate the insecure content state 1044 // from one to the other. 1045 IN_PROC_BROWSER_TEST_F(SSLUITest, TestRunsInsecureContentTwoTabs) { 1046 ASSERT_TRUE(test_server()->Start()); 1047 ASSERT_TRUE(https_server_.Start()); 1048 1049 ui_test_utils::NavigateToURL(browser(), 1050 https_server_.GetURL("files/ssl/blank_page.html")); 1051 1052 WebContents* tab1 = browser()->tab_strip_model()->GetActiveWebContents(); 1053 1054 // This tab should be fine. 1055 CheckAuthenticatedState(tab1, AuthState::NONE); 1056 1057 std::string replacement_path; 1058 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( 1059 "files/ssl/page_runs_insecure_content.html", 1060 test_server()->host_port_pair(), 1061 &replacement_path)); 1062 1063 // Create a new tab in the same process. Using a NEW_FOREGROUND_TAB 1064 // disposition won't usually stay in the same process, but this works 1065 // because we are using process-per-site in SetUpCommandLine. 1066 GURL url = https_server_.GetURL(replacement_path); 1067 chrome::NavigateParams params(browser(), url, content::PAGE_TRANSITION_TYPED); 1068 params.disposition = NEW_FOREGROUND_TAB; 1069 params.source_contents = tab1; 1070 content::WindowedNotificationObserver observer( 1071 content::NOTIFICATION_LOAD_STOP, 1072 content::NotificationService::AllSources()); 1073 chrome::Navigate(¶ms); 1074 WebContents* tab2 = params.target_contents; 1075 observer.Wait(); 1076 1077 // Both tabs should have the same process. 1078 EXPECT_EQ(tab1->GetRenderProcessHost(), tab2->GetRenderProcessHost()); 1079 1080 // The new tab has insecure content. 1081 CheckAuthenticationBrokenState( 1082 tab2, 1083 CertError::NONE, 1084 AuthState::DISPLAYED_INSECURE_CONTENT | AuthState::RAN_INSECURE_CONTENT); 1085 1086 // Which means the origin for the first tab has also been contaminated with 1087 // insecure content. 1088 CheckAuthenticationBrokenState( 1089 tab1, CertError::NONE, AuthState::RAN_INSECURE_CONTENT); 1090 } 1091 1092 // Visits a page with an image over http. Visits another page over https 1093 // referencing that same image over http (hoping it is coming from the webcore 1094 // memory cache). 1095 IN_PROC_BROWSER_TEST_F(SSLUITest, TestDisplaysCachedInsecureContent) { 1096 ASSERT_TRUE(test_server()->Start()); 1097 ASSERT_TRUE(https_server_.Start()); 1098 1099 std::string replacement_path; 1100 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( 1101 "files/ssl/page_displays_insecure_content.html", 1102 test_server()->host_port_pair(), 1103 &replacement_path)); 1104 1105 // Load original page over HTTP. 1106 const GURL url_http = test_server()->GetURL(replacement_path); 1107 ui_test_utils::NavigateToURL(browser(), url_http); 1108 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1109 CheckUnauthenticatedState(tab); 1110 1111 // Load again but over SSL. It should be marked as displaying insecure 1112 // content (even though the image comes from the WebCore memory cache). 1113 const GURL url_https = https_server_.GetURL(replacement_path); 1114 ui_test_utils::NavigateToURL(browser(), url_https); 1115 CheckAuthenticatedState(tab, AuthState::DISPLAYED_INSECURE_CONTENT); 1116 } 1117 1118 // http://crbug.com/84729 1119 #if defined(OS_CHROMEOS) 1120 #define MAYBE_TestRunsCachedInsecureContent \ 1121 DISABLED_TestRunsCachedInsecureContent 1122 #else 1123 #define MAYBE_TestRunsCachedInsecureContent TestRunsCachedInsecureContent 1124 #endif // defined(OS_CHROMEOS) 1125 1126 // Visits a page with script over http. Visits another page over https 1127 // referencing that same script over http (hoping it is coming from the webcore 1128 // memory cache). 1129 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestRunsCachedInsecureContent) { 1130 ASSERT_TRUE(test_server()->Start()); 1131 ASSERT_TRUE(https_server_.Start()); 1132 1133 std::string replacement_path; 1134 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( 1135 "files/ssl/page_runs_insecure_content.html", 1136 test_server()->host_port_pair(), 1137 &replacement_path)); 1138 1139 // Load original page over HTTP. 1140 const GURL url_http = test_server()->GetURL(replacement_path); 1141 ui_test_utils::NavigateToURL(browser(), url_http); 1142 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1143 CheckUnauthenticatedState(tab); 1144 1145 // Load again but over SSL. It should be marked as displaying insecure 1146 // content (even though the image comes from the WebCore memory cache). 1147 const GURL url_https = https_server_.GetURL(replacement_path); 1148 ui_test_utils::NavigateToURL(browser(), url_https); 1149 CheckAuthenticationBrokenState( 1150 tab, 1151 CertError::NONE, 1152 AuthState::DISPLAYED_INSECURE_CONTENT | AuthState::RAN_INSECURE_CONTENT); 1153 } 1154 1155 #if defined(OS_WIN) 1156 // Flaky on Win7 debug (http://crbug.com/368280). 1157 #define MAYBE_TestCNInvalidStickiness DISABLED_TestCNInvalidStickiness 1158 #else 1159 #define MAYBE_TestCNInvalidStickiness TestCNInvalidStickiness 1160 #endif 1161 // This test ensures the CN invalid status does not 'stick' to a certificate 1162 // (see bug #1044942) and that it depends on the host-name. 1163 IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestCNInvalidStickiness) { 1164 ASSERT_TRUE(https_server_.Start()); 1165 ASSERT_TRUE(https_server_mismatched_.Start()); 1166 1167 // First we hit the server with hostname, this generates an invalid policy 1168 // error. 1169 ui_test_utils::NavigateToURL(browser(), 1170 https_server_mismatched_.GetURL("files/ssl/google.html")); 1171 1172 // We get an interstitial page as a result. 1173 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1174 CheckAuthenticationBrokenState(tab, 1175 net::CERT_STATUS_COMMON_NAME_INVALID, 1176 AuthState::SHOWING_INTERSTITIAL); 1177 ProceedThroughInterstitial(tab); 1178 CheckAuthenticationBrokenState( 1179 tab, net::CERT_STATUS_COMMON_NAME_INVALID, AuthState::NONE); 1180 1181 // Now we try again with the right host name this time. 1182 GURL url(https_server_.GetURL("files/ssl/google.html")); 1183 ui_test_utils::NavigateToURL(browser(), url); 1184 1185 // Security state should be OK. 1186 CheckAuthenticatedState(tab, AuthState::NONE); 1187 1188 // Now try again the broken one to make sure it is still broken. 1189 ui_test_utils::NavigateToURL(browser(), 1190 https_server_mismatched_.GetURL("files/ssl/google.html")); 1191 1192 // Since we OKed the interstitial last time, we get right to the page. 1193 CheckAuthenticationBrokenState( 1194 tab, net::CERT_STATUS_COMMON_NAME_INVALID, AuthState::NONE); 1195 } 1196 1197 #if defined(OS_CHROMEOS) 1198 // This test seems to be flaky and hang on chromiumos. 1199 // http://crbug.com/84419 1200 #define MAYBE_TestRefNavigation DISABLED_TestRefNavigation 1201 #else 1202 #define MAYBE_TestRefNavigation TestRefNavigation 1203 #endif 1204 1205 // Test that navigating to a #ref does not change a bad security state. 1206 IN_PROC_BROWSER_TEST_F(SSLUITest, TestRefNavigation) { 1207 ASSERT_TRUE(https_server_expired_.Start()); 1208 1209 ui_test_utils::NavigateToURL(browser(), 1210 https_server_expired_.GetURL("files/ssl/page_with_refs.html")); 1211 1212 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1213 CheckAuthenticationBrokenState( 1214 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL); 1215 1216 ProceedThroughInterstitial(tab); 1217 1218 CheckAuthenticationBrokenState( 1219 tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE); 1220 // Now navigate to a ref in the page, the security state should not have 1221 // changed. 1222 ui_test_utils::NavigateToURL(browser(), 1223 https_server_expired_.GetURL("files/ssl/page_with_refs.html#jp")); 1224 1225 CheckAuthenticationBrokenState( 1226 tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE); 1227 } 1228 1229 // Tests that closing a page that has a unsafe pop-up does not crash the 1230 // browser (bug #1966). 1231 // TODO(jcampan): http://crbug.com/2136 disabled because the popup is not 1232 // opened as it is not initiated by a user gesture. 1233 IN_PROC_BROWSER_TEST_F(SSLUITest, DISABLED_TestCloseTabWithUnsafePopup) { 1234 ASSERT_TRUE(test_server()->Start()); 1235 ASSERT_TRUE(https_server_expired_.Start()); 1236 1237 std::string replacement_path; 1238 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( 1239 "files/ssl/page_with_unsafe_popup.html", 1240 https_server_expired_.host_port_pair(), 1241 &replacement_path)); 1242 1243 ui_test_utils::NavigateToURL(browser(), 1244 test_server()->GetURL(replacement_path)); 1245 1246 WebContents* tab1 = browser()->tab_strip_model()->GetActiveWebContents(); 1247 // It is probably overkill to add a notification for a popup-opening, let's 1248 // just poll. 1249 for (int i = 0; i < 10; i++) { 1250 if (IsShowingWebContentsModalDialog()) 1251 break; 1252 base::MessageLoop::current()->PostDelayedTask( 1253 FROM_HERE, 1254 base::MessageLoop::QuitClosure(), 1255 base::TimeDelta::FromSeconds(1)); 1256 content::RunMessageLoop(); 1257 } 1258 ASSERT_TRUE(IsShowingWebContentsModalDialog()); 1259 1260 // Let's add another tab to make sure the browser does not exit when we close 1261 // the first tab. 1262 GURL url = test_server()->GetURL("files/ssl/google.html"); 1263 content::WindowedNotificationObserver observer( 1264 content::NOTIFICATION_LOAD_STOP, 1265 content::NotificationService::AllSources()); 1266 chrome::AddSelectedTabWithURL(browser(), url, content::PAGE_TRANSITION_TYPED); 1267 observer.Wait(); 1268 1269 // Close the first tab. 1270 chrome::CloseWebContents(browser(), tab1, false); 1271 } 1272 1273 // Visit a page over bad https that is a redirect to a page with good https. 1274 IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectBadToGoodHTTPS) { 1275 ASSERT_TRUE(https_server_.Start()); 1276 ASSERT_TRUE(https_server_expired_.Start()); 1277 1278 GURL url1 = https_server_expired_.GetURL("server-redirect?"); 1279 GURL url2 = https_server_.GetURL("files/ssl/google.html"); 1280 1281 ui_test_utils::NavigateToURL(browser(), GURL(url1.spec() + url2.spec())); 1282 1283 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1284 1285 CheckAuthenticationBrokenState( 1286 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL); 1287 1288 ProceedThroughInterstitial(tab); 1289 1290 // We have been redirected to the good page. 1291 CheckAuthenticatedState(tab, AuthState::NONE); 1292 } 1293 1294 // Visit a page over good https that is a redirect to a page with bad https. 1295 IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectGoodToBadHTTPS) { 1296 ASSERT_TRUE(https_server_.Start()); 1297 ASSERT_TRUE(https_server_expired_.Start()); 1298 1299 GURL url1 = https_server_.GetURL("server-redirect?"); 1300 GURL url2 = https_server_expired_.GetURL("files/ssl/google.html"); 1301 ui_test_utils::NavigateToURL(browser(), GURL(url1.spec() + url2.spec())); 1302 1303 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1304 CheckAuthenticationBrokenState( 1305 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL); 1306 1307 ProceedThroughInterstitial(tab); 1308 1309 CheckAuthenticationBrokenState( 1310 tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE); 1311 } 1312 1313 // Visit a page over http that is a redirect to a page with good HTTPS. 1314 IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectHTTPToGoodHTTPS) { 1315 ASSERT_TRUE(test_server()->Start()); 1316 ASSERT_TRUE(https_server_.Start()); 1317 1318 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1319 1320 // HTTP redirects to good HTTPS. 1321 GURL http_url = test_server()->GetURL("server-redirect?"); 1322 GURL good_https_url = 1323 https_server_.GetURL("files/ssl/google.html"); 1324 1325 ui_test_utils::NavigateToURL(browser(), 1326 GURL(http_url.spec() + good_https_url.spec())); 1327 CheckAuthenticatedState(tab, AuthState::NONE); 1328 } 1329 1330 // Visit a page over http that is a redirect to a page with bad HTTPS. 1331 IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectHTTPToBadHTTPS) { 1332 ASSERT_TRUE(test_server()->Start()); 1333 ASSERT_TRUE(https_server_expired_.Start()); 1334 1335 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1336 1337 GURL http_url = test_server()->GetURL("server-redirect?"); 1338 GURL bad_https_url = 1339 https_server_expired_.GetURL("files/ssl/google.html"); 1340 ui_test_utils::NavigateToURL(browser(), 1341 GURL(http_url.spec() + bad_https_url.spec())); 1342 CheckAuthenticationBrokenState( 1343 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL); 1344 1345 ProceedThroughInterstitial(tab); 1346 1347 CheckAuthenticationBrokenState( 1348 tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE); 1349 } 1350 1351 // Visit a page over https that is a redirect to a page with http (to make sure 1352 // we don't keep the secure state). 1353 IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectHTTPSToHTTP) { 1354 ASSERT_TRUE(test_server()->Start()); 1355 ASSERT_TRUE(https_server_.Start()); 1356 1357 GURL https_url = https_server_.GetURL("server-redirect?"); 1358 GURL http_url = test_server()->GetURL("files/ssl/google.html"); 1359 1360 ui_test_utils::NavigateToURL(browser(), 1361 GURL(https_url.spec() + http_url.spec())); 1362 CheckUnauthenticatedState( 1363 browser()->tab_strip_model()->GetActiveWebContents()); 1364 } 1365 1366 // Visits a page to which we could not connect (bad port) over http and https 1367 // and make sure the security style is correct. 1368 IN_PROC_BROWSER_TEST_F(SSLUITest, TestConnectToBadPort) { 1369 ui_test_utils::NavigateToURL(browser(), GURL("http://localhost:17")); 1370 CheckUnauthenticatedState( 1371 browser()->tab_strip_model()->GetActiveWebContents()); 1372 1373 // Same thing over HTTPS. 1374 ui_test_utils::NavigateToURL(browser(), GURL("https://localhost:17")); 1375 CheckUnauthenticatedState( 1376 browser()->tab_strip_model()->GetActiveWebContents()); 1377 } 1378 1379 // 1380 // Frame navigation 1381 // 1382 1383 // From a good HTTPS top frame: 1384 // - navigate to an OK HTTPS frame 1385 // - navigate to a bad HTTPS (expect unsafe content and filtered frame), then 1386 // back 1387 // - navigate to HTTP (expect insecure content), then back 1388 IN_PROC_BROWSER_TEST_F(SSLUITest, TestGoodFrameNavigation) { 1389 ASSERT_TRUE(test_server()->Start()); 1390 ASSERT_TRUE(https_server_.Start()); 1391 ASSERT_TRUE(https_server_expired_.Start()); 1392 1393 std::string top_frame_path; 1394 ASSERT_TRUE(GetTopFramePath(*test_server(), 1395 https_server_, 1396 https_server_expired_, 1397 &top_frame_path)); 1398 1399 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1400 ui_test_utils::NavigateToURL(browser(), 1401 https_server_.GetURL(top_frame_path)); 1402 1403 CheckAuthenticatedState(tab, AuthState::NONE); 1404 1405 bool success = false; 1406 // Now navigate inside the frame. 1407 { 1408 content::WindowedNotificationObserver observer( 1409 content::NOTIFICATION_LOAD_STOP, 1410 content::Source<NavigationController>(&tab->GetController())); 1411 EXPECT_TRUE(content::ExecuteScriptAndExtractBool( 1412 tab, 1413 "window.domAutomationController.send(clickLink('goodHTTPSLink'));", 1414 &success)); 1415 ASSERT_TRUE(success); 1416 observer.Wait(); 1417 } 1418 1419 // We should still be fine. 1420 CheckAuthenticatedState(tab, AuthState::NONE); 1421 1422 // Now let's hit a bad page. 1423 { 1424 content::WindowedNotificationObserver observer( 1425 content::NOTIFICATION_LOAD_STOP, 1426 content::Source<NavigationController>(&tab->GetController())); 1427 EXPECT_TRUE(content::ExecuteScriptAndExtractBool( 1428 tab, 1429 "window.domAutomationController.send(clickLink('badHTTPSLink'));", 1430 &success)); 1431 ASSERT_TRUE(success); 1432 observer.Wait(); 1433 } 1434 1435 // The security style should still be secure. 1436 CheckAuthenticatedState(tab, AuthState::NONE); 1437 1438 // And the frame should be blocked. 1439 bool is_content_evil = true; 1440 content::RenderFrameHost* content_frame = content::FrameMatchingPredicate( 1441 tab, base::Bind(&content::FrameMatchesName, "contentFrame")); 1442 std::string is_evil_js("window.domAutomationController.send(" 1443 "document.getElementById('evilDiv') != null);"); 1444 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(content_frame, 1445 is_evil_js, 1446 &is_content_evil)); 1447 EXPECT_FALSE(is_content_evil); 1448 1449 // Now go back, our state should still be OK. 1450 { 1451 content::WindowedNotificationObserver observer( 1452 content::NOTIFICATION_LOAD_STOP, 1453 content::Source<NavigationController>(&tab->GetController())); 1454 tab->GetController().GoBack(); 1455 observer.Wait(); 1456 } 1457 CheckAuthenticatedState(tab, AuthState::NONE); 1458 1459 // Navigate to a page served over HTTP. 1460 { 1461 content::WindowedNotificationObserver observer( 1462 content::NOTIFICATION_LOAD_STOP, 1463 content::Source<NavigationController>(&tab->GetController())); 1464 EXPECT_TRUE(content::ExecuteScriptAndExtractBool( 1465 tab, 1466 "window.domAutomationController.send(clickLink('HTTPLink'));", 1467 &success)); 1468 ASSERT_TRUE(success); 1469 observer.Wait(); 1470 } 1471 1472 // Our state should be unathenticated (in the ran mixed script sense) 1473 CheckAuthenticationBrokenState( 1474 tab, 1475 CertError::NONE, 1476 AuthState::DISPLAYED_INSECURE_CONTENT | AuthState::RAN_INSECURE_CONTENT); 1477 1478 // Go back, our state should be unchanged. 1479 { 1480 content::WindowedNotificationObserver observer( 1481 content::NOTIFICATION_LOAD_STOP, 1482 content::Source<NavigationController>(&tab->GetController())); 1483 tab->GetController().GoBack(); 1484 observer.Wait(); 1485 } 1486 1487 CheckAuthenticationBrokenState( 1488 tab, 1489 CertError::NONE, 1490 AuthState::DISPLAYED_INSECURE_CONTENT | AuthState::RAN_INSECURE_CONTENT); 1491 } 1492 1493 // From a bad HTTPS top frame: 1494 // - navigate to an OK HTTPS frame (expected to be still authentication broken). 1495 IN_PROC_BROWSER_TEST_F(SSLUITest, TestBadFrameNavigation) { 1496 ASSERT_TRUE(https_server_.Start()); 1497 ASSERT_TRUE(https_server_expired_.Start()); 1498 1499 std::string top_frame_path; 1500 ASSERT_TRUE(GetTopFramePath(*test_server(), 1501 https_server_, 1502 https_server_expired_, 1503 &top_frame_path)); 1504 1505 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1506 ui_test_utils::NavigateToURL(browser(), 1507 https_server_expired_.GetURL(top_frame_path)); 1508 CheckAuthenticationBrokenState( 1509 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL); 1510 1511 ProceedThroughInterstitial(tab); 1512 1513 // Navigate to a good frame. 1514 bool success = false; 1515 content::WindowedNotificationObserver observer( 1516 content::NOTIFICATION_LOAD_STOP, 1517 content::Source<NavigationController>(&tab->GetController())); 1518 EXPECT_TRUE(content::ExecuteScriptAndExtractBool( 1519 tab, 1520 "window.domAutomationController.send(clickLink('goodHTTPSLink'));", 1521 &success)); 1522 ASSERT_TRUE(success); 1523 observer.Wait(); 1524 1525 // We should still be authentication broken. 1526 CheckAuthenticationBrokenState( 1527 tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE); 1528 } 1529 1530 // From an HTTP top frame, navigate to good and bad HTTPS (security state should 1531 // stay unauthenticated). 1532 // Disabled, flakily exceeds test timeout, http://crbug.com/43437. 1533 IN_PROC_BROWSER_TEST_F(SSLUITest, DISABLED_TestUnauthenticatedFrameNavigation) { 1534 ASSERT_TRUE(test_server()->Start()); 1535 ASSERT_TRUE(https_server_.Start()); 1536 ASSERT_TRUE(https_server_expired_.Start()); 1537 1538 std::string top_frame_path; 1539 ASSERT_TRUE(GetTopFramePath(*test_server(), 1540 https_server_, 1541 https_server_expired_, 1542 &top_frame_path)); 1543 1544 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1545 ui_test_utils::NavigateToURL(browser(), 1546 test_server()->GetURL(top_frame_path)); 1547 CheckUnauthenticatedState(tab); 1548 1549 // Now navigate inside the frame to a secure HTTPS frame. 1550 { 1551 bool success = false; 1552 content::WindowedNotificationObserver observer( 1553 content::NOTIFICATION_LOAD_STOP, 1554 content::Source<NavigationController>(&tab->GetController())); 1555 EXPECT_TRUE(content::ExecuteScriptAndExtractBool( 1556 tab, 1557 "window.domAutomationController.send(clickLink('goodHTTPSLink'));", 1558 &success)); 1559 ASSERT_TRUE(success); 1560 observer.Wait(); 1561 } 1562 1563 // We should still be unauthenticated. 1564 CheckUnauthenticatedState(tab); 1565 1566 // Now navigate to a bad HTTPS frame. 1567 { 1568 bool success = false; 1569 content::WindowedNotificationObserver observer( 1570 content::NOTIFICATION_LOAD_STOP, 1571 content::Source<NavigationController>(&tab->GetController())); 1572 EXPECT_TRUE(content::ExecuteScriptAndExtractBool( 1573 tab, 1574 "window.domAutomationController.send(clickLink('badHTTPSLink'));", 1575 &success)); 1576 ASSERT_TRUE(success); 1577 observer.Wait(); 1578 } 1579 1580 // State should not have changed. 1581 CheckUnauthenticatedState(tab); 1582 1583 // And the frame should have been blocked (see bug #2316). 1584 bool is_content_evil = true; 1585 content::RenderFrameHost* content_frame = content::FrameMatchingPredicate( 1586 tab, base::Bind(&content::FrameMatchesName, "contentFrame")); 1587 std::string is_evil_js("window.domAutomationController.send(" 1588 "document.getElementById('evilDiv') != null);"); 1589 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(content_frame, 1590 is_evil_js, 1591 &is_content_evil)); 1592 EXPECT_FALSE(is_content_evil); 1593 } 1594 1595 IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContentsInWorkerFiltered) { 1596 ASSERT_TRUE(https_server_.Start()); 1597 ASSERT_TRUE(https_server_expired_.Start()); 1598 1599 // This page will spawn a Worker which will try to load content from 1600 // BadCertServer. 1601 std::string page_with_unsafe_worker_path; 1602 ASSERT_TRUE(GetPageWithUnsafeWorkerPath(https_server_expired_, 1603 &page_with_unsafe_worker_path)); 1604 ui_test_utils::NavigateToURL(browser(), https_server_.GetURL( 1605 page_with_unsafe_worker_path)); 1606 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1607 // Expect Worker not to load insecure content. 1608 CheckWorkerLoadResult(tab, false); 1609 // The bad content is filtered, expect the state to be authenticated. 1610 CheckAuthenticatedState(tab, AuthState::NONE); 1611 } 1612 1613 IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContentsInWorker) { 1614 ASSERT_TRUE(https_server_.Start()); 1615 ASSERT_TRUE(https_server_expired_.Start()); 1616 1617 // Navigate to an unsafe site. Proceed with interstitial page to indicate 1618 // the user approves the bad certificate. 1619 ui_test_utils::NavigateToURL(browser(), 1620 https_server_expired_.GetURL("files/ssl/blank_page.html")); 1621 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1622 CheckAuthenticationBrokenState( 1623 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL); 1624 ProceedThroughInterstitial(tab); 1625 CheckAuthenticationBrokenState( 1626 tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE); 1627 1628 // Navigate to safe page that has Worker loading unsafe content. 1629 // Expect content to load but be marked as auth broken due to running insecure 1630 // content. 1631 std::string page_with_unsafe_worker_path; 1632 ASSERT_TRUE(GetPageWithUnsafeWorkerPath(https_server_expired_, 1633 &page_with_unsafe_worker_path)); 1634 ui_test_utils::NavigateToURL(browser(), https_server_.GetURL( 1635 page_with_unsafe_worker_path)); 1636 CheckWorkerLoadResult(tab, true); // Worker loads insecure content 1637 CheckAuthenticationBrokenState( 1638 tab, CertError::NONE, AuthState::RAN_INSECURE_CONTENT); 1639 } 1640 1641 // Test that when the browser blocks displaying insecure content (images), the 1642 // indicator shows a secure page, because the blocking made the otherwise 1643 // unsafe page safe (the notification of this state is handled by other means). 1644 IN_PROC_BROWSER_TEST_F(SSLUITestBlock, TestBlockDisplayingInsecureImage) { 1645 ASSERT_TRUE(test_server()->Start()); 1646 ASSERT_TRUE(https_server_.Start()); 1647 1648 std::string replacement_path; 1649 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( 1650 "files/ssl/page_displays_insecure_content.html", 1651 test_server()->host_port_pair(), 1652 &replacement_path)); 1653 1654 ui_test_utils::NavigateToURL(browser(), 1655 https_server_.GetURL(replacement_path)); 1656 1657 CheckAuthenticatedState(browser()->tab_strip_model()->GetActiveWebContents(), 1658 AuthState::NONE); 1659 } 1660 1661 // Test that when the browser blocks displaying insecure content (iframes), the 1662 // indicator shows a secure page, because the blocking made the otherwise 1663 // unsafe page safe (the notification of this state is handled by other means) 1664 IN_PROC_BROWSER_TEST_F(SSLUITestBlock, TestBlockDisplayingInsecureIframe) { 1665 ASSERT_TRUE(test_server()->Start()); 1666 ASSERT_TRUE(https_server_.Start()); 1667 1668 std::string replacement_path; 1669 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( 1670 "files/ssl/page_displays_insecure_iframe.html", 1671 test_server()->host_port_pair(), 1672 &replacement_path)); 1673 1674 ui_test_utils::NavigateToURL(browser(), 1675 https_server_.GetURL(replacement_path)); 1676 1677 CheckAuthenticatedState(browser()->tab_strip_model()->GetActiveWebContents(), 1678 AuthState::NONE); 1679 } 1680 1681 // Test that when the browser blocks running insecure content, the 1682 // indicator shows a secure page, because the blocking made the otherwise 1683 // unsafe page safe (the notification of this state is handled by other means). 1684 IN_PROC_BROWSER_TEST_F(SSLUITestBlock, TestBlockRunningInsecureContent) { 1685 ASSERT_TRUE(test_server()->Start()); 1686 ASSERT_TRUE(https_server_.Start()); 1687 1688 std::string replacement_path; 1689 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement( 1690 "files/ssl/page_runs_insecure_content.html", 1691 test_server()->host_port_pair(), 1692 &replacement_path)); 1693 1694 ui_test_utils::NavigateToURL(browser(), 1695 https_server_.GetURL(replacement_path)); 1696 1697 CheckAuthenticatedState(browser()->tab_strip_model()->GetActiveWebContents(), 1698 AuthState::NONE); 1699 } 1700 1701 // Visit a page and establish a WebSocket connection over bad https with 1702 // --ignore-certificate-errors. The connection should be established without 1703 // interstitial page showing. 1704 IN_PROC_BROWSER_TEST_F(SSLUITestIgnoreCertErrors, TestWSS) { 1705 ASSERT_TRUE(test_server()->Start()); 1706 ASSERT_TRUE(wss_server_expired_.Start()); 1707 1708 // Setup page title observer. 1709 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1710 content::TitleWatcher watcher(tab, ASCIIToUTF16("PASS")); 1711 watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL")); 1712 1713 // Visit bad HTTPS page. 1714 std::string scheme("https"); 1715 GURL::Replacements replacements; 1716 replacements.SetSchemeStr(scheme); 1717 ui_test_utils::NavigateToURL( 1718 browser(), 1719 wss_server_expired_.GetURL( 1720 "connect_check.html").ReplaceComponents(replacements)); 1721 1722 // We shouldn't have an interstitial page showing here. 1723 1724 // Test page run a WebSocket wss connection test. The result will be shown 1725 // as page title. 1726 const base::string16 result = watcher.WaitAndGetTitle(); 1727 EXPECT_TRUE(LowerCaseEqualsASCII(result, "pass")); 1728 } 1729 1730 // Verifies that the interstitial can proceed, even if JavaScript is disabled. 1731 // http://crbug.com/322948 1732 IN_PROC_BROWSER_TEST_F(SSLUITest, TestInterstitialJavaScriptProceeds) { 1733 browser()->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting( 1734 CONTENT_SETTINGS_TYPE_JAVASCRIPT, CONTENT_SETTING_BLOCK); 1735 1736 ASSERT_TRUE(https_server_expired_.Start()); 1737 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1738 ui_test_utils::NavigateToURL(browser(), 1739 https_server_expired_.GetURL("files/ssl/google.html")); 1740 CheckAuthenticationBrokenState( 1741 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL); 1742 1743 content::WindowedNotificationObserver observer( 1744 content::NOTIFICATION_LOAD_STOP, 1745 content::Source<NavigationController>(&tab->GetController())); 1746 InterstitialPage* interstitial_page = tab->GetInterstitialPage(); 1747 content::RenderViewHost* interstitial_rvh = 1748 interstitial_page->GetRenderViewHostForTesting(); 1749 int result = -1; 1750 std::string javascript = base::StringPrintf( 1751 "window.domAutomationController.send(%d);", 1752 SSLBlockingPage::CMD_PROCEED); 1753 ASSERT_TRUE(content::ExecuteScriptAndExtractInt( 1754 interstitial_rvh, javascript, &result)); 1755 // The above will hang without the fix. 1756 EXPECT_EQ(1, result); 1757 observer.Wait(); 1758 CheckAuthenticationBrokenState( 1759 tab, net::CERT_STATUS_DATE_INVALID, AuthState::NONE); 1760 } 1761 1762 // Verifies that the interstitial can go back, even if JavaScript is disabled. 1763 // http://crbug.com/322948 1764 IN_PROC_BROWSER_TEST_F(SSLUITest, TestInterstitialJavaScriptGoesBack) { 1765 browser()->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting( 1766 CONTENT_SETTINGS_TYPE_JAVASCRIPT, CONTENT_SETTING_BLOCK); 1767 1768 ASSERT_TRUE(https_server_expired_.Start()); 1769 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1770 ui_test_utils::NavigateToURL(browser(), 1771 https_server_expired_.GetURL("files/ssl/google.html")); 1772 CheckAuthenticationBrokenState( 1773 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL); 1774 1775 content::WindowedNotificationObserver observer( 1776 content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED, 1777 content::NotificationService::AllSources()); 1778 InterstitialPage* interstitial_page = tab->GetInterstitialPage(); 1779 content::RenderViewHost* interstitial_rvh = 1780 interstitial_page->GetRenderViewHostForTesting(); 1781 int result = -1; 1782 std::string javascript = base::StringPrintf( 1783 "window.domAutomationController.send(%d);", 1784 SSLBlockingPage::CMD_DONT_PROCEED); 1785 ASSERT_TRUE(content::ExecuteScriptAndExtractInt( 1786 interstitial_rvh, javascript, &result)); 1787 // The above will hang without the fix. 1788 EXPECT_EQ(0, result); 1789 observer.Wait(); 1790 EXPECT_EQ("about:blank", tab->GetVisibleURL().spec()); 1791 } 1792 1793 // Verifies that switching tabs, while showing interstitial page, will not 1794 // affect the visibility of the interestitial. 1795 // https://crbug.com/381439 1796 IN_PROC_BROWSER_TEST_F(SSLUITest, InterstitialNotAffectedByHideShow) { 1797 ASSERT_TRUE(https_server_expired_.Start()); 1798 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 1799 EXPECT_TRUE(tab->GetRenderWidgetHostView()->IsShowing()); 1800 ui_test_utils::NavigateToURL( 1801 browser(), https_server_expired_.GetURL("files/ssl/google.html")); 1802 CheckAuthenticationBrokenState( 1803 tab, net::CERT_STATUS_DATE_INVALID, AuthState::SHOWING_INTERSTITIAL); 1804 EXPECT_TRUE(tab->GetRenderWidgetHostView()->IsShowing()); 1805 1806 AddTabAtIndex(0, 1807 https_server_.GetURL("files/ssl/google.html"), 1808 content::PAGE_TRANSITION_TYPED); 1809 EXPECT_EQ(2, browser()->tab_strip_model()->count()); 1810 EXPECT_EQ(0, browser()->tab_strip_model()->active_index()); 1811 EXPECT_EQ(tab, browser()->tab_strip_model()->GetWebContentsAt(1)); 1812 EXPECT_FALSE(tab->GetRenderWidgetHostView()->IsShowing()); 1813 1814 browser()->tab_strip_model()->ActivateTabAt(1, true); 1815 EXPECT_TRUE(tab->GetRenderWidgetHostView()->IsShowing()); 1816 } 1817 1818 // TODO(jcampan): more tests to do below. 1819 1820 // Visit a page over https that contains a frame with a redirect. 1821 1822 // XMLHttpRequest insecure content in synchronous mode. 1823 1824 // XMLHttpRequest insecure content in asynchronous mode. 1825 1826 // XMLHttpRequest over bad ssl in synchronous mode. 1827 1828 // XMLHttpRequest over OK ssl in synchronous mode. 1829