diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-16 03:29:03 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-16 03:29:03 +0000 |
commit | 3b073b258b19937b1dd9b6b2a609dee207865eba (patch) | |
tree | fb0779236d58e8a49513c1036d891c2e10c9573c /chrome/browser/ssl/ssl_uitest.cc | |
parent | 7fb087e0800d0faaa31e4a029ad6813f251b4848 (diff) | |
download | chromium_src-3b073b258b19937b1dd9b6b2a609dee207865eba.zip chromium_src-3b073b258b19937b1dd9b6b2a609dee207865eba.tar.gz chromium_src-3b073b258b19937b1dd9b6b2a609dee207865eba.tar.bz2 |
Move all the SSL stuff into its own subdir
Review URL: http://codereview.chromium.org/18137
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@8165 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/ssl/ssl_uitest.cc')
-rw-r--r-- | chrome/browser/ssl/ssl_uitest.cc | 932 |
1 files changed, 932 insertions, 0 deletions
diff --git a/chrome/browser/ssl/ssl_uitest.cc b/chrome/browser/ssl/ssl_uitest.cc new file mode 100644 index 0000000..2a84744 --- /dev/null +++ b/chrome/browser/ssl/ssl_uitest.cc @@ -0,0 +1,932 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <Windows.h> +#include <Wincrypt.h> + +#include <string> + +#include "chrome/common/pref_names.h" +#include "chrome/test/automation/browser_proxy.h" +#include "chrome/test/automation/tab_proxy.h" +#include "chrome/test/ui/ui_test.h" +#include "net/base/ssl_test_util.h" +#include "net/url_request/url_request_unittest.h" + +namespace { + +const wchar_t kDocRoot[] = L"chrome/test/data"; + +class SSLUITest : public UITest { + protected: + SSLUITest() { + dom_automation_enabled_ = true; + EXPECT_TRUE(util_.CheckCATrusted()); + } + + TabProxy* GetActiveTabProxy() { + scoped_ptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0)); + EXPECT_TRUE(browser_proxy.get()); + return browser_proxy->GetActiveTab(); + } + + void NavigateTab(TabProxy* tab_proxy, const GURL& url) { + ASSERT_TRUE(tab_proxy->NavigateToURL(url)); + } + + void AppendTab(const GURL& url) { + scoped_ptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0)); + EXPECT_TRUE(browser_proxy.get()); + EXPECT_TRUE(browser_proxy->AppendTab(url)); + } + + HTTPTestServer* PlainServer() { + return HTTPTestServer::CreateServer(kDocRoot); + } + + HTTPSTestServer* GoodCertServer() { + return HTTPSTestServer::CreateServer(util_.kHostName, util_.kOKHTTPSPort, + kDocRoot, util_.GetOKCertPath().ToWStringHack()); + } + + HTTPSTestServer* BadCertServer() { + return HTTPSTestServer::CreateServer(util_.kHostName, util_.kBadHTTPSPort, + kDocRoot, util_.GetExpiredCertPath().ToWStringHack()); + } + + protected: + SSLTestUtil util_; + + DISALLOW_COPY_AND_ASSIGN(SSLUITest); +}; + +} // namespace + +// Visits a regular page over http. +TEST_F(SSLUITest, TestHTTP) { + scoped_refptr<HTTPTestServer> server = PlainServer(); + + scoped_ptr<TabProxy> tab(GetActiveTabProxy()); + NavigateTab(tab.get(), server->TestServerPageW(L"files/ssl/google.html")); + + NavigationEntry::PageType page_type; + EXPECT_TRUE(tab->GetPageType(&page_type)); + EXPECT_EQ(NavigationEntry::NORMAL_PAGE, page_type); + + SecurityStyle security_style; + int cert_status; + int mixed_content_state; + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_UNAUTHENTICATED, security_style); + EXPECT_EQ(0, cert_status); + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); +} + +// Visits a page over http which includes broken https resources (status should +// be OK). +TEST_F(SSLUITest, TestHTTPWithBrokenHTTPSResource) { + scoped_refptr<HTTPTestServer> http_server = PlainServer(); + scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer(); + scoped_ptr<TabProxy> tab(GetActiveTabProxy()); + + NavigateTab(tab.get(), + http_server->TestServerPageW(L"files/ssl/page_with_unsafe_contents.html")); + + SecurityStyle security_style; + int cert_status; + int mixed_content_state; + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_UNAUTHENTICATED, security_style); + EXPECT_EQ(0, cert_status); + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); +} + +// Visits a page over OK https: +TEST_F(SSLUITest, TestOKHTTPS) { + scoped_refptr<HTTPSTestServer> https_server = GoodCertServer(); + scoped_ptr<TabProxy> tab(GetActiveTabProxy()); + NavigateTab(tab.get(), + https_server->TestServerPageW(L"files/ssl/google.html")); + + NavigationEntry::PageType page_type; + EXPECT_TRUE(tab->GetPageType(&page_type)); + EXPECT_EQ(NavigationEntry::NORMAL_PAGE, page_type); + + SecurityStyle security_style; + int cert_status; + int mixed_content_state; + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, security_style); + EXPECT_EQ(0, cert_status & net::CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); +} + +// Visits a page with https error and proceed: +TEST_F(SSLUITest, TestHTTPSExpiredCertAndProceed) { + scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer(); + scoped_ptr<TabProxy> tab(GetActiveTabProxy()); + NavigateTab(tab.get(), + bad_https_server->TestServerPageW(L"files/ssl/google.html")); + + NavigationEntry::PageType page_type; + EXPECT_TRUE(tab->GetPageType(&page_type)); + EXPECT_EQ(NavigationEntry::INTERSTITIAL_PAGE, page_type); + + SecurityStyle security_style; + int cert_status; + int mixed_content_state; + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_AUTHENTICATION_BROKEN, security_style); + EXPECT_EQ(net::CERT_STATUS_DATE_INVALID, + cert_status & net::CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); + + EXPECT_TRUE(tab->TakeActionOnSSLBlockingPage(true)); + EXPECT_TRUE(tab->GetPageType(&page_type)); + EXPECT_EQ(NavigationEntry::NORMAL_PAGE, page_type); + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_AUTHENTICATION_BROKEN, security_style); + EXPECT_EQ(net::CERT_STATUS_DATE_INVALID, + cert_status & net::CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); +} + +// Visits a page with https error and don't proceed (and ensure we can still +// navigate at that point): +TEST_F(SSLUITest, TestHTTPSExpiredCertAndDontProceed) { + scoped_refptr<HTTPTestServer> http_server = PlainServer(); + scoped_refptr<HTTPSTestServer> good_https_server = GoodCertServer(); + scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer(); + scoped_ptr<TabProxy> tab(GetActiveTabProxy()); + + // First navigate to an OK page. + NavigateTab(tab.get(), + good_https_server->TestServerPageW(L"files/ssl/google.html")); + + GURL cross_site_url = + bad_https_server->TestServerPageW(L"files/ssl/google.html"); + // Change the host name from 127.0.0.1 to localhost so it triggers a + // cross-site navigation so we can test http://crbug.com/5800 is gone. + ASSERT_EQ("127.0.0.1", cross_site_url.host()); + GURL::Replacements replacements; + std::string new_host("localhost"); + replacements.SetHostStr(new_host); + cross_site_url = cross_site_url.ReplaceComponents(replacements); + + // Now go to a bad HTTPS page. + NavigateTab(tab.get(), cross_site_url); + + // An interstitial should be showing. + NavigationEntry::PageType page_type; + EXPECT_TRUE(tab->GetPageType(&page_type)); + EXPECT_EQ(NavigationEntry::INTERSTITIAL_PAGE, page_type); + + SecurityStyle security_style; + int cert_status; + int mixed_content_state; + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_AUTHENTICATION_BROKEN, security_style); + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); + + // Simulate user clicking "Take me back". + EXPECT_TRUE(tab->TakeActionOnSSLBlockingPage(false)); + + // We should be back to the original good page. + EXPECT_TRUE(tab->GetPageType(&page_type)); + EXPECT_EQ(NavigationEntry::NORMAL_PAGE, page_type); + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, security_style); + EXPECT_EQ(0, cert_status & net::CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); + + // Try to navigate to a new page. (to make sure bug 5800 is fixed). + NavigateTab(tab.get(), + http_server->TestServerPageW(L"files/ssl/google.html")); + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_UNAUTHENTICATED, security_style); +} + +// +// Mixed contents +// + +// Visits a page with mixed content. +TEST_F(SSLUITest, TestMixedContents) { + scoped_refptr<HTTPSTestServer> https_server = GoodCertServer(); + scoped_refptr<HTTPTestServer> http_server = PlainServer(); + + // Load a page with mixed-content, the default behavior is to show the mixed + // content. + scoped_ptr<TabProxy> tab(GetActiveTabProxy()); + NavigateTab(tab.get(), + https_server->TestServerPageW(L"files/ssl/page_with_mixed_contents.html")); + NavigationEntry::PageType page_type; + EXPECT_TRUE(tab->GetPageType(&page_type)); + EXPECT_EQ(NavigationEntry::NORMAL_PAGE, page_type); + + SecurityStyle security_style; + int cert_status; + int mixed_content_state; + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, security_style); + EXPECT_EQ(0, + cert_status & net::CERT_STATUS_ALL_ERRORS); // No errors expected. + EXPECT_EQ(NavigationEntry::SSLStatus::MIXED_CONTENT, mixed_content_state); + + // Now select the block mixed-content pref and reload the page. + scoped_ptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0)); + EXPECT_TRUE(browser_proxy.get()); + EXPECT_TRUE(browser_proxy->SetIntPreference(prefs::kMixedContentFiltering, + FilterPolicy::FILTER_ALL)); + EXPECT_TRUE(tab->Reload()); + + // The image should be filtered. + int img_width; + EXPECT_TRUE(tab->ExecuteAndExtractInt(L"", + L"window.domAutomationController.send(ImageWidth());", + &img_width)); + // In order to check that the image was not loaded, we check its width. + // The actual image (Google logo) is 114 pixels wide, we assume the broken + // image is less than 100. + EXPECT_GT(100, img_width); + + // The state should be OK since we are not showing the resource. + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, security_style); + EXPECT_EQ(0, cert_status & net::CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); + + // There should be one info-bar to show the mixed-content. + int info_bar_count = 0; + EXPECT_TRUE(tab->GetSSLInfoBarCount(&info_bar_count)); + EXPECT_EQ(1, info_bar_count); + + // Activate the link on the info-bar to show the mixed-content. + EXPECT_TRUE(tab->ClickSSLInfoBarLink(0, true)); + + // The image should show now. + EXPECT_TRUE(tab->ExecuteAndExtractInt(L"", + L"window.domAutomationController.send(ImageWidth());", + &img_width)); + EXPECT_LT(100, img_width); + + // And our status should be mixed-content. + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, security_style); + EXPECT_EQ(0, cert_status & net::CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(NavigationEntry::SSLStatus::MIXED_CONTENT, mixed_content_state); +} + +// Visits a page with unsafe content and make sure that: +// - frames content is replaced with warning +// - images and scripts are filtered out entirely +TEST_F(SSLUITest, TestUnsafeContents) { + scoped_refptr<HTTPSTestServer> good_https_server = GoodCertServer(); + scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer(); + + scoped_ptr<TabProxy> tab(GetActiveTabProxy()); + NavigateTab(tab.get(), + good_https_server->TestServerPageW( + L"files/ssl/page_with_unsafe_contents.html")); + NavigationEntry::PageType page_type; + EXPECT_TRUE(tab->GetPageType(&page_type)); + EXPECT_EQ(NavigationEntry::NORMAL_PAGE, page_type); + + SecurityStyle security_style; + int cert_status; + int mixed_content_state; + // When the bad content is filtered, the state is expected to be + // authenticated. + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, security_style); + EXPECT_EQ(0, + cert_status & net::CERT_STATUS_ALL_ERRORS); // No errors expected. + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); + + // Because of cross-frame scripting restrictions, we cannot access the iframe + // content. So to know if the frame was loaded, we just check if a popup was + // opened (the iframe content opens one). + // Note: because of bug 1115868, no constrained window is opened right now. + // Once the bug is fixed, this will do the real check. + int constrained_window_count = 0; + EXPECT_TRUE(tab->GetConstrainedWindowCount(&constrained_window_count)); + EXPECT_EQ(0, constrained_window_count); + + int img_width; + EXPECT_TRUE(tab->ExecuteAndExtractInt(L"", + L"window.domAutomationController.send(ImageWidth());", + &img_width)); + // In order to check that the image was not loaded, we check its width. + // The actual image (Google logo) is 114 pixels wide, we assume the broken + // image is less than 100. + EXPECT_GT(100, img_width); + + bool js_result = false; + EXPECT_TRUE(tab->ExecuteAndExtractBool(L"", + L"window.domAutomationController.send(IsFooSet());", + &js_result)); + EXPECT_FALSE(js_result); +} + +// Visits a page with mixed content loaded by JS (after the initial page load). +TEST_F(SSLUITest, TestMixedContentsLoadedFromJS) { + scoped_refptr<HTTPSTestServer> https_server = GoodCertServer(); + scoped_refptr<HTTPTestServer> http_server = PlainServer(); + + scoped_ptr<TabProxy> tab(GetActiveTabProxy()); + NavigateTab(tab.get(), https_server->TestServerPageW( + L"files/ssl/page_with_dynamic_mixed_contents.html")); + NavigationEntry::PageType page_type; + EXPECT_TRUE(tab->GetPageType(&page_type)); + EXPECT_EQ(NavigationEntry::NORMAL_PAGE, page_type); + SecurityStyle security_style; + int cert_status; + int mixed_content_state; + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, security_style); + EXPECT_EQ(0, + cert_status & net::CERT_STATUS_ALL_ERRORS); // No errors expected. + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); + + // Load the insecure image. + bool js_result = false; + EXPECT_TRUE(tab->ExecuteAndExtractBool(L"", + L"loadBadImage();", + &js_result)); + EXPECT_TRUE(js_result); + + // We should now have mixed-contents. + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, security_style); + EXPECT_EQ(0, + cert_status & net::CERT_STATUS_ALL_ERRORS); // No errors expected. + EXPECT_EQ(NavigationEntry::SSLStatus::MIXED_CONTENT, mixed_content_state); +} + +// Visits a page with an image over http. Visits another page over https +// referencing that same image over http (hoping it is coming from the webcore +// memory cache). +TEST_F(SSLUITest, TestCachedMixedContents) { + scoped_refptr<HTTPSTestServer> https_server = GoodCertServer(); + scoped_refptr<HTTPTestServer> http_server = PlainServer(); + + scoped_ptr<TabProxy> tab(GetActiveTabProxy()); + NavigateTab(tab.get(), http_server->TestServerPageW( + L"files/ssl/page_with_mixed_contents.html")); + + NavigationEntry::PageType page_type; + EXPECT_TRUE(tab->GetPageType(&page_type)); + EXPECT_EQ(NavigationEntry::NORMAL_PAGE, page_type); + SecurityStyle security_style; + int cert_status; + int mixed_content_state; + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_UNAUTHENTICATED, security_style); + EXPECT_EQ(0, + cert_status & net::CERT_STATUS_ALL_ERRORS); // No errors expected. + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); + + // Load again but over SSL. It should have mixed-contents (even though the + // image comes from the WebCore memory cache). + NavigateTab(tab.get(), https_server->TestServerPageW( + L"files/ssl/page_with_mixed_contents.html")); + + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_TRUE(tab->GetPageType(&page_type)); + EXPECT_EQ(NavigationEntry::NORMAL_PAGE, page_type); + EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, security_style); + EXPECT_EQ(0, + cert_status & net::CERT_STATUS_ALL_ERRORS); // No errors expected. + EXPECT_EQ(NavigationEntry::SSLStatus::MIXED_CONTENT, mixed_content_state); +} + +// This test ensures the CN invalid status does not 'stick' to a certificate +// (see bug #1044942) and that it depends on the host-name. +// TODO(jcampan): this test is flacky and fails sometimes (bug #1065095) +TEST_F(SSLUITest, DISABLED_TestCNInvalidStickiness) { + const std::string kLocalHost = "localhost"; + scoped_refptr<HTTPSTestServer> https_server = + HTTPSTestServer::CreateServer(kLocalHost, util_.kOKHTTPSPort, + kDocRoot, util_.GetOKCertPath().ToWStringHack()); + ASSERT_TRUE(NULL != https_server.get()); + + // First we hit the server with hostname, this generates an invalid policy + // error. + scoped_ptr<TabProxy> tab(GetActiveTabProxy()); + NavigateTab(tab.get(), https_server->TestServerPageW( + L"files/ssl/google.html")); + + // We get an interstitial page as a result. + NavigationEntry::PageType page_type; + EXPECT_TRUE(tab->GetPageType(&page_type)); + EXPECT_EQ(NavigationEntry::INTERSTITIAL_PAGE, page_type); + + SecurityStyle security_style; + int cert_status; + int mixed_content_state; + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_AUTHENTICATION_BROKEN, security_style); + EXPECT_EQ(net::CERT_STATUS_COMMON_NAME_INVALID, + cert_status & net::CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); + + // We proceed through the interstitial page. + EXPECT_TRUE(tab->TakeActionOnSSLBlockingPage(true)); + EXPECT_TRUE(tab->GetPageType(&page_type)); + EXPECT_EQ(NavigationEntry::NORMAL_PAGE, page_type); + + // Now we try again with the right host name this time. + + // Let's change the host-name in the url. + GURL url = https_server->TestServerPageW(L"files/ssl/google.html"); + std::string::size_type hostname_index = url.spec().find(kLocalHost); + ASSERT_TRUE(hostname_index != std::string::npos); // Test sanity check. + std::string new_url; + new_url.append(url.spec().substr(0, hostname_index)); + new_url.append(util_.kHostName); + new_url.append(url.spec().substr(hostname_index + kLocalHost.size())); + + NavigateTab(tab.get(), GURL(new_url)); + + // Security state should be OK. + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, security_style); + EXPECT_EQ(0, + cert_status & net::CERT_STATUS_ALL_ERRORS); // No errors expected. + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); + + // Now try again the broken one to make sure it is still broken. + NavigateTab(tab.get(), https_server->TestServerPageW( + L"files/ssl/google.html")); + + EXPECT_TRUE(tab->GetPageType(&page_type)); + // Since we OKed the interstitial last time, we get right to the page. + EXPECT_EQ(NavigationEntry::NORMAL_PAGE, page_type); + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_AUTHENTICATION_BROKEN, security_style); + EXPECT_EQ(net::CERT_STATUS_COMMON_NAME_INVALID, + cert_status & net::CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); +} + +// Test that navigating to a #ref does not change a bad security state. +TEST_F(SSLUITest, TestRefNavigation) { + scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer(); + scoped_ptr<TabProxy> tab(GetActiveTabProxy()); + NavigateTab(tab.get(), + bad_https_server->TestServerPageW(L"files/ssl/page_with_refs.html")); + + NavigationEntry::PageType page_type; + EXPECT_TRUE(tab->GetPageType(&page_type)); + EXPECT_EQ(page_type, NavigationEntry::INTERSTITIAL_PAGE); + + SecurityStyle security_style; + int cert_status; + int mixed_content_state; + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_AUTHENTICATION_BROKEN, security_style); + EXPECT_EQ(net::CERT_STATUS_DATE_INVALID, cert_status); + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); + + EXPECT_TRUE(tab->TakeActionOnSSLBlockingPage(true)); + EXPECT_TRUE(tab->GetPageType(&page_type)); + EXPECT_EQ(NavigationEntry::NORMAL_PAGE, page_type); + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_AUTHENTICATION_BROKEN, security_style); + EXPECT_EQ(net::CERT_STATUS_DATE_INVALID, + cert_status & net::CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); + + // Now navigate to a ref in the page. + NavigateTab(tab.get(), + bad_https_server->TestServerPageW(L"files/ssl/page_with_refs.html#jp")); + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_AUTHENTICATION_BROKEN, security_style); + EXPECT_EQ(net::CERT_STATUS_DATE_INVALID, + cert_status & net::CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); +} + +// Tests that closing a page that has a unsafe pop-up does not crash the browser +// (bug #1966). +// Disabled because flaky (bug #2136). +TEST_F(SSLUITest, DISABLED_TestCloseTabWithUnsafePopup) { + scoped_refptr<HTTPTestServer> http_server = PlainServer(); + scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer(); + + scoped_ptr<TabProxy> tab(GetActiveTabProxy()); + NavigateTab(tab.get(), + http_server->TestServerPageW( + L"files/ssl/page_with_unsafe_popup.html")); + + int popup_count = 0; + EXPECT_TRUE(tab->GetConstrainedWindowCount(&popup_count)); + EXPECT_EQ(1, popup_count); + + // Let's add another tab to make sure the browser does not exit when we close + // the first tab. + scoped_ptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0)); + EXPECT_TRUE(browser_proxy.get()); + browser_proxy->AppendTab( + http_server->TestServerPageW(L"files/ssl/google.html")); + + // Close the first tab. + tab->Close(); +} + +// Visit a page over bad https that is a redirect to a page with good https. +TEST_F(SSLUITest, TestRedirectBadToGoodHTTPS) { + scoped_refptr<HTTPSTestServer> good_https_server = GoodCertServer(); + scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer(); + + scoped_ptr<TabProxy> tab(GetActiveTabProxy()); + GURL url1 = bad_https_server->TestServerPageW(L"server-redirect?"); + GURL url2 = good_https_server->TestServerPageW(L"files/ssl/google.html"); + NavigateTab(tab.get(), GURL(url1.spec() + url2.spec())); + + NavigationEntry::PageType page_type; + EXPECT_TRUE(tab->GetPageType(&page_type)); + EXPECT_EQ(page_type, NavigationEntry::INTERSTITIAL_PAGE); + + SecurityStyle security_style; + int cert_status; + int mixed_content_state; + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_AUTHENTICATION_BROKEN, security_style); + EXPECT_EQ(net::CERT_STATUS_DATE_INVALID, cert_status); + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); + + EXPECT_TRUE(tab->TakeActionOnSSLBlockingPage(true)); + // We have been redirected to the good page. + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, security_style); + EXPECT_EQ(0, + cert_status & net::CERT_STATUS_ALL_ERRORS); // No errors expected. + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); +} + +// Visit a page over good https that is a redirect to a page with bad https. +TEST_F(SSLUITest, TestRedirectGoodToBadHTTPS) { + scoped_refptr<HTTPSTestServer> good_https_server = GoodCertServer(); + scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer(); + + scoped_ptr<TabProxy> tab(GetActiveTabProxy()); + GURL url1 = good_https_server->TestServerPageW(L"server-redirect?"); + GURL url2 = bad_https_server->TestServerPageW(L"files/ssl/google.html"); + NavigateTab(tab.get(), GURL(url1.spec() + url2.spec())); + + NavigationEntry::PageType page_type; + EXPECT_TRUE(tab->GetPageType(&page_type)); + EXPECT_EQ(page_type, NavigationEntry::INTERSTITIAL_PAGE); + + EXPECT_TRUE(tab->TakeActionOnSSLBlockingPage(true)); + + SecurityStyle security_style; + int cert_status; + int mixed_content_state; + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_AUTHENTICATION_BROKEN, security_style); + EXPECT_EQ(net::CERT_STATUS_DATE_INVALID, + cert_status & net::CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); +} + +// Visit a page over http that is a redirect to a page with https (good and +// bad). +TEST_F(SSLUITest, TestRedirectHTTPToHTTPS) { + scoped_refptr<HTTPTestServer> http_server = PlainServer(); + scoped_refptr<HTTPSTestServer> good_https_server = GoodCertServer(); + scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer(); + + // HTTP redirects to good HTTPS. + scoped_ptr<TabProxy> tab(GetActiveTabProxy()); + GURL http_url = http_server->TestServerPageW(L"server-redirect?"); + GURL good_https_url = + good_https_server->TestServerPageW(L"files/ssl/google.html"); + NavigateTab(tab.get(), GURL(http_url.spec() + good_https_url.spec())); + + SecurityStyle security_style; + int cert_status; + int mixed_content_state; + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, security_style); + EXPECT_EQ(0, cert_status & net::CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); + + // HTTP redirects to bad HTTPS. + GURL bad_https_url = + bad_https_server->TestServerPageW(L"files/ssl/google.html"); + NavigateTab(tab.get(), GURL(http_url.spec() + bad_https_url.spec())); + + NavigationEntry::PageType page_type; + EXPECT_TRUE(tab->GetPageType(&page_type)); + EXPECT_EQ(page_type, NavigationEntry::INTERSTITIAL_PAGE); + + // Continue on the interstitial. + EXPECT_TRUE(tab->TakeActionOnSSLBlockingPage(true)); + + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_AUTHENTICATION_BROKEN, security_style); + EXPECT_EQ(net::CERT_STATUS_DATE_INVALID, + cert_status & net::CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); +} + +// Visit a page over https that is a redirect to a page with http (to make sure +// we don't keep the secure state). +TEST_F(SSLUITest, TestRedirectHTTPSToHTTP) { + scoped_refptr<HTTPTestServer> http_server = PlainServer(); + scoped_refptr<HTTPSTestServer> https_server = GoodCertServer(); + + scoped_ptr<TabProxy> tab(GetActiveTabProxy()); + GURL https_url = https_server->TestServerPageW(L"server-redirect?"); + GURL http_url = http_server->TestServerPageW(L"files/ssl/google.html"); + NavigateTab(tab.get(), GURL(https_url.spec() + http_url.spec())); + + SecurityStyle security_style; + int cert_status; + int mixed_content_state; + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_UNAUTHENTICATED, security_style); + EXPECT_EQ(0, cert_status & net::CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); +} + +// Visits a page to which we could not connect (bad port) over http and https +// and make sure the security style is correct. +TEST_F(SSLUITest, TestConnectToBadPort) { + scoped_ptr<TabProxy> tab(GetActiveTabProxy()); + + GURL http_url("http://localhost:17"); + NavigateTab(tab.get(), http_url); + + SecurityStyle security_style; + int cert_status; + int mixed_content_state; + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_UNAUTHENTICATED, security_style); + EXPECT_EQ(0, cert_status & net::CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); + + // Same thing over HTTPS. + GURL https_url("https://localhost:17"); + NavigateTab(tab.get(), https_url); + + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_UNAUTHENTICATED, security_style); + EXPECT_EQ(0, cert_status & net::CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); +} + +// +// Frame navigation +// + +// From a good HTTPS top frame: +// - navigate to an OK HTTPS frame +// - navigate to a bad HTTPS (expect unsafe content and filtered frame), then +// back +// - navigate to HTTP (expect mixed content), then back +TEST_F(SSLUITest, TestGoodFrameNavigation) { + scoped_refptr<HTTPTestServer> http_server = PlainServer(); + scoped_refptr<HTTPSTestServer> good_https_server = GoodCertServer(); + scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer(); + + scoped_ptr<TabProxy> tab(GetActiveTabProxy()); + NavigateTab(tab.get(), + good_https_server->TestServerPageW(L"files/ssl/top_frame.html")); + + SecurityStyle security_style; + int cert_status; + int mixed_content_state; + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, security_style); + EXPECT_EQ(0, cert_status & net::CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); + + bool success = false; + // Now navigate inside the frame. + int64 last_nav_time = 0; + EXPECT_TRUE(tab->GetLastNavigationTime(&last_nav_time)); + EXPECT_TRUE(tab->ExecuteAndExtractBool(L"", + L"window.domAutomationController.send(clickLink('goodHTTPSLink'));", + &success)); + EXPECT_TRUE(success); + EXPECT_TRUE(tab->WaitForNavigation(last_nav_time)); + + // We should still be fine. + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, security_style); + EXPECT_EQ(0, cert_status & net::CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); + + // Now let's hit a bad page. + EXPECT_TRUE(tab->GetLastNavigationTime(&last_nav_time)); + EXPECT_TRUE(tab->ExecuteAndExtractBool(L"", + L"window.domAutomationController.send(clickLink('badHTTPSLink'));", + &success)); + EXPECT_TRUE(success); + EXPECT_TRUE(tab->WaitForNavigation(last_nav_time)); + + // The security style should still be secure. + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, security_style); + EXPECT_EQ(0, cert_status & net::CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); + + // And the frame should be blocked. + bool is_content_evil = true; + std::wstring content_frame_xpath(L"html/frameset/frame[2]"); + std::wstring is_frame_evil_js( + L"window.domAutomationController" + L".send(document.getElementById('evilDiv') != null);"); + EXPECT_TRUE(tab->ExecuteAndExtractBool(content_frame_xpath, + is_frame_evil_js, + &is_content_evil)); + EXPECT_FALSE(is_content_evil); + + // Now go back, our state should return to OK. + EXPECT_TRUE(tab->GoBack()); + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, security_style); + EXPECT_EQ(0, cert_status & net::CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); + + // Navigate to a page served over HTTP. + EXPECT_TRUE(tab->GetLastNavigationTime(&last_nav_time)); + EXPECT_TRUE(tab->ExecuteAndExtractBool(L"", + L"window.domAutomationController.send(clickLink('HTTPLink'));", + &success)); + EXPECT_TRUE(success); + EXPECT_TRUE(tab->WaitForNavigation(last_nav_time)); + + // Our state should be mixed-content. + // Status should be "contains bad contents". + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, security_style); + EXPECT_EQ(0, cert_status & net::CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(NavigationEntry::SSLStatus::MIXED_CONTENT, mixed_content_state); + + // Go back, our state should be back to OK. + EXPECT_TRUE(tab->GoBack()); + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, security_style); + EXPECT_EQ(0, cert_status & net::CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); +} + +// From a bad HTTPS top frame: +// - navigate to an OK HTTPS frame (expected to be still authentication broken). +TEST_F(SSLUITest, TestBadFrameNavigation) { + scoped_refptr<HTTPSTestServer> good_https_server = GoodCertServer(); + scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer(); + + scoped_ptr<TabProxy> tab(GetActiveTabProxy()); + NavigateTab(tab.get(), + bad_https_server->TestServerPageW(L"files/ssl/top_frame.html")); + + SecurityStyle security_style; + int cert_status; + int mixed_content_state; + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_AUTHENTICATION_BROKEN, security_style); + EXPECT_EQ(net::CERT_STATUS_DATE_INVALID, + cert_status & net::CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); + + // Continue on the interstitial. + EXPECT_TRUE(tab->TakeActionOnSSLBlockingPage(true)); + + // Navigate to a good frame. + bool success = false; + int64 last_nav_time = 0; + EXPECT_TRUE(tab->GetLastNavigationTime(&last_nav_time)); + EXPECT_TRUE(tab->ExecuteAndExtractBool(L"", + L"window.domAutomationController.send(clickLink('goodHTTPSLink'));", + &success)); + EXPECT_TRUE(success); + EXPECT_TRUE(tab->WaitForNavigation(last_nav_time)); + + // We should still be authentication broken. + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_AUTHENTICATION_BROKEN, security_style); + EXPECT_EQ(net::CERT_STATUS_DATE_INVALID, + cert_status & net::CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); +} + +// From an HTTP top frame, navigate to good and bad HTTPS (security state should +// stay unauthenticated). +TEST_F(SSLUITest, TestUnauthenticatedFrameNavigation) { + scoped_refptr<HTTPTestServer> http_server = PlainServer(); + scoped_refptr<HTTPSTestServer> good_https_server = GoodCertServer(); + scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer(); + + scoped_ptr<TabProxy> tab(GetActiveTabProxy()); + NavigateTab(tab.get(), + http_server->TestServerPageW(L"files/ssl/top_frame.html")); + + SecurityStyle security_style; + int cert_status; + int mixed_content_state; + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_UNAUTHENTICATED, security_style); + EXPECT_EQ(0, cert_status & net::CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); + + // Now navigate inside the frame to a secure HTTPS frame. + bool success = false; + int64 last_nav_time = 0; + EXPECT_TRUE(tab->GetLastNavigationTime(&last_nav_time)); + EXPECT_TRUE(tab->ExecuteAndExtractBool(L"", + L"window.domAutomationController.send(clickLink('goodHTTPSLink'));", + &success)); + EXPECT_TRUE(success); + EXPECT_TRUE(tab->WaitForNavigation(last_nav_time)); + + // We should still be unauthenticated. + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_UNAUTHENTICATED, security_style); + EXPECT_EQ(0, cert_status & net::CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); + + // Now navigate to a bad HTTPS frame. + EXPECT_TRUE(tab->GetLastNavigationTime(&last_nav_time)); + EXPECT_TRUE(tab->ExecuteAndExtractBool(L"", + L"window.domAutomationController.send(clickLink('badHTTPSLink'));", + &success)); + EXPECT_TRUE(success); + EXPECT_TRUE(tab->WaitForNavigation(last_nav_time)); + + // State should not have changed. + EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status, + &mixed_content_state)); + EXPECT_EQ(SECURITY_STYLE_UNAUTHENTICATED, security_style); + EXPECT_EQ(0, cert_status & net::CERT_STATUS_ALL_ERRORS); + EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state); + + // And the frame should have been blocked (see bug #2316). + bool is_content_evil = true; + std::wstring content_frame_xpath(L"html/frameset/frame[2]"); + std::wstring is_frame_evil_js( + L"window.domAutomationController" + L".send(document.getElementById('evilDiv') != null);"); + EXPECT_TRUE(tab->ExecuteAndExtractBool(content_frame_xpath, + is_frame_evil_js, + &is_content_evil)); + EXPECT_FALSE(is_content_evil); +} + + +// TODO(jcampan): more tests to do below. + +// Visit a page over https that contains a frame with a redirect. + +// XMLHttpRequest mixed in synchronous mode. + +// XMLHttpRequest mixed in asynchronous mode. + +// XMLHttpRequest over bad ssl in synchronous mode. + +// XMLHttpRequest over OK ssl in synchronous mode. |