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

Side by Side Diff: chrome/browser/ssl/ssl_policy.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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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 "chrome/browser/ssl/ssl_policy.h" 5 #include "chrome/browser/ssl/ssl_policy.h"
6 6
7 #include "base/singleton.h"
8 #include "base/string_piece.h" 7 #include "base/string_piece.h"
9 #include "base/string_util.h" 8 #include "base/string_util.h"
10 #include "chrome/browser/cert_store.h" 9 #include "chrome/browser/cert_store.h"
11 #include "chrome/browser/renderer_host/render_view_host.h" 10 #include "chrome/browser/renderer_host/render_view_host.h"
12 #include "chrome/browser/ssl/ssl_error_info.h" 11 #include "chrome/browser/ssl/ssl_error_info.h"
13 #include "chrome/browser/tab_contents/navigation_entry.h" 12 #include "chrome/browser/tab_contents/navigation_entry.h"
14 #include "chrome/browser/tab_contents/web_contents.h" 13 #include "chrome/browser/tab_contents/web_contents.h"
15 #include "chrome/common/jstemplate_builder.h" 14 #include "chrome/common/jstemplate_builder.h"
16 #include "chrome/common/l10n_util.h" 15 #include "chrome/common/l10n_util.h"
17 #include "chrome/common/notification_service.h" 16 #include "chrome/common/notification_service.h"
(...skipping 13 matching lines...) Expand all
31 #if defined(OS_WIN) 30 #if defined(OS_WIN)
32 // TODO(port): port these files. 31 // TODO(port): port these files.
33 #include "chrome/browser/tab_contents/tab_contents.h" 32 #include "chrome/browser/tab_contents/tab_contents.h"
34 #elif defined(OS_POSIX) 33 #elif defined(OS_POSIX)
35 #include "chrome/common/temp_scaffolding_stubs.h" 34 #include "chrome/common/temp_scaffolding_stubs.h"
36 #endif 35 #endif
37 36
38 // Wrap all these helper classes in an anonymous namespace. 37 // Wrap all these helper classes in an anonymous namespace.
39 namespace { 38 namespace {
40 39
41 static const char kDot = '.'; 40 class ShowMixedContentTask : public Task {
42
43 class ShowUnsafeContentTask : public Task {
44 public: 41 public:
45 ShowUnsafeContentTask(const GURL& main_frame_url, 42 ShowMixedContentTask(SSLPolicy* ssl_policy,
46 SSLManager::ErrorHandler* error_handler); 43 SSLManager::MixedContentHandler* handler);
47 virtual ~ShowUnsafeContentTask(); 44 virtual ~ShowMixedContentTask();
48 45
49 virtual void Run(); 46 virtual void Run();
50 47
51 private: 48 private:
52 scoped_refptr<SSLManager::ErrorHandler> error_handler_; 49 scoped_refptr<SSLManager::MixedContentHandler> handler_;
53 GURL main_frame_url_;
54 50
55 DISALLOW_EVIL_CONSTRUCTORS(ShowUnsafeContentTask); 51 SSLPolicy* ssl_policy_;
52
53 DISALLOW_COPY_AND_ASSIGN(ShowMixedContentTask);
56 }; 54 };
57 55
58 ShowUnsafeContentTask::ShowUnsafeContentTask( 56 ShowMixedContentTask::ShowMixedContentTask(
59 const GURL& main_frame_url, 57 SSLPolicy* ssl_policy, SSLManager::MixedContentHandler* handler)
60 SSLManager::ErrorHandler* error_handler) 58 : ssl_policy_(ssl_policy), handler_(handler) {
61 : error_handler_(error_handler),
62 main_frame_url_(main_frame_url) {
63 } 59 }
64 60
65 ShowUnsafeContentTask::~ShowUnsafeContentTask() { 61 ShowMixedContentTask::~ShowMixedContentTask() {
66 } 62 }
67 63
68 void ShowUnsafeContentTask::Run() { 64 void ShowMixedContentTask::Run() {
69 error_handler_->manager()->AllowShowInsecureContentForURL(main_frame_url_); 65 ssl_policy_->AllowMixedContent(handler_);
70 // Reload the page. 66 handler_->GetWebContents()->controller()->Reload(true);
71 error_handler_->GetWebContents()->controller()->Reload(true);
72 } 67 }
73 68
74 static void ShowErrorPage(SSLPolicy* policy, SSLManager::CertError* error) { 69 static void ShowErrorPage(SSLPolicy* policy, SSLManager::CertError* error) {
75 SSLErrorInfo error_info = policy->GetSSLErrorInfo(error); 70 SSLErrorInfo error_info = policy->GetSSLErrorInfo(error);
76 71
77 // Let's build the html error page. 72 // Let's build the html error page.
78 DictionaryValue strings; 73 DictionaryValue strings;
79 strings.SetString(L"title", l10n_util::GetString(IDS_SSL_ERROR_PAGE_TITLE)); 74 strings.SetString(L"title", l10n_util::GetString(IDS_SSL_ERROR_PAGE_TITLE));
80 strings.SetString(L"headLine", error_info.title()); 75 strings.SetString(L"headLine", error_info.title());
81 strings.SetString(L"description", error_info.details()); 76 strings.SetString(L"description", error_info.details());
(...skipping 27 matching lines...) Expand all
109 security_info); 104 security_info);
110 tab->controller()->GetActiveEntry()->set_page_type( 105 tab->controller()->GetActiveEntry()->set_page_type(
111 NavigationEntry::ERROR_PAGE); 106 NavigationEntry::ERROR_PAGE);
112 } 107 }
113 108
114 static void ShowBlockingPage(SSLPolicy* policy, SSLManager::CertError* error) { 109 static void ShowBlockingPage(SSLPolicy* policy, SSLManager::CertError* error) {
115 SSLBlockingPage* blocking_page = new SSLBlockingPage(error, policy); 110 SSLBlockingPage* blocking_page = new SSLBlockingPage(error, policy);
116 blocking_page->Show(); 111 blocking_page->Show();
117 } 112 }
118 113
119 #if 0 114 static void InitializeEntryIfNeeded(NavigationEntry* entry) {
120 // See TODO(jcampan) below. 115 if (entry->ssl().security_style() != SECURITY_STYLE_UNKNOWN)
121 static bool IsIntranetHost(const std::string& host) { 116 return;
122 const size_t dot = host.find(kDot); 117
123 return dot == std::string::npos || dot == host.length() - 1; 118 SecurityStyle security_style = entry->url().SchemeIsSecure() ?
119 SECURITY_STYLE_AUTHENTICATED : SECURITY_STYLE_UNAUTHENTICATED;
jcampan 2009/03/16 18:43:54 Nit: indent 4 spaces
abarth-chromium 2009/03/16 21:34:21 Fixed.
120
121 entry->ssl().set_security_style(security_style);
124 } 122 }
125 #endif
126 123
127 class CommonNameInvalidPolicy : public SSLPolicy { 124 static void AddMixedContentWarningToConsole(
128 public: 125 SSLManager::MixedContentHandler* handler) {
129 static SSLPolicy* GetInstance() { 126 const std::wstring& msg = l10n_util::GetStringF(
130 return Singleton<CommonNameInvalidPolicy>::get(); 127 IDS_MIXED_CONTENT_LOG_MESSAGE,
131 } 128 UTF8ToWide(handler->frame_origin()),
129 UTF8ToWide(handler->request_url().spec()));
130 handler->manager()->AddMessageToConsole(msg, MESSAGE_LEVEL_WARNING);
131 }
132 132
133 void OnCertError(const GURL& main_frame_url, 133 static bool HasSafeScheme(const GURL& url) {
134 SSLManager::CertError* error) { 134 return (url.SchemeIsSecure() ||
135 OnOverridableCertError(main_frame_url, error); 135 url.SchemeIs(chrome::kDataScheme) ||
136 } 136 url.SchemeIs(chrome::kJavaScriptScheme) ||
137 }; 137 url.SchemeIs(chrome::kAboutScheme));
138 138 }
139 class DateInvalidPolicy : public SSLPolicy {
140 public:
141 static SSLPolicy* GetInstance() {
142 return Singleton<DateInvalidPolicy>::get();
143 }
144
145 void OnCertError(const GURL& main_frame_url,
146 SSLManager::CertError* error) {
147 OnOverridableCertError(main_frame_url, error);
148 }
149 };
150
151 class AuthorityInvalidPolicy : public SSLPolicy {
152 public:
153 static SSLPolicy* GetInstance() {
154 return Singleton<AuthorityInvalidPolicy>::get();
155 }
156
157 void OnCertError(const GURL& main_frame_url,
158 SSLManager::CertError* error) {
159 OnOverridableCertError(main_frame_url, error);
160 }
161 };
162
163 class ContainsErrorsPolicy : public SSLPolicy {
164 public:
165 static SSLPolicy* GetInstance() {
166 return Singleton<ContainsErrorsPolicy>::get();
167 }
168
169 void OnCertError(const GURL& main_frame_url,
170 SSLManager::CertError* error) {
171 OnFatalCertError(main_frame_url, error);
172 }
173 };
174
175 class NoRevocationMechanismPolicy : public SSLPolicy {
176 public:
177 static SSLPolicy* GetInstance() {
178 return Singleton<NoRevocationMechanismPolicy>::get();
179 }
180
181 void OnCertError(const GURL& main_frame_url,
182 SSLManager::CertError* error) {
183 // Silently ignore this error.
184 error->ContinueRequest();
185 }
186 };
187
188 class UnableToCheckRevocationPolicy : public SSLPolicy {
189 public:
190 static SSLPolicy* GetInstance() {
191 return Singleton<UnableToCheckRevocationPolicy>::get();
192 }
193
194 void OnCertError(const GURL& main_frame_url,
195 SSLManager::CertError* error) {
196 // We ignore this error and display an info-bar.
197 error->ContinueRequest();
198 error->manager()->ShowMessage(l10n_util::GetString(
199 IDS_CERT_ERROR_UNABLE_TO_CHECK_REVOCATION_INFO_BAR));
200 }
201 };
202
203 class RevokedPolicy : public SSLPolicy {
204 public:
205 static SSLPolicy* GetInstance() {
206 return Singleton<RevokedPolicy>::get();
207 }
208
209 void OnCertError(const GURL& main_frame_url,
210 SSLManager::CertError* error) {
211 OnFatalCertError(main_frame_url, error);
212 }
213 };
214
215 class InvalidPolicy : public SSLPolicy {
216 public:
217 static SSLPolicy* GetInstance() {
218 return Singleton<InvalidPolicy>::get();
219 }
220
221 void OnCertError(const GURL& main_frame_url,
222 SSLManager::CertError* error) {
223 OnFatalCertError(main_frame_url, error);
224 }
225 };
226
227 class DefaultPolicy : public SSLPolicy {
228 public:
229 DefaultPolicy() {
230 // Load our helper classes to handle various cert errors.
231 DCHECK(SubPolicyIndex(net::ERR_CERT_COMMON_NAME_INVALID) == 0);
232 sub_policies_[0] = CommonNameInvalidPolicy::GetInstance();
233 DCHECK(SubPolicyIndex(net::ERR_CERT_DATE_INVALID) == 1);
234 sub_policies_[1] = DateInvalidPolicy::GetInstance();
235 DCHECK(SubPolicyIndex(net::ERR_CERT_AUTHORITY_INVALID) == 2);
236 sub_policies_[2] = AuthorityInvalidPolicy::GetInstance();
237 DCHECK(SubPolicyIndex(net::ERR_CERT_CONTAINS_ERRORS) == 3);
238 sub_policies_[3] = ContainsErrorsPolicy::GetInstance();
239 DCHECK(SubPolicyIndex(net::ERR_CERT_NO_REVOCATION_MECHANISM) == 4);
240 sub_policies_[4] = NoRevocationMechanismPolicy::GetInstance();
241 DCHECK(SubPolicyIndex(net::ERR_CERT_UNABLE_TO_CHECK_REVOCATION) == 5);
242 sub_policies_[5] = UnableToCheckRevocationPolicy::GetInstance();
243 DCHECK(SubPolicyIndex(net::ERR_CERT_REVOKED) == 6);
244 sub_policies_[6] = RevokedPolicy::GetInstance();
245 DCHECK(SubPolicyIndex(net::ERR_CERT_INVALID) == 7);
246 sub_policies_[7] = InvalidPolicy::GetInstance();
247 DCHECK(SubPolicyIndex(net::ERR_CERT_END) == 8);
248 }
249
250 void OnCertError(const GURL& main_frame_url,
251 SSLManager::CertError* error) {
252 size_t index = SubPolicyIndex(error->cert_error());
253 if (index < 0 || index >= arraysize(sub_policies_)) {
254 NOTREACHED();
255 error->CancelRequest();
256 return;
257 }
258
259 // First we check if we know the policy for this error.
260 net::X509Certificate::Policy::Judgment judgment =
261 error->manager()->QueryPolicy(error->ssl_info().cert,
262 error->request_url().host());
263
264 switch (judgment) {
265 case net::X509Certificate::Policy::ALLOWED:
266 // We've been told to allow this certificate.
267 if (error->manager()->SetMaxSecurityStyle(
268 SECURITY_STYLE_AUTHENTICATION_BROKEN)) {
269 NotificationService::current()->Notify(
270 NotificationType::SSL_STATE_CHANGED,
271 Source<NavigationController>(error->manager()->controller()),
272 Details<NavigationEntry>(
273 error->manager()->controller()->GetActiveEntry()));
274 }
275 error->ContinueRequest();
276 break;
277 case net::X509Certificate::Policy::DENIED:
278 // For now we handle the DENIED as the UNKNOWN, which means a blocking
279 // page is shown to the user every time he comes back to the page.
280 case net::X509Certificate::Policy::UNKNOWN:
281 // We don't know how to handle this error. Ask our sub-policies.
282 sub_policies_[index]->OnCertError(main_frame_url, error);
283 break;
284 default:
285 NOTREACHED();
286 }
287 }
288
289 void OnMixedContent(NavigationController* navigation_controller,
290 const GURL& main_frame_url,
291 SSLManager::MixedContentHandler* mixed_content_handler) {
292 PrefService* prefs = navigation_controller->profile()->GetPrefs();
293 FilterPolicy::Type filter_policy = FilterPolicy::DONT_FILTER;
294 if (!mixed_content_handler->manager()->
295 CanShowInsecureContent(main_frame_url)) {
296 filter_policy = FilterPolicy::FromInt(
297 prefs->GetInteger(prefs::kMixedContentFiltering));
298 }
299 if (filter_policy != FilterPolicy::DONT_FILTER) {
300 mixed_content_handler->manager()->ShowMessageWithLink(
301 l10n_util::GetString(IDS_SSL_INFO_BAR_FILTERED_CONTENT),
302 l10n_util::GetString(IDS_SSL_INFO_BAR_SHOW_CONTENT),
303 new ShowUnsafeContentTask(main_frame_url, mixed_content_handler));
304 }
305 mixed_content_handler->StartRequest(filter_policy);
306
307 NavigationEntry* entry = navigation_controller->GetLastCommittedEntry();
308 DCHECK(entry);
309 // Even though we are loading the mixed-content resource, it will not be
310 // included in the page when we set the policy to FILTER_ALL or
311 // FILTER_ALL_EXCEPT_IMAGES (only images and they are stamped with warning
312 // icons), so we don't set the mixed-content mode in these cases.
313 if (filter_policy == FilterPolicy::DONT_FILTER)
314 entry->ssl().set_has_mixed_content();
315
316 // Print a message indicating the mixed-contents resource in the console.
317 const std::wstring& msg = l10n_util::GetStringF(
318 IDS_MIXED_CONTENT_LOG_MESSAGE,
319 UTF8ToWide(entry->url().spec()),
320 UTF8ToWide(mixed_content_handler->request_url().spec()));
321 mixed_content_handler->manager()->
322 AddMessageToConsole(msg, MESSAGE_LEVEL_WARNING);
323
324 NotificationService::current()->Notify(
325 NotificationType::SSL_STATE_CHANGED,
326 Source<NavigationController>(navigation_controller),
327 Details<NavigationEntry>(entry));
328 }
329
330 void OnDenyCertificate(SSLManager::CertError* error) {
331 size_t index = SubPolicyIndex(error->cert_error());
332 if (index < 0 || index >= arraysize(sub_policies_)) {
333 NOTREACHED();
334 return;
335 }
336 sub_policies_[index]->OnDenyCertificate(error);
337 }
338
339 void OnAllowCertificate(SSLManager::CertError* error) {
340 size_t index = SubPolicyIndex(error->cert_error());
341 if (index < 0 || index >= arraysize(sub_policies_)) {
342 NOTREACHED();
343 return;
344 }
345 sub_policies_[index]->OnAllowCertificate(error);
346 }
347
348 private:
349 // Returns the index of the sub-policy for |cert_error| in the
350 // sub_policies_ array.
351 int SubPolicyIndex(int cert_error) {
352 // Certificate errors are negative integers from net::ERR_CERT_BEGIN
353 // (inclusive) to net::ERR_CERT_END (exclusive) in *decreasing* order.
354 return net::ERR_CERT_BEGIN - cert_error;
355 }
356 SSLPolicy* sub_policies_[net::ERR_CERT_BEGIN - net::ERR_CERT_END];
357 };
358 139
359 } // namespace 140 } // namespace
360 141
361 SSLPolicy* SSLPolicy::GetDefaultPolicy() {
362 // Lazily initialize our default policy instance.
363 static SSLPolicy* default_policy = new DefaultPolicy();
364 return default_policy;
365 }
366
367 SSLPolicy::SSLPolicy() { 142 SSLPolicy::SSLPolicy() {
368 } 143 }
369 144
370 void SSLPolicy::OnCertError(const GURL& main_frame_url, 145 SSLPolicy* SSLPolicy::GetDefaultPolicy() {
371 SSLManager::CertError* error) { 146 return Singleton<SSLPolicy>::get();
372 // Default to secure behavior.
373 error->CancelRequest();
374 } 147 }
375 148
376 void SSLPolicy::OnRequestStarted(SSLManager* manager, const GURL& url, 149 void SSLPolicy::OnCertError(SSLManager::CertError* error) {
377 ResourceType::Type resource_type, 150 // First we check if we know the policy for this error.
378 int ssl_cert_id, int ssl_cert_status) { 151 net::X509Certificate::Policy::Judgment judgment =
379 // These schemes never leave the browser and don't require a warning. 152 error->manager()->QueryPolicy(error->ssl_info().cert,
380 if (url.SchemeIs(chrome::kDataScheme) || 153 error->request_url().host());
381 url.SchemeIs(chrome::kJavaScriptScheme) ||
382 url.SchemeIs(chrome::kAboutScheme))
383 return;
384 154
385 NavigationEntry* entry = manager->controller()->GetActiveEntry(); 155 if (judgment == net::X509Certificate::Policy::ALLOWED) {
386 if (!entry) { 156 error->ContinueRequest();
387 // We may not have an entry for cases such as the inspector.
388 return; 157 return;
389 } 158 }
390 159
391 NavigationEntry::SSLStatus& ssl = entry->ssl(); 160 // The judgment is either DENIED or UNKNOWN.
392 bool changed = false; 161 // For now we handle the DENIED as the UNKNOWN, which means a blocking
393 if (!entry->url().SchemeIsSecure() || // Current page is not secure. 162 // page is shown to the user every time he comes back to the page.
394 resource_type == ResourceType::MAIN_FRAME || // Main frame load.
395 net::IsCertStatusError(ssl.cert_status())) { // There is already
396 // an error for the main page, don't report sub-resources as unsafe
397 // content.
398 // No mixed/unsafe content check necessary.
399 return;
400 }
401 163
402 if (url.SchemeIsSecure()) { 164 switch(error->cert_error()) {
403 // Check for insecure content (anything served over intranet is considered 165 case net::ERR_CERT_COMMON_NAME_INVALID:
404 // insecure). 166 case net::ERR_CERT_DATE_INVALID:
405 167 case net::ERR_CERT_AUTHORITY_INVALID:
406 // TODO(jcampan): bug #1178228 Disabling the broken style for intranet 168 OnOverridableCertError(error);
407 // hosts for beta as it is missing error strings (and cert status). 169 break;
408 // if (IsIntranetHost(url.host()) || 170 case net::ERR_CERT_NO_REVOCATION_MECHANISM:
409 // net::IsCertStatusError(ssl_cert_status)) { 171 // Ignore this error.
410 if (net::IsCertStatusError(ssl_cert_status)) { 172 error->ContinueRequest();
411 // The resource is unsafe. 173 break;
412 if (!ssl.has_unsafe_content()) { 174 case net::ERR_CERT_UNABLE_TO_CHECK_REVOCATION:
413 changed = true; 175 // We ignore this error and display an infobar.
414 ssl.set_has_unsafe_content(); 176 error->ContinueRequest();
415 manager->SetMaxSecurityStyle(SECURITY_STYLE_AUTHENTICATION_BROKEN); 177 error->manager()->ShowMessage(l10n_util::GetString(
416 } 178 IDS_CERT_ERROR_UNABLE_TO_CHECK_REVOCATION_INFO_BAR));
417 } 179 break;
418 } 180 case net::ERR_CERT_CONTAINS_ERRORS:
419 181 case net::ERR_CERT_REVOKED:
420 if (changed) { 182 case net::ERR_CERT_INVALID:
421 // Only send the notification when something actually changed. 183 OnFatalCertError(error);
422 NotificationService::current()->Notify( 184 break;
423 NotificationType::SSL_STATE_CHANGED, 185 default:
424 Source<NavigationController>(manager->controller()), 186 NOTREACHED();
425 NotificationService::NoDetails()); 187 error->CancelRequest();
188 break;
426 } 189 }
427 } 190 }
428 191
429 SecurityStyle SSLPolicy::GetDefaultStyle(const GURL& url) { 192 void SSLPolicy::OnMixedContent(SSLManager::MixedContentHandler* handler) {
430 // Show the secure style for HTTPS. 193 // Get the user's mixed content preference.
431 if (url.SchemeIsSecure()) { 194 PrefService* prefs = handler->GetWebContents()->profile()->GetPrefs();
432 // TODO(jcampan): bug #1178228 Disabling the broken style for intranet 195 FilterPolicy::Type filter_policy =
433 // hosts for beta as it is missing error strings (and cert status). 196 FilterPolicy::FromInt(prefs->GetInteger(prefs::kMixedContentFiltering));
434 // CAs issue certs for intranet hosts to anyone.
435 // if (IsIntranetHost(url.host()))
436 // return SECURITY_STYLE_AUTHENTICATION_BROKEN;
437 197
438 return SECURITY_STYLE_AUTHENTICATED; 198 // If the user have added an exception, doctor the |filter_policy|.
199 if (!handler->manager()->DidAllowMixedContentForHost(
200 GURL(handler->main_frame_origin()).host()))
201 filter_policy = FilterPolicy::DONT_FILTER;
202
203 if (filter_policy != FilterPolicy::DONT_FILTER) {
204 // Give the user a chance to see unfiltered content.
205 handler->manager()->ShowMessageWithLink(
206 l10n_util::GetString(IDS_SSL_INFO_BAR_FILTERED_CONTENT),
207 l10n_util::GetString(IDS_SSL_INFO_BAR_SHOW_CONTENT),
208 new ShowMixedContentTask(this, handler));
439 } 209 }
210 handler->StartRequest(filter_policy);
211 AddMixedContentWarningToConsole(handler);
212 }
440 213
441 // Otherwise, show the unauthenticated style. 214 void SSLPolicy::OnRequestStarted(SSLManager::RequestInfo* info) {
442 return SECURITY_STYLE_UNAUTHENTICATED; 215 if (IsMixedContent(info->url(), info->resource_type(), info->frame_origin()))
216 UpdateStateForMixedContent(info);
217
218 if (net::IsCertStatusError(info->ssl_cert_status()))
219 UpdateStateForUnsafeContent(info);
443 } 220 }
444 221
222 void SSLPolicy::UpdateEntry(SSLManager* manager, NavigationEntry* entry) {
223 DCHECK(entry);
224
225 InitializeEntryIfNeeded(entry);
226
227 if (!entry->url().SchemeIsSecure())
228 return;
229
230 const std::string& host = entry->url().host();
231 if (manager->DidMarkHostAsBroken(host))
232 entry->ssl().set_security_style(SECURITY_STYLE_AUTHENTICATION_BROKEN);
233 }
234
235 // static
236 bool SSLPolicy::IsMixedContent(const GURL& url,
237 ResourceType::Type resource_type,
238 const std::string& frame_origin) {
239 ////////////////////////////////////////////////////////////////////////////
240 // WARNING: This function is called from both the IO and UI threads. Do //
241 // not touch any non-thread-safe objects! You have been warned. //
242 ////////////////////////////////////////////////////////////////////////////
243
244 // We can't possibly have mixed content when loading the main frame.
245 if (resource_type == ResourceType::MAIN_FRAME)
246 return false;
247
248 // If the frame doing the loading is already insecure, then we must have
249 // already dealt with whatever mixed content might be going on.
250 if (!GURL(frame_origin).SchemeIsSecure())
251 return false;
252
253 // We aren't worried about mixed content if we're loading an HTTPS, about,
254 // or data URL.
255 if (HasSafeScheme(url))
256 return false;
257
258 return true;
259 }
260
261 void SSLPolicy::AllowMixedContent(SSLManager::MixedContentHandler* handler) {
262 std::string main_frame_host = GURL(handler->main_frame_origin()).host();
263 handler->manager()->AllowMixedContentForHost(main_frame_host);
264 }
265
266 ////////////////////////////////////////////////////////////////////////////////
267 // SSLBlockingPage::Delegate methods
268
445 SSLErrorInfo SSLPolicy::GetSSLErrorInfo(SSLManager::CertError* error) { 269 SSLErrorInfo SSLPolicy::GetSSLErrorInfo(SSLManager::CertError* error) {
446 return SSLErrorInfo::CreateError( 270 return SSLErrorInfo::CreateError(
447 SSLErrorInfo::NetErrorToErrorType(error->cert_error()), 271 SSLErrorInfo::NetErrorToErrorType(error->cert_error()),
448 error->ssl_info().cert, error->request_url()); 272 error->ssl_info().cert, error->request_url());
449 } 273 }
450 274
451 void SSLPolicy::OnDenyCertificate(SSLManager::CertError* error) { 275 void SSLPolicy::OnDenyCertificate(SSLManager::CertError* error) {
452 // Default behavior for rejecting a certificate.
453 error->CancelRequest(); 276 error->CancelRequest();
454 error->manager()->DenyCertForHost(error->ssl_info().cert, 277 error->manager()->DenyCertForHost(error->ssl_info().cert,
455 error->request_url().host()); 278 error->request_url().host());
456 } 279 }
457 280
458 void SSLPolicy::OnAllowCertificate(SSLManager::CertError* error) { 281 void SSLPolicy::OnAllowCertificate(SSLManager::CertError* error) {
459 // Default behavior for accepting a certificate.
460 // Note that we should not call SetMaxSecurityStyle here, because the active
461 // NavigationEntry has just been deleted (in HideInterstitialPage) and the
462 // new NavigationEntry will not be set until DidNavigate. This is ok,
463 // because the new NavigationEntry will have its max security style set
464 // within DidNavigate.
465 error->ContinueRequest(); 282 error->ContinueRequest();
466 error->manager()->AllowCertForHost(error->ssl_info().cert, 283 error->manager()->AllowCertForHost(error->ssl_info().cert,
467 error->request_url().host()); 284 error->request_url().host());
468 } 285 }
469 286
470 void SSLPolicy::OnOverridableCertError(const GURL& main_frame_url, 287 ////////////////////////////////////////////////////////////////////////////////
471 SSLManager::CertError* error) { 288 // Certificate Error Routines
289
290 void SSLPolicy::OnOverridableCertError(SSLManager::CertError* error) {
472 if (error->resource_type() != ResourceType::MAIN_FRAME) { 291 if (error->resource_type() != ResourceType::MAIN_FRAME) {
473 // A sub-resource has a certificate error. The user doesn't really 292 // A sub-resource has a certificate error. The user doesn't really
474 // have a context for making the right decision, so block the 293 // have a context for making the right decision, so block the
475 // request hard, without an info bar to allow showing the insecure 294 // request hard, without an info bar to allow showing the insecure
476 // content. 295 // content.
477 error->DenyRequest(); 296 error->DenyRequest();
478 return; 297 return;
479 } 298 }
480 // We need to ask the user to approve this certificate. 299 // We need to ask the user to approve this certificate.
481 ShowBlockingPage(this, error); 300 ShowBlockingPage(this, error);
482 } 301 }
483 302
484 void SSLPolicy::OnFatalCertError(const GURL& main_frame_url, 303 void SSLPolicy::OnFatalCertError(SSLManager::CertError* error) {
485 SSLManager::CertError* error) {
486 if (error->resource_type() != ResourceType::MAIN_FRAME) { 304 if (error->resource_type() != ResourceType::MAIN_FRAME) {
487 error->DenyRequest(); 305 error->DenyRequest();
488 return; 306 return;
489 } 307 }
490 error->CancelRequest(); 308 error->CancelRequest();
491 ShowErrorPage(this, error); 309 ShowErrorPage(this, error);
492 // No need to degrade our security indicators because we didn't continue.
493 } 310 }
311
312 ////////////////////////////////////////////////////////////////////////////////
313 // State Updating
314
315 void SSLPolicy::MarkOriginAsBroken(SSLManager* manager,
316 const std::string& origin) {
317 GURL parsed_origin(origin);
318
319 // In particular, the origin "null" will be parsed as invalid.
320 if (!parsed_origin.is_valid() || !parsed_origin.SchemeIsSecure())
321 return;
322
323 manager->MarkHostAsBroken(parsed_origin.host());
324 }
325
326 void SSLPolicy::UpdateStateForMixedContent(SSLManager::RequestInfo* info) {
327 // The frame's origin now contains mixed content and therefore is broken.
328 MarkOriginAsBroken(info->manager(), info->frame_origin());
329
330 // The user approved a mixed content exception for the main frame's origin.
331 // That makes the main frame's origin broken too.
332 MarkOriginAsBroken(info->manager(), info->main_frame_origin());
333 }
334
335 void SSLPolicy::UpdateStateForUnsafeContent(SSLManager::RequestInfo* info) {
336 // This request as a broken cert, which means its host is broken.
337 info->manager()->MarkHostAsBroken(info->url().host());
338
339 if (info->resource_type() != ResourceType::MAIN_FRAME ||
340 info->resource_type() != ResourceType::SUB_FRAME) {
341 // If we're loading some sort of resource into the frame, that frame is now
342 // unsafe.
343 MarkOriginAsBroken(info->manager(), info->frame_origin());
344 }
345
346 if (info->resource_type() != ResourceType::MAIN_FRAME) {
347 // We make the main frame unsafe even if we load an unsafe sub frame.
348 MarkOriginAsBroken(info->manager(), info->main_frame_origin());
349 }
350 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698