| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/ssl/ssl_manager.h" | 5 #include "content/browser/ssl/ssl_manager.h" |
| 6 | 6 |
| 7 #include <set> | |
| 8 | |
| 9 #include "base/bind.h" | 7 #include "base/bind.h" |
| 10 #include "base/supports_user_data.h" | |
| 11 #include "base/utf_string_conversions.h" | 8 #include "base/utf_string_conversions.h" |
| 12 #include "content/browser/loader/resource_dispatcher_host_impl.h" | 9 #include "content/browser/loader/resource_dispatcher_host_impl.h" |
| 13 #include "content/browser/loader/resource_request_info_impl.h" | 10 #include "content/browser/loader/resource_request_info_impl.h" |
| 14 #include "content/browser/ssl/ssl_cert_error_handler.h" | 11 #include "content/browser/ssl/ssl_cert_error_handler.h" |
| 15 #include "content/browser/ssl/ssl_policy.h" | 12 #include "content/browser/ssl/ssl_policy.h" |
| 16 #include "content/browser/ssl/ssl_request_info.h" | 13 #include "content/browser/ssl/ssl_request_info.h" |
| 17 #include "content/browser/web_contents/navigation_entry_impl.h" | 14 #include "content/browser/web_contents/navigation_entry_impl.h" |
| 18 #include "content/browser/web_contents/web_contents_impl.h" | 15 #include "content/browser/web_contents/web_contents_impl.h" |
| 19 #include "content/common/ssl_status_serialization.h" | 16 #include "content/common/ssl_status_serialization.h" |
| 20 #include "content/public/browser/browser_context.h" | |
| 21 #include "content/public/browser/browser_thread.h" | 17 #include "content/public/browser/browser_thread.h" |
| 22 #include "content/public/browser/load_from_memory_cache_details.h" | 18 #include "content/public/browser/load_from_memory_cache_details.h" |
| 23 #include "content/public/browser/navigation_details.h" | 19 #include "content/public/browser/navigation_details.h" |
| 24 #include "content/public/browser/notification_service.h" | 20 #include "content/public/browser/notification_service.h" |
| 25 #include "content/public/browser/notification_source.h" | 21 #include "content/public/browser/notification_source.h" |
| 26 #include "content/public/browser/resource_request_details.h" | 22 #include "content/public/browser/resource_request_details.h" |
| 27 #include "content/public/common/ssl_status.h" | 23 #include "content/public/common/ssl_status.h" |
| 28 #include "net/url_request/url_request.h" | 24 #include "net/url_request/url_request.h" |
| 29 | 25 |
| 30 namespace content { | 26 namespace content { |
| 31 | 27 |
| 32 namespace { | |
| 33 | |
| 34 const char kSSLManagerKeyName[] = "content_ssl_manager"; | |
| 35 | |
| 36 class SSLManagerSet : public base::SupportsUserData::Data { | |
| 37 public: | |
| 38 SSLManagerSet() { | |
| 39 } | |
| 40 | |
| 41 std::set<SSLManager*>& get() { return set_; } | |
| 42 | |
| 43 private: | |
| 44 std::set<SSLManager*> set_; | |
| 45 | |
| 46 DISALLOW_COPY_AND_ASSIGN(SSLManagerSet); | |
| 47 }; | |
| 48 | |
| 49 } // namespace | |
| 50 | |
| 51 // static | 28 // static |
| 52 void SSLManager::OnSSLCertificateError( | 29 void SSLManager::OnSSLCertificateError( |
| 53 const base::WeakPtr<SSLErrorHandler::Delegate>& delegate, | 30 const base::WeakPtr<SSLErrorHandler::Delegate>& delegate, |
| 54 const GlobalRequestID& id, | 31 const GlobalRequestID& id, |
| 55 const ResourceType::Type resource_type, | 32 const ResourceType::Type resource_type, |
| 56 const GURL& url, | 33 const GURL& url, |
| 57 int render_process_id, | 34 int render_process_id, |
| 58 int render_view_id, | 35 int render_view_id, |
| 59 const net::SSLInfo& ssl_info, | 36 const net::SSLInfo& ssl_info, |
| 60 bool fatal) { | 37 bool fatal) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 77 id, | 54 id, |
| 78 resource_type, | 55 resource_type, |
| 79 url, | 56 url, |
| 80 render_process_id, | 57 render_process_id, |
| 81 render_view_id, | 58 render_view_id, |
| 82 ssl_info, | 59 ssl_info, |
| 83 fatal))); | 60 fatal))); |
| 84 } | 61 } |
| 85 | 62 |
| 86 // static | 63 // static |
| 87 void SSLManager::NotifySSLInternalStateChanged(BrowserContext* context) { | 64 void SSLManager::NotifySSLInternalStateChanged( |
| 88 SSLManagerSet* managers = static_cast<SSLManagerSet*>( | 65 NavigationControllerImpl* controller) { |
| 89 context->GetUserData(kSSLManagerKeyName)); | 66 NotificationService::current()->Notify( |
| 90 | 67 NOTIFICATION_SSL_INTERNAL_STATE_CHANGED, |
| 91 for (std::set<SSLManager*>::iterator i = managers->get().begin(); | 68 Source<BrowserContext>(controller->GetBrowserContext()), |
| 92 i != managers->get().end(); ++i) { | 69 NotificationService::NoDetails()); |
| 93 (*i)->UpdateEntry(NavigationEntryImpl::FromNavigationEntry( | |
| 94 (*i)->controller()->GetActiveEntry())); | |
| 95 } | |
| 96 } | 70 } |
| 97 | 71 |
| 98 SSLManager::SSLManager(NavigationControllerImpl* controller) | 72 SSLManager::SSLManager(NavigationControllerImpl* controller) |
| 99 : backend_(controller), | 73 : backend_(controller), |
| 100 policy_(new SSLPolicy(&backend_)), | 74 policy_(new SSLPolicy(&backend_)), |
| 101 controller_(controller) { | 75 controller_(controller) { |
| 102 DCHECK(controller_); | 76 DCHECK(controller_); |
| 103 | 77 |
| 104 // Subscribe to various notifications. | 78 // Subscribe to various notifications. |
| 105 registrar_.Add( | 79 registrar_.Add( |
| 106 this, NOTIFICATION_RESOURCE_RESPONSE_STARTED, | 80 this, NOTIFICATION_RESOURCE_RESPONSE_STARTED, |
| 107 Source<WebContents>(controller_->web_contents())); | 81 Source<WebContents>(controller_->web_contents())); |
| 108 registrar_.Add( | 82 registrar_.Add( |
| 109 this, NOTIFICATION_RESOURCE_RECEIVED_REDIRECT, | 83 this, NOTIFICATION_RESOURCE_RECEIVED_REDIRECT, |
| 110 Source<WebContents>(controller_->web_contents())); | 84 Source<WebContents>(controller_->web_contents())); |
| 111 registrar_.Add( | 85 registrar_.Add( |
| 112 this, NOTIFICATION_LOAD_FROM_MEMORY_CACHE, | 86 this, NOTIFICATION_LOAD_FROM_MEMORY_CACHE, |
| 113 Source<NavigationController>(controller_)); | 87 Source<NavigationController>(controller_)); |
| 114 | 88 registrar_.Add( |
| 115 SSLManagerSet* managers = static_cast<SSLManagerSet*>( | 89 this, NOTIFICATION_SSL_INTERNAL_STATE_CHANGED, |
| 116 controller_->GetBrowserContext()->GetUserData(kSSLManagerKeyName)); | 90 Source<BrowserContext>( |
| 117 if (!managers) { | 91 controller_->GetBrowserContext())); |
| 118 managers = new SSLManagerSet; | |
| 119 controller_->GetBrowserContext()->SetUserData(kSSLManagerKeyName, managers); | |
| 120 } | |
| 121 managers->get().insert(this); | |
| 122 } | 92 } |
| 123 | 93 |
| 124 SSLManager::~SSLManager() { | 94 SSLManager::~SSLManager() { |
| 125 SSLManagerSet* managers = static_cast<SSLManagerSet*>( | |
| 126 controller_->GetBrowserContext()->GetUserData(kSSLManagerKeyName)); | |
| 127 managers->get().erase(this); | |
| 128 } | 95 } |
| 129 | 96 |
| 130 void SSLManager::DidCommitProvisionalLoad( | 97 void SSLManager::DidCommitProvisionalLoad( |
| 131 const NotificationDetails& in_details) { | 98 const NotificationDetails& in_details) { |
| 132 LoadCommittedDetails* details = | 99 LoadCommittedDetails* details = |
| 133 Details<LoadCommittedDetails>(in_details).ptr(); | 100 Details<LoadCommittedDetails>(in_details).ptr(); |
| 134 | 101 |
| 135 NavigationEntryImpl* entry = | 102 NavigationEntryImpl* entry = |
| 136 NavigationEntryImpl::FromNavigationEntry(controller_->GetActiveEntry()); | 103 NavigationEntryImpl::FromNavigationEntry(controller_->GetActiveEntry()); |
| 137 | 104 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 154 entry->GetSSL().cert_id = ssl_cert_id; | 121 entry->GetSSL().cert_id = ssl_cert_id; |
| 155 entry->GetSSL().cert_status = ssl_cert_status; | 122 entry->GetSSL().cert_status = ssl_cert_status; |
| 156 entry->GetSSL().security_bits = ssl_security_bits; | 123 entry->GetSSL().security_bits = ssl_security_bits; |
| 157 entry->GetSSL().connection_status = ssl_connection_status; | 124 entry->GetSSL().connection_status = ssl_connection_status; |
| 158 } | 125 } |
| 159 } | 126 } |
| 160 | 127 |
| 161 UpdateEntry(entry); | 128 UpdateEntry(entry); |
| 162 } | 129 } |
| 163 | 130 |
| 164 void SSLManager::DidDisplayInsecureContent() { | |
| 165 UpdateEntry( | |
| 166 NavigationEntryImpl::FromNavigationEntry(controller_->GetActiveEntry())); | |
| 167 } | |
| 168 | |
| 169 void SSLManager::DidRunInsecureContent(const std::string& security_origin) { | 131 void SSLManager::DidRunInsecureContent(const std::string& security_origin) { |
| 170 NavigationEntryImpl* navigation_entry = | 132 policy()->DidRunInsecureContent( |
| 171 NavigationEntryImpl::FromNavigationEntry(controller_->GetActiveEntry()); | 133 NavigationEntryImpl::FromNavigationEntry(controller_->GetActiveEntry()), |
| 172 policy()->DidRunInsecureContent(navigation_entry, security_origin); | 134 security_origin); |
| 173 UpdateEntry(navigation_entry); | |
| 174 } | 135 } |
| 175 | 136 |
| 176 void SSLManager::Observe(int type, | 137 void SSLManager::Observe(int type, |
| 177 const NotificationSource& source, | 138 const NotificationSource& source, |
| 178 const NotificationDetails& details) { | 139 const NotificationDetails& details) { |
| 179 // Dispatch by type. | 140 // Dispatch by type. |
| 180 switch (type) { | 141 switch (type) { |
| 181 case NOTIFICATION_RESOURCE_RESPONSE_STARTED: | 142 case NOTIFICATION_RESOURCE_RESPONSE_STARTED: |
| 182 DidStartResourceResponse( | 143 DidStartResourceResponse( |
| 183 Details<ResourceRequestDetails>(details).ptr()); | 144 Details<ResourceRequestDetails>(details).ptr()); |
| 184 break; | 145 break; |
| 185 case NOTIFICATION_RESOURCE_RECEIVED_REDIRECT: | 146 case NOTIFICATION_RESOURCE_RECEIVED_REDIRECT: |
| 186 DidReceiveResourceRedirect( | 147 DidReceiveResourceRedirect( |
| 187 Details<ResourceRedirectDetails>(details).ptr()); | 148 Details<ResourceRedirectDetails>(details).ptr()); |
| 188 break; | 149 break; |
| 189 case NOTIFICATION_LOAD_FROM_MEMORY_CACHE: | 150 case NOTIFICATION_LOAD_FROM_MEMORY_CACHE: |
| 190 DidLoadFromMemoryCache( | 151 DidLoadFromMemoryCache( |
| 191 Details<LoadFromMemoryCacheDetails>(details).ptr()); | 152 Details<LoadFromMemoryCacheDetails>(details).ptr()); |
| 192 break; | 153 break; |
| 154 case NOTIFICATION_SSL_INTERNAL_STATE_CHANGED: |
| 155 DidChangeSSLInternalState(); |
| 156 break; |
| 193 default: | 157 default: |
| 194 NOTREACHED() << "The SSLManager received an unexpected notification."; | 158 NOTREACHED() << "The SSLManager received an unexpected notification."; |
| 195 } | 159 } |
| 196 } | 160 } |
| 197 | 161 |
| 198 void SSLManager::DidLoadFromMemoryCache(LoadFromMemoryCacheDetails* details) { | 162 void SSLManager::DidLoadFromMemoryCache(LoadFromMemoryCacheDetails* details) { |
| 199 // Simulate loading this resource through the usual path. | 163 // Simulate loading this resource through the usual path. |
| 200 // Note that we specify SUB_RESOURCE as the resource type as WebCore only | 164 // Note that we specify SUB_RESOURCE as the resource type as WebCore only |
| 201 // caches sub-resources. | 165 // caches sub-resources. |
| 202 // This resource must have been loaded with no filtering because filtered | 166 // This resource must have been loaded with no filtering because filtered |
| (...skipping 24 matching lines...) Expand all Loading... |
| 227 } | 191 } |
| 228 | 192 |
| 229 void SSLManager::DidReceiveResourceRedirect(ResourceRedirectDetails* details) { | 193 void SSLManager::DidReceiveResourceRedirect(ResourceRedirectDetails* details) { |
| 230 // TODO(abarth): Make sure our redirect behavior is correct. If we ever see a | 194 // TODO(abarth): Make sure our redirect behavior is correct. If we ever see a |
| 231 // non-HTTPS resource in the redirect chain, we want to trigger | 195 // non-HTTPS resource in the redirect chain, we want to trigger |
| 232 // insecure content, even if the redirect chain goes back to | 196 // insecure content, even if the redirect chain goes back to |
| 233 // HTTPS. This is because the network attacker can redirect the | 197 // HTTPS. This is because the network attacker can redirect the |
| 234 // HTTP request to https://attacker.com/payload.js. | 198 // HTTP request to https://attacker.com/payload.js. |
| 235 } | 199 } |
| 236 | 200 |
| 201 void SSLManager::DidChangeSSLInternalState() { |
| 202 UpdateEntry( |
| 203 NavigationEntryImpl::FromNavigationEntry(controller_->GetActiveEntry())); |
| 204 } |
| 205 |
| 237 void SSLManager::UpdateEntry(NavigationEntryImpl* entry) { | 206 void SSLManager::UpdateEntry(NavigationEntryImpl* entry) { |
| 238 // We don't always have a navigation entry to update, for example in the | 207 // We don't always have a navigation entry to update, for example in the |
| 239 // case of the Web Inspector. | 208 // case of the Web Inspector. |
| 240 if (!entry) | 209 if (!entry) |
| 241 return; | 210 return; |
| 242 | 211 |
| 243 SSLStatus original_ssl_status = entry->GetSSL(); // Copy! | 212 SSLStatus original_ssl_status = entry->GetSSL(); // Copy! |
| 244 | 213 |
| 245 policy()->UpdateEntry(entry, controller_->web_contents()); | 214 policy()->UpdateEntry(entry, controller_->web_contents()); |
| 246 | 215 |
| 247 if (!entry->GetSSL().Equals(original_ssl_status)) | 216 if (!entry->GetSSL().Equals(original_ssl_status)) { |
| 248 controller_->web_contents()->DidChangeVisibleSSLState(); | 217 NotificationService::current()->Notify( |
| 218 NOTIFICATION_SSL_VISIBLE_STATE_CHANGED, |
| 219 Source<NavigationController>(controller_), |
| 220 NotificationService::NoDetails()); |
| 221 } |
| 249 } | 222 } |
| 250 | 223 |
| 251 } // namespace content | 224 } // namespace content |
| OLD | NEW |