signed_settings.cc revision bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293
1// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/chromeos/login/signed_settings.h" 6 7#include <string> 8#include <vector> 9 10#include "base/ref_counted.h" 11#include "base/stringprintf.h" 12#include "chrome/browser/chrome_thread.h" 13#include "chrome/browser/chromeos/cros/cros_library.h" 14#include "chrome/browser/chromeos/cros/login_library.h" 15#include "chrome/browser/chromeos/login/ownership_service.h" 16 17namespace chromeos { 18 19SignedSettings::SignedSettings() 20 : service_(OwnershipService::GetSharedInstance()) { 21} 22 23SignedSettings::~SignedSettings() {} 24 25class CheckWhitelistOp : public SignedSettings { 26 public: 27 CheckWhitelistOp(const std::string& email, 28 SignedSettings::Delegate<bool>* d); 29 virtual ~CheckWhitelistOp(); 30 bool Execute(); 31 // Implementation of OwnerManager::Delegate::OnKeyOpComplete() 32 void OnKeyOpComplete(const OwnerManager::KeyOpCode return_code, 33 const std::vector<uint8>& payload); 34 35 private: 36 const std::string email_; 37 SignedSettings::Delegate<bool>* d_; 38}; 39 40class WhitelistOp : public SignedSettings, 41 public LoginLibrary::Delegate { 42 public: 43 WhitelistOp(const std::string& email, 44 bool add_to_whitelist, 45 SignedSettings::Delegate<bool>* d); 46 virtual ~WhitelistOp(); 47 bool Execute(); 48 // Implementation of OwnerManager::Delegate::OnKeyOpComplete() 49 void OnKeyOpComplete(const OwnerManager::KeyOpCode return_code, 50 const std::vector<uint8>& payload); 51 // Implementation of LoginLibrary::Delegate::OnComplete() 52 void OnComplete(bool value); 53 54 private: 55 bool InitiateWhitelistOp(const std::vector<uint8>& signature); 56 57 const std::string email_; 58 const bool add_to_whitelist_; 59 SignedSettings::Delegate<bool>* d_; 60}; 61 62class StorePropertyOp : public SignedSettings, 63 public LoginLibrary::Delegate { 64 public: 65 StorePropertyOp(const std::string& name, 66 const std::string& value, 67 SignedSettings::Delegate<bool>* d); 68 virtual ~StorePropertyOp(); 69 bool Execute(); 70 // Implementation of OwnerManager::Delegate::OnKeyOpComplete() 71 void OnKeyOpComplete(const OwnerManager::KeyOpCode return_code, 72 const std::vector<uint8>& payload); 73 // Implementation of LoginLibrary::Delegate::OnComplete() 74 void OnComplete(bool value); 75 76 private: 77 std::string name_; 78 std::string value_; 79 SignedSettings::Delegate<bool>* d_; 80}; 81 82class RetrievePropertyOp : public SignedSettings { 83 public: 84 RetrievePropertyOp(const std::string& name, 85 SignedSettings::Delegate<std::string>* d); 86 virtual ~RetrievePropertyOp(); 87 bool Execute(); 88 // Implementation of OwnerManager::Delegate::OnKeyOpComplete() 89 void OnKeyOpComplete(const OwnerManager::KeyOpCode return_code, 90 const std::vector<uint8>& payload); 91 92 private: 93 std::string name_; 94 std::string value_; 95 SignedSettings::Delegate<std::string>* d_; 96}; 97 98// static 99SignedSettings* SignedSettings::CreateCheckWhitelistOp( 100 const std::string& email, 101 SignedSettings::Delegate<bool>* d) { 102 return new CheckWhitelistOp(email, d); 103} 104 105// static 106SignedSettings* SignedSettings::CreateWhitelistOp( 107 const std::string& email, 108 bool add_to_whitelist, 109 SignedSettings::Delegate<bool>* d) { 110 return new WhitelistOp(email, add_to_whitelist, d); 111} 112 113// static 114SignedSettings* SignedSettings::CreateStorePropertyOp( 115 const std::string& name, 116 const std::string& value, 117 SignedSettings::Delegate<bool>* d) { 118 return new StorePropertyOp(name, value, d); 119} 120 121// static 122SignedSettings* SignedSettings::CreateRetrievePropertyOp( 123 const std::string& name, 124 SignedSettings::Delegate<std::string>* d) { 125 return new RetrievePropertyOp(name, d); 126} 127 128CheckWhitelistOp::CheckWhitelistOp(const std::string& email, 129 SignedSettings::Delegate<bool>* d) 130 : email_(email), 131 d_(d) { 132} 133 134CheckWhitelistOp::~CheckWhitelistOp() {} 135 136bool CheckWhitelistOp::Execute() { 137 CHECK(chromeos::CrosLibrary::Get()->EnsureLoaded()); 138 std::vector<uint8> sig; 139 if (!CrosLibrary::Get()->GetLoginLibrary()->CheckWhitelist(email_, &sig)) 140 return false; 141 142 // Posts a task to the FILE thread to verify |sig|. 143 service_->StartVerifyAttempt(email_, sig, this); 144 return true; 145} 146 147void CheckWhitelistOp::OnKeyOpComplete( 148 const OwnerManager::KeyOpCode return_code, 149 const std::vector<uint8>& payload) { 150 // Ensure we're on the UI thread, due to the need to send DBus traffic. 151 if (!ChromeThread::CurrentlyOn(ChromeThread::UI)) { 152 ChromeThread::PostTask( 153 ChromeThread::UI, FROM_HERE, 154 NewRunnableMethod(this, 155 &CheckWhitelistOp::OnKeyOpComplete, 156 return_code, payload)); 157 return; 158 } 159 if (return_code == OwnerManager::SUCCESS) 160 d_->OnSettingsOpSucceeded(true); 161 else 162 d_->OnSettingsOpFailed(); 163} 164 165WhitelistOp::WhitelistOp(const std::string& email, 166 bool add_to_whitelist, 167 SignedSettings::Delegate<bool>* d) 168 : email_(email), 169 add_to_whitelist_(add_to_whitelist), 170 d_(d) { 171} 172 173WhitelistOp::~WhitelistOp() {} 174 175bool WhitelistOp::Execute() { 176 // Posts a task to the FILE thread to sign |email_|. 177 service_->StartSigningAttempt(email_, this); 178 return true; 179} 180 181void WhitelistOp::OnKeyOpComplete(const OwnerManager::KeyOpCode return_code, 182 const std::vector<uint8>& payload) { 183 // Ensure we're on the UI thread, due to the need to send DBus traffic. 184 if (!ChromeThread::CurrentlyOn(ChromeThread::UI)) { 185 ChromeThread::PostTask( 186 ChromeThread::UI, FROM_HERE, 187 NewRunnableMethod(this, 188 &WhitelistOp::OnKeyOpComplete, 189 return_code, payload)); 190 return; 191 } 192 // Now, sure we're on the UI thread. 193 bool success = false; 194 if (return_code == OwnerManager::SUCCESS) { 195 // OnComplete() will be called when this is done. 196 success = InitiateWhitelistOp(payload); 197 } 198 if (!success) 199 d_->OnSettingsOpFailed(); 200} 201 202void WhitelistOp::OnComplete(bool value) { 203 if (value) 204 d_->OnSettingsOpSucceeded(value); 205 else 206 d_->OnSettingsOpFailed(); 207} 208 209bool WhitelistOp::InitiateWhitelistOp(const std::vector<uint8>& signature) { 210 LoginLibrary* library = CrosLibrary::Get()->GetLoginLibrary(); 211 if (add_to_whitelist_) 212 return library->WhitelistAsync(email_, signature, this); 213 return library->UnwhitelistAsync(email_, signature, this); 214} 215 216StorePropertyOp::StorePropertyOp(const std::string& name, 217 const std::string& value, 218 SignedSettings::Delegate<bool>* d) 219 : name_(name), 220 value_(value), 221 d_(d) { 222} 223 224StorePropertyOp::~StorePropertyOp() {} 225 226bool StorePropertyOp::Execute() { 227 // Posts a task to the FILE thread to sign |name_|=|value_|. 228 std::string to_sign = base::StringPrintf("%s=%s", 229 name_.c_str(), 230 value_.c_str()); 231 service_->StartSigningAttempt(to_sign, this); 232 return true; 233} 234 235void StorePropertyOp::OnKeyOpComplete(const OwnerManager::KeyOpCode return_code, 236 const std::vector<uint8>& payload) { 237 // Ensure we're on the UI thread, due to the need to send DBus traffic. 238 if (!ChromeThread::CurrentlyOn(ChromeThread::UI)) { 239 ChromeThread::PostTask( 240 ChromeThread::UI, FROM_HERE, 241 NewRunnableMethod(this, 242 &StorePropertyOp::OnKeyOpComplete, 243 return_code, payload)); 244 return; 245 } 246 // Now, sure we're on the UI thread. 247 bool success = false; 248 if (return_code == OwnerManager::SUCCESS) { 249 // OnComplete() will be called when this is done. 250 success = CrosLibrary::Get()->GetLoginLibrary()->StorePropertyAsync(name_, 251 value_, 252 payload, 253 this); 254 } 255 if (!success) 256 d_->OnSettingsOpFailed(); 257} 258 259void StorePropertyOp::OnComplete(bool value) { 260 if (value) 261 d_->OnSettingsOpSucceeded(value); 262 else 263 d_->OnSettingsOpFailed(); 264} 265 266RetrievePropertyOp::RetrievePropertyOp(const std::string& name, 267 SignedSettings::Delegate<std::string>* d) 268 : name_(name), 269 d_(d) { 270} 271 272RetrievePropertyOp::~RetrievePropertyOp() {} 273 274bool RetrievePropertyOp::Execute() { 275 CHECK(chromeos::CrosLibrary::Get()->EnsureLoaded()); 276 std::vector<uint8> sig; 277 if (!CrosLibrary::Get()->GetLoginLibrary()->RetrieveProperty(name_, 278 &value_, 279 &sig)) { 280 return false; 281 } 282 std::string to_verify = base::StringPrintf("%s=%s", 283 name_.c_str(), 284 value_.c_str()); 285 // Posts a task to the FILE thread to verify |sig|. 286 service_->StartVerifyAttempt(to_verify, sig, this); 287 return true; 288} 289 290void RetrievePropertyOp::OnKeyOpComplete( 291 const OwnerManager::KeyOpCode return_code, 292 const std::vector<uint8>& payload) { 293 if (!ChromeThread::CurrentlyOn(ChromeThread::UI)) { 294 ChromeThread::PostTask( 295 ChromeThread::UI, FROM_HERE, 296 NewRunnableMethod(this, 297 &RetrievePropertyOp::OnKeyOpComplete, 298 return_code, payload)); 299 return; 300 } 301 // Now, sure we're on the UI thread. 302 if (return_code == OwnerManager::SUCCESS) 303 d_->OnSettingsOpSucceeded(value_); 304 else 305 d_->OnSettingsOpFailed(); 306} 307 308} // namespace chromeos 309