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

Side by Side Diff: chrome/browser/chromeos/login/signed_settings.cc

Issue 8163011: PART3: Removed whitelist special ops. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased on the new PART2. (I think it should be 100% the same but I'd rather upload it) Created 9 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 (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/chromeos/login/signed_settings.h" 5 #include "chrome/browser/chromeos/login/signed_settings.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 return false; 73 return false;
74 } 74 }
75 75
76 // static 76 // static
77 SignedSettings::ReturnCode SignedSettings::MapKeyOpCode( 77 SignedSettings::ReturnCode SignedSettings::MapKeyOpCode(
78 OwnerManager::KeyOpCode return_code) { 78 OwnerManager::KeyOpCode return_code) {
79 return (return_code == OwnerManager::KEY_UNAVAILABLE ? 79 return (return_code == OwnerManager::KEY_UNAVAILABLE ?
80 KEY_UNAVAILABLE : BAD_SIGNATURE); 80 KEY_UNAVAILABLE : BAD_SIGNATURE);
81 } 81 }
82 82
83 // static
84 bool SignedSettings::EnumerateWhitelist(std::vector<std::string>* whitelisted) {
85 OwnershipService* service = OwnershipService::GetSharedInstance();
86 if (!service->has_cached_policy())
87 return false;
88 em::ChromeDeviceSettingsProto pol;
89 pol.ParseFromString(service->cached_policy().policy_value());
90 if (!pol.has_user_whitelist())
91 return false;
92
93 const RepeatedPtrField<std::string>& whitelist =
94 pol.user_whitelist().user_whitelist();
95 for (RepeatedPtrField<std::string>::const_iterator it = whitelist.begin();
96 it != whitelist.end();
97 ++it) {
98 whitelisted->push_back(*it);
99 }
100 return true;
101 }
102
103 class CheckWhitelistOp : public SignedSettings {
104 public:
105 CheckWhitelistOp(const std::string& email,
106 SignedSettings::Delegate<bool>* d);
107 virtual ~CheckWhitelistOp();
108 void Execute();
109 void Fail(SignedSettings::ReturnCode code);
110 void Succeed(bool value);
111 // Implementation of OwnerManager::Delegate
112 void OnKeyOpComplete(const OwnerManager::KeyOpCode return_code,
113 const std::vector<uint8>& payload);
114
115 private:
116 bool LookUpInPolicy(const std::string& email);
117 // Always call d_->OnSettingOpCompleted() via this call.
118 // It guarantees that the callback will not be triggered until _after_
119 // Execute() returns, which is implicitly assumed by SignedSettingsHelper
120 // in some cases.
121 void PerformCallback(SignedSettings::ReturnCode code, bool value);
122
123 const std::string email_;
124 SignedSettings::Delegate<bool>* d_;
125 };
126
127 class WhitelistOp : public SignedSettings,
128 public SignedSettings::Delegate<bool> {
129 public:
130 WhitelistOp(const std::string& email,
131 bool add_to_whitelist,
132 SignedSettings::Delegate<bool>* d);
133 virtual ~WhitelistOp();
134 void Execute();
135 void Fail(SignedSettings::ReturnCode code);
136 void Succeed(bool value);
137 // Implementation of OwnerManager::Delegate
138 void OnKeyOpComplete(const OwnerManager::KeyOpCode return_code,
139 const std::vector<uint8>& payload);
140 // Implementation of SignedSettings::Delegate
141 void OnSettingsOpCompleted(ReturnCode code, bool value);
142
143 private:
144 void ModifyWhitelist(const std::string& email,
145 bool add_to_whitelist,
146 em::UserWhitelistProto* whitelist_proto);
147 // Always call d_->OnSettingOpCompleted() via this call.
148 // It guarantees that the callback will not be triggered until _after_
149 // Execute() returns, which is implicitly assumed by SignedSettingsHelper
150 // in some cases.
151 void PerformCallback(SignedSettings::ReturnCode code, bool value);
152
153 const std::string email_;
154 const bool add_to_whitelist_;
155 SignedSettings::Delegate<bool>* d_;
156 em::PolicyFetchResponse to_store_;
157 scoped_refptr<SignedSettings> store_op_;
158 };
159
160 class StorePropertyOp : public SignedSettings, 83 class StorePropertyOp : public SignedSettings,
161 public SignedSettings::Delegate<bool> { 84 public SignedSettings::Delegate<bool> {
162 public: 85 public:
163 StorePropertyOp(const std::string& name, 86 StorePropertyOp(const std::string& name,
164 const base::Value& value, 87 const base::Value& value,
165 SignedSettings::Delegate<bool>* d); 88 SignedSettings::Delegate<bool>* d);
166 virtual ~StorePropertyOp(); 89 virtual ~StorePropertyOp();
167 void Execute(); 90 void Execute();
168 void Fail(SignedSettings::ReturnCode code); 91 void Fail(SignedSettings::ReturnCode code);
169 void Succeed(bool value); 92 void Succeed(bool value);
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 void PerformCallback(SignedSettings::ReturnCode code, 188 void PerformCallback(SignedSettings::ReturnCode code,
266 const em::PolicyFetchResponse& value); 189 const em::PolicyFetchResponse& value);
267 190
268 void ProcessPolicy(const char* out, const unsigned int len); 191 void ProcessPolicy(const char* out, const unsigned int len);
269 192
270 em::PolicyFetchResponse policy_; 193 em::PolicyFetchResponse policy_;
271 SignedSettings::Delegate<const em::PolicyFetchResponse&>* d_; 194 SignedSettings::Delegate<const em::PolicyFetchResponse&>* d_;
272 }; 195 };
273 196
274 // static 197 // static
275 SignedSettings* SignedSettings::CreateCheckWhitelistOp(
276 const std::string& email,
277 SignedSettings::Delegate<bool>* d) {
278 DCHECK(d != NULL);
279 return new CheckWhitelistOp(Authenticator::Canonicalize(email), d);
280 }
281
282 // static
283 SignedSettings* SignedSettings::CreateWhitelistOp(
284 const std::string& email,
285 bool add_to_whitelist,
286 SignedSettings::Delegate<bool>* d) {
287 DCHECK(d != NULL);
288 return new WhitelistOp(Authenticator::Canonicalize(email),
289 add_to_whitelist,
290 d);
291 }
292
293 // static
294 SignedSettings* SignedSettings::CreateStorePropertyOp( 198 SignedSettings* SignedSettings::CreateStorePropertyOp(
295 const std::string& name, 199 const std::string& name,
296 const base::Value& value, 200 const base::Value& value,
297 SignedSettings::Delegate<bool>* d) { 201 SignedSettings::Delegate<bool>* d) {
298 DCHECK(d != NULL); 202 DCHECK(d != NULL);
299 return new StorePropertyOp(name, value, d); 203 return new StorePropertyOp(name, value, d);
300 } 204 }
301 205
302 // static 206 // static
303 SignedSettings* SignedSettings::CreateRetrievePropertyOp( 207 SignedSettings* SignedSettings::CreateRetrievePropertyOp(
(...skipping 12 matching lines...) Expand all
316 return new StorePolicyOp(policy, d); 220 return new StorePolicyOp(policy, d);
317 } 221 }
318 222
319 // static 223 // static
320 SignedSettings* SignedSettings::CreateRetrievePolicyOp( 224 SignedSettings* SignedSettings::CreateRetrievePolicyOp(
321 SignedSettings::Delegate<const em::PolicyFetchResponse&>* d) { 225 SignedSettings::Delegate<const em::PolicyFetchResponse&>* d) {
322 DCHECK(d != NULL); 226 DCHECK(d != NULL);
323 return new RetrievePolicyOp(d); 227 return new RetrievePolicyOp(d);
324 } 228 }
325 229
326 CheckWhitelistOp::CheckWhitelistOp(const std::string& email,
327 SignedSettings::Delegate<bool>* d)
328 : email_(email),
329 d_(d) {
330 }
331
332 CheckWhitelistOp::~CheckWhitelistOp() {}
333
334 void CheckWhitelistOp::Execute() {
335 CHECK(chromeos::CrosLibrary::Get()->EnsureLoaded());
336 std::vector<uint8> sig;
337 std::string email_to_check = email_;
338 if (!service_->has_cached_policy()) {
339 TryToFetchPolicyAndCallBack();
340 return;
341 }
342 if (LookUpInPolicy(email_to_check)) {
343 VLOG(2) << "Whitelist check was successful for " << email_to_check;
344 Succeed(true);
345 return;
346 }
347 // If the exact match was not found try to match against a wildcard entry
348 // where the domain only matches (e.g. *@example.com). In theory we should
349 // always have correctly formated mail address here but a little precaution
350 // does no harm.
351 if (email_.find('@') != std::string::npos) {
352 email_to_check = std::string("*").append(email_.substr(email_.find('@')));
353 if (LookUpInPolicy(email_to_check)) {
354 VLOG(2) << "Whitelist check was successful for " << email_to_check;
355 Succeed(true);
356 return;
357 }
358 }
359 Fail(NOT_FOUND);
360 return;
361 }
362
363 void CheckWhitelistOp::Fail(SignedSettings::ReturnCode code) {
364 BrowserThread::PostTask(
365 BrowserThread::UI, FROM_HERE,
366 base::Bind(&CheckWhitelistOp::PerformCallback, this, code, false));
367 }
368
369 void CheckWhitelistOp::Succeed(bool value) {
370 BrowserThread::PostTask(
371 BrowserThread::UI, FROM_HERE,
372 base::Bind(&CheckWhitelistOp::PerformCallback, this, SUCCESS, value));
373 }
374
375 void CheckWhitelistOp::OnKeyOpComplete(
376 const OwnerManager::KeyOpCode return_code,
377 const std::vector<uint8>& payload) {
378 NOTREACHED();
379 // Ensure we're on the UI thread, due to the need to send DBus traffic.
380 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
381 BrowserThread::PostTask(
382 BrowserThread::UI, FROM_HERE,
383 base::Bind(&CheckWhitelistOp::OnKeyOpComplete, this, return_code,
384 payload));
385 return;
386 }
387 if (return_code == OwnerManager::SUCCESS) {
388 VLOG(2) << "Whitelist check was successful.";
389 Succeed(true);
390 } else {
391 VLOG(2) << "Whitelist check failed.";
392 Fail(SignedSettings::MapKeyOpCode(return_code));
393 }
394 }
395
396 bool CheckWhitelistOp::LookUpInPolicy(const std::string& email) {
397 em::ChromeDeviceSettingsProto pol;
398 pol.ParseFromString(service_->cached_policy().policy_value());
399 if (!pol.has_user_whitelist())
400 return false;
401
402 const RepeatedPtrField<std::string>& whitelist =
403 pol.user_whitelist().user_whitelist();
404 for (RepeatedPtrField<std::string>::const_iterator it = whitelist.begin();
405 it != whitelist.end();
406 ++it) {
407 if (email == *it)
408 return true;
409 }
410 return false;
411 }
412
413 void CheckWhitelistOp::PerformCallback(SignedSettings::ReturnCode code,
414 bool value) {
415 d_->OnSettingsOpCompleted(code, value);
416 }
417
418 WhitelistOp::WhitelistOp(const std::string& email,
419 bool add_to_whitelist,
420 SignedSettings::Delegate<bool>* d)
421 : email_(email),
422 add_to_whitelist_(add_to_whitelist),
423 d_(d) {
424 }
425
426 WhitelistOp::~WhitelistOp() {}
427
428 void WhitelistOp::Execute() {
429 if (!service_->has_cached_policy()) {
430 TryToFetchPolicyAndCallBack();
431 return;
432 }
433 em::PolicyData to_sign;
434 to_sign.CheckTypeAndMergeFrom(service_->cached_policy());
435 em::ChromeDeviceSettingsProto pol;
436 pol.ParseFromString(to_sign.policy_value());
437 em::UserWhitelistProto* whitelist_proto = pol.mutable_user_whitelist();
438 ModifyWhitelist(email_, add_to_whitelist_, whitelist_proto);
439 to_sign.set_policy_value(pol.SerializeAsString());
440 to_store_.set_policy_data(to_sign.SerializeAsString());
441 service_->StartSigningAttempt(to_store_.policy_data(), this);
442 }
443
444 void WhitelistOp::Fail(SignedSettings::ReturnCode code) {
445 BrowserThread::PostTask(
446 BrowserThread::UI, FROM_HERE,
447 base::Bind(&WhitelistOp::PerformCallback, this, code, false));
448 }
449
450 void WhitelistOp::Succeed(bool value) {
451 BrowserThread::PostTask(
452 BrowserThread::UI, FROM_HERE,
453 base::Bind(&WhitelistOp::PerformCallback, this, SUCCESS, value));
454 }
455
456 void WhitelistOp::OnKeyOpComplete(const OwnerManager::KeyOpCode return_code,
457 const std::vector<uint8>& sig) {
458 // Ensure we're on the UI thread, due to the need to send DBus traffic.
459 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
460 BrowserThread::PostTask(
461 BrowserThread::UI, FROM_HERE,
462 base::Bind(&WhitelistOp::OnKeyOpComplete, this, return_code, sig));
463 return;
464 }
465 VLOG(2) << "WhitelistOp::OnKeyOpComplete return_code = " << return_code;
466 // Now, sure we're on the UI thread.
467 if (return_code == OwnerManager::SUCCESS) {
468 to_store_.set_policy_data_signature(
469 std::string(reinterpret_cast<const char*>(&sig[0]), sig.size()));
470 store_op_ = CreateStorePolicyOp(&to_store_, this);
471 // d_->OnSettingsOpCompleted() will be called by this call.
472 store_op_->Execute();
473 } else {
474 Fail(SignedSettings::MapKeyOpCode(return_code));
475 }
476 }
477
478 void WhitelistOp::OnSettingsOpCompleted(ReturnCode code, bool value) {
479 if (value && to_store_.has_policy_data()) {
480 em::PolicyData poldata;
481 poldata.ParseFromString(to_store_.policy_data());
482 service_->set_cached_policy(poldata);
483 Succeed(value);
484 return;
485 }
486 Fail(NOT_FOUND);
487 }
488
489 void WhitelistOp::ModifyWhitelist(const std::string& email,
490 bool add_to_whitelist,
491 em::UserWhitelistProto* whitelist_proto) {
492 int i = 0;
493 const RepeatedPtrField<string>& whitelist = whitelist_proto->user_whitelist();
494 for (RepeatedPtrField<string>::const_iterator it = whitelist.begin();
495 it != whitelist.end();
496 ++it, ++i) {
497 if (email == *it)
498 break;
499 }
500 // |i| contains the index of |email|, if it is in |whitelist|.
501 if (add_to_whitelist) {
502 if (i >= whitelist.size()) // |email| was not in |whitelist|, we must add.
503 whitelist_proto->add_user_whitelist(email);
504 return;
505 } else {
506 if (i < whitelist.size()) { // |email| was in |whitelist|, we must remove.
507 RepeatedPtrField<string>* change_list =
508 whitelist_proto->mutable_user_whitelist();
509 change_list->SwapElements(i, whitelist.size() - 1); // Move to end.
510 change_list->RemoveLast();
511 }
512 return;
513 }
514 LOG(WARNING) << "Whitelist modification no-op: " << email;
515 }
516
517 void WhitelistOp::PerformCallback(SignedSettings::ReturnCode code, bool value) {
518 d_->OnSettingsOpCompleted(code, value);
519 }
520
521 StorePropertyOp::StorePropertyOp(const std::string& name, 230 StorePropertyOp::StorePropertyOp(const std::string& name,
522 const base::Value& value, 231 const base::Value& value,
523 SignedSettings::Delegate<bool>* d) 232 SignedSettings::Delegate<bool>* d)
524 : name_(name), 233 : name_(name),
525 value_(value.DeepCopy()), 234 value_(value.DeepCopy()),
526 d_(d), 235 d_(d),
527 store_op_(NULL) { 236 store_op_(NULL) {
528 } 237 }
529 238
530 StorePropertyOp::~StorePropertyOp() {} 239 StorePropertyOp::~StorePropertyOp() {}
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after
995 sig.assign(sig_ptr, sig_ptr + policy_.policy_data_signature().length()); 704 sig.assign(sig_ptr, sig_ptr + policy_.policy_data_signature().length());
996 service_->StartVerifyAttempt(policy_.policy_data(), sig, this); 705 service_->StartVerifyAttempt(policy_.policy_data(), sig, this);
997 } 706 }
998 707
999 void RetrievePolicyOp::PerformCallback(SignedSettings::ReturnCode code, 708 void RetrievePolicyOp::PerformCallback(SignedSettings::ReturnCode code,
1000 const em::PolicyFetchResponse& value) { 709 const em::PolicyFetchResponse& value) {
1001 d_->OnSettingsOpCompleted(code, value); 710 d_->OnSettingsOpCompleted(code, value);
1002 } 711 }
1003 712
1004 } // namespace chromeos 713 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698