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

Side by Side Diff: chrome/browser/ssl/ssl_policy.cc

Issue 48060: SSLPolicy Fix: Step 7.... (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
« no previous file with comments | « chrome/browser/ssl/ssl_policy.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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" 7 #include "base/singleton.h"
8 #include "base/string_piece.h" 8 #include "base/string_piece.h"
9 #include "base/string_util.h" 9 #include "base/string_util.h"
10 #include "chrome/browser/cert_store.h" 10 #include "chrome/browser/cert_store.h"
(...skipping 20 matching lines...) Expand all
31 #if defined(OS_WIN) 31 #if defined(OS_WIN)
32 // TODO(port): port these files. 32 // TODO(port): port these files.
33 #include "chrome/browser/tab_contents/tab_contents.h" 33 #include "chrome/browser/tab_contents/tab_contents.h"
34 #elif defined(OS_POSIX) 34 #elif defined(OS_POSIX)
35 #include "chrome/common/temp_scaffolding_stubs.h" 35 #include "chrome/common/temp_scaffolding_stubs.h"
36 #endif 36 #endif
37 37
38 // Wrap all these helper classes in an anonymous namespace. 38 // Wrap all these helper classes in an anonymous namespace.
39 namespace { 39 namespace {
40 40
41 static const char kDot = '.';
42
43 class ShowUnsafeContentTask : public Task { 41 class ShowUnsafeContentTask : public Task {
44 public: 42 public:
45 ShowUnsafeContentTask(const GURL& main_frame_url, 43 ShowUnsafeContentTask(const GURL& main_frame_url,
46 SSLManager::ErrorHandler* error_handler); 44 SSLManager::ErrorHandler* error_handler);
47 virtual ~ShowUnsafeContentTask(); 45 virtual ~ShowUnsafeContentTask();
48 46
49 virtual void Run(); 47 virtual void Run();
50 48
51 private: 49 private:
52 scoped_refptr<SSLManager::ErrorHandler> error_handler_; 50 scoped_refptr<SSLManager::ErrorHandler> error_handler_;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 security_info); 107 security_info);
110 tab->controller()->GetActiveEntry()->set_page_type( 108 tab->controller()->GetActiveEntry()->set_page_type(
111 NavigationEntry::ERROR_PAGE); 109 NavigationEntry::ERROR_PAGE);
112 } 110 }
113 111
114 static void ShowBlockingPage(SSLPolicy* policy, SSLManager::CertError* error) { 112 static void ShowBlockingPage(SSLPolicy* policy, SSLManager::CertError* error) {
115 SSLBlockingPage* blocking_page = new SSLBlockingPage(error, policy); 113 SSLBlockingPage* blocking_page = new SSLBlockingPage(error, policy);
116 blocking_page->Show(); 114 blocking_page->Show();
117 } 115 }
118 116
119 #if 0
120 // See TODO(jcampan) below.
121 static bool IsIntranetHost(const std::string& host) {
122 const size_t dot = host.find(kDot);
123 return dot == std::string::npos || dot == host.length() - 1;
124 }
125 #endif
126
127 class CommonNameInvalidPolicy : public SSLPolicy {
128 public:
129 static SSLPolicy* GetInstance() {
130 return Singleton<CommonNameInvalidPolicy>::get();
131 }
132
133 void OnCertError(const GURL& main_frame_url,
134 SSLManager::CertError* error) {
135 OnOverridableCertError(main_frame_url, error);
136 }
137 };
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_VISIBLE_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_VISIBLE_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
359 } // namespace 117 } // namespace
360 118
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() { 119 SSLPolicy::SSLPolicy() {
368 } 120 }
369 121
122 SSLPolicy* SSLPolicy::GetDefaultPolicy() {
123 return Singleton<SSLPolicy>::get();
124 }
125
370 void SSLPolicy::OnCertError(const GURL& main_frame_url, 126 void SSLPolicy::OnCertError(const GURL& main_frame_url,
371 SSLManager::CertError* error) { 127 SSLManager::CertError* error) {
372 // Default to secure behavior. 128 // First we check if we know the policy for this error.
373 error->CancelRequest(); 129 net::X509Certificate::Policy::Judgment judgment =
130 error->manager()->QueryPolicy(error->ssl_info().cert,
131 error->request_url().host());
132
133 if (judgment == net::X509Certificate::Policy::ALLOWED) {
134 // We've been told to allow this certificate.
135 if (error->manager()->SetMaxSecurityStyle(
136 SECURITY_STYLE_AUTHENTICATION_BROKEN)) {
137 NotificationService::current()->Notify(
138 NotificationType::SSL_VISIBLE_STATE_CHANGED,
139 Source<NavigationController>(error->manager()->controller()),
140 Details<NavigationEntry>(
141 error->manager()->controller()->GetActiveEntry()));
142 }
143 error->ContinueRequest();
144 return;
145 }
146
147 // The judgment is either DENIED or UNKNOWN.
148 // For now we handle the DENIED as the UNKNOWN, which means a blocking
149 // page is shown to the user every time he comes back to the page.
150
151 switch(error->cert_error()) {
152 case net::ERR_CERT_COMMON_NAME_INVALID:
153 case net::ERR_CERT_DATE_INVALID:
154 case net::ERR_CERT_AUTHORITY_INVALID:
155 OnOverridableCertError(main_frame_url, error);
156 break;
157 case net::ERR_CERT_NO_REVOCATION_MECHANISM:
158 // Ignore this error.
159 error->ContinueRequest();
160 break;
161 case net::ERR_CERT_UNABLE_TO_CHECK_REVOCATION:
162 // We ignore this error and display an infobar.
163 error->ContinueRequest();
164 error->manager()->ShowMessage(l10n_util::GetString(
165 IDS_CERT_ERROR_UNABLE_TO_CHECK_REVOCATION_INFO_BAR));
166 break;
167 case net::ERR_CERT_CONTAINS_ERRORS:
168 case net::ERR_CERT_REVOKED:
169 case net::ERR_CERT_INVALID:
170 OnFatalCertError(main_frame_url, error);
171 break;
172 default:
173 NOTREACHED();
174 error->CancelRequest();
175 break;
176 }
177 }
178
179 void SSLPolicy::OnMixedContent(
180 NavigationController* navigation_controller,
181 const GURL& main_frame_url,
182 SSLManager::MixedContentHandler* mixed_content_handler) {
183 PrefService* prefs = navigation_controller->profile()->GetPrefs();
184 FilterPolicy::Type filter_policy = FilterPolicy::DONT_FILTER;
185 if (!mixed_content_handler->manager()->
186 CanShowInsecureContent(main_frame_url)) {
187 filter_policy = FilterPolicy::FromInt(
188 prefs->GetInteger(prefs::kMixedContentFiltering));
189 }
190 if (filter_policy != FilterPolicy::DONT_FILTER) {
191 mixed_content_handler->manager()->ShowMessageWithLink(
192 l10n_util::GetString(IDS_SSL_INFO_BAR_FILTERED_CONTENT),
193 l10n_util::GetString(IDS_SSL_INFO_BAR_SHOW_CONTENT),
194 new ShowUnsafeContentTask(main_frame_url, mixed_content_handler));
195 }
196 mixed_content_handler->StartRequest(filter_policy);
197
198 NavigationEntry* entry = navigation_controller->GetLastCommittedEntry();
199 DCHECK(entry);
200 // Even though we are loading the mixed-content resource, it will not be
201 // included in the page when we set the policy to FILTER_ALL or
202 // FILTER_ALL_EXCEPT_IMAGES (only images and they are stamped with warning
203 // icons), so we don't set the mixed-content mode in these cases.
204 if (filter_policy == FilterPolicy::DONT_FILTER)
205 entry->ssl().set_has_mixed_content();
206
207 // Print a message indicating the mixed-contents resource in the console.
208 const std::wstring& msg = l10n_util::GetStringF(
209 IDS_MIXED_CONTENT_LOG_MESSAGE,
210 UTF8ToWide(entry->url().spec()),
211 UTF8ToWide(mixed_content_handler->request_url().spec()));
212 mixed_content_handler->manager()->
213 AddMessageToConsole(msg, MESSAGE_LEVEL_WARNING);
214
215 NotificationService::current()->Notify(
216 NotificationType::SSL_VISIBLE_STATE_CHANGED,
217 Source<NavigationController>(navigation_controller),
218 Details<NavigationEntry>(entry));
374 } 219 }
375 220
376 void SSLPolicy::OnRequestStarted(SSLManager* manager, const GURL& url, 221 void SSLPolicy::OnRequestStarted(SSLManager* manager, const GURL& url,
377 ResourceType::Type resource_type, 222 ResourceType::Type resource_type,
378 int ssl_cert_id, int ssl_cert_status) { 223 int ssl_cert_id, int ssl_cert_status) {
379 // These schemes never leave the browser and don't require a warning. 224 // These schemes never leave the browser and don't require a warning.
380 if (url.SchemeIs(chrome::kDataScheme) || 225 if (url.SchemeIs(chrome::kDataScheme) ||
381 url.SchemeIs(chrome::kJavaScriptScheme) || 226 url.SchemeIs(chrome::kJavaScriptScheme) ||
382 url.SchemeIs(chrome::kAboutScheme)) 227 url.SchemeIs(chrome::kAboutScheme))
383 return; 228 return;
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 void SSLPolicy::OnFatalCertError(const GURL& main_frame_url, 347 void SSLPolicy::OnFatalCertError(const GURL& main_frame_url,
503 SSLManager::CertError* error) { 348 SSLManager::CertError* error) {
504 if (error->resource_type() != ResourceType::MAIN_FRAME) { 349 if (error->resource_type() != ResourceType::MAIN_FRAME) {
505 error->DenyRequest(); 350 error->DenyRequest();
506 return; 351 return;
507 } 352 }
508 error->CancelRequest(); 353 error->CancelRequest();
509 ShowErrorPage(this, error); 354 ShowErrorPage(this, error);
510 // No need to degrade our security indicators because we didn't continue. 355 // No need to degrade our security indicators because we didn't continue.
511 } 356 }
OLDNEW
« no previous file with comments | « chrome/browser/ssl/ssl_policy.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698