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> | 7 #include <set> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
11 #include "base/supports_user_data.h" | 11 #include "base/supports_user_data.h" |
12 #include "content/browser/loader/resource_dispatcher_host_impl.h" | 12 #include "content/browser/loader/resource_dispatcher_host_impl.h" |
13 #include "content/browser/loader/resource_request_info_impl.h" | 13 #include "content/browser/loader/resource_request_info_impl.h" |
14 #include "content/browser/ssl/ssl_cert_error_handler.h" | 14 #include "content/browser/ssl/ssl_cert_error_handler.h" |
15 #include "content/browser/ssl/ssl_policy.h" | 15 #include "content/browser/ssl/ssl_policy.h" |
16 #include "content/browser/ssl/ssl_request_info.h" | 16 #include "content/browser/ssl/ssl_request_info.h" |
17 #include "content/browser/web_contents/navigation_entry_impl.h" | 17 #include "content/browser/web_contents/navigation_entry_impl.h" |
18 #include "content/browser/web_contents/web_contents_impl.h" | 18 #include "content/browser/web_contents/web_contents_impl.h" |
19 #include "content/common/ssl_status_serialization.h" | 19 #include "content/common/ssl_status_serialization.h" |
20 #include "content/public/browser/browser_context.h" | 20 #include "content/public/browser/browser_context.h" |
21 #include "content/public/browser/browser_thread.h" | 21 #include "content/public/browser/browser_thread.h" |
22 #include "content/public/browser/load_from_memory_cache_details.h" | 22 #include "content/public/browser/load_from_memory_cache_details.h" |
23 #include "content/public/browser/navigation_details.h" | 23 #include "content/public/browser/navigation_details.h" |
24 #include "content/public/browser/notification_service.h" | |
25 #include "content/public/browser/notification_source.h" | |
26 #include "content/public/browser/resource_request_details.h" | 24 #include "content/public/browser/resource_request_details.h" |
27 #include "content/public/common/ssl_status.h" | 25 #include "content/public/common/ssl_status.h" |
28 #include "net/url_request/url_request.h" | 26 #include "net/url_request/url_request.h" |
29 | 27 |
30 namespace content { | 28 namespace content { |
31 | 29 |
32 namespace { | 30 namespace { |
33 | 31 |
34 const char kSSLManagerKeyName[] = "content_ssl_manager"; | 32 const char kSSLManagerKeyName[] = "content_ssl_manager"; |
35 | 33 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 (*i)->controller()->GetActiveEntry())); | 90 (*i)->controller()->GetActiveEntry())); |
93 } | 91 } |
94 } | 92 } |
95 | 93 |
96 SSLManager::SSLManager(NavigationControllerImpl* controller) | 94 SSLManager::SSLManager(NavigationControllerImpl* controller) |
97 : backend_(controller), | 95 : backend_(controller), |
98 policy_(new SSLPolicy(&backend_)), | 96 policy_(new SSLPolicy(&backend_)), |
99 controller_(controller) { | 97 controller_(controller) { |
100 DCHECK(controller_); | 98 DCHECK(controller_); |
101 | 99 |
102 // Subscribe to various notifications. | |
103 registrar_.Add( | |
104 this, NOTIFICATION_RESOURCE_RESPONSE_STARTED, | |
105 Source<WebContents>(controller_->web_contents())); | |
106 registrar_.Add( | |
107 this, NOTIFICATION_RESOURCE_RECEIVED_REDIRECT, | |
108 Source<WebContents>(controller_->web_contents())); | |
109 registrar_.Add( | |
110 this, NOTIFICATION_LOAD_FROM_MEMORY_CACHE, | |
111 Source<NavigationController>(controller_)); | |
112 | |
113 SSLManagerSet* managers = static_cast<SSLManagerSet*>( | 100 SSLManagerSet* managers = static_cast<SSLManagerSet*>( |
114 controller_->GetBrowserContext()->GetUserData(kSSLManagerKeyName)); | 101 controller_->GetBrowserContext()->GetUserData(kSSLManagerKeyName)); |
115 if (!managers) { | 102 if (!managers) { |
116 managers = new SSLManagerSet; | 103 managers = new SSLManagerSet; |
117 controller_->GetBrowserContext()->SetUserData(kSSLManagerKeyName, managers); | 104 controller_->GetBrowserContext()->SetUserData(kSSLManagerKeyName, managers); |
118 } | 105 } |
119 managers->get().insert(this); | 106 managers->get().insert(this); |
120 } | 107 } |
121 | 108 |
122 SSLManager::~SSLManager() { | 109 SSLManager::~SSLManager() { |
123 SSLManagerSet* managers = static_cast<SSLManagerSet*>( | 110 SSLManagerSet* managers = static_cast<SSLManagerSet*>( |
124 controller_->GetBrowserContext()->GetUserData(kSSLManagerKeyName)); | 111 controller_->GetBrowserContext()->GetUserData(kSSLManagerKeyName)); |
125 managers->get().erase(this); | 112 managers->get().erase(this); |
126 } | 113 } |
127 | 114 |
128 void SSLManager::DidCommitProvisionalLoad( | 115 void SSLManager::DidCommitProvisionalLoad(const LoadCommittedDetails& details) { |
129 const NotificationDetails& in_details) { | |
130 LoadCommittedDetails* details = | |
131 Details<LoadCommittedDetails>(in_details).ptr(); | |
132 | |
133 NavigationEntryImpl* entry = | 116 NavigationEntryImpl* entry = |
134 NavigationEntryImpl::FromNavigationEntry(controller_->GetActiveEntry()); | 117 NavigationEntryImpl::FromNavigationEntry(controller_->GetActiveEntry()); |
135 | 118 |
136 if (details->is_main_frame) { | 119 if (details.is_main_frame) { |
137 if (entry) { | 120 if (entry) { |
138 // Decode the security details. | 121 // Decode the security details. |
139 int ssl_cert_id; | 122 int ssl_cert_id; |
140 net::CertStatus ssl_cert_status; | 123 net::CertStatus ssl_cert_status; |
141 int ssl_security_bits; | 124 int ssl_security_bits; |
142 int ssl_connection_status; | 125 int ssl_connection_status; |
143 DeserializeSecurityInfo(details->serialized_security_info, | 126 DeserializeSecurityInfo(details.serialized_security_info, |
144 &ssl_cert_id, | 127 &ssl_cert_id, |
145 &ssl_cert_status, | 128 &ssl_cert_status, |
146 &ssl_security_bits, | 129 &ssl_security_bits, |
147 &ssl_connection_status); | 130 &ssl_connection_status); |
148 | 131 |
149 // We may not have an entry if this is a navigation to an initial blank | 132 // We may not have an entry if this is a navigation to an initial blank |
150 // page. Reset the SSL information and add the new data we have. | 133 // page. Reset the SSL information and add the new data we have. |
151 entry->GetSSL() = SSLStatus(); | 134 entry->GetSSL() = SSLStatus(); |
152 entry->GetSSL().cert_id = ssl_cert_id; | 135 entry->GetSSL().cert_id = ssl_cert_id; |
153 entry->GetSSL().cert_status = ssl_cert_status; | 136 entry->GetSSL().cert_status = ssl_cert_status; |
(...skipping 10 matching lines...) Expand all Loading... |
164 NavigationEntryImpl::FromNavigationEntry(controller_->GetActiveEntry())); | 147 NavigationEntryImpl::FromNavigationEntry(controller_->GetActiveEntry())); |
165 } | 148 } |
166 | 149 |
167 void SSLManager::DidRunInsecureContent(const std::string& security_origin) { | 150 void SSLManager::DidRunInsecureContent(const std::string& security_origin) { |
168 NavigationEntryImpl* navigation_entry = | 151 NavigationEntryImpl* navigation_entry = |
169 NavigationEntryImpl::FromNavigationEntry(controller_->GetActiveEntry()); | 152 NavigationEntryImpl::FromNavigationEntry(controller_->GetActiveEntry()); |
170 policy()->DidRunInsecureContent(navigation_entry, security_origin); | 153 policy()->DidRunInsecureContent(navigation_entry, security_origin); |
171 UpdateEntry(navigation_entry); | 154 UpdateEntry(navigation_entry); |
172 } | 155 } |
173 | 156 |
174 void SSLManager::Observe(int type, | 157 void SSLManager::DidLoadFromMemoryCache( |
175 const NotificationSource& source, | 158 const LoadFromMemoryCacheDetails& details) { |
176 const NotificationDetails& details) { | |
177 // Dispatch by type. | |
178 switch (type) { | |
179 case NOTIFICATION_RESOURCE_RESPONSE_STARTED: | |
180 DidStartResourceResponse( | |
181 Details<ResourceRequestDetails>(details).ptr()); | |
182 break; | |
183 case NOTIFICATION_RESOURCE_RECEIVED_REDIRECT: | |
184 DidReceiveResourceRedirect( | |
185 Details<ResourceRedirectDetails>(details).ptr()); | |
186 break; | |
187 case NOTIFICATION_LOAD_FROM_MEMORY_CACHE: | |
188 DidLoadFromMemoryCache( | |
189 Details<LoadFromMemoryCacheDetails>(details).ptr()); | |
190 break; | |
191 default: | |
192 NOTREACHED() << "The SSLManager received an unexpected notification."; | |
193 } | |
194 } | |
195 | |
196 void SSLManager::DidLoadFromMemoryCache(LoadFromMemoryCacheDetails* details) { | |
197 // Simulate loading this resource through the usual path. | 159 // Simulate loading this resource through the usual path. |
198 // Note that we specify SUB_RESOURCE as the resource type as WebCore only | 160 // Note that we specify SUB_RESOURCE as the resource type as WebCore only |
199 // caches sub-resources. | 161 // caches sub-resources. |
200 // This resource must have been loaded with no filtering because filtered | 162 // This resource must have been loaded with no filtering because filtered |
201 // resouces aren't cachable. | 163 // resouces aren't cachable. |
202 scoped_refptr<SSLRequestInfo> info(new SSLRequestInfo( | 164 scoped_refptr<SSLRequestInfo> info(new SSLRequestInfo( |
203 details->url, | 165 details.url, |
204 ResourceType::SUB_RESOURCE, | 166 ResourceType::SUB_RESOURCE, |
205 details->pid, | 167 details.pid, |
206 details->cert_id, | 168 details.cert_id, |
207 details->cert_status)); | 169 details.cert_status)); |
208 | 170 |
209 // Simulate loading this resource through the usual path. | 171 // Simulate loading this resource through the usual path. |
210 policy()->OnRequestStarted(info.get()); | 172 policy()->OnRequestStarted(info.get()); |
211 } | 173 } |
212 | 174 |
213 void SSLManager::DidStartResourceResponse(ResourceRequestDetails* details) { | 175 void SSLManager::DidStartResourceResponse( |
| 176 const ResourceRequestDetails& details) { |
214 scoped_refptr<SSLRequestInfo> info(new SSLRequestInfo( | 177 scoped_refptr<SSLRequestInfo> info(new SSLRequestInfo( |
215 details->url, | 178 details.url, |
216 details->resource_type, | 179 details.resource_type, |
217 details->origin_child_id, | 180 details.origin_child_id, |
218 details->ssl_cert_id, | 181 details.ssl_cert_id, |
219 details->ssl_cert_status)); | 182 details.ssl_cert_status)); |
220 | 183 |
221 // Notify our policy that we started a resource request. Ideally, the | 184 // Notify our policy that we started a resource request. Ideally, the |
222 // policy should have the ability to cancel the request, but we can't do | 185 // policy should have the ability to cancel the request, but we can't do |
223 // that yet. | 186 // that yet. |
224 policy()->OnRequestStarted(info.get()); | 187 policy()->OnRequestStarted(info.get()); |
225 } | 188 } |
226 | 189 |
227 void SSLManager::DidReceiveResourceRedirect(ResourceRedirectDetails* details) { | 190 void SSLManager::DidReceiveResourceRedirect( |
| 191 const ResourceRedirectDetails& details) { |
228 // TODO(abarth): Make sure our redirect behavior is correct. If we ever see a | 192 // TODO(abarth): Make sure our redirect behavior is correct. If we ever see a |
229 // non-HTTPS resource in the redirect chain, we want to trigger | 193 // non-HTTPS resource in the redirect chain, we want to trigger |
230 // insecure content, even if the redirect chain goes back to | 194 // insecure content, even if the redirect chain goes back to |
231 // HTTPS. This is because the network attacker can redirect the | 195 // HTTPS. This is because the network attacker can redirect the |
232 // HTTP request to https://attacker.com/payload.js. | 196 // HTTP request to https://attacker.com/payload.js. |
233 } | 197 } |
234 | 198 |
235 void SSLManager::UpdateEntry(NavigationEntryImpl* entry) { | 199 void SSLManager::UpdateEntry(NavigationEntryImpl* entry) { |
236 // We don't always have a navigation entry to update, for example in the | 200 // We don't always have a navigation entry to update, for example in the |
237 // case of the Web Inspector. | 201 // case of the Web Inspector. |
238 if (!entry) | 202 if (!entry) |
239 return; | 203 return; |
240 | 204 |
241 SSLStatus original_ssl_status = entry->GetSSL(); // Copy! | 205 SSLStatus original_ssl_status = entry->GetSSL(); // Copy! |
242 | 206 |
243 policy()->UpdateEntry(entry, controller_->web_contents()); | 207 policy()->UpdateEntry(entry, controller_->web_contents()); |
244 | 208 |
245 if (!entry->GetSSL().Equals(original_ssl_status)) | 209 if (!entry->GetSSL().Equals(original_ssl_status)) |
246 controller_->web_contents()->DidChangeVisibleSSLState(); | 210 controller_->web_contents()->DidChangeVisibleSSLState(); |
247 } | 211 } |
248 | 212 |
249 } // namespace content | 213 } // namespace content |
OLD | NEW |