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