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

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

Issue 42314: SSLPolicy fix: Step 9. (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') | chrome/browser/ssl/ssl_uitest.cc » ('j') | 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 void MarkOriginAsBroken(SSLManager* manager, const std::string& origin) {
42 GURL parsed_origin(origin);
43 if (!parsed_origin.SchemeIsSecure())
44 return;
45
46 manager->MarkHostAsBroken(parsed_origin.host());
47 }
48
49 static void AllowMixedContentForOrigin(SSLManager* manager,
50 const std::string& origin) {
51 GURL parsed_origin(origin);
52 if (!parsed_origin.SchemeIsSecure())
53 return;
54
55 manager->AllowMixedContentForHost(parsed_origin.host());
56 }
57
58 static void UpdateStateForMixedContent(SSLManager::RequestInfo* info) {
59 if (info->resource_type() != ResourceType::MAIN_FRAME ||
60 info->resource_type() != ResourceType::SUB_FRAME) {
61 // The frame's origin now contains mixed content and therefore is broken.
62 MarkOriginAsBroken(info->manager(), info->frame_origin());
63 }
64
65 if (info->resource_type() != ResourceType::MAIN_FRAME) {
66 // The user approved a mixed content exception for the main frame's origin.
67 // That makes the main frame's origin broken too.
68 MarkOriginAsBroken(info->manager(), info->main_frame_origin());
69 }
70 }
71
72 static void UpdateStateForUnsafeContent(SSLManager::RequestInfo* info) {
73 // This request as a broken cert, which means its host is broken.
74 info->manager()->MarkHostAsBroken(info->url().host());
75
76 UpdateStateForMixedContent(info);
77 }
78
41 class ShowMixedContentTask : public Task { 79 class ShowMixedContentTask : public Task {
42 public: 80 public:
43 ShowMixedContentTask(SSLManager::MixedContentHandler* handler); 81 ShowMixedContentTask(SSLManager::MixedContentHandler* handler);
44 virtual ~ShowMixedContentTask(); 82 virtual ~ShowMixedContentTask();
45 83
46 virtual void Run(); 84 virtual void Run();
47 85
48 private: 86 private:
49 scoped_refptr<SSLManager::MixedContentHandler> handler_; 87 scoped_refptr<SSLManager::MixedContentHandler> handler_;
50 88
51 DISALLOW_COPY_AND_ASSIGN(ShowMixedContentTask); 89 DISALLOW_COPY_AND_ASSIGN(ShowMixedContentTask);
52 }; 90 };
53 91
54 ShowMixedContentTask::ShowMixedContentTask( 92 ShowMixedContentTask::ShowMixedContentTask(
55 SSLManager::MixedContentHandler* handler) 93 SSLManager::MixedContentHandler* handler)
56 : handler_(handler) { 94 : handler_(handler) {
57 } 95 }
58 96
59 ShowMixedContentTask::~ShowMixedContentTask() { 97 ShowMixedContentTask::~ShowMixedContentTask() {
60 } 98 }
61 99
62 void ShowMixedContentTask::Run() { 100 void ShowMixedContentTask::Run() {
63 handler_->manager()->AllowMixedContentForHost( 101 AllowMixedContentForOrigin(handler_->manager(), handler_->frame_origin());
64 GURL(handler_->main_frame_origin()).host()); 102 AllowMixedContentForOrigin(handler_->manager(),
65 103 handler_->main_frame_origin());
66 // Reload the page.
67 handler_->manager()->controller()->Reload(true); 104 handler_->manager()->controller()->Reload(true);
68 } 105 }
69 106
70 static void ShowErrorPage(SSLPolicy* policy, SSLManager::CertError* error) { 107 static void ShowErrorPage(SSLPolicy* policy, SSLManager::CertError* error) {
71 SSLErrorInfo error_info = policy->GetSSLErrorInfo(error); 108 SSLErrorInfo error_info = policy->GetSSLErrorInfo(error);
72 109
73 // Let's build the html error page. 110 // Let's build the html error page.
74 DictionaryValue strings; 111 DictionaryValue strings;
75 strings.SetString(L"title", l10n_util::GetString(IDS_SSL_ERROR_PAGE_TITLE)); 112 strings.SetString(L"title", l10n_util::GetString(IDS_SSL_ERROR_PAGE_TITLE));
76 strings.SetString(L"headLine", error_info.title()); 113 strings.SetString(L"headLine", error_info.title());
(...skipping 28 matching lines...) Expand all
105 security_info); 142 security_info);
106 tab->controller()->GetActiveEntry()->set_page_type( 143 tab->controller()->GetActiveEntry()->set_page_type(
107 NavigationEntry::ERROR_PAGE); 144 NavigationEntry::ERROR_PAGE);
108 } 145 }
109 146
110 static void ShowBlockingPage(SSLPolicy* policy, SSLManager::CertError* error) { 147 static void ShowBlockingPage(SSLPolicy* policy, SSLManager::CertError* error) {
111 SSLBlockingPage* blocking_page = new SSLBlockingPage(error, policy); 148 SSLBlockingPage* blocking_page = new SSLBlockingPage(error, policy);
112 blocking_page->Show(); 149 blocking_page->Show();
113 } 150 }
114 151
152 static void InitializeEntryIfNeeded(NavigationEntry* entry) {
153 if (entry->ssl().security_style() != SECURITY_STYLE_UNKNOWN)
154 return;
155
156 entry->ssl().set_security_style(entry->url().SchemeIsSecure() ?
157 SECURITY_STYLE_AUTHENTICATED : SECURITY_STYLE_UNAUTHENTICATED);
158 }
159
160 static void AddMixedContentWarningToConsole(
161 SSLManager::MixedContentHandler* handler) {
162 const std::wstring& msg = l10n_util::GetStringF(
163 IDS_MIXED_CONTENT_LOG_MESSAGE,
164 UTF8ToWide(handler->frame_origin()),
165 UTF8ToWide(handler->request_url().spec()));
166 handler->manager()->AddMessageToConsole(msg, MESSAGE_LEVEL_WARNING);
167 }
168
115 } // namespace 169 } // namespace
116 170
117 SSLPolicy::SSLPolicy() { 171 SSLPolicy::SSLPolicy() {
118 } 172 }
119 173
120 SSLPolicy* SSLPolicy::GetDefaultPolicy() { 174 SSLPolicy* SSLPolicy::GetDefaultPolicy() {
121 return Singleton<SSLPolicy>::get(); 175 return Singleton<SSLPolicy>::get();
122 } 176 }
123 177
124 void SSLPolicy::OnCertError(SSLManager::CertError* error) { 178 void SSLPolicy::OnCertError(SSLManager::CertError* error) {
125 // First we check if we know the policy for this error. 179 // First we check if we know the policy for this error.
126 net::X509Certificate::Policy::Judgment judgment = 180 net::X509Certificate::Policy::Judgment judgment =
127 error->manager()->QueryPolicy(error->ssl_info().cert, 181 error->manager()->QueryPolicy(error->ssl_info().cert,
128 error->request_url().host()); 182 error->request_url().host());
129 183
130 if (judgment == net::X509Certificate::Policy::ALLOWED) { 184 if (judgment == net::X509Certificate::Policy::ALLOWED) {
131 // We've been told to allow this certificate.
132 if (error->manager()->SetMaxSecurityStyle(
133 SECURITY_STYLE_AUTHENTICATION_BROKEN)) {
134 NotificationService::current()->Notify(
135 NotificationType::SSL_VISIBLE_STATE_CHANGED,
136 Source<NavigationController>(error->manager()->controller()),
137 Details<NavigationEntry>(
138 error->manager()->controller()->GetActiveEntry()));
139 }
140 error->ContinueRequest(); 185 error->ContinueRequest();
141 return; 186 return;
142 } 187 }
143 188
144 // The judgment is either DENIED or UNKNOWN. 189 // The judgment is either DENIED or UNKNOWN.
145 // For now we handle the DENIED as the UNKNOWN, which means a blocking 190 // For now we handle the DENIED as the UNKNOWN, which means a blocking
146 // page is shown to the user every time he comes back to the page. 191 // page is shown to the user every time he comes back to the page.
147 192
148 switch(error->cert_error()) { 193 switch(error->cert_error()) {
149 case net::ERR_CERT_COMMON_NAME_INVALID: 194 case net::ERR_CERT_COMMON_NAME_INVALID:
(...skipping 22 matching lines...) Expand all
172 break; 217 break;
173 } 218 }
174 } 219 }
175 220
176 void SSLPolicy::OnMixedContent(SSLManager::MixedContentHandler* handler) { 221 void SSLPolicy::OnMixedContent(SSLManager::MixedContentHandler* handler) {
177 // Get the user's mixed content preference. 222 // Get the user's mixed content preference.
178 PrefService* prefs = handler->GetWebContents()->profile()->GetPrefs(); 223 PrefService* prefs = handler->GetWebContents()->profile()->GetPrefs();
179 FilterPolicy::Type filter_policy = 224 FilterPolicy::Type filter_policy =
180 FilterPolicy::FromInt(prefs->GetInteger(prefs::kMixedContentFiltering)); 225 FilterPolicy::FromInt(prefs->GetInteger(prefs::kMixedContentFiltering));
181 226
182 // If the user have added an exception, doctor the |filter_policy|. 227 // If the user has added an exception, doctor the |filter_policy|.
183 if (handler->manager()->DidAllowMixedContentForHost( 228 std::string host = GURL(handler->main_frame_origin()).host();
184 GURL(handler->main_frame_origin()).host())) 229 if (handler->manager()->DidAllowMixedContentForHost(host) ||
230 handler->manager()->DidMarkHostAsBroken(host))
185 filter_policy = FilterPolicy::DONT_FILTER; 231 filter_policy = FilterPolicy::DONT_FILTER;
186 232
187 if (filter_policy != FilterPolicy::DONT_FILTER) { 233 if (filter_policy != FilterPolicy::DONT_FILTER) {
188 handler->manager()->ShowMessageWithLink( 234 handler->manager()->ShowMessageWithLink(
189 l10n_util::GetString(IDS_SSL_INFO_BAR_FILTERED_CONTENT), 235 l10n_util::GetString(IDS_SSL_INFO_BAR_FILTERED_CONTENT),
190 l10n_util::GetString(IDS_SSL_INFO_BAR_SHOW_CONTENT), 236 l10n_util::GetString(IDS_SSL_INFO_BAR_SHOW_CONTENT),
191 new ShowMixedContentTask(handler)); 237 new ShowMixedContentTask(handler));
192 } 238 }
239
193 handler->StartRequest(filter_policy); 240 handler->StartRequest(filter_policy);
194 241 AddMixedContentWarningToConsole(handler);
195 NavigationEntry* entry =
196 handler->manager()->controller()->GetLastCommittedEntry();
197 // We might not have a navigation entry in some cases (e.g. when a»
198 // HTTPS page opens a popup with no URL and then populate it with»
199 // document.write()). See bug http://crbug.com/3845.
200 if (!entry)
201 return;
202
203 // Even though we are loading the mixed-content resource, it will not be
204 // included in the page when we set the policy to FILTER_ALL or
205 // FILTER_ALL_EXCEPT_IMAGES (only images and they are stamped with warning
206 // icons), so we don't set the mixed-content mode in these cases.
207 if (filter_policy == FilterPolicy::DONT_FILTER)
208 entry->ssl().set_has_mixed_content();
209
210 // Print a message indicating the mixed-contents resource in the console.
211 const std::wstring& msg = l10n_util::GetStringF(
212 IDS_MIXED_CONTENT_LOG_MESSAGE,
213 UTF8ToWide(entry->url().spec()),
214 UTF8ToWide(handler->request_url().spec()));
215 handler->manager()->AddMessageToConsole(msg, MESSAGE_LEVEL_WARNING);
216
217 NotificationService::current()->Notify(
218 NotificationType::SSL_VISIBLE_STATE_CHANGED,
219 Source<NavigationController>(handler->manager()->controller()),
220 Details<NavigationEntry>(entry));
221 } 242 }
222 243
223 void SSLPolicy::OnRequestStarted(SSLManager::RequestInfo* info) { 244 void SSLPolicy::OnRequestStarted(SSLManager::RequestInfo* info) {
224 // These schemes never leave the browser and don't require a warning. 245 if (net::IsCertStatusError(info->ssl_cert_status()))
225 if (info->url().SchemeIs(chrome::kDataScheme) || 246 UpdateStateForUnsafeContent(info);
226 info->url().SchemeIs(chrome::kJavaScriptScheme) || 247
227 info->url().SchemeIs(chrome::kAboutScheme)) 248 if (IsMixedContent(info->url(),
249 info->resource_type(),
250 info->filter_policy(),
251 info->frame_origin()))
252 UpdateStateForMixedContent(info);
253 }
254
255 void SSLPolicy::UpdateEntry(SSLManager* manager, NavigationEntry* entry) {
256 DCHECK(entry);
257
258 InitializeEntryIfNeeded(entry);
259
260 if (!entry->url().SchemeIsSecure())
228 return; 261 return;
229 262
230 NavigationEntry* entry = info->manager()->controller()->GetActiveEntry(); 263 // An HTTPS response may not have a certificate for some reason. When that
231 if (!entry) { 264 // happens, use the unauthenticated (HTTP) rather than the authentication
232 // We may not have an entry for cases such as the inspector. 265 // broken security style so that we can detect this error condition.
266 if (!entry->ssl().cert_id()) {
267 entry->ssl().set_security_style(SECURITY_STYLE_UNAUTHENTICATED);
233 return; 268 return;
234 } 269 }
235 270
236 NavigationEntry::SSLStatus& ssl = entry->ssl(); 271 if (net::IsCertStatusError(entry->ssl().cert_status())) {
237 bool changed = false; 272 entry->ssl().set_security_style(SECURITY_STYLE_AUTHENTICATION_BROKEN);
238 if (!entry->url().SchemeIsSecure() || // Current page is not secure.
239 info->resource_type() == ResourceType::MAIN_FRAME || // Main frame load.
240 net::IsCertStatusError(ssl.cert_status())) { // There is already
241 // an error for the main page, don't report sub-resources as unsafe
242 // content.
243 // No mixed/unsafe content check necessary.
244 return; 273 return;
245 } 274 }
246 275
247 if (info->url().SchemeIsSecure()) { 276 if (manager->DidMarkHostAsBroken(entry->url().host()))
248 // Check for insecure content (anything served over intranet is considered 277 entry->ssl().set_has_mixed_content();
249 // insecure).
250
251 // TODO(jcampan): bug #1178228 Disabling the broken style for intranet
252 // hosts for beta as it is missing error strings (and cert status).
253 // if (IsIntranetHost(url.host()) ||
254 // net::IsCertStatusError(info->ssl_cert_status())) {
255 if (net::IsCertStatusError(info->ssl_cert_status())) {
256 // The resource is unsafe.
257 if (!ssl.has_unsafe_content()) {
258 changed = true;
259 ssl.set_has_unsafe_content();
260 info->manager()->SetMaxSecurityStyle(
261 SECURITY_STYLE_AUTHENTICATION_BROKEN);
262 }
263 }
264 }
265
266 if (changed) {
267 // Only send the notification when something actually changed.
268 NotificationService::current()->Notify(
269 NotificationType::SSL_VISIBLE_STATE_CHANGED,
270 Source<NavigationController>(info->manager()->controller()),
271 NotificationService::NoDetails());
272 }
273 }
274
275 SecurityStyle SSLPolicy::GetDefaultStyle(const GURL& url) {
276 // Show the secure style for HTTPS.
277 if (url.SchemeIsSecure()) {
278 // TODO(jcampan): bug #1178228 Disabling the broken style for intranet
279 // hosts for beta as it is missing error strings (and cert status).
280 // CAs issue certs for intranet hosts to anyone.
281 // if (IsIntranetHost(url.host()))
282 // return SECURITY_STYLE_AUTHENTICATION_BROKEN;
283
284 return SECURITY_STYLE_AUTHENTICATED;
285 }
286
287 // Otherwise, show the unauthenticated style.
288 return SECURITY_STYLE_UNAUTHENTICATED;
289 } 278 }
290 279
291 // static 280 // static
292 bool SSLPolicy::IsMixedContent(const GURL& url, 281 bool SSLPolicy::IsMixedContent(const GURL& url,
293 ResourceType::Type resource_type, 282 ResourceType::Type resource_type,
294 const std::string& main_frame_origin) { 283 FilterPolicy::Type filter_policy,
284 const std::string& frame_origin) {
295 //////////////////////////////////////////////////////////////////////////// 285 ////////////////////////////////////////////////////////////////////////////
296 // WARNING: This function is called from both the IO and UI threads. Do // 286 // WARNING: This function is called from both the IO and UI threads. Do //
297 // not touch any non-thread-safe objects! You have been warned. // 287 // not touch any non-thread-safe objects! You have been warned. //
298 //////////////////////////////////////////////////////////////////////////// 288 ////////////////////////////////////////////////////////////////////////////
299 289
300 // We can't possibly have mixed content when loading the main frame. 290 // We can't possibly have mixed content when loading the main frame.
301 if (resource_type == ResourceType::MAIN_FRAME) 291 if (resource_type == ResourceType::MAIN_FRAME)
302 return false; 292 return false;
303 293
304 // TODO(abarth): This is wrong, but it matches our current behavior. 294 // If we've filtered the resource, then it's no longer dangerous.
305 // I'll fix this in a subsequent step. 295 if (filter_policy != FilterPolicy::DONT_FILTER)
306 return GURL(main_frame_origin).SchemeIsSecure() && !url.SchemeIsSecure(); 296 return false;
297
298 // If the frame doing the loading is already insecure, then we must have
299 // already dealt with whatever mixed content might be going on.
300 if (!GURL(frame_origin).SchemeIsSecure())
301 return false;
302
303 // We aren't worried about mixed content if we're loading an HTTPS URL.
304 if (url.SchemeIsSecure())
305 return false;
306
307 return true;
307 } 308 }
308 309
309 //////////////////////////////////////////////////////////////////////////////// 310 ////////////////////////////////////////////////////////////////////////////////
310 // SSLBlockingPage::Delegate methods 311 // SSLBlockingPage::Delegate methods
311 312
312 SSLErrorInfo SSLPolicy::GetSSLErrorInfo(SSLManager::CertError* error) { 313 SSLErrorInfo SSLPolicy::GetSSLErrorInfo(SSLManager::CertError* error) {
313 return SSLErrorInfo::CreateError( 314 return SSLErrorInfo::CreateError(
314 SSLErrorInfo::NetErrorToErrorType(error->cert_error()), 315 SSLErrorInfo::NetErrorToErrorType(error->cert_error()),
315 error->ssl_info().cert, error->request_url()); 316 error->ssl_info().cert, error->request_url());
316 } 317 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 353
353 void SSLPolicy::OnFatalCertError(SSLManager::CertError* error) { 354 void SSLPolicy::OnFatalCertError(SSLManager::CertError* error) {
354 if (error->resource_type() != ResourceType::MAIN_FRAME) { 355 if (error->resource_type() != ResourceType::MAIN_FRAME) {
355 error->DenyRequest(); 356 error->DenyRequest();
356 return; 357 return;
357 } 358 }
358 error->CancelRequest(); 359 error->CancelRequest();
359 ShowErrorPage(this, error); 360 ShowErrorPage(this, error);
360 // No need to degrade our security indicators because we didn't continue. 361 // No need to degrade our security indicators because we didn't continue.
361 } 362 }
OLDNEW
« no previous file with comments | « chrome/browser/ssl/ssl_policy.h ('k') | chrome/browser/ssl/ssl_uitest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698