Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(225)

Unified Diff: chrome/browser/ssl/ssl_manager.cc

Issue 46094: Fix our handling of mixed SSL / non-SSL content.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 11 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ssl/ssl_manager.cc
===================================================================
--- chrome/browser/ssl/ssl_manager.cc (revision 11701)
+++ chrome/browser/ssl/ssl_manager.cc (working copy)
@@ -121,6 +121,8 @@
Source<NavigationController>(controller_));
registrar_.Add(this, NotificationType::LOAD_FROM_MEMORY_CACHE,
Source<NavigationController>(controller_));
+ registrar_.Add(this, NotificationType::SSL_INTERNAL_STATE_CHANGED,
+ NotificationService::AllSources());
}
SSLManager::~SSLManager() {
@@ -161,21 +163,6 @@
}
// Delegate API method.
-bool SSLManager::SetMaxSecurityStyle(SecurityStyle style) {
- NavigationEntry* entry = controller_->GetActiveEntry();
- if (!entry) {
- NOTREACHED();
- return false;
- }
-
- if (entry->ssl().security_style() > style) {
- entry->ssl().set_security_style(style);
- return true;
- }
- return false;
-}
-
-// Delegate API method.
void SSLManager::AddMessageToConsole(const std::wstring& msg,
ConsoleMessageLevel level) {
TabContents* tab_contents = controller_->GetTabContents(TAB_CONTENTS_WEB);
@@ -190,16 +177,29 @@
}
// Delegate API method.
+void SSLManager::MarkHostAsBroken(const std::string& host) {
+ ssl_host_state_->MarkHostAsBroken(host);
+ DispatchSSLInternalStateChanged();
+}
+
+// Delegate API method.
+bool SSLManager::DidMarkHostAsBroken(const std::string& host) const {
+ return ssl_host_state_->DidMarkHostAsBroken(host);
+}
+
+// Delegate API method.
void SSLManager::DenyCertForHost(net::X509Certificate* cert,
const std::string& host) {
// Remember that we don't like this cert for this host.
ssl_host_state_->DenyCertForHost(cert, host);
+ DispatchSSLInternalStateChanged();
}
// Delegate API method.
void SSLManager::AllowCertForHost(net::X509Certificate* cert,
const std::string& host) {
ssl_host_state_->AllowCertForHost(cert, host);
+ DispatchSSLInternalStateChanged();
}
// Delegate API method.
@@ -208,12 +208,15 @@
return ssl_host_state_->QueryPolicy(cert, host);
}
-bool SSLManager::CanShowInsecureContent(const GURL& url) {
- return ssl_host_state_->CanShowInsecureContent(url);
+// Delegate API method.
+void SSLManager::AllowMixedContentForHost(const std::string& host) {
+ ssl_host_state_->AllowMixedContentForHost(host);
+ DispatchSSLInternalStateChanged();
}
-void SSLManager::AllowShowInsecureContentForURL(const GURL& url) {
- ssl_host_state_->AllowShowInsecureContentForURL(url);
+// Delegate API method.
+bool SSLManager::DidAllowMixedContentForHost(const std::string& host) const {
+ return ssl_host_state_->DidAllowMixedContentForHost(host);
}
bool SSLManager::ProcessedSSLErrorFromRequest() const {
@@ -231,6 +234,9 @@
SSLManager::ErrorHandler::ErrorHandler(ResourceDispatcherHost* rdh,
URLRequest* request,
+ ResourceType::Type resource_type,
+ const std::string& frame_origin,
+ const std::string& main_frame_origin,
MessageLoop* ui_loop)
: ui_loop_(ui_loop),
io_loop_(MessageLoop::current()),
@@ -238,6 +244,9 @@
request_id_(0, 0),
resource_dispatcher_host_(rdh),
request_url_(request->url()),
+ resource_type_(resource_type),
+ frame_origin_(frame_origin),
+ main_frame_origin_(main_frame_origin),
request_has_been_notified_(false) {
DCHECK(MessageLoop::current() != ui_loop);
@@ -428,12 +437,14 @@
ResourceDispatcherHost* rdh,
URLRequest* request,
ResourceType::Type resource_type,
+ const std::string& frame_origin,
+ const std::string& main_frame_origin,
int cert_error,
net::X509Certificate* cert,
MessageLoop* ui_loop)
- : ErrorHandler(rdh, request, ui_loop),
- cert_error_(cert_error),
- resource_type_(resource_type) {
+ : ErrorHandler(rdh, request, resource_type, frame_origin,
+ main_frame_origin, ui_loop),
+ cert_error_(cert_error) {
DCHECK(request == resource_dispatcher_host_->GetURLRequest(request_id_));
// We cannot use the request->ssl_info(), it's not been initialized yet, so
@@ -458,50 +469,53 @@
// A certificate error occurred. Construct a CertError object and hand it
// over to the UI thread for processing.
ui_loop->PostTask(FROM_HERE,
- NewRunnableMethod(new CertError(rdh, request, info->resource_type,
- cert_error, cert, ui_loop),
+ NewRunnableMethod(new CertError(rdh,
+ request,
+ info->resource_type,
+ info->frame_origin,
+ info->main_frame_origin,
+ cert_error,
+ cert,
+ ui_loop),
&CertError::Dispatch));
}
// static
-void SSLManager::OnMixedContentRequest(ResourceDispatcherHost* rdh,
- URLRequest* request,
- MessageLoop* ui_loop) {
+bool SSLManager::ShouldDelayRequest(ResourceDispatcherHost* rdh,
+ URLRequest* request,
+ MessageLoop* ui_loop) {
+ ResourceDispatcherHost::ExtraRequestInfo* info =
+ ResourceDispatcherHost::ExtraInfoForRequest(request);
+ DCHECK(info);
+
+ // We cheat here and talk to the SSLPolicy on the IO channel because we need
+ // to respond synchronously to avoid delaying all network requests...
+ SSLPolicy::IsMixedContent(request->url(),
jcampan 2009/03/16 18:43:54 Don't you want to return false if IsMixedContent r
abarth-chromium 2009/03/16 21:34:21 Yes. :)
+ info->resource_type,
+ info->frame_origin);
+
+
ui_loop->PostTask(FROM_HERE,
- NewRunnableMethod(new MixedContentHandler(rdh, request, ui_loop),
+ NewRunnableMethod(new MixedContentHandler(rdh, request,
+ info->resource_type,
+ info->frame_origin,
+ info->main_frame_origin,
+ ui_loop),
&MixedContentHandler::Dispatch));
+ return true;
}
void SSLManager::OnCertError(CertError* error) {
- // Ask our delegate to deal with the error.
- NavigationEntry* entry = controller_->GetActiveEntry();
- // We might not have a navigation entry in some cases (e.g. when a
- // HTTPS page opens a popup with no URL and then populate it with
- // document.write()). See bug http://crbug.com/3845.
- if (!entry)
- return;
-
- delegate()->OnCertError(entry->url(), error);
+ delegate()->OnCertError(error);
}
void SSLManager::OnMixedContent(MixedContentHandler* mixed_content) {
- // Ask our delegate to deal with the mixed content.
- NavigationEntry* entry = controller_->GetActiveEntry();
- // We might not have a navigation entry in some cases (e.g. when a
- // HTTPS page opens a popup with no URL and then populate it with
- // document.write()). See bug http://crbug.com/3845.
- if (!entry)
- return;
-
- delegate()->OnMixedContent(controller_, entry->url(), mixed_content);
+ delegate()->OnMixedContent(mixed_content);
}
void SSLManager::Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
- // We should only be getting notifications from our controller.
- DCHECK(source == Source<NavigationController>(controller_));
-
// Dispatch by type.
switch (type.value) {
case NotificationType::NAV_ENTRY_COMMITTED:
@@ -522,43 +536,77 @@
DidLoadFromMemoryCache(
Details<LoadFromMemoryCacheDetails>(details).ptr());
break;
+ case NotificationType::SSL_INTERNAL_STATE_CHANGED:
+ DidChangeSSLInternalState();
+ break;
default:
NOTREACHED() << "The SSLManager received an unexpected notification.";
}
}
-void SSLManager::InitializeEntryIfNeeded(NavigationEntry* entry) {
+void SSLManager::DispatchSSLInternalStateChanged() {
+ NotificationService::current()->Notify(
+ NotificationType::SSL_INTERNAL_STATE_CHANGED,
+ Source<NavigationController>(controller_),
+ NotificationService::NoDetails());
+}
+
+void SSLManager::DispatchSSLVisibleStateChanged() {
+ NotificationService::current()->Notify(
+ NotificationType::SSL_VISIBLE_STATE_CHANGED,
+ Source<NavigationController>(controller_),
+ NotificationService::NoDetails());
+}
+
+void SSLManager::UpdateEntry(NavigationEntry* entry) {
DCHECK(entry);
- // If the security style of the entry is SECURITY_STYLE_UNKNOWN, then it is a
- // fresh entry and should get the default style.
- if (entry->ssl().security_style() == SECURITY_STYLE_UNKNOWN) {
- entry->ssl().set_security_style(
- delegate()->GetDefaultStyle(entry->url()));
- }
+ NavigationEntry::SSLStatus original_status = entry->ssl(); // Copy!
+
+ delegate()->UpdateEntry(this, entry);
+
+ if (original_status.security_style() != entry->ssl().security_style() ||
+ original_status.has_mixed_content() != entry->ssl().has_mixed_content() ||
+ original_status.has_unsafe_content() != entry->ssl().has_unsafe_content())
+ DispatchSSLVisibleStateChanged();
}
void SSLManager::NavigationStateChanged() {
- NavigationEntry* active_entry = controller_->GetActiveEntry();
- if (!active_entry)
+ NavigationEntry* entry = controller_->GetActiveEntry();
+ if (!entry)
return; // Nothing showing yet.
// This might be a new entry we've never seen before.
- InitializeEntryIfNeeded(active_entry);
+ UpdateEntry(entry);
}
void SSLManager::DidLoadFromMemoryCache(LoadFromMemoryCacheDetails* details) {
DCHECK(details);
- // Simulate loading this resource through the usual path.
// Note that we specify SUB_RESOURCE as the resource type as WebCore only
// caches sub-resources.
- delegate()->OnRequestStarted(this, details->url(),
- ResourceType::SUB_RESOURCE,
- details->ssl_cert_id(),
- details->ssl_cert_status());
+ scoped_refptr<RequestInfo> info = new RequestInfo(
+ this,
+ details->url(),
+ ResourceType::SUB_RESOURCE,
+ details->frame_origin(),
+ details->main_frame_origin(),
+ details->ssl_cert_id(),
+ details->ssl_cert_status());
+
+ // Simulate loading this resource through the usual path.
+ delegate()->OnRequestStarted(info.get());
}
+void SSLManager::DidChangeSSLInternalState() {
+ NavigationEntry* entry = controller_->GetActiveEntry();
+ if (!entry)
+ return; // Nothing showing yet.
+
+ // We might have to update the current entry if our SSL state changes.
+ UpdateEntry(entry);
+}
+
void SSLManager::DidCommitProvisionalLoad(
const NotificationDetails& in_details) {
NavigationController::LoadCommittedDetails* details =
@@ -574,7 +622,7 @@
DeserializeSecurityInfo(details->serialized_security_info,
&ssl_cert_id, &ssl_cert_status, &ssl_security_bits);
- bool changed = false;
+ bool entry_changed = false;
if (details->is_main_frame) {
// Update the SSL states of the pending entry.
NavigationEntry* entry = controller_->GetActiveEntry();
@@ -582,11 +630,11 @@
// 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();
- InitializeEntryIfNeeded(entry); // For security_style.
+ UpdateEntry(entry); // For security_style.
entry->ssl().set_cert_id(ssl_cert_id);
entry->ssl().set_cert_status(ssl_cert_status);
entry->ssl().set_security_bits(ssl_security_bits);
- changed = true;
+ entry_changed = true;
}
ShowPendingMessages();
@@ -597,15 +645,19 @@
// broken security style so that we can detect this error condition.
if (net::IsCertStatusError(ssl_cert_status) &&
!details->is_content_filtered) {
- changed |= SetMaxSecurityStyle(SECURITY_STYLE_AUTHENTICATION_BROKEN);
+ // TODO(abarth): This is wrong. It's the SSLPolicy's job to set the max
+ // security style.
+ //SetMaxSecurityStyle(SECURITY_STYLE_AUTHENTICATION_BROKEN);
if (!details->is_main_frame &&
!details->entry->ssl().has_unsafe_content()) {
details->entry->ssl().set_has_unsafe_content();
- changed = true;
+ entry_changed = true;
}
} else if (details->entry->url().SchemeIsSecure() && !ssl_cert_id) {
if (details->is_main_frame) {
- changed |= SetMaxSecurityStyle(SECURITY_STYLE_UNAUTHENTICATED);
+ // TODO(abarth): This is wrong. It's the SSLPolicy's job to set the max
+ // security style.
+ //SetMaxSecurityStyle(SECURITY_STYLE_UNAUTHENTICATED);
} else {
// If the frame has been blocked we keep our security style as
// authenticated in that case as nothing insecure is actually showing or
@@ -613,18 +665,13 @@
if (!details->is_content_filtered &&
!details->entry->ssl().has_mixed_content()) {
details->entry->ssl().set_has_mixed_content();
- changed = true;
+ entry_changed = true;
}
}
}
- if (changed) {
- // Only send the notification when something actually changed.
- NotificationService::current()->Notify(
- NotificationType::SSL_STATE_CHANGED,
- Source<NavigationController>(controller_),
- NotificationService::NoDetails());
- }
+ if (entry_changed)
+ DispatchSSLVisibleStateChanged();
}
void SSLManager::DidFailProvisionalLoadWithError(
@@ -642,18 +689,25 @@
void SSLManager::DidStartResourceResponse(ResourceRequestDetails* details) {
DCHECK(details);
+ scoped_refptr<RequestInfo> info = new RequestInfo(
+ this,
+ details->url(),
+ details->resource_type(),
+ details->frame_origin(),
+ details->main_frame_origin(),
+ details->ssl_cert_id(),
+ details->ssl_cert_status());
+
// Notify our delegate that we started a resource request. Ideally, the
// delegate should have the ability to cancel the request, but we can't do
// that yet.
- delegate()->OnRequestStarted(this, details->url(),
- details->resource_type(),
- details->ssl_cert_id() ,
- details->ssl_cert_status());
+ delegate()->OnRequestStarted(info.get());
}
void SSLManager::DidReceiveResourceRedirect(ResourceRedirectDetails* details) {
// TODO(jcampan): when we receive a redirect for a sub-resource, we may want
// to clear any mixed/unsafe content error that it may have triggered.
+ // Really??? I'm not sure that's right. -- abarth (3/14/2009)
}
void SSLManager::ShowPendingMessages() {

Powered by Google App Engine
This is Rietveld 408576698