OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/chrome_ssl_host_state_delegate.h" | 5 #include "chrome/browser/ssl/chrome_ssl_host_state_delegate.h" |
6 | 6 |
| 7 #include <set> |
| 8 |
7 #include "base/base64.h" | 9 #include "base/base64.h" |
8 #include "base/bind.h" | 10 #include "base/bind.h" |
9 #include "base/command_line.h" | 11 #include "base/command_line.h" |
10 #include "base/logging.h" | 12 #include "base/logging.h" |
11 #include "base/metrics/field_trial.h" | 13 #include "base/metrics/field_trial.h" |
12 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
13 #include "base/time/clock.h" | 15 #include "base/time/clock.h" |
14 #include "base/time/default_clock.h" | 16 #include "base/time/default_clock.h" |
15 #include "base/time/time.h" | 17 #include "base/time/time.h" |
| 18 #include "base/values.h" |
16 #include "chrome/browser/content_settings/host_content_settings_map.h" | 19 #include "chrome/browser/content_settings/host_content_settings_map.h" |
17 #include "chrome/browser/profiles/profile.h" | 20 #include "chrome/browser/profiles/profile.h" |
18 #include "chrome/common/chrome_switches.h" | 21 #include "chrome/common/chrome_switches.h" |
19 #include "components/content_settings/core/common/content_settings_types.h" | 22 #include "components/content_settings/core/common/content_settings_types.h" |
20 #include "components/variations/variations_associated_data.h" | 23 #include "components/variations/variations_associated_data.h" |
21 #include "net/base/hash_value.h" | 24 #include "net/base/hash_value.h" |
22 #include "net/cert/x509_certificate.h" | 25 #include "net/cert/x509_certificate.h" |
23 #include "net/http/http_transaction_factory.h" | 26 #include "net/http/http_transaction_factory.h" |
24 #include "net/url_request/url_request_context.h" | 27 #include "net/url_request/url_request_context.h" |
25 #include "net/url_request/url_request_context_getter.h" | 28 #include "net/url_request/url_request_context_getter.h" |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 // canonicalizes all hosts into a secure scheme GURL to use with content | 68 // canonicalizes all hosts into a secure scheme GURL to use with content |
66 // settings. The returned GURL will be the passed in host with an empty path and | 69 // settings. The returned GURL will be the passed in host with an empty path and |
67 // https:// as the scheme. | 70 // https:// as the scheme. |
68 GURL GetSecureGURLForHost(const std::string& host) { | 71 GURL GetSecureGURLForHost(const std::string& host) { |
69 std::string url = "https://" + host; | 72 std::string url = "https://" + host; |
70 return GURL(url); | 73 return GURL(url); |
71 } | 74 } |
72 | 75 |
73 // This is a helper function that returns the length of time before a | 76 // This is a helper function that returns the length of time before a |
74 // certificate decision expires based on the command line flags. Returns a | 77 // certificate decision expires based on the command line flags. Returns a |
75 // non-negative value in seconds or a value of -1 indicating that decisions | 78 // non-negative value in seconds or a value of -1 indicating that decisions |
76 // should not be remembered after the current session has ended (but should be | 79 // should not be remembered after the current session has ended (but should be |
77 // remembered indefinitely as long as the session does not end), which is the | 80 // remembered indefinitely as long as the session does not end), which is the |
78 // "old" style of certificate decision memory. Uses the experimental group | 81 // "old" style of certificate decision memory. Uses the experimental group |
79 // unless overridden by a command line flag. | 82 // unless overridden by a command line flag. |
80 int64 GetExpirationDelta() { | 83 int64 GetExpirationDelta() { |
81 // Check command line flags first to give them priority, then check | 84 // Check command line flags first to give them priority, then check |
82 // experimental groups. | 85 // experimental groups. |
83 if (CommandLine::ForCurrentProcess()->HasSwitch( | 86 if (CommandLine::ForCurrentProcess()->HasSwitch( |
84 switches::kRememberCertErrorDecisions)) { | 87 switches::kRememberCertErrorDecisions)) { |
85 std::string switch_value = | 88 std::string switch_value = |
(...skipping 25 matching lines...) Expand all Loading... |
111 kRememberCertificateErrorDecisionsFieldTrialLengthParam); | 114 kRememberCertificateErrorDecisionsFieldTrialLengthParam); |
112 if (!param.empty() && base::StringToInt64(base::StringPiece(param), | 115 if (!param.empty() && base::StringToInt64(base::StringPiece(param), |
113 &field_trial_param_length)) { | 116 &field_trial_param_length)) { |
114 return field_trial_param_length; | 117 return field_trial_param_length; |
115 } | 118 } |
116 } | 119 } |
117 | 120 |
118 return kForgetAtSessionEndSwitchValue; | 121 return kForgetAtSessionEndSwitchValue; |
119 } | 122 } |
120 | 123 |
121 std::string GetKey(net::X509Certificate* cert, net::CertStatus error) { | 124 std::string GetKey(const net::X509Certificate* cert, |
| 125 const net::CertStatus error) { |
122 // Since a security decision will be made based on the fingerprint, Chrome | 126 // Since a security decision will be made based on the fingerprint, Chrome |
123 // should use the SHA-256 fingerprint for the certificate. | 127 // should use the SHA-256 fingerprint for the certificate. |
124 net::SHA256HashValue fingerprint = | 128 net::SHA256HashValue fingerprint = |
125 net::X509Certificate::CalculateChainFingerprint256( | 129 net::X509Certificate::CalculateChainFingerprint256( |
126 cert->os_cert_handle(), cert->GetIntermediateCertificates()); | 130 cert->os_cert_handle(), cert->GetIntermediateCertificates()); |
127 std::string base64_fingerprint; | 131 std::string base64_fingerprint; |
128 base::Base64Encode( | 132 base::Base64Encode( |
129 base::StringPiece(reinterpret_cast<const char*>(fingerprint.data), | 133 base::StringPiece(reinterpret_cast<const char*>(fingerprint.data), |
130 sizeof(fingerprint.data)), | 134 sizeof(fingerprint.data)), |
131 &base64_fingerprint); | 135 &base64_fingerprint); |
132 return base::UintToString(error) + base64_fingerprint; | 136 return base::UintToString(error) + base64_fingerprint; |
133 } | 137 } |
134 | 138 |
135 } // namespace | 139 } // namespace |
136 | 140 |
137 // This helper function gets the dictionary of certificate fingerprints to | 141 // This helper function gets the dictionary of certificate fingerprints to |
138 // errors of certificates that have been accepted by the user from the content | 142 // errors of certificates that have been accepted by the user from the content |
139 // dictionary that has been passed in. The returned pointer is owned by the the | 143 // dictionary that has been passed in. The returned pointer is owned by the the |
140 // argument dict that is passed in. | 144 // argument dict that is passed in. |
141 // | 145 // |
142 // If create_entries is set to |DoNotCreateDictionaryEntries|, | 146 // If create_entries is set to |DO_NOT_CREATE_DICTIONARY_ENTRIES|, |
143 // GetValidCertDecisionsDict will return NULL if there is anything invalid about | 147 // GetValidCertDecisionsDict will return NULL if there is anything invalid about |
144 // the setting, such as an invalid version or invalid value types (in addition | 148 // the setting, such as an invalid version or invalid value types (in addition |
145 // to there not be any values in the dictionary). If create_entries is set to | 149 // to there not being any values in the dictionary). If create_entries is set to |
146 // |CreateDictionaryEntries|, if no dictionary is found or the decisions are | 150 // |CREATE_DICTIONARY_ENTRIES|, if no dictionary is found or the decisions are |
147 // expired, a new dictionary will be created | 151 // expired, a new dictionary will be created. |
148 base::DictionaryValue* ChromeSSLHostStateDelegate::GetValidCertDecisionsDict( | 152 base::DictionaryValue* ChromeSSLHostStateDelegate::GetValidCertDecisionsDict( |
149 base::DictionaryValue* dict, | 153 base::DictionaryValue* dict, |
150 CreateDictionaryEntriesDisposition create_entries, | 154 CreateDictionaryEntriesDisposition create_entries, |
151 bool* expired_previous_decision) { | 155 bool* expired_previous_decision) { |
152 // This needs to be done first in case the method is short circuited by an | 156 // This needs to be done first in case the method is short circuited by an |
153 // early failure. | 157 // early failure. |
154 *expired_previous_decision = false; | 158 *expired_previous_decision = false; |
155 | 159 |
156 // Extract the version of the certificate decision structure from the content | 160 // Extract the version of the certificate decision structure from the content |
157 // setting. | 161 // setting. |
158 int version; | 162 int version; |
159 bool success = dict->GetInteger(kSSLCertDecisionVersionKey, &version); | 163 bool success = dict->GetInteger(kSSLCertDecisionVersionKey, &version); |
160 if (!success) { | 164 if (!success) { |
161 if (create_entries == DoNotCreateDictionaryEntries) | 165 if (create_entries == DO_NOT_CREATE_DICTIONARY_ENTRIES) |
162 return NULL; | 166 return NULL; |
163 | 167 |
164 dict->SetInteger(kSSLCertDecisionVersionKey, | 168 dict->SetInteger(kSSLCertDecisionVersionKey, |
165 kDefaultSSLCertDecisionVersion); | 169 kDefaultSSLCertDecisionVersion); |
166 version = kDefaultSSLCertDecisionVersion; | 170 version = kDefaultSSLCertDecisionVersion; |
167 } | 171 } |
168 | 172 |
169 // If the version is somehow a newer version than Chrome can handle, there's | 173 // If the version is somehow a newer version than Chrome can handle, there's |
170 // really nothing to do other than fail silently and pretend it doesn't exist | 174 // really nothing to do other than fail silently and pretend it doesn't exist |
171 // (or is malformed). | 175 // (or is malformed). |
(...skipping 21 matching lines...) Expand all Loading... |
193 LOG(ERROR) << "Failed to parse a certificate error exception that has a " | 197 LOG(ERROR) << "Failed to parse a certificate error exception that has a " |
194 << "bad value for an expiration time: " | 198 << "bad value for an expiration time: " |
195 << decision_expiration_string; | 199 << decision_expiration_string; |
196 return NULL; | 200 return NULL; |
197 } | 201 } |
198 decision_expiration = | 202 decision_expiration = |
199 base::Time::FromInternalValue(decision_expiration_int64); | 203 base::Time::FromInternalValue(decision_expiration_int64); |
200 } | 204 } |
201 | 205 |
202 // Check to see if the user's certificate decision has expired. | 206 // Check to see if the user's certificate decision has expired. |
203 // - Expired and |create_entries| is DoNotCreateDictionaryEntries, return | 207 // - Expired and |create_entries| is DO_NOT_CREATE_DICTIONARY_ENTRIES, return |
204 // NULL. | 208 // NULL. |
205 // - Expired and |create_entries| is CreateDictionaryEntries, update the | 209 // - Expired and |create_entries| is CREATE_DICTIONARY_ENTRIES, update the |
206 // expiration time. | 210 // expiration time. |
207 if (should_remember_ssl_decisions_ != | 211 if (should_remember_ssl_decisions_ != |
208 ForgetSSLExceptionDecisionsAtSessionEnd && | 212 FORGET_SSL_EXCEPTION_DECISIONS_AT_SESSION_END && |
209 decision_expiration.ToInternalValue() <= now.ToInternalValue()) { | 213 decision_expiration.ToInternalValue() <= now.ToInternalValue()) { |
210 *expired_previous_decision = true; | 214 *expired_previous_decision = true; |
211 | 215 |
212 if (create_entries == DoNotCreateDictionaryEntries) | 216 if (create_entries == DO_NOT_CREATE_DICTIONARY_ENTRIES) |
213 return NULL; | 217 return NULL; |
214 | 218 |
215 expired = true; | 219 expired = true; |
216 base::Time expiration_time = | 220 base::Time expiration_time = |
217 now + default_ssl_cert_decision_expiration_delta_; | 221 now + default_ssl_cert_decision_expiration_delta_; |
218 // Unfortunately, JSON (and thus content settings) doesn't support int64 | 222 // Unfortunately, JSON (and thus content settings) doesn't support int64 |
219 // values, only doubles. Since this mildly depends on precision, it is | 223 // values, only doubles. Since this mildly depends on precision, it is |
220 // better to store the value as a string. | 224 // better to store the value as a string. |
221 dict->SetString(kSSLCertDecisionExpirationTimeKey, | 225 dict->SetString(kSSLCertDecisionExpirationTimeKey, |
222 base::Int64ToString(expiration_time.ToInternalValue())); | 226 base::Int64ToString(expiration_time.ToInternalValue())); |
223 } | 227 } |
224 | 228 |
225 // Extract the map of certificate fingerprints to errors from the setting. | 229 // Extract the map of certificate fingerprints to errors from the setting. |
226 base::DictionaryValue* cert_error_dict = NULL; // Will be owned by dict | 230 base::DictionaryValue* cert_error_dict = NULL; // Will be owned by dict |
227 if (expired || | 231 if (expired || |
228 !dict->GetDictionary(kSSLCertDecisionCertErrorMapKey, &cert_error_dict)) { | 232 !dict->GetDictionary(kSSLCertDecisionCertErrorMapKey, &cert_error_dict)) { |
229 if (create_entries == DoNotCreateDictionaryEntries) | 233 if (create_entries == DO_NOT_CREATE_DICTIONARY_ENTRIES) |
230 return NULL; | 234 return NULL; |
231 | 235 |
232 cert_error_dict = new base::DictionaryValue(); | 236 cert_error_dict = new base::DictionaryValue(); |
233 // dict takes ownership of cert_error_dict | 237 // dict takes ownership of cert_error_dict |
234 dict->Set(kSSLCertDecisionCertErrorMapKey, cert_error_dict); | 238 dict->Set(kSSLCertDecisionCertErrorMapKey, cert_error_dict); |
235 } | 239 } |
236 | 240 |
237 return cert_error_dict; | 241 return cert_error_dict; |
238 } | 242 } |
239 | 243 |
240 // If |should_remember_ssl_decisions_| is | 244 // If |should_remember_ssl_decisions_| is |
241 // ForgetSSLExceptionDecisionsAtSessionEnd, that means that all invalid | 245 // FORGET_SSL_EXCEPTION_DECISIONS_AT_SESSION_END, that means that all invalid |
242 // certificate proceed decisions should be forgotten when the session ends. At | 246 // certificate proceed decisions should be forgotten when the session ends. At |
243 // attempt is made in the destructor to remove the entries, but in the case that | 247 // attempt is made in the destructor to remove the entries, but in the case that |
244 // things didn't shut down cleanly, on start, Clear is called to guarantee a | 248 // things didn't shut down cleanly, on start, Clear is called to guarantee a |
245 // clean state. | 249 // clean state. |
246 ChromeSSLHostStateDelegate::ChromeSSLHostStateDelegate(Profile* profile) | 250 ChromeSSLHostStateDelegate::ChromeSSLHostStateDelegate(Profile* profile) |
247 : clock_(new base::DefaultClock()), profile_(profile) { | 251 : clock_(new base::DefaultClock()), profile_(profile) { |
248 int64 expiration_delta = GetExpirationDelta(); | 252 int64 expiration_delta = GetExpirationDelta(); |
249 if (expiration_delta == kForgetAtSessionEndSwitchValue) { | 253 if (expiration_delta == kForgetAtSessionEndSwitchValue) { |
250 should_remember_ssl_decisions_ = ForgetSSLExceptionDecisionsAtSessionEnd; | 254 should_remember_ssl_decisions_ = |
| 255 FORGET_SSL_EXCEPTION_DECISIONS_AT_SESSION_END; |
251 expiration_delta = 0; | 256 expiration_delta = 0; |
252 Clear(); | 257 Clear(); |
253 } else { | 258 } else { |
254 should_remember_ssl_decisions_ = RememberSSLExceptionDecisionsForDelta; | 259 should_remember_ssl_decisions_ = REMEMBER_SSL_EXCEPTION_DECISIONS_FOR_DELTA; |
255 } | 260 } |
256 default_ssl_cert_decision_expiration_delta_ = | 261 default_ssl_cert_decision_expiration_delta_ = |
257 base::TimeDelta::FromSeconds(expiration_delta); | 262 base::TimeDelta::FromSeconds(expiration_delta); |
258 } | 263 } |
259 | 264 |
260 ChromeSSLHostStateDelegate::~ChromeSSLHostStateDelegate() { | 265 ChromeSSLHostStateDelegate::~ChromeSSLHostStateDelegate() { |
261 if (should_remember_ssl_decisions_ == ForgetSSLExceptionDecisionsAtSessionEnd) | 266 if (should_remember_ssl_decisions_ == |
| 267 FORGET_SSL_EXCEPTION_DECISIONS_AT_SESSION_END) |
262 Clear(); | 268 Clear(); |
263 } | 269 } |
264 | 270 |
265 void ChromeSSLHostStateDelegate::DenyCert(const std::string& host, | 271 void ChromeSSLHostStateDelegate::DenyCert(const std::string& host, |
266 net::X509Certificate* cert, | 272 const net::X509Certificate* cert, |
267 net::CertStatus error) { | 273 const net::CertStatus error) { |
268 ChangeCertPolicy(host, cert, error, net::CertPolicy::DENIED); | 274 ChangeCertPolicy(host, cert, error, net::CertPolicy::DENIED); |
269 } | 275 } |
270 | 276 |
271 void ChromeSSLHostStateDelegate::AllowCert(const std::string& host, | 277 void ChromeSSLHostStateDelegate::AllowCert(const std::string& host, |
272 net::X509Certificate* cert, | 278 const net::X509Certificate* cert, |
273 net::CertStatus error) { | 279 const net::CertStatus error) { |
274 ChangeCertPolicy(host, cert, error, net::CertPolicy::ALLOWED); | 280 ChangeCertPolicy(host, cert, error, net::CertPolicy::ALLOWED); |
275 } | 281 } |
276 | 282 |
277 void ChromeSSLHostStateDelegate::Clear() { | 283 void ChromeSSLHostStateDelegate::Clear() { |
278 profile_->GetHostContentSettingsMap()->ClearSettingsForOneType( | 284 profile_->GetHostContentSettingsMap()->ClearSettingsForOneType( |
279 CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS); | 285 CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS); |
280 } | 286 } |
281 | 287 |
282 net::CertPolicy::Judgment ChromeSSLHostStateDelegate::QueryPolicy( | 288 net::CertPolicy::Judgment ChromeSSLHostStateDelegate::QueryPolicy( |
283 const std::string& host, | 289 const std::string& host, |
284 net::X509Certificate* cert, | 290 const net::X509Certificate* cert, |
285 net::CertStatus error, | 291 const net::CertStatus error, |
286 bool* expired_previous_decision) { | 292 bool* expired_previous_decision) { |
287 HostContentSettingsMap* map = profile_->GetHostContentSettingsMap(); | 293 HostContentSettingsMap* map = profile_->GetHostContentSettingsMap(); |
288 GURL url = GetSecureGURLForHost(host); | 294 GURL url = GetSecureGURLForHost(host); |
289 scoped_ptr<base::Value> value(map->GetWebsiteSetting( | 295 scoped_ptr<base::Value> value(map->GetWebsiteSetting( |
290 url, url, CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS, std::string(), NULL)); | 296 url, url, CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS, std::string(), NULL)); |
291 | 297 |
292 // Set a default value in case this method is short circuited and doesn't do a | 298 // Set a default value in case this method is short circuited and doesn't do a |
293 // full query. | 299 // full query. |
294 *expired_previous_decision = false; | 300 *expired_previous_decision = false; |
295 if (!value.get() || !value->IsType(base::Value::TYPE_DICTIONARY)) | 301 if (!value.get() || !value->IsType(base::Value::TYPE_DICTIONARY)) |
296 return net::CertPolicy::UNKNOWN; | 302 return net::CertPolicy::UNKNOWN; |
297 | 303 |
298 base::DictionaryValue* dict; // Owned by value | 304 base::DictionaryValue* dict; // Owned by value |
299 int policy_decision; | 305 int policy_decision; |
300 bool success = value->GetAsDictionary(&dict); | 306 bool success = value->GetAsDictionary(&dict); |
301 DCHECK(success); | 307 DCHECK(success); |
302 | 308 |
303 base::DictionaryValue* cert_error_dict; // Owned by value | 309 base::DictionaryValue* cert_error_dict; // Owned by value |
304 cert_error_dict = GetValidCertDecisionsDict( | 310 cert_error_dict = GetValidCertDecisionsDict( |
305 dict, DoNotCreateDictionaryEntries, expired_previous_decision); | 311 dict, DO_NOT_CREATE_DICTIONARY_ENTRIES, expired_previous_decision); |
306 if (!cert_error_dict) { | 312 if (!cert_error_dict) { |
307 // This revoke is necessary to clear any old expired setting that may | 313 // This revoke is necessary to clear any old expired setting that may be |
308 // lingering in the case that an old decision expried. | 314 // lingering in the case that an old decision expried. |
309 RevokeUserDecisions(host); | 315 RevokeUserDecisions(host); |
310 return net::CertPolicy::UNKNOWN; | 316 return net::CertPolicy::UNKNOWN; |
311 } | 317 } |
312 | 318 |
313 success = cert_error_dict->GetIntegerWithoutPathExpansion(GetKey(cert, error), | 319 success = cert_error_dict->GetIntegerWithoutPathExpansion(GetKey(cert, error), |
314 &policy_decision); | 320 &policy_decision); |
315 | 321 |
316 // If a policy decision was successfully retrieved and it's a valid value of | 322 // If a policy decision was successfully retrieved and it's a valid value of |
317 // ALLOWED or DENIED, return the valid value. Otherwise, return UNKNOWN. | 323 // ALLOWED or DENIED, return the valid value. Otherwise, return UNKNOWN. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 // stack a way revoke SSLConfig's allowed_bad_certs lists per socket. | 355 // stack a way revoke SSLConfig's allowed_bad_certs lists per socket. |
350 // | 356 // |
351 // For now, RevokeUserDecisionsHard is our solution for the rare case where it | 357 // For now, RevokeUserDecisionsHard is our solution for the rare case where it |
352 // is necessary to revoke the preferences immediately. It does so by flushing | 358 // is necessary to revoke the preferences immediately. It does so by flushing |
353 // idle sockets. | 359 // idle sockets. |
354 void ChromeSSLHostStateDelegate::RevokeUserDecisionsHard( | 360 void ChromeSSLHostStateDelegate::RevokeUserDecisionsHard( |
355 const std::string& host) { | 361 const std::string& host) { |
356 RevokeUserDecisions(host); | 362 RevokeUserDecisions(host); |
357 scoped_refptr<net::URLRequestContextGetter> getter( | 363 scoped_refptr<net::URLRequestContextGetter> getter( |
358 profile_->GetRequestContext()); | 364 profile_->GetRequestContext()); |
359 profile_->GetRequestContext()->GetNetworkTaskRunner()->PostTask( | 365 getter->GetNetworkTaskRunner()->PostTask( |
360 FROM_HERE, base::Bind(&CloseIdleConnections, getter)); | 366 FROM_HERE, base::Bind(&CloseIdleConnections, getter)); |
361 } | 367 } |
362 | 368 |
363 bool ChromeSSLHostStateDelegate::HasUserDecision(const std::string& host) { | 369 bool ChromeSSLHostStateDelegate::HasUserDecision( |
| 370 const std::string& host) const { |
364 GURL url = GetSecureGURLForHost(host); | 371 GURL url = GetSecureGURLForHost(host); |
365 const ContentSettingsPattern pattern = | 372 const ContentSettingsPattern pattern = |
366 ContentSettingsPattern::FromURLNoWildcard(url); | 373 ContentSettingsPattern::FromURLNoWildcard(url); |
367 HostContentSettingsMap* map = profile_->GetHostContentSettingsMap(); | 374 HostContentSettingsMap* map = profile_->GetHostContentSettingsMap(); |
368 | 375 |
369 scoped_ptr<base::Value> value(map->GetWebsiteSetting( | 376 scoped_ptr<base::Value> value(map->GetWebsiteSetting( |
370 url, url, CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS, std::string(), NULL)); | 377 url, url, CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS, std::string(), NULL)); |
371 | 378 |
372 if (!value.get() || !value->IsType(base::Value::TYPE_DICTIONARY)) | 379 if (!value.get() || !value->IsType(base::Value::TYPE_DICTIONARY)) |
373 return false; | 380 return false; |
374 | 381 |
375 base::DictionaryValue* dict; // Owned by value | 382 base::DictionaryValue* dict; // Owned by value |
376 bool success = value->GetAsDictionary(&dict); | 383 bool success = value->GetAsDictionary(&dict); |
377 DCHECK(success); | 384 DCHECK(success); |
378 | 385 |
379 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) { | 386 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) { |
380 int policy_decision; // Owned by dict | 387 int policy_decision; // Owned by dict |
381 success = it.value().GetAsInteger(&policy_decision); | 388 success = it.value().GetAsInteger(&policy_decision); |
382 if (success && (static_cast<net::CertPolicy::Judgment>(policy_decision) != | 389 if (success && (static_cast<net::CertPolicy::Judgment>(policy_decision) != |
383 net::CertPolicy::UNKNOWN)) | 390 net::CertPolicy::UNKNOWN)) |
384 return true; | 391 return true; |
385 } | 392 } |
386 | 393 |
387 return false; | 394 return false; |
388 } | 395 } |
389 | 396 |
390 void ChromeSSLHostStateDelegate::HostRanInsecureContent(const std::string& host, | 397 void ChromeSSLHostStateDelegate::HostRanInsecureContent(const std::string& host, |
391 int pid) { | 398 const int pid) { |
392 ran_insecure_content_hosts_.insert(BrokenHostEntry(host, pid)); | 399 ran_insecure_content_hosts_.insert(BrokenHostEntry(host, pid)); |
393 } | 400 } |
394 | 401 |
395 bool ChromeSSLHostStateDelegate::DidHostRunInsecureContent( | 402 bool ChromeSSLHostStateDelegate::DidHostRunInsecureContent( |
396 const std::string& host, | 403 const std::string& host, |
397 int pid) const { | 404 const int pid) const { |
398 return !!ran_insecure_content_hosts_.count(BrokenHostEntry(host, pid)); | 405 return !!ran_insecure_content_hosts_.count(BrokenHostEntry(host, pid)); |
399 } | 406 } |
400 void ChromeSSLHostStateDelegate::SetClock(scoped_ptr<base::Clock> clock) { | 407 void ChromeSSLHostStateDelegate::SetClock(scoped_ptr<base::Clock> clock) { |
401 clock_.reset(clock.release()); | 408 clock_.reset(clock.release()); |
402 } | 409 } |
403 | 410 |
404 void ChromeSSLHostStateDelegate::ChangeCertPolicy( | 411 void ChromeSSLHostStateDelegate::ChangeCertPolicy( |
405 const std::string& host, | 412 const std::string& host, |
406 net::X509Certificate* cert, | 413 const net::X509Certificate* cert, |
407 net::CertStatus error, | 414 const net::CertStatus error, |
408 net::CertPolicy::Judgment judgment) { | 415 const net::CertPolicy::Judgment judgment) { |
409 GURL url = GetSecureGURLForHost(host); | 416 GURL url = GetSecureGURLForHost(host); |
410 const ContentSettingsPattern pattern = | 417 const ContentSettingsPattern pattern = |
411 ContentSettingsPattern::FromURLNoWildcard(url); | 418 ContentSettingsPattern::FromURLNoWildcard(url); |
412 HostContentSettingsMap* map = profile_->GetHostContentSettingsMap(); | 419 HostContentSettingsMap* map = profile_->GetHostContentSettingsMap(); |
413 scoped_ptr<base::Value> value(map->GetWebsiteSetting( | 420 scoped_ptr<base::Value> value(map->GetWebsiteSetting( |
414 url, url, CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS, std::string(), NULL)); | 421 url, url, CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS, std::string(), NULL)); |
415 | 422 |
416 if (!value.get() || !value->IsType(base::Value::TYPE_DICTIONARY)) | 423 if (!value.get() || !value->IsType(base::Value::TYPE_DICTIONARY)) |
417 value.reset(new base::DictionaryValue()); | 424 value.reset(new base::DictionaryValue()); |
418 | 425 |
419 base::DictionaryValue* dict; | 426 base::DictionaryValue* dict; |
420 bool success = value->GetAsDictionary(&dict); | 427 bool success = value->GetAsDictionary(&dict); |
421 DCHECK(success); | 428 DCHECK(success); |
422 | 429 |
423 bool expired_previous_decision; // unused value in this function | 430 bool expired_previous_decision; // unused value in this function |
424 base::DictionaryValue* cert_dict = GetValidCertDecisionsDict( | 431 base::DictionaryValue* cert_dict = GetValidCertDecisionsDict( |
425 dict, CreateDictionaryEntries, &expired_previous_decision); | 432 dict, CREATE_DICTIONARY_ENTRIES, &expired_previous_decision); |
426 // If a a valid certificate dictionary cannot be extracted from the content | 433 // If a a valid certificate dictionary cannot be extracted from the content |
427 // setting, that means it's in an unknown format. Unfortunately, there's | 434 // setting, that means it's in an unknown format. Unfortunately, there's |
428 // nothing to be done in that case, so a silent fail is the only option. | 435 // nothing to be done in that case, so a silent fail is the only option. |
429 if (!cert_dict) | 436 if (!cert_dict) |
430 return; | 437 return; |
431 | 438 |
432 dict->SetIntegerWithoutPathExpansion(kSSLCertDecisionVersionKey, | 439 dict->SetIntegerWithoutPathExpansion(kSSLCertDecisionVersionKey, |
433 kDefaultSSLCertDecisionVersion); | 440 kDefaultSSLCertDecisionVersion); |
434 cert_dict->SetIntegerWithoutPathExpansion(GetKey(cert, error), judgment); | 441 cert_dict->SetIntegerWithoutPathExpansion(GetKey(cert, error), judgment); |
435 | 442 |
436 // The map takes ownership of the value, so it is released in the call to | 443 // The map takes ownership of the value, so it is released in the call to |
437 // SetWebsiteSetting. | 444 // SetWebsiteSetting. |
438 map->SetWebsiteSetting(pattern, | 445 map->SetWebsiteSetting(pattern, |
439 pattern, | 446 pattern, |
440 CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS, | 447 CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS, |
441 std::string(), | 448 std::string(), |
442 value.release()); | 449 value.release()); |
443 } | 450 } |
OLD | NEW |