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

Unified Diff: chrome/browser/chromeos/attestation/platform_verification_flow.cc

Issue 31043008: Changed platform verification user consent logic to be per-domain. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix browser_tests Created 7 years, 1 month 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 side-by-side diff with in-line comments
Download patch
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 cbbc50cf6e75349f37a01b20d69a95432ca5e9a4..77f93f50c6c98bf84cf3df481c4961cb435e6bba 100644
--- a/chrome/browser/chromeos/attestation/platform_verification_flow.cc
+++ b/chrome/browser/chromeos/attestation/platform_verification_flow.cc
@@ -14,7 +14,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/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 +28,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 +66,6 @@ class DefaultDelegate : public PlatformVerificationFlow::Delegate {
virtual ~DefaultDelegate() {}
virtual void ShowConsentPrompt(
- PlatformVerificationFlow::ConsentType type,
content::WebContents* web_contents,
const PlatformVerificationFlow::Delegate::ConsentCallback& callback)
OVERRIDE {
@@ -79,6 +83,7 @@ PlatformVerificationFlow::PlatformVerificationFlow()
user_manager_(UserManager::Get()),
delegate_(NULL),
testing_prefs_(NULL),
+ testing_content_settings_(NULL),
weak_factory_(this) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
scoped_ptr<ServerProxy> attestation_ca_client(new AttestationCAClient());
@@ -103,6 +108,7 @@ PlatformVerificationFlow::PlatformVerificationFlow(
user_manager_(user_manager),
delegate_(delegate),
testing_prefs_(NULL),
+ testing_content_settings_(NULL),
weak_factory_(this) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
}
@@ -116,6 +122,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 +149,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 +173,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 +185,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 +192,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 +302,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();
+ return url;
}
User* PlatformVerificationFlow::GetUser(content::WebContents* web_contents) {
@@ -299,6 +315,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 +346,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

Powered by Google App Engine
This is Rietveld 408576698