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