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