Chromium Code Reviews| Index: chrome/browser/chromeos/attestation/platform_verification_flow.cc |
| diff --git a/chrome/browser/chromeos/attestation/platform_verification_flow.cc b/chrome/browser/chromeos/attestation/platform_verification_flow.cc |
| index d6ef3ace1ee2847e7048b4176e3ec1fea8cf49fb..a0b23db6847965275faadc236652aa3bff21d884 100644 |
| --- a/chrome/browser/chromeos/attestation/platform_verification_flow.cc |
| +++ b/chrome/browser/chromeos/attestation/platform_verification_flow.cc |
| @@ -13,8 +13,9 @@ |
| #include "chrome/browser/chromeos/login/user.h" |
| #include "chrome/browser/chromeos/login/user_manager.h" |
| #include "chrome/browser/chromeos/settings/cros_settings.h" |
| -#include "chrome/browser/prefs/scoped_user_pref_update.h" |
| +#include "chrome/browser/content_settings/host_content_settings_map.h" |
| #include "chrome/browser/profiles/profile.h" |
| +#include "chrome/common/content_settings_pattern.h" |
| #include "chrome/common/pref_names.h" |
| #include "chromeos/attestation/attestation_flow.h" |
| #include "chromeos/cryptohome/async_method_caller.h" |
| @@ -26,9 +27,12 @@ |
| #include "content/public/browser/browser_thread.h" |
| #include "content/public/browser/user_metrics.h" |
| #include "content/public/browser/web_contents.h" |
| +#include "content/public/common/url_constants.h" |
| namespace { |
| +const char kDefaultHttpsPort[] = "443"; |
| + |
| // A callback method to handle DBus errors. |
| void DBusCallback(const base::Callback<void(bool)>& on_success, |
| const base::Closure& on_failure, |
| @@ -61,7 +65,6 @@ class DefaultDelegate : public PlatformVerificationFlow::Delegate { |
| virtual ~DefaultDelegate() {} |
| virtual void ShowConsentPrompt( |
| - PlatformVerificationFlow::ConsentType type, |
| content::WebContents* web_contents, |
| const PlatformVerificationFlow::Delegate::ConsentCallback& callback) |
| OVERRIDE { |
| @@ -116,6 +119,11 @@ void PlatformVerificationFlow::ChallengePlatformKey( |
| const std::string& challenge, |
| const ChallengeCallback& callback) { |
| DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| + if (!GetURL(web_contents).is_valid()) { |
| + LOG(WARNING) << "PlatformVerificationFlow: Invalid URL."; |
| + ReportError(callback, INTERNAL_ERROR); |
| + return; |
| + } |
| if (!IsAttestationEnabled(web_contents)) { |
| LOG(INFO) << "PlatformVerificationFlow: Feature disabled."; |
| ReportError(callback, POLICY_REJECTED); |
| @@ -138,12 +146,23 @@ void PlatformVerificationFlow::CheckConsent(content::WebContents* web_contents, |
| const std::string& challenge, |
| const ChallengeCallback& callback, |
| bool attestation_enrolled) { |
| - ConsentType consent_type = CONSENT_TYPE_NONE; |
| - if (!attestation_enrolled || IsFirstUse(web_contents)) { |
| - consent_type = CONSENT_TYPE_ATTESTATION; |
| - } else if (IsAlwaysAskRequired(web_contents)) { |
| - consent_type = CONSENT_TYPE_ALWAYS; |
| + PrefService* pref_service = GetPrefs(web_contents); |
| + if (!pref_service) { |
| + LOG(ERROR) << "Failed to get user prefs."; |
| + ReportError(callback, INTERNAL_ERROR); |
| + return; |
| } |
| + bool consent_required = ( |
| + // Consent required if attestation has never been enrolled on this device. |
| + !attestation_enrolled || |
| + // Consent required if this is the first use of attestation for content |
| + // protection on this device. |
| + !pref_service->GetBoolean(prefs::kRAConsentFirstTime) || |
| + // Consent required if consent has never been given for this domain. |
| + !GetDomainPref(GetContentSettings(web_contents), |
| + GetURL(web_contents), |
| + NULL)); |
| + |
| Delegate::ConsentCallback consent_callback = base::Bind( |
| &PlatformVerificationFlow::OnConsentResponse, |
| weak_factory_.GetWeakPtr(), |
| @@ -151,14 +170,11 @@ void PlatformVerificationFlow::CheckConsent(content::WebContents* web_contents, |
| service_id, |
| challenge, |
| callback, |
| - consent_type); |
| - if (consent_type == CONSENT_TYPE_NONE) { |
| + consent_required); |
| + if (consent_required) |
| + delegate_->ShowConsentPrompt(web_contents, consent_callback); |
| + else |
| consent_callback.Run(CONSENT_RESPONSE_NONE); |
| - } else { |
| - delegate_->ShowConsentPrompt(consent_type, |
| - web_contents, |
| - consent_callback); |
| - } |
| } |
| void PlatformVerificationFlow::RegisterProfilePrefs( |
| @@ -166,12 +182,6 @@ void PlatformVerificationFlow::RegisterProfilePrefs( |
| prefs->RegisterBooleanPref(prefs::kRAConsentFirstTime, |
| false, |
| user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
| - prefs->RegisterDictionaryPref( |
| - prefs::kRAConsentDomains, |
| - user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
| - prefs->RegisterBooleanPref(prefs::kRAConsentAlways, |
| - false, |
| - user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
| } |
| void PlatformVerificationFlow::OnConsentResponse( |
| @@ -179,16 +189,16 @@ void PlatformVerificationFlow::OnConsentResponse( |
| const std::string& service_id, |
| const std::string& challenge, |
| const ChallengeCallback& callback, |
| - ConsentType consent_type, |
| + bool consent_required, |
| ConsentResponse consent_response) { |
| - if (consent_type != CONSENT_TYPE_NONE) { |
| + if (consent_required) { |
| if (consent_response == CONSENT_RESPONSE_NONE) { |
| // No user response - do not proceed and do not modify any settings. |
| LOG(WARNING) << "PlatformVerificationFlow: No response from user."; |
| ReportError(callback, USER_REJECTED); |
| return; |
| } |
| - if (!UpdateSettings(web_contents, consent_type, consent_response)) { |
| + if (!UpdateSettings(web_contents, consent_response)) { |
| ReportError(callback, INTERNAL_ERROR); |
| return; |
| } |
| @@ -289,7 +299,10 @@ const GURL& PlatformVerificationFlow::GetURL( |
| content::WebContents* web_contents) { |
| if (!testing_url_.is_empty()) |
| return testing_url_; |
| - return web_contents->GetLastCommittedURL(); |
| + const GURL& url = web_contents->GetLastCommittedURL(); |
| + if (!url.is_valid()) |
| + return web_contents->GetVisibleURL(); |
|
Jun Mukai
2013/10/29 00:26:51
Why is this condition necessary?
Darren Krahn
2013/10/29 17:37:30
When I was manually testing I came across the cond
DaleCurtis
2013/10/30 18:13:45
No idea about this. It seems unlikely to be true
|
| + return url; |
| } |
| User* PlatformVerificationFlow::GetUser(content::WebContents* web_contents) { |
| @@ -299,6 +312,14 @@ User* PlatformVerificationFlow::GetUser(content::WebContents* web_contents) { |
| Profile::FromBrowserContext(web_contents->GetBrowserContext())); |
| } |
| +HostContentSettingsMap* PlatformVerificationFlow::GetContentSettings( |
| + content::WebContents* web_contents) { |
| + if (testing_content_settings_) |
| + return testing_content_settings_; |
| + return Profile::FromBrowserContext(web_contents->GetBrowserContext())-> |
| + GetHostContentSettingsMap(); |
| +} |
| + |
| bool PlatformVerificationFlow::IsAttestationEnabled( |
| content::WebContents* web_contents) { |
| // Check the device policy for the feature. |
| @@ -322,92 +343,77 @@ bool PlatformVerificationFlow::IsAttestationEnabled( |
| // Check the user preference for this domain. |
| bool enabled_for_domain = false; |
| - bool found = GetDomainPref(web_contents, &enabled_for_domain); |
| + bool found = GetDomainPref(GetContentSettings(web_contents), |
| + GetURL(web_contents), |
| + &enabled_for_domain); |
| return (!found || enabled_for_domain); |
| } |
| -bool PlatformVerificationFlow::IsFirstUse(content::WebContents* web_contents) { |
| - PrefService* pref_service = GetPrefs(web_contents); |
| - if (!pref_service) { |
| - LOG(ERROR) << "Failed to get user prefs."; |
| - return true; |
| - } |
| - return !pref_service->GetBoolean(prefs::kRAConsentFirstTime); |
| -} |
| - |
| -bool PlatformVerificationFlow::IsAlwaysAskRequired( |
| - content::WebContents* web_contents) { |
| - PrefService* pref_service = GetPrefs(web_contents); |
| - if (!pref_service) { |
| - LOG(ERROR) << "Failed to get user prefs."; |
| - return true; |
| - } |
| - if (!pref_service->GetBoolean(prefs::kRAConsentAlways)) |
| - return false; |
| - // Show the consent UI if the user has not already explicitly allowed or |
| - // denied for this domain. |
| - return !GetDomainPref(web_contents, NULL); |
| -} |
| - |
| bool PlatformVerificationFlow::UpdateSettings( |
| content::WebContents* web_contents, |
| - ConsentType consent_type, |
| ConsentResponse consent_response) { |
| PrefService* pref_service = GetPrefs(web_contents); |
| if (!pref_service) { |
| LOG(ERROR) << "Failed to get user prefs."; |
| return false; |
| } |
| - if (consent_type == CONSENT_TYPE_ATTESTATION) { |
| - if (consent_response == CONSENT_RESPONSE_DENY) { |
| - pref_service->SetBoolean(prefs::kEnableDRM, false); |
| - } else if (consent_response == CONSENT_RESPONSE_ALLOW) { |
| - pref_service->SetBoolean(prefs::kRAConsentFirstTime, true); |
| - RecordDomainConsent(web_contents, true); |
| - } else if (consent_response == CONSENT_RESPONSE_ALWAYS_ASK) { |
| - pref_service->SetBoolean(prefs::kRAConsentFirstTime, true); |
| - pref_service->SetBoolean(prefs::kRAConsentAlways, true); |
| - RecordDomainConsent(web_contents, true); |
| - } |
| - } else if (consent_type == CONSENT_TYPE_ALWAYS) { |
| - bool allowed = (consent_response == CONSENT_RESPONSE_ALLOW || |
| - consent_response == CONSENT_RESPONSE_ALWAYS_ASK); |
| - RecordDomainConsent(web_contents, allowed); |
| - } |
| + pref_service->SetBoolean(prefs::kRAConsentFirstTime, true); |
| + RecordDomainConsent(GetContentSettings(web_contents), |
| + GetURL(web_contents), |
| + (consent_response == CONSENT_RESPONSE_ALLOW)); |
| return true; |
| } |
| bool PlatformVerificationFlow::GetDomainPref( |
| - content::WebContents* web_contents, |
| + HostContentSettingsMap* content_settings, |
| + const GURL& url, |
| bool* pref_value) { |
| - PrefService* pref_service = GetPrefs(web_contents); |
| - CHECK(pref_service); |
| - base::DictionaryValue::Iterator iter( |
| - *pref_service->GetDictionary(prefs::kRAConsentDomains)); |
| - const GURL& url = GetURL(web_contents); |
| - while (!iter.IsAtEnd()) { |
| - if (url.DomainIs(iter.key().c_str())) { |
| - if (pref_value) { |
| - if (!iter.value().GetAsBoolean(pref_value)) { |
| - LOG(ERROR) << "Unexpected pref type."; |
| - *pref_value = false; |
| - } |
| - } |
| - return true; |
| - } |
| - iter.Advance(); |
| - } |
| - return false; |
| + CHECK(content_settings); |
| + CHECK(url.is_valid()); |
| + ContentSetting setting = content_settings->GetContentSetting( |
| + url, |
| + url, |
| + CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER, |
| + std::string()); |
| + if (setting != CONTENT_SETTING_ALLOW && setting != CONTENT_SETTING_BLOCK) |
| + return false; |
| + if (pref_value) |
| + *pref_value = (setting == CONTENT_SETTING_ALLOW); |
| + return true; |
| } |
| void PlatformVerificationFlow::RecordDomainConsent( |
| - content::WebContents* web_contents, |
| + HostContentSettingsMap* content_settings, |
| + const GURL& url, |
| bool allow_domain) { |
| - PrefService* pref_service = GetPrefs(web_contents); |
| - CHECK(pref_service); |
| - DictionaryPrefUpdate updater(pref_service, prefs::kRAConsentDomains); |
| - const GURL& url = GetURL(web_contents); |
| - updater->SetBoolean(url.host(), allow_domain); |
| + CHECK(content_settings); |
| + CHECK(url.is_valid()); |
| + // Build a pattern to represent scheme and host. |
| + scoped_ptr<ContentSettingsPattern::BuilderInterface> builder( |
| + ContentSettingsPattern::CreateBuilder(false)); |
| + builder->WithScheme(url.scheme()) |
| + ->WithDomainWildcard() |
| + ->WithHost(url.host()) |
| + ->WithPathWildcard(); |
| + if (!url.port().empty()) |
| + builder->WithPort(url.port()); |
| + else if (url.SchemeIs(content::kHttpsScheme)) |
| + builder->WithPort(kDefaultHttpsPort); |
| + else if (url.SchemeIs(content::kHttpScheme)) |
| + builder->WithPortWildcard(); |
| + ContentSettingsPattern pattern = builder->Build(); |
| + if (pattern.IsValid()) { |
| + ContentSetting setting = allow_domain ? CONTENT_SETTING_ALLOW |
| + : CONTENT_SETTING_BLOCK; |
| + content_settings->SetContentSetting( |
| + pattern, |
| + pattern, |
| + CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER, |
| + std::string(), |
| + setting); |
| + } else { |
| + LOG(WARNING) << "Not recording action: invalid URL pattern"; |
| + } |
| } |
| } // namespace attestation |