ssl_browser_tests.cc revision 23730a6e56a168d1879203e4b3819bb36e3d8f1f
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// Disabled under LeakSanitizer due to memory leaks. http://crbug.com/317363
580#if defined(OS_WIN) || defined(LEAK_SANITIZER)
581#define MAYBE_TestWSSInvalidCertAndClose DISABLED_TestWSSInvalidCertAndClose
582#else
583#define MAYBE_TestWSSInvalidCertAndClose TestWSSInvalidCertAndClose
584#endif
585IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestWSSInvalidCertAndClose) {
586  ASSERT_TRUE(test_server()->Start());
587  ASSERT_TRUE(wss_server_expired_.Start());
588
589  // Setup page title observer.
590  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
591  content::TitleWatcher watcher(tab, ASCIIToUTF16("PASS"));
592  watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
593
594  // Create GURLs to test pages.
595  std::string master_url_path = base::StringPrintf("%s?%d",
596      test_server()->GetURL("files/ssl/wss_close.html").spec().c_str(),
597      wss_server_expired_.host_port_pair().port());
598  GURL master_url(master_url_path);
599  std::string slave_url_path = base::StringPrintf("%s?%d",
600      test_server()->GetURL("files/ssl/wss_close_slave.html").spec().c_str(),
601      wss_server_expired_.host_port_pair().port());
602  GURL slave_url(slave_url_path);
603
604  // Create tabs and visit pages which keep on creating wss connections.
605  WebContents* tabs[16];
606  for (int i = 0; i < 16; ++i) {
607    tabs[i] = chrome::AddSelectedTabWithURL(browser(), slave_url,
608                                            content::PAGE_TRANSITION_LINK);
609  }
610  chrome::SelectNextTab(browser());
611
612  // Visit a page which waits for one TLS handshake failure.
613  // The title will be changed to 'PASS'.
614  ui_test_utils::NavigateToURL(browser(), master_url);
615  const base::string16 result = watcher.WaitAndGetTitle();
616  EXPECT_TRUE(LowerCaseEqualsASCII(result, "pass"));
617
618  // Close tabs which contains the test page.
619  for (int i = 0; i < 16; ++i)
620    chrome::CloseWebContents(browser(), tabs[i], false);
621  chrome::CloseWebContents(browser(), tab, false);
622}
623
624// Visit a HTTPS page and proceeds despite an invalid certificate. The page
625// requests WSS connection to the same origin host to check if WSS connection
626// share certificates policy with HTTPS correcly.
627IN_PROC_BROWSER_TEST_F(SSLUITest, TestWSSInvalidCertAndGoForward) {
628  ASSERT_TRUE(test_server()->Start());
629  ASSERT_TRUE(wss_server_expired_.Start());
630
631  // Setup page title observer.
632  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
633  content::TitleWatcher watcher(tab, ASCIIToUTF16("PASS"));
634  watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
635
636  // Visit bad HTTPS page.
637  std::string scheme("https");
638  GURL::Replacements replacements;
639  replacements.SetSchemeStr(scheme);
640  ui_test_utils::NavigateToURL(
641      browser(),
642      wss_server_expired_.GetURL(
643          "connect_check.html").ReplaceComponents(replacements));
644  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false,
645                                 true);  // Interstitial showing
646
647  // Proceed anyway.
648  ProceedThroughInterstitial(tab);
649
650  // Test page run a WebSocket wss connection test. The result will be shown
651  // as page title.
652  const base::string16 result = watcher.WaitAndGetTitle();
653  EXPECT_TRUE(LowerCaseEqualsASCII(result, "pass"));
654}
655
656#if defined(USE_NSS)
657// SSL client certificate tests are only enabled when using NSS for private key
658// storage, as only NSS can avoid modifying global machine state when testing.
659// See http://crbug.com/51132
660
661// Visit a HTTPS page which requires client cert authentication. The client
662// cert will be selected automatically, then a test which uses WebSocket runs.
663// Disabled:  http://crbug.com/159985
664IN_PROC_BROWSER_TEST_F(SSLUITest, DISABLED_TestWSSClientCert) {
665  // Open a temporary NSS DB for testing.
666  crypto::ScopedTestNSSDB test_nssdb;
667  ASSERT_TRUE(test_nssdb.is_open());
668
669  // Import client cert for test. These interfaces require NSS.
670  net::NSSCertDatabase* cert_db = net::NSSCertDatabase::GetInstance();
671  scoped_refptr<net::CryptoModule> crypt_module = cert_db->GetPublicModule();
672  std::string pkcs12_data;
673  base::FilePath cert_path = net::GetTestCertsDirectory().Append(
674      FILE_PATH_LITERAL("websocket_client_cert.p12"));
675  EXPECT_TRUE(base::ReadFileToString(cert_path, &pkcs12_data));
676  EXPECT_EQ(net::OK,
677            cert_db->ImportFromPKCS12(
678                crypt_module.get(), pkcs12_data, base::string16(), true, NULL));
679
680  // Start WebSocket test server with TLS and client cert authentication.
681  net::SpawnedTestServer::SSLOptions options(
682      net::SpawnedTestServer::SSLOptions::CERT_OK);
683  options.request_client_certificate = true;
684  base::FilePath ca_path = net::GetTestCertsDirectory().Append(
685      FILE_PATH_LITERAL("websocket_cacert.pem"));
686  options.client_authorities.push_back(ca_path);
687  net::SpawnedTestServer wss_server(net::SpawnedTestServer::TYPE_WSS,
688                             options,
689                             net::GetWebSocketTestDataDirectory());
690  ASSERT_TRUE(wss_server.Start());
691  std::string scheme("https");
692  GURL::Replacements replacements;
693  replacements.SetSchemeStr(scheme);
694  GURL url = wss_server.GetURL("connect_check.html").ReplaceComponents(
695      replacements);
696
697  // Setup page title observer.
698  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
699  content::TitleWatcher watcher(tab, ASCIIToUTF16("PASS"));
700  watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
701
702  // Add an entry into AutoSelectCertificateForUrls policy for automatic client
703  // cert selection.
704  Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
705  DCHECK(profile);
706  scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
707  dict->SetString("ISSUER.CN", "pywebsocket");
708  profile->GetHostContentSettingsMap()->SetWebsiteSetting(
709      ContentSettingsPattern::FromURL(url),
710      ContentSettingsPattern::FromURL(url),
711      CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE,
712      std::string(),
713      dict.release());
714
715  // Visit a HTTPS page which requires client certs.
716  ui_test_utils::NavigateToURL(browser(), url);
717  CheckAuthenticatedState(tab, false);
718
719  // Test page runs a WebSocket wss connection test. The result will be shown
720  // as page title.
721  const base::string16 result = watcher.WaitAndGetTitle();
722  EXPECT_TRUE(LowerCaseEqualsASCII(result, "pass"));
723}
724#endif  // defined(USE_NSS)
725
726// Flaky on CrOS http://crbug.com/92292
727#if defined(OS_CHROMEOS)
728#define MAYBE_TestHTTPSErrorWithNoNavEntry \
729    DISABLED_TestHTTPSErrorWithNoNavEntry
730#else
731#define MAYBE_TestHTTPSErrorWithNoNavEntry TestHTTPSErrorWithNoNavEntry
732#endif  // defined(OS_CHROMEOS)
733
734// Open a page with a HTTPS error in a tab with no prior navigation (through a
735// link with a blank target).  This is to test that the lack of navigation entry
736// does not cause any problems (it was causing a crasher, see
737// http://crbug.com/19941).
738IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestHTTPSErrorWithNoNavEntry) {
739  ASSERT_TRUE(https_server_expired_.Start());
740
741  GURL url = https_server_expired_.GetURL("files/ssl/google.htm");
742  WebContents* tab2 = chrome::AddSelectedTabWithURL(
743      browser(), url, content::PAGE_TRANSITION_TYPED);
744  content::WaitForLoadStop(tab2);
745
746  // Verify our assumption that there was no prior navigation.
747  EXPECT_FALSE(chrome::CanGoBack(browser()));
748
749  // We should have an interstitial page showing.
750  ASSERT_TRUE(tab2->GetInterstitialPage());
751}
752
753IN_PROC_BROWSER_TEST_F(SSLUITest, TestBadHTTPSDownload) {
754  ASSERT_TRUE(test_server()->Start());
755  ASSERT_TRUE(https_server_expired_.Start());
756  GURL url_non_dangerous = test_server()->GetURL(std::string());
757  GURL url_dangerous =
758      https_server_expired_.GetURL("files/downloads/dangerous/dangerous.exe");
759  base::ScopedTempDir downloads_directory_;
760
761  // Need empty temp dir to avoid having Chrome ask us for a new filename
762  // when we've downloaded dangerous.exe one hundred times.
763  ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir());
764
765  browser()->profile()->GetPrefs()->SetFilePath(
766      prefs::kDownloadDefaultDirectory,
767      downloads_directory_.path());
768
769  // Visit a non-dangerous page.
770  ui_test_utils::NavigateToURL(browser(), url_non_dangerous);
771
772  // Now, start a transition to dangerous download.
773  {
774    content::WindowedNotificationObserver observer(
775        content::NOTIFICATION_LOAD_STOP,
776        content::NotificationService::AllSources());
777    chrome::NavigateParams navigate_params(browser(), url_dangerous,
778                                           content::PAGE_TRANSITION_TYPED);
779    chrome::Navigate(&navigate_params);
780    observer.Wait();
781  }
782
783  // To exit the browser cleanly (and this test) we need to complete the
784  // download after completing this test.
785  content::DownloadTestObserverTerminal dangerous_download_observer(
786      content::BrowserContext::GetDownloadManager(browser()->profile()),
787      1,
788      content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_ACCEPT);
789
790  // Proceed through the SSL interstitial. This doesn't use
791  // |ProceedThroughInterstitial| since no page load will commit.
792  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
793  ASSERT_TRUE(tab != NULL);
794  ASSERT_TRUE(tab->GetInterstitialPage() != NULL);
795  {
796    content::WindowedNotificationObserver observer(
797        chrome::NOTIFICATION_DOWNLOAD_INITIATED,
798        content::NotificationService::AllSources());
799    tab->GetInterstitialPage()->Proceed();
800    observer.Wait();
801  }
802
803  // There should still be an interstitial at this point. Press the
804  // back button on the browser. Note that this doesn't wait for a
805  // NAV_ENTRY_COMMITTED notification because going back with an
806  // active interstitial simply hides the interstitial.
807  ASSERT_TRUE(tab->GetInterstitialPage() != NULL);
808  EXPECT_TRUE(chrome::CanGoBack(browser()));
809  chrome::GoBack(browser(), CURRENT_TAB);
810
811  dangerous_download_observer.WaitForFinished();
812}
813
814//
815// Insecure content
816//
817
818#if defined(OS_WIN)
819// http://crbug.com/152940 Flaky on win.
820#define MAYBE_TestDisplaysInsecureContent DISABLED_TestDisplaysInsecureContent
821#else
822#define MAYBE_TestDisplaysInsecureContent TestDisplaysInsecureContent
823#endif
824
825// Visits a page that displays insecure content.
826IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestDisplaysInsecureContent) {
827  ASSERT_TRUE(test_server()->Start());
828  ASSERT_TRUE(https_server_.Start());
829
830  std::string replacement_path;
831  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
832      "files/ssl/page_displays_insecure_content.html",
833      test_server()->host_port_pair(),
834      &replacement_path));
835
836  // Load a page that displays insecure content.
837  ui_test_utils::NavigateToURL(browser(),
838                               https_server_.GetURL(replacement_path));
839
840  CheckAuthenticatedState(
841      browser()->tab_strip_model()->GetActiveWebContents(), true);
842}
843
844// Visits a page that runs insecure content and tries to suppress the insecure
845// content warnings by randomizing location.hash.
846// Based on http://crbug.com/8706
847IN_PROC_BROWSER_TEST_F(SSLUITest,
848                       TestRunsInsecuredContentRandomizeHash) {
849  ASSERT_TRUE(test_server()->Start());
850  ASSERT_TRUE(https_server_.Start());
851
852  ui_test_utils::NavigateToURL(browser(), https_server_.GetURL(
853      "files/ssl/page_runs_insecure_content.html"));
854
855  CheckAuthenticationBrokenState(
856      browser()->tab_strip_model()->GetActiveWebContents(), 0, true, false);
857}
858
859// Visits a page with unsafe content and make sure that:
860// - frames content is replaced with warning
861// - images and scripts are filtered out entirely
862IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContents) {
863  ASSERT_TRUE(https_server_.Start());
864  ASSERT_TRUE(https_server_expired_.Start());
865
866  std::string replacement_path;
867  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
868      "files/ssl/page_with_unsafe_contents.html",
869      https_server_expired_.host_port_pair(),
870      &replacement_path));
871  ui_test_utils::NavigateToURL(browser(),
872                               https_server_.GetURL(replacement_path));
873
874  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
875  // When the bad content is filtered, the state is expected to be
876  // authenticated.
877  CheckAuthenticatedState(tab, false);
878
879  // Because of cross-frame scripting restrictions, we cannot access the iframe
880  // content.  So to know if the frame was loaded, we just check if a popup was
881  // opened (the iframe content opens one).
882  // Note: because of bug 1115868, no web contents modal dialog is opened right
883  //       now.  Once the bug is fixed, this will do the real check.
884  EXPECT_FALSE(IsShowingWebContentsModalDialog());
885
886  int img_width;
887  EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
888      tab,
889      "window.domAutomationController.send(ImageWidth());",
890      &img_width));
891  // In order to check that the image was not loaded, we check its width.
892  // The actual image (Google logo) is 114 pixels wide, we assume the broken
893  // image is less than 100.
894  EXPECT_LT(img_width, 100);
895
896  bool js_result = false;
897  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
898      tab,
899      "window.domAutomationController.send(IsFooSet());",
900      &js_result));
901  EXPECT_FALSE(js_result);
902}
903
904// Visits a page with insecure content loaded by JS (after the initial page
905// load).
906IN_PROC_BROWSER_TEST_F(SSLUITest, TestDisplaysInsecureContentLoadedFromJS) {
907  ASSERT_TRUE(test_server()->Start());
908  ASSERT_TRUE(https_server_.Start());
909
910  std::string replacement_path;
911  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
912      "files/ssl/page_with_dynamic_insecure_content.html",
913      test_server()->host_port_pair(),
914      &replacement_path));
915  ui_test_utils::NavigateToURL(browser(), https_server_.GetURL(
916      replacement_path));
917
918  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
919  CheckAuthenticatedState(tab, false);
920
921  // Load the insecure image.
922  bool js_result = false;
923  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
924      tab,
925      "loadBadImage();",
926      &js_result));
927  EXPECT_TRUE(js_result);
928
929  // We should now have insecure content.
930  CheckAuthenticatedState(tab, true);
931}
932
933// Visits two pages from the same origin: one that displays insecure content and
934// one that doesn't.  The test checks that we do not propagate the insecure
935// content state from one to the other.
936IN_PROC_BROWSER_TEST_F(SSLUITest, TestDisplaysInsecureContentTwoTabs) {
937  ASSERT_TRUE(test_server()->Start());
938  ASSERT_TRUE(https_server_.Start());
939
940  ui_test_utils::NavigateToURL(browser(),
941      https_server_.GetURL("files/ssl/blank_page.html"));
942
943  WebContents* tab1 = browser()->tab_strip_model()->GetActiveWebContents();
944
945  // This tab should be fine.
946  CheckAuthenticatedState(tab1, false);
947
948  // Create a new tab.
949  std::string replacement_path;
950  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
951      "files/ssl/page_displays_insecure_content.html",
952      test_server()->host_port_pair(),
953      &replacement_path));
954
955  GURL url = https_server_.GetURL(replacement_path);
956  chrome::NavigateParams params(browser(), url, content::PAGE_TRANSITION_TYPED);
957  params.disposition = NEW_FOREGROUND_TAB;
958  params.tabstrip_index = 0;
959  params.source_contents = tab1;
960  content::WindowedNotificationObserver observer(
961      content::NOTIFICATION_LOAD_STOP,
962      content::NotificationService::AllSources());
963  chrome::Navigate(&params);
964  WebContents* tab2 = params.target_contents;
965  observer.Wait();
966
967  // The new tab has insecure content.
968  CheckAuthenticatedState(tab2, true);
969
970  // The original tab should not be contaminated.
971  CheckAuthenticatedState(tab1, false);
972}
973
974// Visits two pages from the same origin: one that runs insecure content and one
975// that doesn't.  The test checks that we propagate the insecure content state
976// from one to the other.
977IN_PROC_BROWSER_TEST_F(SSLUITest, TestRunsInsecureContentTwoTabs) {
978  ASSERT_TRUE(test_server()->Start());
979  ASSERT_TRUE(https_server_.Start());
980
981  ui_test_utils::NavigateToURL(browser(),
982      https_server_.GetURL("files/ssl/blank_page.html"));
983
984  WebContents* tab1 = browser()->tab_strip_model()->GetActiveWebContents();
985
986  // This tab should be fine.
987  CheckAuthenticatedState(tab1, false);
988
989  std::string replacement_path;
990  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
991      "files/ssl/page_runs_insecure_content.html",
992      test_server()->host_port_pair(),
993      &replacement_path));
994
995  // Create a new tab in the same process.  Using a NEW_FOREGROUND_TAB
996  // disposition won't usually stay in the same process, but this works
997  // because we are using process-per-site in SetUpCommandLine.
998  GURL url = https_server_.GetURL(replacement_path);
999  chrome::NavigateParams params(browser(), url, content::PAGE_TRANSITION_TYPED);
1000  params.disposition = NEW_FOREGROUND_TAB;
1001  params.source_contents = tab1;
1002  content::WindowedNotificationObserver observer(
1003      content::NOTIFICATION_LOAD_STOP,
1004      content::NotificationService::AllSources());
1005  chrome::Navigate(&params);
1006  WebContents* tab2 = params.target_contents;
1007  observer.Wait();
1008
1009  // Both tabs should have the same process.
1010  EXPECT_EQ(tab1->GetRenderProcessHost(), tab2->GetRenderProcessHost());
1011
1012  // The new tab has insecure content.
1013  CheckAuthenticationBrokenState(tab2, 0, true, false);
1014
1015  // Which means the origin for the first tab has also been contaminated with
1016  // insecure content.
1017  CheckAuthenticationBrokenState(tab1, 0, true, false);
1018}
1019
1020// Visits a page with an image over http.  Visits another page over https
1021// referencing that same image over http (hoping it is coming from the webcore
1022// memory cache).
1023IN_PROC_BROWSER_TEST_F(SSLUITest, TestDisplaysCachedInsecureContent) {
1024  ASSERT_TRUE(test_server()->Start());
1025  ASSERT_TRUE(https_server_.Start());
1026
1027  std::string replacement_path;
1028  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
1029      "files/ssl/page_displays_insecure_content.html",
1030      test_server()->host_port_pair(),
1031      &replacement_path));
1032
1033  // Load original page over HTTP.
1034  const GURL url_http = test_server()->GetURL(replacement_path);
1035  ui_test_utils::NavigateToURL(browser(), url_http);
1036  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1037  CheckUnauthenticatedState(tab);
1038
1039  // Load again but over SSL.  It should be marked as displaying insecure
1040  // content (even though the image comes from the WebCore memory cache).
1041  const GURL url_https = https_server_.GetURL(replacement_path);
1042  ui_test_utils::NavigateToURL(browser(), url_https);
1043  CheckAuthenticatedState(tab, true);
1044}
1045
1046// http://crbug.com/84729
1047#if defined(OS_CHROMEOS)
1048#define MAYBE_TestRunsCachedInsecureContent \
1049    DISABLED_TestRunsCachedInsecureContent
1050#else
1051#define MAYBE_TestRunsCachedInsecureContent TestRunsCachedInsecureContent
1052#endif  // defined(OS_CHROMEOS)
1053
1054// Visits a page with script over http.  Visits another page over https
1055// referencing that same script over http (hoping it is coming from the webcore
1056// memory cache).
1057IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestRunsCachedInsecureContent) {
1058  ASSERT_TRUE(test_server()->Start());
1059  ASSERT_TRUE(https_server_.Start());
1060
1061  std::string replacement_path;
1062  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
1063      "files/ssl/page_runs_insecure_content.html",
1064      test_server()->host_port_pair(),
1065      &replacement_path));
1066
1067  // Load original page over HTTP.
1068  const GURL url_http = test_server()->GetURL(replacement_path);
1069  ui_test_utils::NavigateToURL(browser(), url_http);
1070  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1071  CheckUnauthenticatedState(tab);
1072
1073  // Load again but over SSL.  It should be marked as displaying insecure
1074  // content (even though the image comes from the WebCore memory cache).
1075  const GURL url_https = https_server_.GetURL(replacement_path);
1076  ui_test_utils::NavigateToURL(browser(), url_https);
1077  CheckAuthenticationBrokenState(tab, 0, true, false);
1078}
1079
1080// This test ensures the CN invalid status does not 'stick' to a certificate
1081// (see bug #1044942) and that it depends on the host-name.
1082IN_PROC_BROWSER_TEST_F(SSLUITest, TestCNInvalidStickiness) {
1083  ASSERT_TRUE(https_server_.Start());
1084  ASSERT_TRUE(https_server_mismatched_.Start());
1085
1086  // First we hit the server with hostname, this generates an invalid policy
1087  // error.
1088  ui_test_utils::NavigateToURL(browser(),
1089      https_server_mismatched_.GetURL("files/ssl/google.html"));
1090
1091  // We get an interstitial page as a result.
1092  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1093  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
1094                                 false, true);  // Interstitial showing.
1095  ProceedThroughInterstitial(tab);
1096  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
1097                                 false, false);  // No interstitial showing.
1098
1099  // Now we try again with the right host name this time.
1100  GURL url(https_server_.GetURL("files/ssl/google.html"));
1101  ui_test_utils::NavigateToURL(browser(), url);
1102
1103  // Security state should be OK.
1104  CheckAuthenticatedState(tab, false);
1105
1106  // Now try again the broken one to make sure it is still broken.
1107  ui_test_utils::NavigateToURL(browser(),
1108      https_server_mismatched_.GetURL("files/ssl/google.html"));
1109
1110  // Since we OKed the interstitial last time, we get right to the page.
1111  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
1112                                 false, false);  // No interstitial showing.
1113}
1114
1115#if defined(OS_CHROMEOS)
1116// This test seems to be flaky and hang on chromiumos.
1117// http://crbug.com/84419
1118#define MAYBE_TestRefNavigation DISABLED_TestRefNavigation
1119#else
1120#define MAYBE_TestRefNavigation TestRefNavigation
1121#endif
1122
1123// Test that navigating to a #ref does not change a bad security state.
1124IN_PROC_BROWSER_TEST_F(SSLUITest, TestRefNavigation) {
1125  ASSERT_TRUE(https_server_expired_.Start());
1126
1127  ui_test_utils::NavigateToURL(browser(),
1128      https_server_expired_.GetURL("files/ssl/page_with_refs.html"));
1129
1130  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1131  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false,
1132                                 true);  // Interstitial showing.
1133
1134  ProceedThroughInterstitial(tab);
1135
1136  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false,
1137                                 false);  // No interstitial showing.
1138
1139  // Now navigate to a ref in the page, the security state should not have
1140  // changed.
1141  ui_test_utils::NavigateToURL(browser(),
1142      https_server_expired_.GetURL("files/ssl/page_with_refs.html#jp"));
1143
1144  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false,
1145                                 false);  // No interstitial showing.
1146}
1147
1148// Tests that closing a page that has a unsafe pop-up does not crash the
1149// browser (bug #1966).
1150// TODO(jcampan): http://crbug.com/2136 disabled because the popup is not
1151//                opened as it is not initiated by a user gesture.
1152IN_PROC_BROWSER_TEST_F(SSLUITest, DISABLED_TestCloseTabWithUnsafePopup) {
1153  ASSERT_TRUE(test_server()->Start());
1154  ASSERT_TRUE(https_server_expired_.Start());
1155
1156  std::string replacement_path;
1157  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
1158      "files/ssl/page_with_unsafe_popup.html",
1159      https_server_expired_.host_port_pair(),
1160      &replacement_path));
1161
1162  ui_test_utils::NavigateToURL(browser(),
1163                               test_server()->GetURL(replacement_path));
1164
1165  WebContents* tab1 = browser()->tab_strip_model()->GetActiveWebContents();
1166  // It is probably overkill to add a notification for a popup-opening, let's
1167  // just poll.
1168  for (int i = 0; i < 10; i++) {
1169    if (IsShowingWebContentsModalDialog())
1170      break;
1171    base::MessageLoop::current()->PostDelayedTask(
1172        FROM_HERE,
1173        base::MessageLoop::QuitClosure(),
1174        base::TimeDelta::FromSeconds(1));
1175    content::RunMessageLoop();
1176  }
1177  ASSERT_TRUE(IsShowingWebContentsModalDialog());
1178
1179  // Let's add another tab to make sure the browser does not exit when we close
1180  // the first tab.
1181  GURL url = test_server()->GetURL("files/ssl/google.html");
1182  content::WindowedNotificationObserver observer(
1183      content::NOTIFICATION_LOAD_STOP,
1184      content::NotificationService::AllSources());
1185  chrome::AddSelectedTabWithURL(browser(), url, content::PAGE_TRANSITION_TYPED);
1186  observer.Wait();
1187
1188  // Close the first tab.
1189  chrome::CloseWebContents(browser(), tab1, false);
1190}
1191
1192// Visit a page over bad https that is a redirect to a page with good https.
1193IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectBadToGoodHTTPS) {
1194  ASSERT_TRUE(https_server_.Start());
1195  ASSERT_TRUE(https_server_expired_.Start());
1196
1197  GURL url1 = https_server_expired_.GetURL("server-redirect?");
1198  GURL url2 = https_server_.GetURL("files/ssl/google.html");
1199
1200  ui_test_utils::NavigateToURL(browser(), GURL(url1.spec() + url2.spec()));
1201
1202  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1203
1204  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false,
1205                                 true);  // Interstitial showing.
1206
1207  ProceedThroughInterstitial(tab);
1208
1209  // We have been redirected to the good page.
1210  CheckAuthenticatedState(tab, false);
1211}
1212
1213// Visit a page over good https that is a redirect to a page with bad https.
1214IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectGoodToBadHTTPS) {
1215  ASSERT_TRUE(https_server_.Start());
1216  ASSERT_TRUE(https_server_expired_.Start());
1217
1218  GURL url1 = https_server_.GetURL("server-redirect?");
1219  GURL url2 = https_server_expired_.GetURL("files/ssl/google.html");
1220  ui_test_utils::NavigateToURL(browser(), GURL(url1.spec() + url2.spec()));
1221
1222  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1223  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false,
1224                                 true);  // Interstitial showing.
1225
1226  ProceedThroughInterstitial(tab);
1227
1228  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false,
1229                                 false);  // No interstitial showing.
1230}
1231
1232// Visit a page over http that is a redirect to a page with good HTTPS.
1233IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectHTTPToGoodHTTPS) {
1234  ASSERT_TRUE(test_server()->Start());
1235  ASSERT_TRUE(https_server_.Start());
1236
1237  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1238
1239  // HTTP redirects to good HTTPS.
1240  GURL http_url = test_server()->GetURL("server-redirect?");
1241  GURL good_https_url =
1242      https_server_.GetURL("files/ssl/google.html");
1243
1244  ui_test_utils::NavigateToURL(browser(),
1245                               GURL(http_url.spec() + good_https_url.spec()));
1246  CheckAuthenticatedState(tab, false);
1247}
1248
1249// Visit a page over http that is a redirect to a page with bad HTTPS.
1250IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectHTTPToBadHTTPS) {
1251  ASSERT_TRUE(test_server()->Start());
1252  ASSERT_TRUE(https_server_expired_.Start());
1253
1254  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1255
1256  GURL http_url = test_server()->GetURL("server-redirect?");
1257  GURL bad_https_url =
1258      https_server_expired_.GetURL("files/ssl/google.html");
1259  ui_test_utils::NavigateToURL(browser(),
1260                               GURL(http_url.spec() + bad_https_url.spec()));
1261  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false,
1262                                 true);  // Interstitial showing.
1263
1264  ProceedThroughInterstitial(tab);
1265
1266  CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false,
1267                                 false);  // No interstitial showing.
1268}
1269
1270// Visit a page over https that is a redirect to a page with http (to make sure
1271// we don't keep the secure state).
1272IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectHTTPSToHTTP) {
1273  ASSERT_TRUE(test_server()->Start());
1274  ASSERT_TRUE(https_server_.Start());
1275
1276  GURL https_url = https_server_.GetURL("server-redirect?");
1277  GURL http_url = test_server()->GetURL("files/ssl/google.html");
1278
1279  ui_test_utils::NavigateToURL(browser(),
1280                               GURL(https_url.spec() + http_url.spec()));
1281  CheckUnauthenticatedState(
1282      browser()->tab_strip_model()->GetActiveWebContents());
1283}
1284
1285// Visits a page to which we could not connect (bad port) over http and https
1286// and make sure the security style is correct.
1287IN_PROC_BROWSER_TEST_F(SSLUITest, TestConnectToBadPort) {
1288  ui_test_utils::NavigateToURL(browser(), GURL("http://localhost:17"));
1289  CheckUnauthenticatedState(
1290      browser()->tab_strip_model()->GetActiveWebContents());
1291
1292  // Same thing over HTTPS.
1293  ui_test_utils::NavigateToURL(browser(), GURL("https://localhost:17"));
1294  CheckUnauthenticatedState(
1295      browser()->tab_strip_model()->GetActiveWebContents());
1296}
1297
1298//
1299// Frame navigation
1300//
1301
1302// From a good HTTPS top frame:
1303// - navigate to an OK HTTPS frame
1304// - navigate to a bad HTTPS (expect unsafe content and filtered frame), then
1305//   back
1306// - navigate to HTTP (expect insecure content), then back
1307IN_PROC_BROWSER_TEST_F(SSLUITest, TestGoodFrameNavigation) {
1308  ASSERT_TRUE(test_server()->Start());
1309  ASSERT_TRUE(https_server_.Start());
1310  ASSERT_TRUE(https_server_expired_.Start());
1311
1312  std::string top_frame_path;
1313  ASSERT_TRUE(GetTopFramePath(*test_server(),
1314                              https_server_,
1315                              https_server_expired_,
1316                              &top_frame_path));
1317
1318  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
1319  ui_test_utils::NavigateToURL(browser(),
1320                               https_server_.GetURL(top_frame_path));
1321
1322  CheckAuthenticatedState(tab, false);
1323
1324  bool success = false;
1325  // Now navigate inside the frame.
1326  {
1327    content::WindowedNotificationObserver observer(
1328        content::NOTIFICATION_LOAD_STOP,
1329        content::Source<NavigationController>(&tab->GetController()));
1330    EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
1331        tab,
1332        "window.domAutomationController.send(clickLink('goodHTTPSLink'));",
1333        &success));
1334    ASSERT_TRUE(success);
1335    observer.Wait();
1336  }
1337
1338  // We should still be fine.
1339  CheckAuthenticatedState(tab, false);
1340
1341  // Now let's hit a bad page.
1342  {
1343    content::WindowedNotificationObserver observer(
1344        content::NOTIFICATION_LOAD_STOP,
1345        content::Source<NavigationController>(&tab->GetController()));
1346    EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
1347        tab,
1348        "window.domAutomationController.send(clickLink('badHTTPSLink'));",
1349        &success));
1350    ASSERT_TRUE(success);
1351    observer.Wait();
1352  }
1353
1354  // The security style should still be secure.
1355  CheckAuthenticatedState(tab, false);
1356
1357  // And the frame should be blocked.
1358  bool is_content_evil = true;
1359  content::RenderFrameHost* content_frame = content::FrameMatchingPredicate(
1360        tab, base::Bind(&content::FrameMatchesName, "contentFrame"));
1361  std::string is_evil_js("window.domAutomationController.send("
1362                         "document.getElementById('evilDiv') != null);");
1363  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(content_frame,
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  content::RenderFrameHost* content_frame = content::FrameMatchingPredicate(
1499        tab, base::Bind(&content::FrameMatchesName, "contentFrame"));
1500  std::string is_evil_js("window.domAutomationController.send("
1501                         "document.getElementById('evilDiv') != null);");
1502  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(content_frame,
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