diff options
author | estark <estark@chromium.org> | 2015-12-09 12:55:41 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-12-09 20:56:42 +0000 |
commit | 910b457a9d91a7e8858121d4c199c301bb3e8f10 (patch) | |
tree | 29917f7fbda46939b66e6ca5bb0b575d048f3ed1 | |
parent | d89375a7b98ba2551855cc7967b20f95e251beb0 (diff) | |
download | chromium_src-910b457a9d91a7e8858121d4c199c301bb3e8f10.zip chromium_src-910b457a9d91a7e8858121d4c199c301bb3e8f10.tar.gz chromium_src-910b457a9d91a7e8858121d4c199c301bb3e8f10.tar.bz2 |
Reland of Downgrade lock icon for broken-HTTPS subresources (patchset #2 id:300001 of https://codereview.chromium.org/1497423002/ )
Reason for revert:
Relanding since the speculative revert didn't seem to help with crbug.com/565540
Original issue's description:
> Revert of Downgrade lock icon for broken-HTTPS subresources (patchset #11 id:200001 of https://codereview.chromium.org/1415923015/ )
>
> Reason for revert:
> Speculatively reverting to see if it makes https://code.google.com/p/chromium/issues/detail?id=565540 go away
>
> Note that this revert preserves the histogrammed
> bad_message.h value that was added in CL 1415923015
>
> Original issue's description:
> > Downgrade lock icon for broken-HTTPS subresources
> >
> > This CL attaches a boolean to resource responses to indicate if they
> > have certificate errors. If Blink sees a resource with a cert error, it
> > notifies the renderer via FrameLoaderClient, who then notifies the
> > browser, who treats the situation like mixed content.
> >
> > The browser (//content) ignores subresources with cert errors on HTTP
> > pages, and subresources with the same cert errors as the main
> > resource. This allows embedders to distinguish broken-HTTPS foo.com with
> > a subresource from broken-HTTPS bar.com and broken-HTTPS foo.com with a
> > subresource from broken-HTTPS foo.com.
> >
> > BUG=477868
> >
> > Committed: https://crrev.com/8bfb78c859ab5993eada6db30e4de50aa7403f1c
> > Cr-Commit-Position: refs/heads/master@{#362246}
>
> TBR=jochen@chromium.org,jww@chromium.org,mkwst@chromium.org
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=477868
>
> Committed: https://crrev.com/51ea371ad45bb5887dacf7fca6fe0feef8941262
> Cr-Commit-Position: refs/heads/master@{#363388}
TBR=jochen@chromium.org,jww@chromium.org,mkwst@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=477868
Review URL: https://codereview.chromium.org/1506203004
Cr-Commit-Position: refs/heads/master@{#364152}
31 files changed, 378 insertions, 64 deletions
diff --git a/chrome/browser/ssl/ssl_browser_tests.cc b/chrome/browser/ssl/ssl_browser_tests.cc index 061b4f9..c56e085 100644 --- a/chrome/browser/ssl/ssl_browser_tests.cc +++ b/chrome/browser/ssl/ssl_browser_tests.cc @@ -555,6 +555,36 @@ class SSLUITest net::EmbeddedTestServer https_server_mismatched_; net::SpawnedTestServer wss_server_expired_; + protected: + // Navigates to an interstitial and clicks through the certificate + // error; then navigates to a page at |path| that loads unsafe content. + void SetUpUnsafeContentsWithUserException(const std::string& path) { + ASSERT_TRUE(https_server_.Start()); + // Note that it is necessary to user https_server_mismatched_ here over the + // other invalid cert servers. This is because the test relies on the two + // servers having different hosts since SSL exceptions are per-host, not per + // origin, and https_server_mismatched_ uses 'localhost' rather than + // '127.0.0.1'. + ASSERT_TRUE(https_server_mismatched_.Start()); + + // Navigate to an unsafe site. Proceed with interstitial page to indicate + // the user approves the bad certificate. + ui_test_utils::NavigateToURL( + browser(), https_server_mismatched_.GetURL("/ssl/blank_page.html")); + WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); + CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID, + AuthState::SHOWING_INTERSTITIAL); + ProceedThroughInterstitial(tab); + CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID, + AuthState::NONE); + + std::string replacement_path; + GetFilePathWithHostAndPortReplacement( + path, https_server_mismatched_.host_port_pair(), &replacement_path); + ui_test_utils::NavigateToURL(browser(), + https_server_.GetURL(replacement_path)); + } + private: typedef net::SpawnedTestServer::SSLOptions SSLOptions; @@ -2125,10 +2155,7 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContentsInWorkerFiltered) { // This test, and the related test TestUnsafeContentsWithUserException, verify // that if unsafe content is loaded but the host of that unsafe content has a -// user exception, the content runs and the security style remains -// authenticated. This is not necessarily the behavior that should exist, but it -// is verification that it does behave that way. See https://crbug.com/477868 -// for more inforamtion on this. +// user exception, the content runs and the security style is downgraded. IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContentsInWorkerWithUserException) { ASSERT_TRUE(https_server_.Start()); // Note that it is necessary to user https_server_mismatched_ here over the @@ -2158,44 +2185,56 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContentsInWorkerWithUserException) { ui_test_utils::NavigateToURL( browser(), https_server_.GetURL(page_with_unsafe_worker_path)); CheckWorkerLoadResult(tab, true); // Worker loads insecure content - CheckAuthenticatedState(tab, CertError::NONE); + CheckAuthenticationBrokenState(tab, CertError::NONE, + AuthState::RAN_INSECURE_CONTENT); } // Visits a page with unsafe content and makes sure that if a user exception to // the certificate error is present, the image is loaded and script executes. -// -// See the comment above SSLUITest.TestUnsafeContentsInWorkerWithUserException -// for a discussion about the desired behavior. IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContentsWithUserException) { - ASSERT_TRUE(https_server_.Start()); - // Note that it is necessary to user https_server_mismatched_ here over the - // other invalid cert servers. This is because the test relies on the two - // servers having different hosts since SSL exceptions are per-host, not per - // origin, and https_server_mismatched_ uses 'localhost' rather than - // '127.0.0.1'. - ASSERT_TRUE(https_server_mismatched_.Start()); - - // Navigate to an unsafe site. Proceed with interstitial page to indicate - // the user approves the bad certificate. - ui_test_utils::NavigateToURL( - browser(), https_server_mismatched_.GetURL("/ssl/blank_page.html")); WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); - CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID, - AuthState::SHOWING_INTERSTITIAL); - ProceedThroughInterstitial(tab); - CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID, - AuthState::NONE); + ASSERT_NO_FATAL_FAILURE(SetUpUnsafeContentsWithUserException( + "/ssl/page_with_unsafe_contents.html")); + CheckAuthenticationBrokenState( + tab, CertError::NONE, + AuthState::RAN_INSECURE_CONTENT | AuthState::DISPLAYED_INSECURE_CONTENT); + int img_width; + EXPECT_TRUE(content::ExecuteScriptAndExtractInt( + tab, "window.domAutomationController.send(ImageWidth());", &img_width)); + // In order to check that the image was loaded, we check its width. + // The actual image (Google logo) is 114 pixels wide, so we assume a good + // image is greater than 100. + EXPECT_GT(img_width, 100); + + bool js_result = false; + EXPECT_TRUE(content::ExecuteScriptAndExtractBool( + tab, "window.domAutomationController.send(IsFooSet());", &js_result)); + EXPECT_TRUE(js_result); + + // Test that active subresources with the same certificate errors as + // the main resources don't cause mixed content UI downgrades. (Such + // errors would be confusing and duplicative.) std::string replacement_path; GetFilePathWithHostAndPortReplacement( "/ssl/page_with_unsafe_contents.html", https_server_mismatched_.host_port_pair(), &replacement_path); - ui_test_utils::NavigateToURL(browser(), - https_server_.GetURL(replacement_path)); + ui_test_utils::NavigateToURL( + browser(), https_server_mismatched_.GetURL(replacement_path)); + js_result = false; + EXPECT_TRUE(content::ExecuteScriptAndExtractBool( + tab, "window.domAutomationController.send(IsFooSet());", &js_result)); + EXPECT_TRUE(js_result); + CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID, + AuthState::NONE); +} - // When the bad content is filtered, the state is expected to be - // authenticated. - CheckAuthenticatedState(tab, AuthState::NONE); +// Like the test above, but only displaying inactive content (an image). +IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeImageWithUserException) { + WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); + ASSERT_NO_FATAL_FAILURE( + SetUpUnsafeContentsWithUserException("/ssl/page_with_unsafe_image.html")); + CheckAuthenticatedState(tab, AuthState::DISPLAYED_INSECURE_CONTENT); int img_width; EXPECT_TRUE(content::ExecuteScriptAndExtractInt( @@ -2204,12 +2243,6 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContentsWithUserException) { // The actual image (Google logo) is 114 pixels wide, so we assume a good // image is greater than 100. EXPECT_GT(img_width, 100); - - bool js_result = false; - EXPECT_TRUE(content::ExecuteScriptAndExtractBool( - tab, "window.domAutomationController.send(IsFooSet());", &js_result)); - EXPECT_TRUE(js_result); - CheckAuthenticatedState(tab, CertError::NONE); } // Test that when the browser blocks displaying insecure content (images), the diff --git a/chrome/test/data/ssl/page_with_dynamic_unsafe_image.html b/chrome/test/data/ssl/page_with_dynamic_unsafe_image.html new file mode 100644 index 0000000..d232531 --- /dev/null +++ b/chrome/test/data/ssl/page_with_dynamic_unsafe_image.html @@ -0,0 +1,13 @@ +<html> +<head><title>Page with unsafe image loaded dynamically</title> +<script> + var url = "https://REPLACE_WITH_HOST_AND_PORT/ssl/google_files/logo.gif"; + + function AddImage() { + var img = document.createElement("img"); + img.src = url; + document.body.appendChild(img); + } +</script> +<body></body> +</html> diff --git a/chrome/test/data/ssl/page_with_unsafe_image.html b/chrome/test/data/ssl/page_with_unsafe_image.html new file mode 100644 index 0000000..9136e37 --- /dev/null +++ b/chrome/test/data/ssl/page_with_unsafe_image.html @@ -0,0 +1,14 @@ +<html> +<head><title>Page with unsafe image</title> +<script> + function ImageWidth() { + return document.getElementById("bad_image").width; + } +</script> +</head> + +<body> +This page contains an image which is served over an insecure HTTPS connection...<br> +<img id="bad_image" src="https://REPLACE_WITH_HOST_AND_PORT/ssl/google_files/logo.gif"/> +</body> +</html> diff --git a/content/browser/loader/resource_loader.cc b/content/browser/loader/resource_loader.cc index 6238b25..e8a404f 100644 --- a/content/browser/loader/resource_loader.cc +++ b/content/browser/loader/resource_loader.cc @@ -115,6 +115,9 @@ void PopulateResourceResponse(ResourceRequestInfoImpl* info, GetSSLStatusForRequest(request->url(), request->ssl_info(), info->GetChildID(), &ssl_status); response->head.security_info = SerializeSecurityInfo(ssl_status); + response->head.has_major_certificate_errors = + net::IsCertStatusError(ssl_status.cert_status) && + !net::IsCertStatusMinorError(ssl_status.cert_status); } else { // We should not have any SSL state. DCHECK(!request->ssl_info().cert_status); diff --git a/content/browser/ssl/ssl_manager.cc b/content/browser/ssl/ssl_manager.cc index cd6c2be..c1b42f0 100644 --- a/content/browser/ssl/ssl_manager.cc +++ b/content/browser/ssl/ssl_manager.cc @@ -134,11 +134,7 @@ void SSLManager::DidCommitProvisionalLoad(const LoadCommittedDetails& details) { NotifyDidChangeVisibleSSLState(); } -void SSLManager::DidDisplayInsecureContent() { - UpdateEntry(controller_->GetLastCommittedEntry()); -} - -void SSLManager::DidRunInsecureContent(const std::string& security_origin) { +void SSLManager::DidRunInsecureContent(const GURL& security_origin) { NavigationEntryImpl* navigation_entry = controller_->GetLastCommittedEntry(); policy()->DidRunInsecureContent(navigation_entry, security_origin); UpdateEntry(navigation_entry); diff --git a/content/browser/ssl/ssl_manager.h b/content/browser/ssl/ssl_manager.h index 6e46705..fb31a25 100644 --- a/content/browser/ssl/ssl_manager.h +++ b/content/browser/ssl/ssl_manager.h @@ -31,6 +31,7 @@ struct LoadCommittedDetails; struct LoadFromMemoryCacheDetails; struct ResourceRedirectDetails; struct ResourceRequestDetails; +struct SSLStatus; // The SSLManager SSLManager controls the SSL UI elements in a WebContents. It // listens for various events that influence when these elements should or @@ -88,8 +89,7 @@ class CONTENT_EXPORT SSLManager { void DidReceiveResourceRedirect(const ResourceRedirectDetails& details); // Insecure content entry point. - void DidDisplayInsecureContent(); - void DidRunInsecureContent(const std::string& security_origin); + void DidRunInsecureContent(const GURL& security_origin); private: // Updates the NavigationEntry with our current state. This will diff --git a/content/browser/ssl/ssl_policy.cc b/content/browser/ssl/ssl_policy.cc index ed8d80b3..06677dc 100644 --- a/content/browser/ssl/ssl_policy.cc +++ b/content/browser/ssl/ssl_policy.cc @@ -105,7 +105,7 @@ void SSLPolicy::OnCertError(SSLCertErrorHandler* handler) { } void SSLPolicy::DidRunInsecureContent(NavigationEntryImpl* entry, - const std::string& security_origin) { + const GURL& security_origin) { if (!entry) return; @@ -113,20 +113,16 @@ void SSLPolicy::DidRunInsecureContent(NavigationEntryImpl* entry, if (!site_instance) return; - backend_->HostRanInsecureContent(GURL(security_origin).host(), + backend_->HostRanInsecureContent(security_origin.host(), site_instance->GetProcess()->GetID()); } 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. - - if (net::IsCertStatusError(info->ssl_cert_status())) { - backend_->HostRanInsecureContent(info->url().host(), info->child_id()); - } else if (info->ssl_cert_id() && info->url().SchemeIsCryptographic()) { - // If the scheme is https: or wss: *and* the security info for the cert has - // been set (i.e. the cert id is not 0), revoke any previous decisions that + if (info->ssl_cert_id() && info->url().SchemeIsCryptographic() && + !net::IsCertStatusError(info->ssl_cert_status())) { + // If the scheme is https: or wss: *and* the security info for the + // cert has been set (i.e. the cert id is not 0) and the cert did + // not have any errors, revoke any previous decisions that // have occurred. If the cert info has not been set, do nothing since it // isn't known if the connection was actually a valid connection or if it // had a cert error. diff --git a/content/browser/ssl/ssl_policy.h b/content/browser/ssl/ssl_policy.h index 2855a1b..c002bfc 100644 --- a/content/browser/ssl/ssl_policy.h +++ b/content/browser/ssl/ssl_policy.h @@ -36,7 +36,7 @@ class SSLPolicy { void OnCertError(SSLCertErrorHandler* handler); void DidRunInsecureContent(NavigationEntryImpl* entry, - const std::string& security_origin); + const GURL& security_origin); // We have started a resource request with the given info. void OnRequestStarted(SSLRequestInfo* info); diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 327617d..1ca34e2 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc @@ -632,6 +632,10 @@ bool WebContentsImpl::OnMessageReceived(RenderViewHost* render_view_host, OnDidDisplayInsecureContent) IPC_MESSAGE_HANDLER(FrameHostMsg_DidRunInsecureContent, OnDidRunInsecureContent) + IPC_MESSAGE_HANDLER(FrameHostMsg_DidDisplayContentWithCertificateErrors, + OnDidDisplayContentWithCertificateErrors) + IPC_MESSAGE_HANDLER(FrameHostMsg_DidRunContentWithCertificateErrors, + OnDidRunContentWithCertificateErrors) IPC_MESSAGE_HANDLER(ViewHostMsg_GoToEntryAtOffset, OnGoToEntryAtOffset) IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateZoomLimits, OnUpdateZoomLimits) IPC_MESSAGE_HANDLER(ViewHostMsg_PageScaleFactorChanged, @@ -3170,12 +3174,12 @@ void WebContentsImpl::OnDidDisplayInsecureContent() { GetController().GetBrowserContext()); } -void WebContentsImpl::OnDidRunInsecureContent( - const std::string& security_origin, const GURL& target_url) { +void WebContentsImpl::OnDidRunInsecureContent(const GURL& security_origin, + const GURL& target_url) { LOG(WARNING) << security_origin << " ran insecure content from " << target_url.possibly_invalid_spec(); RecordAction(base::UserMetricsAction("SSL.RanInsecureContent")); - if (base::EndsWith(security_origin, kDotGoogleDotCom, + if (base::EndsWith(security_origin.spec(), kDotGoogleDotCom, base::CompareCase::INSENSITIVE_ASCII)) RecordAction(base::UserMetricsAction("SSL.RanInsecureContentGoogle")); controller_.ssl_manager()->DidRunInsecureContent(security_origin); @@ -3183,6 +3187,39 @@ void WebContentsImpl::OnDidRunInsecureContent( GetController().GetBrowserContext()); } +void WebContentsImpl::OnDidDisplayContentWithCertificateErrors( + const GURL& url, + const std::string& security_info) { + SSLStatus ssl; + if (!DeserializeSecurityInfo(security_info, &ssl)) { + bad_message::ReceivedBadMessage( + GetRenderProcessHost(), + bad_message::WC_CONTENT_WITH_CERT_ERRORS_BAD_SECURITY_INFO); + return; + } + + displayed_insecure_content_ = true; + SSLManager::NotifySSLInternalStateChanged( + GetController().GetBrowserContext()); +} + +void WebContentsImpl::OnDidRunContentWithCertificateErrors( + const GURL& security_origin, + const GURL& url, + const std::string& security_info) { + SSLStatus ssl; + if (!DeserializeSecurityInfo(security_info, &ssl)) { + bad_message::ReceivedBadMessage( + GetRenderProcessHost(), + bad_message::WC_CONTENT_WITH_CERT_ERRORS_BAD_SECURITY_INFO); + return; + } + + controller_.ssl_manager()->DidRunInsecureContent(security_origin); + SSLManager::NotifySSLInternalStateChanged( + GetController().GetBrowserContext()); +} + void WebContentsImpl::OnDocumentLoadedInFrame() { if (!HasValidFrameSource()) return; diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index 5ef8108..a46f717 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h @@ -837,8 +837,14 @@ class CONTENT_EXPORT WebContentsImpl const std::string& mime_type, ResourceType resource_type); void OnDidDisplayInsecureContent(); - void OnDidRunInsecureContent(const std::string& security_origin, + void OnDidRunInsecureContent(const GURL& security_origin, const GURL& target_url); + void OnDidDisplayContentWithCertificateErrors( + const GURL& url, + const std::string& security_info); + void OnDidRunContentWithCertificateErrors(const GURL& security_origin, + const GURL& url, + const std::string& security_info); void OnDocumentLoadedInFrame(); void OnDidFinishLoad(const GURL& url); void OnGoToEntryAtOffset(int offset); diff --git a/content/child/web_url_loader_impl.cc b/content/child/web_url_loader_impl.cc index bea6020..dbcff21 100644 --- a/content/child/web_url_loader_impl.cc +++ b/content/child/web_url_loader_impl.cc @@ -887,6 +887,7 @@ void WebURLLoaderImpl::PopulateURLResponse(const GURL& url, response->setTextEncodingName(WebString::fromUTF8(info.charset)); response->setExpectedContentLength(info.content_length); response->setSecurityInfo(info.security_info); + response->setHasMajorCertificateErrors(info.has_major_certificate_errors); response->setAppCacheID(info.appcache_id); response->setAppCacheManifestURL(info.appcache_manifest_url); response->setWasCached(!info.load_timing.request_start_time.is_null() && diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index 72d6751..f9604de 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h @@ -1225,9 +1225,22 @@ IPC_MESSAGE_ROUTED0(FrameHostMsg_DidDisplayInsecureContent) // Sent when the renderer runs insecure content in a secure origin. IPC_MESSAGE_ROUTED2(FrameHostMsg_DidRunInsecureContent, - std::string /* security_origin */, + GURL /* security_origin */, GURL /* target URL */) +// Sent when the renderer displays content that was loaded with +// certificate errors. +IPC_MESSAGE_ROUTED2(FrameHostMsg_DidDisplayContentWithCertificateErrors, + GURL /* resource url */, + std::string /* serialized security info */) + +// Sent when the renderer runs content that was loaded with certificate +// errors. +IPC_MESSAGE_ROUTED3(FrameHostMsg_DidRunContentWithCertificateErrors, + GURL /* security_origin */, + GURL /* resource url */, + std::string /* serialized security info */) + // Response to FrameMsg_GetSavableResourceLinks. IPC_MESSAGE_ROUTED3(FrameHostMsg_SavableResourceLinksResponse, std::vector<GURL> /* savable resource links */, diff --git a/content/common/resource_messages.h b/content/common/resource_messages.h index 0c970ae..65e7f00 100644 --- a/content/common/resource_messages.h +++ b/content/common/resource_messages.h @@ -119,6 +119,7 @@ IPC_STRUCT_TRAITS_BEGIN(content::ResourceResponseInfo) IPC_STRUCT_TRAITS_MEMBER(mime_type) IPC_STRUCT_TRAITS_MEMBER(charset) IPC_STRUCT_TRAITS_MEMBER(security_info) + IPC_STRUCT_TRAITS_MEMBER(has_major_certificate_errors) IPC_STRUCT_TRAITS_MEMBER(content_length) IPC_STRUCT_TRAITS_MEMBER(encoded_data_length) IPC_STRUCT_TRAITS_MEMBER(appcache_id) diff --git a/content/public/common/resource_response.cc b/content/public/common/resource_response.cc index 12f1dd7..1277355 100644 --- a/content/public/common/resource_response.cc +++ b/content/public/common/resource_response.cc @@ -19,6 +19,8 @@ scoped_refptr<ResourceResponse> ResourceResponse::DeepCopy() const { new_response->head.mime_type = head.mime_type; new_response->head.charset = head.charset; new_response->head.security_info = head.security_info; + new_response->head.has_major_certificate_errors = + head.has_major_certificate_errors; new_response->head.content_length = head.content_length; new_response->head.encoded_data_length = head.encoded_data_length; new_response->head.appcache_id = head.appcache_id; diff --git a/content/public/common/resource_response_info.cc b/content/public/common/resource_response_info.cc index 1d4e304..f05ee19 100644 --- a/content/public/common/resource_response_info.cc +++ b/content/public/common/resource_response_info.cc @@ -10,7 +10,8 @@ namespace content { ResourceResponseInfo::ResourceResponseInfo() - : content_length(-1), + : has_major_certificate_errors(false), + content_length(-1), encoded_data_length(-1), appcache_id(kAppCacheNoCacheId), was_fetched_via_spdy(false), @@ -22,8 +23,7 @@ ResourceResponseInfo::ResourceResponseInfo() was_fallback_required_by_service_worker(false), response_type_via_service_worker( blink::WebServiceWorkerResponseTypeDefault), - is_using_lofi(false) { -} + is_using_lofi(false) {} ResourceResponseInfo::~ResourceResponseInfo() { } diff --git a/content/public/common/resource_response_info.h b/content/public/common/resource_response_info.h index 1a0f126..8b81f6d 100644 --- a/content/public/common/resource_response_info.h +++ b/content/public/common/resource_response_info.h @@ -50,6 +50,9 @@ struct ResourceResponseInfo { // response. This may include information about the SSL connection used. std::string security_info; + // True if the resource was loaded in spite of certificate errors. + bool has_major_certificate_errors; + // Content length if available. -1 if not available int64 content_length; diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 271720e..9e432ba9 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc @@ -48,6 +48,7 @@ #include "content/common/savable_subframe.h" #include "content/common/service_worker/service_worker_types.h" #include "content/common/site_isolation_policy.h" +#include "content/common/ssl_status_serialization.h" #include "content/common/swapped_out_messages.h" #include "content/common/view_messages.h" #include "content/public/common/bindings_policy.h" @@ -575,6 +576,38 @@ WebString ConvertRelativePathToHtmlAttribute(const base::FilePath& path) { path.NormalizePathSeparatorsTo(FILE_PATH_LITERAL('/')).AsUTF8Unsafe()); } +bool IsContentWithCertificateErrorsRelevantToUI( + const blink::WebURL& url, + const blink::WebCString& security_info, + const blink::WebURL& main_resource_url, + const blink::WebCString& main_resource_security_info) { + content::SSLStatus ssl_status; + content::SSLStatus main_resource_ssl_status; + CHECK(DeserializeSecurityInfo(security_info, &ssl_status)); + CHECK(DeserializeSecurityInfo(main_resource_security_info, + &main_resource_ssl_status)); + + if (!GURL(main_resource_url).SchemeIsCryptographic()) + return false; + + // Do not handle subresource certificate errors if they are the same + // as errors that occured during the main page load. This compares + // most, but not all, fields of SSLStatus. For example, this check + // does not compare |content_status| because the navigation entry + // might have mixed content but also have the exact same SSL + // connection properties as the subresource, thereby making the + // subresource errors duplicative. + return (!url::Origin(GURL(url)) + .IsSameOriginWith(url::Origin(GURL(main_resource_url))) || + main_resource_ssl_status.security_style != + ssl_status.security_style || + main_resource_ssl_status.cert_id != ssl_status.cert_id || + main_resource_ssl_status.cert_status != ssl_status.cert_status || + main_resource_ssl_status.security_bits != ssl_status.security_bits || + main_resource_ssl_status.connection_status != + ssl_status.connection_status); +} + } // namespace // static @@ -3680,12 +3713,38 @@ void RenderFrameImpl::didRunInsecureContent( const blink::WebSecurityOrigin& origin, const blink::WebURL& target) { Send(new FrameHostMsg_DidRunInsecureContent( - routing_id_, origin.toString().utf8(), target)); + routing_id_, GURL(origin.toString().utf8()), target)); GetContentClient()->renderer()->RecordRapporURL( "ContentSettings.MixedScript.RanMixedScript", GURL(origin.toString().utf8())); } +void RenderFrameImpl::didDisplayContentWithCertificateErrors( + const blink::WebURL& url, + const blink::WebCString& security_info, + const blink::WebURL& main_resource_url, + const blink::WebCString& main_resource_security_info) { + if (!IsContentWithCertificateErrorsRelevantToUI( + url, security_info, main_resource_url, main_resource_security_info)) { + return; + } + Send(new FrameHostMsg_DidDisplayContentWithCertificateErrors(routing_id_, url, + security_info)); +} + +void RenderFrameImpl::didRunContentWithCertificateErrors( + const blink::WebURL& url, + const blink::WebCString& security_info, + const blink::WebURL& main_resource_url, + const blink::WebCString& main_resource_security_info) { + if (!IsContentWithCertificateErrorsRelevantToUI( + url, security_info, main_resource_url, main_resource_security_info)) { + return; + } + Send(new FrameHostMsg_DidRunContentWithCertificateErrors( + routing_id_, GURL(main_resource_url).GetOrigin(), url, security_info)); +} + void RenderFrameImpl::didChangePerformanceTiming() { FOR_EACH_OBSERVER(RenderFrameObserver, observers_, diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 8d3c4f3..9da61e0 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h @@ -522,6 +522,16 @@ class CONTENT_EXPORT RenderFrameImpl void didDisplayInsecureContent() override; void didRunInsecureContent(const blink::WebSecurityOrigin& origin, const blink::WebURL& target) override; + void didDisplayContentWithCertificateErrors( + const blink::WebURL& url, + const blink::WebCString& security_info, + const blink::WebURL& main_resource_url, + const blink::WebCString& main_resource_security_info) override; + void didRunContentWithCertificateErrors( + const blink::WebURL& url, + const blink::WebCString& security_info, + const blink::WebURL& main_resource_url, + const blink::WebCString& main_resource_security_info) override; void didChangePerformanceTiming() override; void didCreateScriptContext(blink::WebLocalFrame* frame, v8::Local<v8::Context> context, diff --git a/third_party/WebKit/Source/core/loader/EmptyClients.h b/third_party/WebKit/Source/core/loader/EmptyClients.h index 9f4f7bd..a0ae277 100644 --- a/third_party/WebKit/Source/core/loader/EmptyClients.h +++ b/third_party/WebKit/Source/core/loader/EmptyClients.h @@ -234,6 +234,8 @@ public: void didRunInsecureContent(SecurityOrigin*, const KURL&) override {} void didDetectXSS(const KURL&, bool) override {} void didDispatchPingLoader(const KURL&) override {} + void didDisplayContentWithCertificateErrors(const KURL&, const CString&, const WebURL& mainResourceUrl, const CString& mainResourceSecurityInfo) override {} + void didRunContentWithCertificateErrors(const KURL&, const CString&, const WebURL& mainResourceUrl, const CString& mainResourceSecurityInfo) override {} void selectorMatchChanged(const Vector<String>&, const Vector<String>&) override {} PassRefPtrWillBeRawPtr<LocalFrame> createFrame(const FrameLoadRequest&, const AtomicString&, HTMLFrameOwnerElement*) override; PassRefPtrWillBeRawPtr<Widget> createPlugin(HTMLPlugInElement*, const KURL&, const Vector<String>&, const Vector<String>&, const String&, bool, DetachedPluginPolicy) override; diff --git a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp index 6be16e9..41bed10 100644 --- a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp +++ b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp @@ -34,6 +34,7 @@ #include "bindings/core/v8/ScriptController.h" #include "core/dom/Document.h" #include "core/fetch/ClientHintsPreferences.h" +#include "core/fetch/ResourceLoader.h" #include "core/fetch/UniqueIdentifier.h" #include "core/frame/FrameConsole.h" #include "core/frame/FrameHost.h" @@ -239,6 +240,9 @@ void FrameFetchContext::dispatchDidReceiveResponse(unsigned long identifier, con m_documentLoader->clientHintsPreferences().updateFromAcceptClientHintsHeader(response.httpHeaderField("accept-ch"), fetcher); } + if (response.hasMajorCertificateErrors() && resourceLoader) + MixedContentChecker::handleCertificateError(frame(), resourceLoader->originalRequest(), response); + frame()->loader().progress().incrementProgress(identifier, response); frame()->loader().client()->dispatchDidReceiveResponse(m_documentLoader, identifier, response); TRACE_EVENT_INSTANT1("devtools.timeline", "ResourceReceiveResponse", TRACE_EVENT_SCOPE_THREAD, "data", InspectorReceiveResponseEvent::data(identifier, frame(), response)); diff --git a/third_party/WebKit/Source/core/loader/FrameLoaderClient.h b/third_party/WebKit/Source/core/loader/FrameLoaderClient.h index b492489..42e507d 100644 --- a/third_party/WebKit/Source/core/loader/FrameLoaderClient.h +++ b/third_party/WebKit/Source/core/loader/FrameLoaderClient.h @@ -129,6 +129,13 @@ public: virtual void didDetectXSS(const KURL&, bool didBlockEntirePage) = 0; virtual void didDispatchPingLoader(const KURL&) = 0; + // The given main resource displayed content with certificate errors + // with the given URL and security info. + virtual void didDisplayContentWithCertificateErrors(const KURL&, const CString& securityInfo, const WebURL& mainResourceUrl, const CString& mainResourceSecurityInfo) = 0; + // The given main resource ran content with certificate errors with + // the given URL and security info. + virtual void didRunContentWithCertificateErrors(const KURL&, const CString& securityInfo, const WebURL& mainResourceUrl, const CString& mainResourceSecurityInfo) = 0; + // Will be called when |PerformanceTiming| events are updated virtual void didChangePerformanceTiming() { } diff --git a/third_party/WebKit/Source/core/loader/MixedContentChecker.cpp b/third_party/WebKit/Source/core/loader/MixedContentChecker.cpp index fdcc09b..f525cda 100644 --- a/third_party/WebKit/Source/core/loader/MixedContentChecker.cpp +++ b/third_party/WebKit/Source/core/loader/MixedContentChecker.cpp @@ -458,6 +458,27 @@ LocalFrame* MixedContentChecker::effectiveFrameForFrameType(LocalFrame* frame, W return effectiveFrame; } +void MixedContentChecker::handleCertificateError(LocalFrame* frame, const ResourceRequest& request, const ResourceResponse& response) +{ + WebURLRequest::FrameType frameType = request.frameType(); + LocalFrame* effectiveFrame = effectiveFrameForFrameType(frame, frameType); + if (frameType == WebURLRequest::FrameTypeTopLevel || !effectiveFrame) + return; + + FrameLoaderClient* client = effectiveFrame->loader().client(); + WebURLRequest::RequestContext requestContext = request.requestContext(); + ContextType contextType = MixedContentChecker::contextTypeFromContext(requestContext, frame); + if (contextType == ContextTypeBlockable) { + client->didRunContentWithCertificateErrors(response.url(), response.getSecurityInfo(), effectiveFrame->document()->url(), effectiveFrame->loader().documentLoader()->response().getSecurityInfo()); + } else { + // contextTypeFromContext() never returns NotMixedContent (it + // computes the type of mixed content, given that the content is + // mixed). + ASSERT(contextType != ContextTypeNotMixedContent); + client->didDisplayContentWithCertificateErrors(response.url(), response.getSecurityInfo(), effectiveFrame->document()->url(), effectiveFrame->loader().documentLoader()->response().getSecurityInfo()); + } +} + MixedContentChecker::ContextType MixedContentChecker::contextTypeForInspector(LocalFrame* frame, const ResourceRequest& request) { LocalFrame* effectiveFrame = effectiveFrameForFrameType(frame, request.frameType()); diff --git a/third_party/WebKit/Source/core/loader/MixedContentChecker.h b/third_party/WebKit/Source/core/loader/MixedContentChecker.h index d88780b..e2e50c4 100644 --- a/third_party/WebKit/Source/core/loader/MixedContentChecker.h +++ b/third_party/WebKit/Source/core/loader/MixedContentChecker.h @@ -31,6 +31,7 @@ #ifndef MixedContentChecker_h #define MixedContentChecker_h +#include "base/gtest_prod_util.h" #include "core/CoreExport.h" #include "platform/heap/Handle.h" #include "platform/network/ResourceRequest.h" @@ -42,6 +43,7 @@ namespace blink { class FrameLoaderClient; class LocalFrame; class KURL; +class ResourceResponse; class SecurityOrigin; class CORE_EXPORT MixedContentChecker final { @@ -75,7 +77,10 @@ public: // for a mixed content check for the given frame type. static LocalFrame* effectiveFrameForFrameType(LocalFrame*, WebURLRequest::FrameType); + static void handleCertificateError(LocalFrame*, const ResourceRequest&, const ResourceResponse&); + private: + FRIEND_TEST_ALL_PREFIXES(MixedContentCheckerTest, HandleCertificateError); enum MixedContentType { Display, Execution, diff --git a/third_party/WebKit/Source/core/loader/MixedContentCheckerTest.cpp b/third_party/WebKit/Source/core/loader/MixedContentCheckerTest.cpp index 4291c0a..8b4cb21 100644 --- a/third_party/WebKit/Source/core/loader/MixedContentCheckerTest.cpp +++ b/third_party/WebKit/Source/core/loader/MixedContentCheckerTest.cpp @@ -5,9 +5,12 @@ #include "config.h" #include "core/loader/MixedContentChecker.h" +#include "core/loader/EmptyClients.h" #include "core/testing/DummyPageHolder.h" +#include "platform/network/ResourceResponse.h" #include "platform/weborigin/KURL.h" #include "platform/weborigin/SecurityOrigin.h" +#include "testing/gmock/include/gmock/gmock-generated-function-mockers.h" #include "testing/gtest/include/gtest/gtest.h" #include "wtf/RefPtr.h" #include <base/macros.h> @@ -67,4 +70,48 @@ TEST(MixedContentCheckerTest, ContextTypeForInspector) EXPECT_EQ(MixedContentChecker::ContextTypeOptionallyBlockable, MixedContentChecker::contextTypeForInspector(&dummyPageHolder->frame(), blockableMixedContent)); } +namespace { + + class MockFrameLoaderClient : public EmptyFrameLoaderClient { + public: + MockFrameLoaderClient() + : EmptyFrameLoaderClient() + { + } + MOCK_METHOD4(didDisplayContentWithCertificateErrors, void(const KURL&, const CString&, const WebURL&, const CString&)); + MOCK_METHOD4(didRunContentWithCertificateErrors, void(const KURL&, const CString&, const WebURL&, const CString&)); + }; + +} // namespace + +TEST(MixedContentCheckerTest, HandleCertificateError) +{ + MockFrameLoaderClient* client = new MockFrameLoaderClient; + OwnPtr<DummyPageHolder> dummyPageHolder = DummyPageHolder::create(IntSize(1, 1), nullptr, adoptPtrWillBeNoop(client)); + + KURL mainResourceUrl(KURL(), "https://example.test"); + KURL displayedUrl(KURL(), "https://example-displayed.test"); + KURL ranUrl(KURL(), "https://example-ran.test"); + + dummyPageHolder->frame().document()->setURL(mainResourceUrl); + ResourceRequest request1(ranUrl); + request1.setRequestContext(WebURLRequest::RequestContextScript); + request1.setFrameType(WebURLRequest::FrameTypeNone); + ResourceResponse response1; + response1.setURL(ranUrl); + response1.setSecurityInfo("security info1"); + EXPECT_CALL(*client, didRunContentWithCertificateErrors(ranUrl, response1.getSecurityInfo(), WebURL(mainResourceUrl), CString())); + MixedContentChecker::handleCertificateError(&dummyPageHolder->frame(), request1, response1); + + ResourceRequest request2(displayedUrl); + request2.setRequestContext(WebURLRequest::RequestContextImage); + request2.setFrameType(WebURLRequest::FrameTypeNone); + ResourceResponse response2; + ASSERT_EQ(MixedContentChecker::ContextTypeOptionallyBlockable, MixedContentChecker::contextTypeFromContext(request2.requestContext(), &dummyPageHolder->frame())); + response2.setURL(displayedUrl); + response2.setSecurityInfo("security info2"); + EXPECT_CALL(*client, didDisplayContentWithCertificateErrors(displayedUrl, response2.getSecurityInfo(), WebURL(mainResourceUrl), CString())); + MixedContentChecker::handleCertificateError(&dummyPageHolder->frame(), request2, response2); +} + } // namespace blink diff --git a/third_party/WebKit/Source/platform/exported/WebURLResponse.cpp b/third_party/WebKit/Source/platform/exported/WebURLResponse.cpp index 46f5dbf..6998d9a 100644 --- a/third_party/WebKit/Source/platform/exported/WebURLResponse.cpp +++ b/third_party/WebKit/Source/platform/exported/WebURLResponse.cpp @@ -305,6 +305,11 @@ void WebURLResponse::setSecurityInfo(const WebCString& securityInfo) m_private->m_resourceResponse->setSecurityInfo(securityInfo); } +void WebURLResponse::setHasMajorCertificateErrors(bool value) +{ + m_private->m_resourceResponse->setHasMajorCertificateErrors(value); +} + WebURLResponse::SecurityStyle WebURLResponse::securityStyle() const { return static_cast<SecurityStyle>(m_private->m_resourceResponse->securityStyle()); diff --git a/third_party/WebKit/Source/platform/network/ResourceResponse.cpp b/third_party/WebKit/Source/platform/network/ResourceResponse.cpp index 37de0b6..1ba750e 100644 --- a/third_party/WebKit/Source/platform/network/ResourceResponse.cpp +++ b/third_party/WebKit/Source/platform/network/ResourceResponse.cpp @@ -48,6 +48,7 @@ ResourceResponse::ResourceResponse() , m_date(0.0) , m_expires(0.0) , m_lastModified(0.0) + , m_hasMajorCertificateErrors(false) , m_securityStyle(SecurityStyleUnknown) , m_httpVersion(HTTPVersionUnknown) , m_appCacheID(0) @@ -84,6 +85,7 @@ ResourceResponse::ResourceResponse(const KURL& url, const AtomicString& mimeType , m_date(0.0) , m_expires(0.0) , m_lastModified(0.0) + , m_hasMajorCertificateErrors(false) , m_securityStyle(SecurityStyleUnknown) , m_httpVersion(HTTPVersionUnknown) , m_appCacheID(0) @@ -116,6 +118,7 @@ PassOwnPtr<ResourceResponse> ResourceResponse::adopt(PassOwnPtr<CrossThreadResou response->setLastModifiedDate(data->m_lastModifiedDate); response->setResourceLoadTiming(data->m_resourceLoadTiming.release()); response->m_securityInfo = data->m_securityInfo; + response->m_hasMajorCertificateErrors = data->m_hasMajorCertificateErrors; response->m_securityStyle = data->m_securityStyle; response->m_securityDetails.protocol = data->m_securityDetails.protocol; response->m_securityDetails.cipher = data->m_securityDetails.cipher; @@ -161,6 +164,7 @@ PassOwnPtr<CrossThreadResourceResponseData> ResourceResponse::copyData() const if (m_resourceLoadTiming) data->m_resourceLoadTiming = m_resourceLoadTiming->deepCopy(); data->m_securityInfo = CString(m_securityInfo.data(), m_securityInfo.length()); + data->m_hasMajorCertificateErrors = m_hasMajorCertificateErrors; data->m_securityStyle = m_securityStyle; data->m_securityDetails.protocol = m_securityDetails.protocol.isolatedCopy(); data->m_securityDetails.cipher = m_securityDetails.cipher.isolatedCopy(); diff --git a/third_party/WebKit/Source/platform/network/ResourceResponse.h b/third_party/WebKit/Source/platform/network/ResourceResponse.h index 58080de..9c19606 100644 --- a/third_party/WebKit/Source/platform/network/ResourceResponse.h +++ b/third_party/WebKit/Source/platform/network/ResourceResponse.h @@ -160,6 +160,9 @@ public: const CString& getSecurityInfo() const { return m_securityInfo; } void setSecurityInfo(const CString& securityInfo) { m_securityInfo = securityInfo; } + bool hasMajorCertificateErrors() const { return m_hasMajorCertificateErrors; } + void setHasMajorCertificateErrors(bool hasMajorCertificateErrors) { m_hasMajorCertificateErrors = hasMajorCertificateErrors; } + SecurityStyle securityStyle() const { return m_securityStyle; } void setSecurityStyle(SecurityStyle securityStyle) { m_securityStyle = securityStyle; } @@ -268,6 +271,10 @@ private: // string if not over HTTPS). CString m_securityInfo; + // True if the resource was retrieved by the embedder in spite of + // certificate errors. + bool m_hasMajorCertificateErrors; + // The security style of the resource. // This only contains a valid value when the DevTools Network domain is // enabled. (Otherwise, it contains a default value of Unknown.) @@ -357,6 +364,7 @@ public: time_t m_lastModifiedDate; RefPtr<ResourceLoadTiming> m_resourceLoadTiming; CString m_securityInfo; + bool m_hasMajorCertificateErrors; ResourceResponse::SecurityStyle m_securityStyle; ResourceResponse::SecurityDetails m_securityDetails; ResourceResponse::HTTPVersion m_httpVersion; diff --git a/third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp b/third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp index df4026a..19de8ca 100644 --- a/third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp +++ b/third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp @@ -677,6 +677,18 @@ void FrameLoaderClientImpl::didDispatchPingLoader(const KURL& url) m_webFrame->client()->didDispatchPingLoader(m_webFrame, url); } +void FrameLoaderClientImpl::didDisplayContentWithCertificateErrors(const KURL& url, const CString& securityInfo, const WebURL& mainResourceUrl, const CString& mainResourceSecurityInfo) +{ + if (m_webFrame->client()) + m_webFrame->client()->didDisplayContentWithCertificateErrors(url, securityInfo, mainResourceUrl, mainResourceSecurityInfo); +} + +void FrameLoaderClientImpl::didRunContentWithCertificateErrors(const KURL& url, const CString& securityInfo, const WebURL& mainResourceUrl, const CString& mainResourceSecurityInfo) +{ + if (m_webFrame->client()) + m_webFrame->client()->didRunContentWithCertificateErrors(url, securityInfo, mainResourceUrl, mainResourceSecurityInfo); +} + void FrameLoaderClientImpl::didChangePerformanceTiming() { if (m_webFrame->client()) diff --git a/third_party/WebKit/Source/web/FrameLoaderClientImpl.h b/third_party/WebKit/Source/web/FrameLoaderClientImpl.h index 518325b..360f5b0 100644 --- a/third_party/WebKit/Source/web/FrameLoaderClientImpl.h +++ b/third_party/WebKit/Source/web/FrameLoaderClientImpl.h @@ -113,6 +113,8 @@ public: void didRunInsecureContent(SecurityOrigin*, const KURL& insecureURL) override; void didDetectXSS(const KURL&, bool didBlockEntirePage) override; void didDispatchPingLoader(const KURL&) override; + void didDisplayContentWithCertificateErrors(const KURL&, const CString& securityInfo, const WebURL& mainResourceUrl, const CString& mainResourceSecurityInfo) override; + void didRunContentWithCertificateErrors(const KURL&, const CString& securityInfo, const WebURL& mainResourceUrl, const CString& mainResourceSecurityInfo) override; void didChangePerformanceTiming() override; void selectorMatchChanged(const Vector<String>& addedSelectors, const Vector<String>& removedSelectors) override; PassRefPtrWillBeRawPtr<DocumentLoader> createDocumentLoader(LocalFrame*, const ResourceRequest&, const SubstituteData&) override; diff --git a/third_party/WebKit/public/platform/WebURLResponse.h b/third_party/WebKit/public/platform/WebURLResponse.h index c7a5b0b..3a64468 100644 --- a/third_party/WebKit/public/platform/WebURLResponse.h +++ b/third_party/WebKit/public/platform/WebURLResponse.h @@ -146,6 +146,8 @@ public: BLINK_PLATFORM_EXPORT WebCString securityInfo() const; BLINK_PLATFORM_EXPORT void setSecurityInfo(const WebCString&); + BLINK_PLATFORM_EXPORT void setHasMajorCertificateErrors(bool); + BLINK_PLATFORM_EXPORT SecurityStyle securityStyle() const; BLINK_PLATFORM_EXPORT void setSecurityStyle(SecurityStyle); diff --git a/third_party/WebKit/public/web/WebFrameClient.h b/third_party/WebKit/public/web/WebFrameClient.h index e603a05..89f2cef 100644 --- a/third_party/WebKit/public/web/WebFrameClient.h +++ b/third_party/WebKit/public/web/WebFrameClient.h @@ -67,6 +67,7 @@ class WebColorChooser; class WebColorChooserClient; class WebContentDecryptionModule; class WebCookieJar; +class WebCString; class WebDataSource; class WebEncryptedMediaClient; class WebExternalPopupMenu; @@ -449,6 +450,13 @@ public: // A PingLoader was created, and a request dispatched to a URL. virtual void didDispatchPingLoader(WebLocalFrame*, const WebURL&) { } + // This frame has displayed inactive content (such as an image) from + // a connection with certificate errors. + virtual void didDisplayContentWithCertificateErrors(const WebURL& url, const WebCString& securityInfo, const WebURL& mainResourceUrl, const WebCString& mainResourceSecurityInfo) {} + // This frame has run active content (such as a script) from a + // connection with certificate errors. + virtual void didRunContentWithCertificateErrors(const WebURL& url, const WebCString& securityInfo, const WebURL& mainResourceUrl, const WebCString& mainResourceSecurityInfo) {} + // A performance timing event (e.g. first paint) occurred virtual void didChangePerformanceTiming() { } |