| 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 |