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

Side by Side 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: Created 7 years, 2 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "platform_verification_flow.h" 5 #include "platform_verification_flow.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/prefs/pref_service.h" 9 #include "base/prefs/pref_service.h"
10 #include "chrome/browser/chromeos/attestation/attestation_ca_client.h" 10 #include "chrome/browser/chromeos/attestation/attestation_ca_client.h"
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 namespace chromeos { 54 namespace chromeos {
55 namespace attestation { 55 namespace attestation {
56 56
57 // A default implementation of the Delegate interface. 57 // A default implementation of the Delegate interface.
58 class DefaultDelegate : public PlatformVerificationFlow::Delegate { 58 class DefaultDelegate : public PlatformVerificationFlow::Delegate {
59 public: 59 public:
60 DefaultDelegate() {} 60 DefaultDelegate() {}
61 virtual ~DefaultDelegate() {} 61 virtual ~DefaultDelegate() {}
62 62
63 virtual void ShowConsentPrompt( 63 virtual void ShowConsentPrompt(
64 PlatformVerificationFlow::ConsentType type,
65 content::WebContents* web_contents, 64 content::WebContents* web_contents,
66 const PlatformVerificationFlow::Delegate::ConsentCallback& callback) 65 const PlatformVerificationFlow::Delegate::ConsentCallback& callback)
67 OVERRIDE { 66 OVERRIDE {
68 PlatformVerificationDialog::ShowDialog(web_contents, callback); 67 PlatformVerificationDialog::ShowDialog(web_contents, callback);
69 } 68 }
70 69
71 private: 70 private:
72 DISALLOW_COPY_AND_ASSIGN(DefaultDelegate); 71 DISALLOW_COPY_AND_ASSIGN(DefaultDelegate);
73 }; 72 };
74 73
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 content::WebContents* web_contents, 113 content::WebContents* web_contents,
115 const std::string& service_id, 114 const std::string& service_id,
116 const std::string& challenge, 115 const std::string& challenge,
117 const ChallengeCallback& callback) { 116 const ChallengeCallback& callback) {
118 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 117 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
119 if (!IsAttestationEnabled(web_contents)) { 118 if (!IsAttestationEnabled(web_contents)) {
120 LOG(INFO) << "PlatformVerificationFlow: Feature disabled."; 119 LOG(INFO) << "PlatformVerificationFlow: Feature disabled.";
121 ReportError(callback, POLICY_REJECTED); 120 ReportError(callback, POLICY_REJECTED);
122 return; 121 return;
123 } 122 }
123 if (GetURLSpec(web_contents).empty()) {
124 LOG(WARNING) << "PlatformVerificationFlow: Invalid URL.";
125 ReportError(callback, INTERNAL_ERROR);
126 return;
127 }
124 BoolDBusMethodCallback dbus_callback = base::Bind( 128 BoolDBusMethodCallback dbus_callback = base::Bind(
125 &DBusCallback, 129 &DBusCallback,
126 base::Bind(&PlatformVerificationFlow::CheckConsent, 130 base::Bind(&PlatformVerificationFlow::CheckConsent,
127 weak_factory_.GetWeakPtr(), 131 weak_factory_.GetWeakPtr(),
128 web_contents, 132 web_contents,
129 service_id, 133 service_id,
130 challenge, 134 challenge,
131 callback), 135 callback),
132 base::Bind(&ReportError, callback, INTERNAL_ERROR)); 136 base::Bind(&ReportError, callback, INTERNAL_ERROR));
133 cryptohome_client_->TpmAttestationIsEnrolled(dbus_callback); 137 cryptohome_client_->TpmAttestationIsEnrolled(dbus_callback);
134 } 138 }
135 139
136 void PlatformVerificationFlow::CheckConsent(content::WebContents* web_contents, 140 void PlatformVerificationFlow::CheckConsent(content::WebContents* web_contents,
137 const std::string& service_id, 141 const std::string& service_id,
138 const std::string& challenge, 142 const std::string& challenge,
139 const ChallengeCallback& callback, 143 const ChallengeCallback& callback,
140 bool attestation_enrolled) { 144 bool attestation_enrolled) {
141 ConsentType consent_type = CONSENT_TYPE_NONE; 145 PrefService* pref_service = GetPrefs(web_contents);
142 if (!attestation_enrolled || IsFirstUse(web_contents)) { 146 if (!pref_service) {
143 consent_type = CONSENT_TYPE_ATTESTATION; 147 LOG(ERROR) << "Failed to get user prefs.";
144 } else if (IsAlwaysAskRequired(web_contents)) { 148 ReportError(callback, INTERNAL_ERROR);
145 consent_type = CONSENT_TYPE_ALWAYS; 149 return;
146 } 150 }
151 bool consent_required = (
152 // Consent required if attestation has never been enrolled on this device.
153 !attestation_enrolled ||
154 // Consent required if this is the first use of attestation for content
155 // protection on this device.
156 !pref_service->GetBoolean(prefs::kRAConsentFirstTime) ||
157 // Consent required if consent has never been given for this domain.
158 !GetDomainPref(pref_service, GetURLSpec(web_contents), NULL));
159
147 Delegate::ConsentCallback consent_callback = base::Bind( 160 Delegate::ConsentCallback consent_callback = base::Bind(
148 &PlatformVerificationFlow::OnConsentResponse, 161 &PlatformVerificationFlow::OnConsentResponse,
149 weak_factory_.GetWeakPtr(), 162 weak_factory_.GetWeakPtr(),
150 web_contents, 163 web_contents,
151 service_id, 164 service_id,
152 challenge, 165 challenge,
153 callback, 166 callback,
154 consent_type); 167 consent_required);
155 if (consent_type == CONSENT_TYPE_NONE) { 168 if (!consent_required) {
156 consent_callback.Run(CONSENT_RESPONSE_NONE); 169 consent_callback.Run(CONSENT_RESPONSE_NONE);
157 } else { 170 } else {
158 delegate_->ShowConsentPrompt(consent_type, 171 delegate_->ShowConsentPrompt(web_contents,
pastarmovj 2013/10/24 09:56:36 nit: This should fit on one line and then you will
Darren Krahn 2013/10/28 23:49:52 Done.
159 web_contents,
160 consent_callback); 172 consent_callback);
161 } 173 }
162 } 174 }
163 175
164 void PlatformVerificationFlow::RegisterProfilePrefs( 176 void PlatformVerificationFlow::RegisterProfilePrefs(
165 user_prefs::PrefRegistrySyncable* prefs) { 177 user_prefs::PrefRegistrySyncable* prefs) {
166 prefs->RegisterBooleanPref(prefs::kRAConsentFirstTime, 178 prefs->RegisterBooleanPref(prefs::kRAConsentFirstTime,
167 false, 179 false,
168 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 180 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
169 prefs->RegisterDictionaryPref( 181 prefs->RegisterDictionaryPref(
170 prefs::kRAConsentDomains, 182 prefs::kRAConsentDomains,
171 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 183 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
172 prefs->RegisterBooleanPref(prefs::kRAConsentAlways,
173 false,
174 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
175 } 184 }
176 185
177 void PlatformVerificationFlow::OnConsentResponse( 186 void PlatformVerificationFlow::OnConsentResponse(
178 content::WebContents* web_contents, 187 content::WebContents* web_contents,
179 const std::string& service_id, 188 const std::string& service_id,
180 const std::string& challenge, 189 const std::string& challenge,
181 const ChallengeCallback& callback, 190 const ChallengeCallback& callback,
182 ConsentType consent_type, 191 bool consent_required,
183 ConsentResponse consent_response) { 192 ConsentResponse consent_response) {
184 if (consent_type != CONSENT_TYPE_NONE) { 193 if (consent_required) {
185 if (consent_response == CONSENT_RESPONSE_NONE) { 194 if (consent_response == CONSENT_RESPONSE_NONE) {
186 // No user response - do not proceed and do not modify any settings. 195 // No user response - do not proceed and do not modify any settings.
187 LOG(WARNING) << "PlatformVerificationFlow: No response from user."; 196 LOG(WARNING) << "PlatformVerificationFlow: No response from user.";
188 ReportError(callback, USER_REJECTED); 197 ReportError(callback, USER_REJECTED);
189 return; 198 return;
190 } 199 }
191 if (!UpdateSettings(web_contents, consent_type, consent_response)) { 200 if (!UpdateSettings(web_contents, consent_response)) {
192 ReportError(callback, INTERNAL_ERROR); 201 ReportError(callback, INTERNAL_ERROR);
193 return; 202 return;
194 } 203 }
195 if (consent_response == CONSENT_RESPONSE_DENY) { 204 if (consent_response == CONSENT_RESPONSE_DENY) {
196 LOG(INFO) << "PlatformVerificationFlow: User rejected request."; 205 LOG(INFO) << "PlatformVerificationFlow: User rejected request.";
197 content::RecordAction( 206 content::RecordAction(
198 content::UserMetricsAction("PlatformVerificationRejected")); 207 content::UserMetricsAction("PlatformVerificationRejected"));
199 ReportError(callback, USER_REJECTED); 208 ReportError(callback, USER_REJECTED);
200 return; 209 return;
201 } else if (consent_response == CONSENT_RESPONSE_ALLOW) { 210 } else if (consent_response == CONSENT_RESPONSE_ALLOW) {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 LOG(INFO) << "PlatformVerificationFlow: Platform successfully verified."; 287 LOG(INFO) << "PlatformVerificationFlow: Platform successfully verified.";
279 } 288 }
280 289
281 PrefService* PlatformVerificationFlow::GetPrefs( 290 PrefService* PlatformVerificationFlow::GetPrefs(
282 content::WebContents* web_contents) { 291 content::WebContents* web_contents) {
283 if (testing_prefs_) 292 if (testing_prefs_)
284 return testing_prefs_; 293 return testing_prefs_;
285 return user_prefs::UserPrefs::Get(web_contents->GetBrowserContext()); 294 return user_prefs::UserPrefs::Get(web_contents->GetBrowserContext());
286 } 295 }
287 296
288 const GURL& PlatformVerificationFlow::GetURL( 297 std::string PlatformVerificationFlow::GetURLSpec(
289 content::WebContents* web_contents) { 298 content::WebContents* web_contents) {
290 if (!testing_url_.is_empty()) 299 GURL url;
291 return testing_url_; 300 if (!testing_url_.is_empty()) {
292 return web_contents->GetLastCommittedURL(); 301 url = testing_url_;
302 } else {
303 url = web_contents->GetLastCommittedURL();
Jun Mukai 2013/10/23 20:26:12 nit: you don't need braces or 1-line if-else. or,
Darren Krahn 2013/10/28 23:49:52 Done.
304 }
305 if (!url.is_valid())
306 return std::string();
307 GURL origin = url.GetOrigin();
308 if (!origin.is_valid())
309 return std::string();
310 return origin.spec();
293 } 311 }
294 312
295 User* PlatformVerificationFlow::GetUser(content::WebContents* web_contents) { 313 User* PlatformVerificationFlow::GetUser(content::WebContents* web_contents) {
296 if (!web_contents) 314 if (!web_contents)
297 return user_manager_->GetActiveUser(); 315 return user_manager_->GetActiveUser();
298 return user_manager_->GetUserByProfile( 316 return user_manager_->GetUserByProfile(
299 Profile::FromBrowserContext(web_contents->GetBrowserContext())); 317 Profile::FromBrowserContext(web_contents->GetBrowserContext()));
300 } 318 }
301 319
302 bool PlatformVerificationFlow::IsAttestationEnabled( 320 bool PlatformVerificationFlow::IsAttestationEnabled(
(...skipping 12 matching lines...) Expand all
315 PrefService* pref_service = GetPrefs(web_contents); 333 PrefService* pref_service = GetPrefs(web_contents);
316 if (!pref_service) { 334 if (!pref_service) {
317 LOG(ERROR) << "Failed to get user prefs."; 335 LOG(ERROR) << "Failed to get user prefs.";
318 return false; 336 return false;
319 } 337 }
320 if (!pref_service->GetBoolean(prefs::kEnableDRM)) 338 if (!pref_service->GetBoolean(prefs::kEnableDRM))
321 return false; 339 return false;
322 340
323 // Check the user preference for this domain. 341 // Check the user preference for this domain.
324 bool enabled_for_domain = false; 342 bool enabled_for_domain = false;
325 bool found = GetDomainPref(web_contents, &enabled_for_domain); 343 bool found = GetDomainPref(pref_service,
344 GetURLSpec(web_contents),
345 &enabled_for_domain);
326 return (!found || enabled_for_domain); 346 return (!found || enabled_for_domain);
327 } 347 }
328 348
329 bool PlatformVerificationFlow::IsFirstUse(content::WebContents* web_contents) {
330 PrefService* pref_service = GetPrefs(web_contents);
331 if (!pref_service) {
332 LOG(ERROR) << "Failed to get user prefs.";
333 return true;
334 }
335 return !pref_service->GetBoolean(prefs::kRAConsentFirstTime);
336 }
337
338 bool PlatformVerificationFlow::IsAlwaysAskRequired(
339 content::WebContents* web_contents) {
340 PrefService* pref_service = GetPrefs(web_contents);
341 if (!pref_service) {
342 LOG(ERROR) << "Failed to get user prefs.";
343 return true;
344 }
345 if (!pref_service->GetBoolean(prefs::kRAConsentAlways))
346 return false;
347 // Show the consent UI if the user has not already explicitly allowed or
348 // denied for this domain.
349 return !GetDomainPref(web_contents, NULL);
350 }
351
352 bool PlatformVerificationFlow::UpdateSettings( 349 bool PlatformVerificationFlow::UpdateSettings(
353 content::WebContents* web_contents, 350 content::WebContents* web_contents,
354 ConsentType consent_type,
355 ConsentResponse consent_response) { 351 ConsentResponse consent_response) {
356 PrefService* pref_service = GetPrefs(web_contents); 352 PrefService* pref_service = GetPrefs(web_contents);
357 if (!pref_service) { 353 if (!pref_service) {
358 LOG(ERROR) << "Failed to get user prefs."; 354 LOG(ERROR) << "Failed to get user prefs.";
359 return false; 355 return false;
360 } 356 }
361 if (consent_type == CONSENT_TYPE_ATTESTATION) { 357 pref_service->SetBoolean(prefs::kRAConsentFirstTime, true);
362 if (consent_response == CONSENT_RESPONSE_DENY) { 358 RecordDomainConsent(pref_service,
363 pref_service->SetBoolean(prefs::kEnableDRM, false); 359 GetURLSpec(web_contents),
364 } else if (consent_response == CONSENT_RESPONSE_ALLOW) { 360 (consent_response == CONSENT_RESPONSE_ALLOW));
365 pref_service->SetBoolean(prefs::kRAConsentFirstTime, true);
366 RecordDomainConsent(web_contents, true);
367 } else if (consent_response == CONSENT_RESPONSE_ALWAYS_ASK) {
368 pref_service->SetBoolean(prefs::kRAConsentFirstTime, true);
369 pref_service->SetBoolean(prefs::kRAConsentAlways, true);
370 RecordDomainConsent(web_contents, true);
371 }
372 } else if (consent_type == CONSENT_TYPE_ALWAYS) {
373 bool allowed = (consent_response == CONSENT_RESPONSE_ALLOW ||
374 consent_response == CONSENT_RESPONSE_ALWAYS_ASK);
375 RecordDomainConsent(web_contents, allowed);
376 }
377 return true; 361 return true;
378 } 362 }
379 363
380 bool PlatformVerificationFlow::GetDomainPref( 364 bool PlatformVerificationFlow::GetDomainPref(PrefService* pref_service,
381 content::WebContents* web_contents, 365 const std::string& url_spec,
382 bool* pref_value) { 366 bool* pref_value) {
383 PrefService* pref_service = GetPrefs(web_contents);
384 CHECK(pref_service); 367 CHECK(pref_service);
385 base::DictionaryValue::Iterator iter( 368 CHECK(!url_spec.empty());
386 *pref_service->GetDictionary(prefs::kRAConsentDomains)); 369 const base::DictionaryValue* values =
387 const GURL& url = GetURL(web_contents); 370 pref_service->GetDictionary(prefs::kRAConsentDomains);
Jun Mukai 2013/10/23 20:26:12 Can we use kContentSettings and chrome/common/cont
Darren Krahn 2013/10/28 23:49:52 I've reused the content setting used in clank.
388 while (!iter.IsAtEnd()) { 371 CHECK(values);
389 if (url.DomainIs(iter.key().c_str())) { 372 bool tmp = false;
390 if (pref_value) { 373 bool result = values->GetBoolean(url_spec, &tmp);
391 if (!iter.value().GetAsBoolean(pref_value)) { 374 if (pref_value)
392 LOG(ERROR) << "Unexpected pref type."; 375 *pref_value = tmp;
393 *pref_value = false; 376 return result;
394 }
395 }
396 return true;
397 }
398 iter.Advance();
399 }
400 return false;
401 } 377 }
402 378
403 void PlatformVerificationFlow::RecordDomainConsent( 379 void PlatformVerificationFlow::RecordDomainConsent(PrefService* pref_service,
404 content::WebContents* web_contents, 380 const std::string& url_spec,
405 bool allow_domain) { 381 bool allow_domain) {
406 PrefService* pref_service = GetPrefs(web_contents);
407 CHECK(pref_service); 382 CHECK(pref_service);
383 CHECK(!url_spec.empty());
408 DictionaryPrefUpdate updater(pref_service, prefs::kRAConsentDomains); 384 DictionaryPrefUpdate updater(pref_service, prefs::kRAConsentDomains);
409 const GURL& url = GetURL(web_contents); 385 updater->SetBoolean(url_spec, allow_domain);
410 updater->SetBoolean(url.host(), allow_domain);
411 } 386 }
412 387
413 } // namespace attestation 388 } // namespace attestation
414 } // namespace chromeos 389 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698