diff options
author | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-15 02:59:07 +0000 |
---|---|---|
committer | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-15 02:59:07 +0000 |
commit | 132048857e69b3f07e7d50bda996d1923c9c8e7b (patch) | |
tree | d98c67ef93da6b9cd31acf1532e6f2dbba18a97c /chrome/browser/ssl | |
parent | f3b6d491f7f4233b4862f7352f6ed477f3f1e95a (diff) | |
download | chromium_src-132048857e69b3f07e7d50bda996d1923c9c8e7b.zip chromium_src-132048857e69b3f07e7d50bda996d1923c9c8e7b.tar.gz chromium_src-132048857e69b3f07e7d50bda996d1923c9c8e7b.tar.bz2 |
Revert 47347 - (Original patch reviewed at http://codereview.chromium.org/2067003 )
Track "display" and "run" separately for mixed content, and make the latter downgrade the SSL state to "authentication broken".
Make the "display" state only affect the current tab (not the entire host).
Fix an SSL browser test by supplying the appropriate SiteInstance*.
Move a test from "disabled" to "flaky" since it at least passes for me.
Make the SSLManager header and .cc files put functions in the same order, and make that order somewhat saner.
Falied TestGoodFrameNavigation on Mac 10.5 browser tests
among other things:
/b/slave/chromium-rel-mac-builder/build/src/chrome/browser/ssl/ssl_browser_tests.cc:43: Failure
Value of: entry->ssl().displayed_mixed_content()
Actual: false
Expected: displayed_mixed_content
Which is: true
BUG=15072, 18626, 40932, 42758
TEST=Covered by browser tests
Review URL: http://codereview.chromium.org/2063008
TBR=pkasting@chromium.org
Review URL: http://codereview.chromium.org/2095006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@47357 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/ssl')
-rw-r--r-- | chrome/browser/ssl/ssl_browser_tests.cc | 167 | ||||
-rw-r--r-- | chrome/browser/ssl/ssl_host_state.cc | 17 | ||||
-rw-r--r-- | chrome/browser/ssl/ssl_host_state.h | 15 | ||||
-rw-r--r-- | chrome/browser/ssl/ssl_host_state_unittest.cc | 26 | ||||
-rw-r--r-- | chrome/browser/ssl/ssl_manager.cc | 249 | ||||
-rw-r--r-- | chrome/browser/ssl/ssl_manager.h | 68 | ||||
-rw-r--r-- | chrome/browser/ssl/ssl_policy.cc | 98 | ||||
-rw-r--r-- | chrome/browser/ssl/ssl_policy.h | 18 | ||||
-rw-r--r-- | chrome/browser/ssl/ssl_policy_backend.cc | 23 | ||||
-rw-r--r-- | chrome/browser/ssl/ssl_policy_backend.h | 15 |
10 files changed, 326 insertions, 370 deletions
diff --git a/chrome/browser/ssl/ssl_browser_tests.cc b/chrome/browser/ssl/ssl_browser_tests.cc index 74d9dbe..a2fa261b 100644 --- a/chrome/browser/ssl/ssl_browser_tests.cc +++ b/chrome/browser/ssl/ssl_browser_tests.cc @@ -34,14 +34,13 @@ class SSLUITest : public InProcessBrowserTest { } void CheckAuthenticatedState(TabContents* tab, - bool displayed_mixed_content) { + bool mixed_content) { NavigationEntry* entry = tab->controller().GetActiveEntry(); ASSERT_TRUE(entry); EXPECT_EQ(NavigationEntry::NORMAL_PAGE, entry->page_type()); EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, entry->ssl().security_style()); EXPECT_EQ(0, entry->ssl().cert_status() & net::CERT_STATUS_ALL_ERRORS); - EXPECT_EQ(displayed_mixed_content, entry->ssl().displayed_mixed_content()); - EXPECT_FALSE(entry->ssl().ran_mixed_content()); + EXPECT_EQ(mixed_content, entry->ssl().has_mixed_content()); } void CheckUnauthenticatedState(TabContents* tab) { @@ -50,13 +49,11 @@ class SSLUITest : public InProcessBrowserTest { EXPECT_EQ(NavigationEntry::NORMAL_PAGE, entry->page_type()); EXPECT_EQ(SECURITY_STYLE_UNAUTHENTICATED, entry->ssl().security_style()); EXPECT_EQ(0, entry->ssl().cert_status() & net::CERT_STATUS_ALL_ERRORS); - EXPECT_FALSE(entry->ssl().displayed_mixed_content()); - EXPECT_FALSE(entry->ssl().ran_mixed_content()); + EXPECT_FALSE(entry->ssl().has_mixed_content()); } void CheckAuthenticationBrokenState(TabContents* tab, int error, - bool ran_mixed_content, bool interstitial) { NavigationEntry* entry = tab->controller().GetActiveEntry(); ASSERT_TRUE(entry); @@ -69,8 +66,7 @@ class SSLUITest : public InProcessBrowserTest { // to SECURITY_STYLE_AUTHENTICATION_BROKEN. ASSERT_NE(net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION, error); EXPECT_EQ(error, entry->ssl().cert_status() & net::CERT_STATUS_ALL_ERRORS); - EXPECT_FALSE(entry->ssl().displayed_mixed_content()); - EXPECT_EQ(ran_mixed_content, entry->ssl().ran_mixed_content()); + EXPECT_FALSE(entry->ssl().has_mixed_content()); } void CheckWorkerLoadResult(TabContents* tab, bool expectLoaded) { @@ -164,12 +160,12 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTPSExpiredCertAndProceed) { bad_https_server->TestServerPage("files/ssl/google.html")); TabContents* tab = browser()->GetSelectedTabContents(); - CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false, + CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, true); // Interstitial showing ProceedThroughInterstitial(tab); - CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false, + CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false); // No interstitial showing } @@ -208,7 +204,7 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, DISABLED_TestHTTPSExpiredCertAndDontProceed) { // An interstitial should be showing. CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID, - false, true); + true); // Interstitial showing. // Simulate user clicking "Take me back". InterstitialPage* interstitial_page = tab->interstitial_page(); @@ -241,7 +237,7 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTPSExpiredCertAndGoBackViaButton) { // Now go to a bad HTTPS page that shows an interstitial. ui_test_utils::NavigateToURL(browser(), bad_https_server->TestServerPage("files/ssl/google.html")); - CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false, + CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, true); // Interstitial showing // Simulate user clicking on back button (crbug.com/39248). @@ -270,7 +266,7 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, FLAKY_TestHTTPSExpiredCertAndGoBackViaMenu) { // Now go to a bad HTTPS page that shows an interstitial. ui_test_utils::NavigateToURL(browser(), bad_https_server->TestServerPage("files/ssl/google.html")); - CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false, + CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, true); // Interstitial showing // Simulate user clicking and holding on back button (crbug.com/37215). @@ -310,7 +306,7 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, FLAKY_TestHTTPSExpiredCertAndGoForward) { // Now go to a bad HTTPS page that shows an interstitial. ui_test_utils::NavigateToURL(browser(), bad_https_server->TestServerPage("files/ssl/google.html")); - CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false, + CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, true); // Interstitial showing // Simulate user clicking and holding on forward button. @@ -372,34 +368,34 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTPSErrorWithNoNavEntry) { // Mixed contents // -// Visits a page that displays mixed content. -IN_PROC_BROWSER_TEST_F(SSLUITest, TestDisplaysMixedContent) { +// Visits a page with mixed content. +IN_PROC_BROWSER_TEST_F(SSLUITest, TestMixedContents) { scoped_refptr<HTTPSTestServer> https_server = GoodCertServer(); ASSERT_TRUE(https_server.get() != NULL); scoped_refptr<HTTPTestServer> http_server = PlainServer(); ASSERT_TRUE(http_server.get() != NULL); - // Load a page that displays mixed content. + // Load a page with mixed-content, the default behavior is to show the mixed + // content. ui_test_utils::NavigateToURL(browser(), https_server->TestServerPage( - "files/ssl/page_displays_mixed_content.html")); + "files/ssl/page_with_mixed_contents.html")); CheckAuthenticatedState(browser()->GetSelectedTabContents(), true); } -// Visits a page that runs mixed content and tries to suppress the mixed content -// warnings by randomizing location.hash. +// Visits a page with an http script that tries to suppress our mixed content +// warnings by randomize location.hash. // Based on http://crbug.com/8706 -IN_PROC_BROWSER_TEST_F(SSLUITest, TestRunsMixedContentRandomizeHash) { +IN_PROC_BROWSER_TEST_F(SSLUITest, TestMixedContentsRandomizeHash) { scoped_refptr<HTTPSTestServer> https_server = GoodCertServer(); ASSERT_TRUE(https_server.get() != NULL); scoped_refptr<HTTPTestServer> http_server = PlainServer(); ASSERT_TRUE(http_server.get() != NULL); ui_test_utils::NavigateToURL(browser(), - https_server->TestServerPage("files/ssl/page_runs_mixed_content.html")); + https_server->TestServerPage("files/ssl/page_with_http_script.html")); - CheckAuthenticationBrokenState(browser()->GetSelectedTabContents(), 0, true, - false); + CheckAuthenticatedState(browser()->GetSelectedTabContents(), true); } // Visits a page with unsafe content and make sure that: @@ -438,13 +434,13 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, FLAKY_TestUnsafeContents) { bool js_result = false; EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( - tab->render_view_host(), std::wstring(), + tab->render_view_host(), 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). -IN_PROC_BROWSER_TEST_F(SSLUITest, TestDisplaysMixedContentLoadedFromJS) { +IN_PROC_BROWSER_TEST_F(SSLUITest, TestMixedContentsLoadedFromJS) { scoped_refptr<HTTPSTestServer> https_server = GoodCertServer(); ASSERT_TRUE(https_server.get() != NULL); scoped_refptr<HTTPTestServer> http_server = PlainServer(); @@ -466,42 +462,11 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, TestDisplaysMixedContentLoadedFromJS) { CheckAuthenticatedState(tab, true); } -// Visits two pages from the same origin: one that displays mixed content and -// one that doesn't. The test checks that we do not propagate the mixed content -// state from one to the other. -IN_PROC_BROWSER_TEST_F(SSLUITest, TestDisplaysMixedContentTwoTabs) { - scoped_refptr<HTTPSTestServer> https_server = GoodCertServer(); - ASSERT_TRUE(https_server.get() != NULL); - scoped_refptr<HTTPTestServer> http_server = PlainServer(); - ASSERT_TRUE(http_server.get() != NULL); - - ui_test_utils::NavigateToURL(browser(), - https_server->TestServerPage("files/ssl/blank_page.html")); - - TabContents* tab1 = browser()->GetSelectedTabContents(); - - // This tab should be fine. - CheckAuthenticatedState(tab1, false); - - // Create a new tab. - GURL url = https_server->TestServerPage( - "files/ssl/page_displays_mixed_content.html"); - TabContents* tab2 = browser()->AddTabWithURL(url, GURL(), - PageTransition::TYPED, 0, Browser::ADD_SELECTED, tab1->GetSiteInstance(), - std::string()); - ui_test_utils::WaitForNavigation(&(tab2->controller())); - - // The new tab has mixed content. - CheckAuthenticatedState(tab2, true); - - // The original tab should not be contaminated. - CheckAuthenticatedState(tab1, false); -} - -// Visits two pages from the same origin: one that runs mixed content and one -// that doesn't. The test checks that we propagate the mixed content state from -// one to the other. -IN_PROC_BROWSER_TEST_F(SSLUITest, TestRunsMixedContentTwoTabs) { +// Visits two pages from the same origin: one with mixed content and one +// without. The test checks that we propagate the mixed content state from one +// to the other. +// TODO(jcampan): http://crbug.com/15072 this test fails. +IN_PROC_BROWSER_TEST_F(SSLUITest, DISABLED_TestMixedContentsTwoTabs) { scoped_refptr<HTTPSTestServer> https_server = GoodCertServer(); ASSERT_TRUE(https_server.get() != NULL); scoped_refptr<HTTPTestServer> http_server = PlainServer(); @@ -517,62 +482,40 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, TestRunsMixedContentTwoTabs) { // Create a new tab. GURL url = - https_server->TestServerPage("files/ssl/page_runs_mixed_content.html"); + https_server->TestServerPage("files/ssl/page_with_http_script.html"); TabContents* tab2 = browser()->AddTabWithURL(url, GURL(), - PageTransition::TYPED, 0, Browser::ADD_SELECTED, tab1->GetSiteInstance(), - std::string()); + PageTransition::TYPED, 0, Browser::ADD_SELECTED, NULL, std::string()); ui_test_utils::WaitForNavigation(&(tab2->controller())); // The new tab has mixed content. - CheckAuthenticationBrokenState(tab2, 0, true, false); + CheckAuthenticatedState(tab2, true); // Which means the origin for the first tab has also been contaminated with // mixed content. - CheckAuthenticationBrokenState(tab1, 0, true, false); + CheckAuthenticatedState(tab1, true); } // 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). -IN_PROC_BROWSER_TEST_F(SSLUITest, TestDisplaysCachedMixedContent) { +IN_PROC_BROWSER_TEST_F(SSLUITest, TestCachedMixedContents) { scoped_refptr<HTTPSTestServer> https_server = GoodCertServer(); ASSERT_TRUE(https_server.get() != NULL); scoped_refptr<HTTPTestServer> http_server = PlainServer(); ASSERT_TRUE(http_server.get() != NULL); ui_test_utils::NavigateToURL(browser(), http_server->TestServerPage( - "files/ssl/page_displays_mixed_content.html")); + "files/ssl/page_with_mixed_contents.html")); TabContents* tab = browser()->GetSelectedTabContents(); CheckUnauthenticatedState(tab); - // Load again but over SSL. It should be marked as displaying mixed content - // (even though the image comes from the WebCore memory cache). + // Load again but over SSL. It should have mixed-contents (even though the + // image comes from the WebCore memory cache). ui_test_utils::NavigateToURL(browser(), https_server->TestServerPage( - "files/ssl/page_displays_mixed_content.html")); + "files/ssl/page_with_mixed_contents.html")); CheckAuthenticatedState(tab, true); } -// Visits a page with script over http. Visits another page over https -// referencing that same script over http (hoping it is coming from the webcore -// memory cache). -IN_PROC_BROWSER_TEST_F(SSLUITest, TestRunsCachedMixedContent) { - scoped_refptr<HTTPSTestServer> https_server = GoodCertServer(); - ASSERT_TRUE(https_server.get() != NULL); - scoped_refptr<HTTPTestServer> http_server = PlainServer(); - ASSERT_TRUE(http_server.get() != NULL); - - ui_test_utils::NavigateToURL(browser(), - http_server->TestServerPage("files/ssl/page_runs_mixed_content.html")); - TabContents* tab = browser()->GetSelectedTabContents(); - CheckUnauthenticatedState(tab); - - // Load again but over SSL. It should be marked as displaying mixed content - // (even though the image comes from the WebCore memory cache). - ui_test_utils::NavigateToURL(browser(), - https_server->TestServerPage("files/ssl/page_runs_mixed_content.html")); - CheckAuthenticationBrokenState(tab, 0, true, false); -} - // This test ensures the CN invalid status does not 'stick' to a certificate // (see bug #1044942) and that it depends on the host-name. IN_PROC_BROWSER_TEST_F(SSLUITest, TestCNInvalidStickiness) { @@ -589,12 +532,12 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, TestCNInvalidStickiness) { // We get an interstitial page as a result. TabContents* tab = browser()->GetSelectedTabContents(); CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID, - false, true); // Interstitial showing. + true); // Interstitial showing. ProceedThroughInterstitial(tab); CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID, - false, false); // No interstitial showing. + false); // No interstitial showing. // Now we try again with the right host name this time. @@ -618,7 +561,7 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, TestCNInvalidStickiness) { // Since we OKed the interstitial last time, we get right to the page. CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID, - false, false); // No interstitial showing. + false); // No interstitial showing. } // Test that navigating to a #ref does not change a bad security state. @@ -630,12 +573,12 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, TestRefNavigation) { bad_https_server->TestServerPage("files/ssl/page_with_refs.html")); TabContents* tab = browser()->GetSelectedTabContents(); - CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false, + CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, true); // Interstitial showing. ProceedThroughInterstitial(tab); - CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false, + CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false); // No interstitial showing. // Now navigate to a ref in the page, the security state should not have @@ -643,7 +586,7 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, TestRefNavigation) { ui_test_utils::NavigateToURL(browser(), bad_https_server->TestServerPage("files/ssl/page_with_refs.html#jp")); - CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false, + CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false); // No interstitial showing. } @@ -699,7 +642,7 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, FLAKY_TestRedirectBadToGoodHTTPS) { TabContents* tab = browser()->GetSelectedTabContents(); - CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false, + CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, true); // Interstitial showing. ProceedThroughInterstitial(tab); @@ -721,12 +664,12 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, FLAKY_TestRedirectGoodToBadHTTPS) { ui_test_utils::NavigateToURL(browser(), GURL(url1.spec() + url2.spec())); TabContents* tab = browser()->GetSelectedTabContents(); - CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false, + CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, true); // Interstitial showing. ProceedThroughInterstitial(tab); - CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false, + CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false); // No interstitial showing. } @@ -763,12 +706,12 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, FLAKY_TestRedirectHTTPToBadHTTPS) { bad_https_server->TestServerPage("files/ssl/google.html"); ui_test_utils::NavigateToURL(browser(), GURL(http_url.spec() + bad_https_url.spec())); - CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false, + CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, true); // Interstitial showing. ProceedThroughInterstitial(tab); - CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false, + CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false); // No interstitial showing. } @@ -809,7 +752,7 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, TestConnectToBadPort) { // - navigate to a bad HTTPS (expect unsafe content and filtered frame), then // back // - navigate to HTTP (expect mixed content), then back -IN_PROC_BROWSER_TEST_F(SSLUITest, FLAKY_TestGoodFrameNavigation) { +IN_PROC_BROWSER_TEST_F(SSLUITest, DISABLED_TestGoodFrameNavigation) { scoped_refptr<HTTPTestServer> http_server = PlainServer(); ASSERT_TRUE(http_server.get() != NULL); scoped_refptr<HTTPSTestServer> good_https_server = GoodCertServer(); @@ -890,7 +833,7 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, FLAKY_TestBadFrameNavigation) { TabContents* tab = browser()->GetSelectedTabContents(); ui_test_utils::NavigateToURL(browser(), bad_https_server->TestServerPage("files/ssl/top_frame.html")); - CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false, + CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, true); // Interstitial showing ProceedThroughInterstitial(tab); @@ -905,8 +848,7 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, FLAKY_TestBadFrameNavigation) { ui_test_utils::WaitForNavigation(&tab->controller()); // We should still be authentication broken. - CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false, - false); + CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false); } // From an HTTP top frame, navigate to good and bad HTTPS (security state should @@ -990,19 +932,18 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, FLAKY_TestUnsafeContentsInWorker) { ui_test_utils::NavigateToURL(browser(), bad_https_server->TestServerPage("files/ssl/blank_page.html")); TabContents* tab = browser()->GetSelectedTabContents(); - CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false, + CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, true); // Interstitial showing ProceedThroughInterstitial(tab); - CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false, + CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, false); // No Interstitial // Navigate to safe page that has Worker loading unsafe content. - // Expect content to load but be marked as auth broken due to running mixed - // content. + // Expect content to load but 'mixed' indicators show up. ui_test_utils::NavigateToURL(browser(), good_https_server->TestServerPage( "files/ssl/page_with_unsafe_worker.html")); CheckWorkerLoadResult(tab, true); // Worker loads mixed content - CheckAuthenticationBrokenState(tab, 0, true, false); + CheckAuthenticatedState(tab, true); } // TODO(jcampan): more tests to do below. diff --git a/chrome/browser/ssl/ssl_host_state.cc b/chrome/browser/ssl/ssl_host_state.cc index e12c458..7e6d3cc 100644 --- a/chrome/browser/ssl/ssl_host_state.cc +++ b/chrome/browser/ssl/ssl_host_state.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2006-2009 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. @@ -23,21 +23,22 @@ SSLHostState::SSLHostState() { SSLHostState::~SSLHostState() { } -void SSLHostState::HostRanInsecureContent(const std::string& host, int pid) { +void SSLHostState::MarkHostAsBroken(const std::string& host, int pid) { DCHECK(CalledOnValidThread()); - ran_insecure_content_hosts_.insert(BrokenHostEntry(host, pid)); + + broken_hosts_.insert(BrokenHostEntry(host, pid)); } -bool SSLHostState::DidHostRunInsecureContent(const std::string& host, - int pid) const { +bool SSLHostState::DidMarkHostAsBroken(const std::string& host, int pid) { DCHECK(CalledOnValidThread()); - // CAs issue certificates for intranet hosts to everyone. Therefore, we - // always treat intranet hosts as having run insecure content. + // CAs issue certificate for intranet hosts to everyone. Therefore, we always + // treat intranet hosts as broken. if (IsIntranetHost(host)) return true; - return !!ran_insecure_content_hosts_.count(BrokenHostEntry(host, pid)); + return (broken_hosts_.find( + BrokenHostEntry(host, pid)) != broken_hosts_.end()); } void SSLHostState::DenyCertForHost(net::X509Certificate* cert, diff --git a/chrome/browser/ssl/ssl_host_state.h b/chrome/browser/ssl/ssl_host_state.h index 3c87900..5a8d774 100644 --- a/chrome/browser/ssl/ssl_host_state.h +++ b/chrome/browser/ssl/ssl_host_state.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2006-2009 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. @@ -27,11 +27,14 @@ class SSLHostState : public NonThreadSafe { SSLHostState(); ~SSLHostState(); - // Records that a host has run insecure content. - void HostRanInsecureContent(const std::string& host, int pid); + // Records that a host is "broken" in a particular render process. That is, + // the origin for that host has been contaminated with insecure content, + // either via HTTP or via HTTPS with a bad certificate. + void MarkHostAsBroken(const std::string& host, int pid); - // Returns whether the specified host ran insecure content. - bool DidHostRunInsecureContent(const std::string& host, int pid) const; + // Returns whether the specified host was marked as broken in a particular + // render process. + bool DidMarkHostAsBroken(const std::string& host, int pid); // Records that |cert| is permitted to be used for |host| in the future. void DenyCertForHost(net::X509Certificate* cert, const std::string& host); @@ -51,7 +54,7 @@ class SSLHostState : public NonThreadSafe { // Hosts which have been contaminated with insecure content in the // specified process. Note that insecure content can travel between // same-origin frames in one processs but cannot jump between processes. - std::set<BrokenHostEntry> ran_insecure_content_hosts_; + std::set<BrokenHostEntry> broken_hosts_; // Certificate policies for each host. std::map<std::string, net::X509Certificate::Policy> cert_policy_for_host_; diff --git a/chrome/browser/ssl/ssl_host_state_unittest.cc b/chrome/browser/ssl/ssl_host_state_unittest.cc index 09db79b..2a3db46 100644 --- a/chrome/browser/ssl/ssl_host_state_unittest.cc +++ b/chrome/browser/ssl/ssl_host_state_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2009 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. @@ -91,24 +91,24 @@ unsigned char google_der[] = { class SSLHostStateTest : public testing::Test { }; -TEST_F(SSLHostStateTest, DidHostRunInsecureContent) { +TEST_F(SSLHostStateTest, MarkHostAsBroken) { SSLHostState state; - EXPECT_FALSE(state.DidHostRunInsecureContent("www.google.com", 42)); - EXPECT_FALSE(state.DidHostRunInsecureContent("www.google.com", 191)); - EXPECT_FALSE(state.DidHostRunInsecureContent("example.com", 42)); + EXPECT_FALSE(state.DidMarkHostAsBroken("www.google.com", 42)); + EXPECT_FALSE(state.DidMarkHostAsBroken("www.google.com", 191)); + EXPECT_FALSE(state.DidMarkHostAsBroken("example.com", 42)); - state.HostRanInsecureContent("www.google.com", 42); + state.MarkHostAsBroken("www.google.com", 42); - EXPECT_TRUE(state.DidHostRunInsecureContent("www.google.com", 42)); - EXPECT_FALSE(state.DidHostRunInsecureContent("www.google.com", 191)); - EXPECT_FALSE(state.DidHostRunInsecureContent("example.com", 42)); + EXPECT_TRUE(state.DidMarkHostAsBroken("www.google.com", 42)); + EXPECT_FALSE(state.DidMarkHostAsBroken("www.google.com", 191)); + EXPECT_FALSE(state.DidMarkHostAsBroken("example.com", 42)); - state.HostRanInsecureContent("example.com", 42); + state.MarkHostAsBroken("example.com", 42); - EXPECT_TRUE(state.DidHostRunInsecureContent("www.google.com", 42)); - EXPECT_FALSE(state.DidHostRunInsecureContent("www.google.com", 191)); - EXPECT_TRUE(state.DidHostRunInsecureContent("example.com", 42)); + EXPECT_TRUE(state.DidMarkHostAsBroken("www.google.com", 42)); + EXPECT_FALSE(state.DidMarkHostAsBroken("www.google.com", 191)); + EXPECT_TRUE(state.DidMarkHostAsBroken("example.com", 42)); } TEST_F(SSLHostStateTest, QueryPolicy) { diff --git a/chrome/browser/ssl/ssl_manager.cc b/chrome/browser/ssl/ssl_manager.cc index 99729b6..7683221 100644 --- a/chrome/browser/ssl/ssl_manager.cc +++ b/chrome/browser/ssl/ssl_manager.cc @@ -28,86 +28,6 @@ void SSLManager::RegisterUserPrefs(PrefService* prefs) { FilterPolicy::DONT_FILTER); } -// static -void SSLManager::OnSSLCertificateError(ResourceDispatcherHost* rdh, - URLRequest* request, - int cert_error, - net::X509Certificate* cert) { - DLOG(INFO) << "OnSSLCertificateError() cert_error: " << cert_error << - " url: " << request->url().spec(); - - ResourceDispatcherHostRequestInfo* info = - ResourceDispatcherHost::InfoForRequest(request); - DCHECK(info); - - // A certificate error occurred. Construct a SSLCertErrorHandler object and - // hand it over to the UI thread for processing. - ChromeThread::PostTask( - ChromeThread::UI, FROM_HERE, - NewRunnableMethod(new SSLCertErrorHandler(rdh, - request, - info->resource_type(), - info->frame_origin(), - info->main_frame_origin(), - cert_error, - cert), - &SSLCertErrorHandler::Dispatch)); -} - -// static -void SSLManager::NotifySSLInternalStateChanged() { - NotificationService::current()->Notify( - NotificationType::SSL_INTERNAL_STATE_CHANGED, - NotificationService::AllSources(), - NotificationService::NoDetails()); -} - -// static -std::string SSLManager::SerializeSecurityInfo(int cert_id, - int cert_status, - int security_bits) { - Pickle pickle; - pickle.WriteInt(cert_id); - pickle.WriteInt(cert_status); - pickle.WriteInt(security_bits); - return std::string(static_cast<const char*>(pickle.data()), pickle.size()); -} - -// static -bool SSLManager::DeserializeSecurityInfo(const std::string& state, - int* cert_id, - int* cert_status, - int* security_bits) { - DCHECK(cert_id && cert_status && security_bits); - if (state.empty()) { - // No SSL used. - *cert_id = 0; - *cert_status = 0; - *security_bits = -1; - return false; - } - - Pickle pickle(state.data(), static_cast<int>(state.size())); - void * iter = NULL; - return pickle.ReadInt(&iter, cert_id) && - pickle.ReadInt(&iter, cert_status) && - pickle.ReadInt(&iter, security_bits); -} - -// static -std::wstring SSLManager::GetEVCertName(const net::X509Certificate& cert) { - // EV are required to have an organization name and country. - if (cert.subject().organization_names.empty() || - cert.subject().country_name.empty()) { - NOTREACHED(); - return std::wstring(); - } - - return l10n_util::GetStringF(IDS_SECURE_CONNECTION_EV, - UTF8ToWide(cert.subject().organization_names[0]), - UTF8ToWide(cert.subject().country_name)); -} - SSLManager::SSLManager(NavigationController* controller) : backend_(controller), policy_(new SSLPolicy(&backend_)), @@ -130,33 +50,44 @@ SSLManager::SSLManager(NavigationController* controller) SSLManager::~SSLManager() { } -void SSLManager::DidCommitProvisionalLoad( - const NotificationDetails& in_details) { - NavigationController::LoadCommittedDetails* details = - Details<NavigationController::LoadCommittedDetails>(in_details).ptr(); - +bool SSLManager::ProcessedSSLErrorFromRequest() const { NavigationEntry* entry = controller_->GetActiveEntry(); + if (!entry) { + NOTREACHED(); + return false; + } - if (details->is_main_frame) { - if (entry) { - // Decode the security details. - int ssl_cert_id, ssl_cert_status, ssl_security_bits; - DeserializeSecurityInfo(details->serialized_security_info, - &ssl_cert_id, - &ssl_cert_status, - &ssl_security_bits); + return net::IsCertStatusError(entry->ssl().cert_status()); +} - // We may not have an entry if this is a navigation to an initial blank - // page. Reset the SSL information and add the new data we have. - entry->ssl() = NavigationEntry::SSLStatus(); - entry->ssl().set_cert_id(ssl_cert_id); - entry->ssl().set_cert_status(ssl_cert_status); - entry->ssl().set_security_bits(ssl_security_bits); - } - backend_.ShowPendingMessages(); - } +// static +void SSLManager::OnSSLCertificateError(ResourceDispatcherHost* rdh, + URLRequest* request, + int cert_error, + net::X509Certificate* cert) { + DLOG(INFO) << "OnSSLCertificateError() cert_error: " << cert_error << + " url: " << request->url().spec(); - UpdateEntry(entry); + ResourceDispatcherHostRequestInfo* info = + ResourceDispatcherHost::InfoForRequest(request); + DCHECK(info); + + // A certificate error occurred. Construct a SSLCertErrorHandler object and + // hand it over to the UI thread for processing. + ChromeThread::PostTask( + ChromeThread::UI, FROM_HERE, + NewRunnableMethod(new SSLCertErrorHandler(rdh, + request, + info->resource_type(), + info->frame_origin(), + info->main_frame_origin(), + cert_error, + cert), + &SSLCertErrorHandler::Dispatch)); +} + +void SSLManager::DidDisplayInsecureContent() { + policy()->DidDisplayInsecureContent(controller_->GetActiveEntry()); } void SSLManager::DidRunInsecureContent(const std::string& security_origin) { @@ -164,16 +95,6 @@ void SSLManager::DidRunInsecureContent(const std::string& security_origin) { security_origin); } -bool SSLManager::ProcessedSSLErrorFromRequest() const { - NavigationEntry* entry = controller_->GetActiveEntry(); - if (!entry) { - NOTREACHED(); - return false; - } - - return net::IsCertStatusError(entry->ssl().cert_status()); -} - void SSLManager::Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details) { @@ -202,6 +123,27 @@ void SSLManager::Observe(NotificationType type, } } +void SSLManager::DispatchSSLVisibleStateChanged() { + NotificationService::current()->Notify( + NotificationType::SSL_VISIBLE_STATE_CHANGED, + Source<NavigationController>(controller_), + NotificationService::NoDetails()); +} + +void SSLManager::UpdateEntry(NavigationEntry* entry) { + // We don't always have a navigation entry to update, for example in the + // case of the Web Inspector. + if (!entry) + return; + + NavigationEntry::SSLStatus original_ssl_status = entry->ssl(); // Copy! + + policy()->UpdateEntry(entry); + + if (!entry->ssl().Equals(original_ssl_status)) + DispatchSSLVisibleStateChanged(); +} + void SSLManager::DidLoadFromMemoryCache(LoadFromMemoryCacheDetails* details) { DCHECK(details); @@ -224,6 +166,35 @@ void SSLManager::DidLoadFromMemoryCache(LoadFromMemoryCacheDetails* details) { policy()->OnRequestStarted(info.get()); } +void SSLManager::DidCommitProvisionalLoad( + const NotificationDetails& in_details) { + NavigationController::LoadCommittedDetails* details = + Details<NavigationController::LoadCommittedDetails>(in_details).ptr(); + + NavigationEntry* entry = controller_->GetActiveEntry(); + + if (details->is_main_frame) { + if (entry) { + // Decode the security details. + int ssl_cert_id, ssl_cert_status, ssl_security_bits; + DeserializeSecurityInfo(details->serialized_security_info, + &ssl_cert_id, + &ssl_cert_status, + &ssl_security_bits); + + // We may not have an entry if this is a navigation to an initial blank + // page. Reset the SSL information and add the new data we have. + entry->ssl() = NavigationEntry::SSLStatus(); + entry->ssl().set_cert_id(ssl_cert_id); + entry->ssl().set_cert_status(ssl_cert_status); + entry->ssl().set_security_bits(ssl_security_bits); + } + backend_.ShowPendingMessages(); + } + + UpdateEntry(entry); +} + void SSLManager::DidFailProvisionalLoadWithError( ProvisionalLoadDetails* details) { DCHECK(details); @@ -267,20 +238,48 @@ void SSLManager::DidChangeSSLInternalState() { UpdateEntry(controller_->GetActiveEntry()); } -void SSLManager::UpdateEntry(NavigationEntry* entry) { - // We don't always have a navigation entry to update, for example in the - // case of the Web Inspector. - if (!entry) - return; +// static +std::string SSLManager::SerializeSecurityInfo(int cert_id, + int cert_status, + int security_bits) { + Pickle pickle; + pickle.WriteInt(cert_id); + pickle.WriteInt(cert_status); + pickle.WriteInt(security_bits); + return std::string(static_cast<const char*>(pickle.data()), pickle.size()); +} - NavigationEntry::SSLStatus original_ssl_status = entry->ssl(); // Copy! +// static +bool SSLManager::DeserializeSecurityInfo(const std::string& state, + int* cert_id, + int* cert_status, + int* security_bits) { + DCHECK(cert_id && cert_status && security_bits); + if (state.empty()) { + // No SSL used. + *cert_id = 0; + *cert_status = 0; + *security_bits = -1; + return false; + } - policy()->UpdateEntry(entry, controller_->tab_contents()); + Pickle pickle(state.data(), static_cast<int>(state.size())); + void * iter = NULL; + return pickle.ReadInt(&iter, cert_id) && + pickle.ReadInt(&iter, cert_status) && + pickle.ReadInt(&iter, security_bits); +} - if (!entry->ssl().Equals(original_ssl_status)) { - NotificationService::current()->Notify( - NotificationType::SSL_VISIBLE_STATE_CHANGED, - Source<NavigationController>(controller_), - NotificationService::NoDetails()); +// static +std::wstring SSLManager::GetEVCertName(const net::X509Certificate& cert) { + // EV are required to have an organization name and country. + if (cert.subject().organization_names.empty() || + cert.subject().country_name.empty()) { + NOTREACHED(); + return std::wstring(); } + + return l10n_util::GetStringF(IDS_SECURE_CONNECTION_EV, + UTF8ToWide(cert.subject().organization_names[0]), + UTF8ToWide(cert.subject().country_name)); } diff --git a/chrome/browser/ssl/ssl_manager.h b/chrome/browser/ssl/ssl_manager.h index 7d6c134..f9e1685 100644 --- a/chrome/browser/ssl/ssl_manager.h +++ b/chrome/browser/ssl/ssl_manager.h @@ -38,6 +38,18 @@ class URLRequest; class SSLManager : public NotificationObserver { public: + // Construct an SSLManager for the specified tab. + // If |delegate| is NULL, SSLPolicy::GetDefaultPolicy() is used. + explicit SSLManager(NavigationController* controller); + ~SSLManager(); + + SSLPolicy* policy() { return policy_.get(); } + SSLPolicyBackend* backend() { return &backend_; } + + // The navigation controller associated with this SSLManager. The + // NavigationController is guaranteed to outlive the SSLManager. + NavigationController* controller() { return controller_; } + static void RegisterUserPrefs(PrefService* prefs); // Entry point for SSLCertificateErrors. This function begins the process @@ -51,9 +63,25 @@ class SSLManager : public NotificationObserver { int cert_error, net::X509Certificate* cert); - // Called when SSL state for a host or tab changes. Broadcasts the - // SSL_INTERNAL_STATE_CHANGED notification. - static void NotifySSLInternalStateChanged(); + // Mixed content entry points. + void DidDisplayInsecureContent(); + void DidRunInsecureContent(const std::string& security_origin); + + // Entry point for navigation. This function begins the process of updating + // the security UI when the main frame navigates to a new URL. + // + // Called on the UI thread. + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + + // This entry point is called directly (instead of via the notification + // service) because we need more precise control of the order in which folks + // are notified of this event. + void DidCommitProvisionalLoad(const NotificationDetails& details); + + // Called to determine if there were any processed SSL errors from request. + bool ProcessedSSLErrorFromRequest() const; // Convenience methods for serializing/deserializing the security info. static std::string SerializeSecurityInfo(int cert_id, @@ -67,37 +95,6 @@ class SSLManager : public NotificationObserver { // Returns "<organization_name> [<country>]". static std::wstring GetEVCertName(const net::X509Certificate& cert); - // Construct an SSLManager for the specified tab. - // If |delegate| is NULL, SSLPolicy::GetDefaultPolicy() is used. - explicit SSLManager(NavigationController* controller); - ~SSLManager(); - - SSLPolicy* policy() { return policy_.get(); } - SSLPolicyBackend* backend() { return &backend_; } - - // The navigation controller associated with this SSLManager. The - // NavigationController is guaranteed to outlive the SSLManager. - NavigationController* controller() { return controller_; } - - // This entry point is called directly (instead of via the notification - // service) because we need more precise control of the order in which folks - // are notified of this event. - void DidCommitProvisionalLoad(const NotificationDetails& details); - - // Mixed content entry point. - void DidRunInsecureContent(const std::string& security_origin); - - // Called to determine if there were any processed SSL errors from request. - bool ProcessedSSLErrorFromRequest() const; - - // Entry point for navigation. This function begins the process of updating - // the security UI when the main frame navigates to a new URL. - // - // Called on the UI thread. - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); - private: // SSLMessageInfo contains the information necessary for displaying a message // in an info-bar. @@ -133,6 +130,9 @@ class SSLManager : public NotificationObserver { void DidReceiveResourceRedirect(ResourceRedirectDetails* details); void DidChangeSSLInternalState(); + // Dispatch NotificationType::SSL_VISIBLE_STATE_CHANGED notification. + void DispatchSSLVisibleStateChanged(); + // Update the NavigationEntry with our current state. void UpdateEntry(NavigationEntry* entry); diff --git a/chrome/browser/ssl/ssl_policy.cc b/chrome/browser/ssl/ssl_policy.cc index 4405972..7335abc 100644 --- a/chrome/browser/ssl/ssl_policy.cc +++ b/chrome/browser/ssl/ssl_policy.cc @@ -83,6 +83,15 @@ void SSLPolicy::OnCertError(SSLCertErrorHandler* handler) { } } +void SSLPolicy::DidDisplayInsecureContent(NavigationEntry* entry) { + if (!entry) + return; + + // TODO(abarth): We don't actually need to break the whole origin here, + // but we can handle that in a later patch. + DidRunInsecureContent(entry, entry->url().spec()); +} + void SSLPolicy::DidRunInsecureContent(NavigationEntry* entry, const std::string& security_origin) { if (!entry) @@ -92,52 +101,16 @@ void SSLPolicy::DidRunInsecureContent(NavigationEntry* entry, if (!site_instance) return; - backend_->HostRanInsecureContent(GURL(security_origin).host(), - site_instance->GetProcess()->id()); + backend_->MarkHostAsBroken(GURL(security_origin).host(), + site_instance->GetProcess()->id()); } void SSLPolicy::OnRequestStarted(SSLRequestInfo* info) { - // TODO(abarth): This mechanism is wrong. What we should be doing is sending - // this information back through WebKit and out some FrameLoaderClient - // methods. - // - // The behavior for HTTPS resources with cert errors should be as follows: - // 1) If we don't know anything about this host (the one hosting the - // resource), the resource load just fails. - // 2) If the user has previously approved the same certificate error for - // this host in a full-page interstitial, then we'll proceed with the - // load. - // 3) If we proceed with the load, we should treat the resources as if they - // were loaded over HTTP, w.r.t. the display vs. run distinction above. - // - // However, right now we don't have the proper context to understand where - // these resources will be used. Consequently, we're conservative and treat - // them all like DidRunInsecureContent(). - - if (net::IsCertStatusError(info->ssl_cert_status())) { - backend_->HostRanInsecureContent(info->url().host(), info->child_id()); - - // TODO(abarth): We should eventually remove the main_frame_origin and - // frame_origin properties. First, not every resource load is associated - // with a frame, so they don't always make sense. Second, the - // main_frame_origin is computed from the first_party_for_cookies, which has - // been hacked to death to support third-party cookie blocking. - - if (info->resource_type() != ResourceType::MAIN_FRAME && - info->resource_type() != ResourceType::SUB_FRAME) { - // The frame's origin now contains mixed content and therefore is broken. - OriginRanInsecureContent(info->frame_origin(), info->child_id()); - } - - if (info->resource_type() != ResourceType::MAIN_FRAME) { - // The main frame now contains a frame with mixed content. Therefore, we - // mark the main frame's origin as broken too. - OriginRanInsecureContent(info->main_frame_origin(), info->child_id()); - } - } + if (net::IsCertStatusError(info->ssl_cert_status())) + UpdateStateForUnsafeContent(info); } -void SSLPolicy::UpdateEntry(NavigationEntry* entry, TabContents* tab_contents) { +void SSLPolicy::UpdateEntry(NavigationEntry* entry) { DCHECK(entry); InitializeEntryIfNeeded(entry); @@ -167,15 +140,9 @@ void SSLPolicy::UpdateEntry(NavigationEntry* entry, TabContents* tab_contents) { // necessarily have site instances. Without a process, the entry can't // possibly have mixed content. See bug http://crbug.com/12423. if (site_instance && - backend_->DidHostRunInsecureContent(entry->url().host(), - site_instance->GetProcess()->id())) { - entry->ssl().set_security_style(SECURITY_STYLE_AUTHENTICATION_BROKEN); - entry->ssl().set_ran_mixed_content(); - return; - } - - if (tab_contents->displayed_insecure_content()) - entry->ssl().set_displayed_mixed_content(); + backend_->DidMarkHostAsBroken(entry->url().host(), + site_instance->GetProcess()->id())) + entry->ssl().set_has_mixed_content(); } //////////////////////////////////////////////////////////////////////////////// @@ -240,8 +207,33 @@ void SSLPolicy::InitializeEntryIfNeeded(NavigationEntry* entry) { SECURITY_STYLE_AUTHENTICATED : SECURITY_STYLE_UNAUTHENTICATED); } -void SSLPolicy::OriginRanInsecureContent(const std::string& origin, int pid) { +void SSLPolicy::MarkOriginAsBroken(const std::string& origin, int pid) { GURL parsed_origin(origin); - if (parsed_origin.SchemeIsSecure()) - backend_->HostRanInsecureContent(parsed_origin.host(), pid); + if (!parsed_origin.SchemeIsSecure()) + return; + + backend_->MarkHostAsBroken(parsed_origin.host(), pid); +} + +void SSLPolicy::UpdateStateForMixedContent(SSLRequestInfo* info) { + // TODO(abarth): This function isn't right because we need to remove + // info->main_frame_origin(). + + if (info->resource_type() != ResourceType::MAIN_FRAME && + info->resource_type() != ResourceType::SUB_FRAME) { + // The frame's origin now contains mixed content and therefore is broken. + MarkOriginAsBroken(info->frame_origin(), info->child_id()); + } + + if (info->resource_type() != ResourceType::MAIN_FRAME) { + // The main frame now contains a frame with mixed content. Therefore, we + // mark the main frame's origin as broken too. + MarkOriginAsBroken(info->main_frame_origin(), info->child_id()); + } +} + +void SSLPolicy::UpdateStateForUnsafeContent(SSLRequestInfo* info) { + // This request as a broken cert, which means its host is broken. + backend_->MarkHostAsBroken(info->url().host(), info->child_id()); + UpdateStateForMixedContent(info); } diff --git a/chrome/browser/ssl/ssl_policy.h b/chrome/browser/ssl/ssl_policy.h index 8c8a5f8..adb574f 100644 --- a/chrome/browser/ssl/ssl_policy.h +++ b/chrome/browser/ssl/ssl_policy.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -29,6 +29,7 @@ class SSLPolicy : public SSLBlockingPage::Delegate { // An error occurred with the certificate in an SSL connection. void OnCertError(SSLCertErrorHandler* handler); + void DidDisplayInsecureContent(NavigationEntry* entry); void DidRunInsecureContent(NavigationEntry* entry, const std::string& security_origin); @@ -36,8 +37,7 @@ class SSLPolicy : public SSLBlockingPage::Delegate { void OnRequestStarted(SSLRequestInfo* info); // Update the SSL information in |entry| to match the current state. - // |tab_contents| is the TabContents associated with this entry. - void UpdateEntry(NavigationEntry* entry, TabContents* tab_contents); + void UpdateEntry(NavigationEntry* entry); SSLPolicyBackend* backend() const { return backend_; } @@ -59,8 +59,16 @@ class SSLPolicy : public SSLBlockingPage::Delegate { // it with the default style for its URL. void InitializeEntryIfNeeded(NavigationEntry* entry); - // Mark |origin| as having run insecure content in the process with ID |pid|. - void OriginRanInsecureContent(const std::string& origin, int pid); + // Mark |origin| as containing insecure content in the process with ID |pid|. + void MarkOriginAsBroken(const std::string& origin, int pid); + + // Called after we've decided that |info| represents a request for mixed + // content. Updates our internal state to reflect that we've loaded |info|. + void UpdateStateForMixedContent(SSLRequestInfo* info); + + // Called after we've decided that |info| represents a request for unsafe + // content. Updates our internal state to reflect that we've loaded |info|. + void UpdateStateForUnsafeContent(SSLRequestInfo* info); // The backend we use to enact our decisions. SSLPolicyBackend* backend_; diff --git a/chrome/browser/ssl/ssl_policy_backend.cc b/chrome/browser/ssl/ssl_policy_backend.cc index 7674fca..db030ea 100644 --- a/chrome/browser/ssl/ssl_policy_backend.cc +++ b/chrome/browser/ssl/ssl_policy_backend.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2009 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. @@ -11,6 +11,7 @@ #include "chrome/browser/tab_contents/navigation_controller.h" #include "chrome/browser/tab_contents/navigation_entry.h" #include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/common/notification_service.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" @@ -102,15 +103,14 @@ void SSLPolicyBackend::ShowMessageWithLink(const std::wstring& msg, } } -void SSLPolicyBackend::HostRanInsecureContent(const std::string& host, - int id) { - ssl_host_state_->HostRanInsecureContent(host, id); - SSLManager::NotifySSLInternalStateChanged(); +void SSLPolicyBackend::MarkHostAsBroken(const std::string& host, int id) { + ssl_host_state_->MarkHostAsBroken(host, id); + DispatchSSLInternalStateChanged(); } -bool SSLPolicyBackend::DidHostRunInsecureContent(const std::string& host, - int pid) const { - return ssl_host_state_->DidHostRunInsecureContent(host, pid); +bool SSLPolicyBackend::DidMarkHostAsBroken(const std::string& host, + int pid) const { + return ssl_host_state_->DidMarkHostAsBroken(host, pid); } void SSLPolicyBackend::DenyCertForHost(net::X509Certificate* cert, @@ -128,6 +128,13 @@ net::X509Certificate::Policy::Judgment SSLPolicyBackend::QueryPolicy( return ssl_host_state_->QueryPolicy(cert, host); } +void SSLPolicyBackend::DispatchSSLInternalStateChanged() { + NotificationService::current()->Notify( + NotificationType::SSL_INTERNAL_STATE_CHANGED, + Source<NavigationController>(controller_), + NotificationService::NoDetails()); +} + void SSLPolicyBackend::ShowPendingMessages() { std::vector<SSLMessageInfo>::const_iterator iter; for (iter = pending_messages_.begin(); diff --git a/chrome/browser/ssl/ssl_policy_backend.h b/chrome/browser/ssl/ssl_policy_backend.h index b795314..059534b 100644 --- a/chrome/browser/ssl/ssl_policy_backend.h +++ b/chrome/browser/ssl/ssl_policy_backend.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2009 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. @@ -31,11 +31,13 @@ class SSLPolicyBackend { const std::wstring& link_text, Task* task); - // Records that a host has run insecure content. - void HostRanInsecureContent(const std::string& host, int pid); + // Records that a host is "broken," that is, the origin for that host has been + // contaminated with insecure content, either via HTTP or via HTTPS with a + // bad certificate. + void MarkHostAsBroken(const std::string& host, int pid); - // Returns whether the specified host ran insecure content. - bool DidHostRunInsecureContent(const std::string& host, int pid) const; + // Returns whether the specified host was marked as broken. + bool DidMarkHostAsBroken(const std::string& host, int pid) const; // Records that |cert| is permitted to be used for |host| in the future. void DenyCertForHost(net::X509Certificate* cert, const std::string& host); @@ -78,6 +80,9 @@ class SSLPolicyBackend { Task* action; }; + // Dispatch NotificationType::SSL_INTERNAL_STATE_CHANGED notification. + void DispatchSSLInternalStateChanged(); + // The NavigationController that owns this SSLManager. We are responsible // for the security UI of this tab. NavigationController* controller_; |