login_library.cc revision dc0f95d653279beabeb9817299e2902918ba123e
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 3// found in the LICENSE file. 4 5#include "chrome/browser/chromeos/cros/login_library.h" 6 7#include "base/message_loop.h" 8#include "chrome/browser/browser_process.h" 9#include "chrome/browser/chromeos/cros/cros_library.h" 10#include "chrome/browser/chromeos/login/signed_settings_temp_storage.h" 11#include "content/browser/browser_thread.h" 12#include "content/common/notification_service.h" 13#include "content/common/notification_type.h" 14 15namespace chromeos { 16 17class LoginLibraryImpl : public LoginLibrary { 18 public: 19 LoginLibraryImpl() 20 : set_owner_key_callback_(NULL), 21 whitelist_op_callback_(NULL), 22 property_op_callback_(NULL) { 23 if (CrosLibrary::Get()->EnsureLoaded()) 24 Init(); 25 } 26 virtual ~LoginLibraryImpl() { 27 if (session_connection_) { 28 chromeos::DisconnectSession(session_connection_); 29 } 30 } 31 32 bool EmitLoginPromptReady() { 33 return chromeos::EmitLoginPromptReady(); 34 } 35 36 bool CheckWhitelist(const std::string& email, 37 std::vector<uint8>* OUT_signature) { 38 CryptoBlob* sig = NULL; 39 if (chromeos::CheckWhitelistSafe(email.c_str(), &sig)) { 40 OUT_signature->assign(sig->data, sig->data + sig->length); 41 chromeos::FreeCryptoBlob(sig); 42 return true; 43 } 44 return false; 45 } 46 47 bool RetrieveProperty(const std::string& name, 48 std::string* OUT_value, 49 std::vector<uint8>* OUT_signature) { 50 Property* prop = NULL; 51 if (chromeos::RetrievePropertySafe(name.c_str(), &prop)) { 52 OUT_value->assign(prop->value); 53 CryptoBlob* sig = prop->signature; 54 OUT_signature->assign(sig->data, sig->data + sig->length); 55 chromeos::FreeProperty(prop); 56 return true; 57 } 58 return false; 59 } 60 61 bool StorePropertyAsync(const std::string& name, 62 const std::string& value, 63 const std::vector<uint8>& signature, 64 Delegate* callback) { 65 DCHECK(callback) << "must provide a callback to StorePropertyAsync()"; 66 if (property_op_callback_) 67 return false; 68 property_op_callback_ = callback; 69 Property* prop = chromeos::CreateProperty(name.c_str(), 70 value.c_str(), 71 &signature[0], 72 signature.size()); 73 bool rv = chromeos::StorePropertySafe(prop); 74 chromeos::FreeProperty(prop); 75 return rv; 76 } 77 78 bool UnwhitelistAsync(const std::string& email, 79 const std::vector<uint8>& signature, 80 Delegate* callback) { 81 DCHECK(callback) << "must provide a callback to UnwhitelistAsync()"; 82 if (whitelist_op_callback_) 83 return false; 84 whitelist_op_callback_ = callback; 85 CryptoBlob* sig = chromeos::CreateCryptoBlob(&signature[0], 86 signature.size()); 87 bool rv = chromeos::UnwhitelistSafe(email.c_str(), sig); 88 chromeos::FreeCryptoBlob(sig); 89 return rv; 90 } 91 92 bool WhitelistAsync(const std::string& email, 93 const std::vector<uint8>& signature, 94 Delegate* callback) { 95 DCHECK(callback) << "must provide a callback to WhitelistAsync()"; 96 if (whitelist_op_callback_) 97 return false; 98 whitelist_op_callback_ = callback; 99 CryptoBlob* sig = chromeos::CreateCryptoBlob(&signature[0], 100 signature.size()); 101 bool rv = chromeos::WhitelistSafe(email.c_str(), sig); 102 chromeos::FreeCryptoBlob(sig); 103 return rv; 104 } 105 106 bool EnumerateWhitelisted(std::vector<std::string>* whitelisted) { 107 UserList* list = NULL; 108 if (chromeos::EnumerateWhitelistedSafe(&list)) { 109 for (int i = 0; i < list->num_users; i++) 110 whitelisted->push_back(std::string(list->users[i])); 111 chromeos::FreeUserList(list); 112 return true; 113 } 114 return false; 115 } 116 117 bool StartSession(const std::string& user_email, 118 const std::string& unique_id /* unused */) { 119 // only pass unique_id through once we use it for something. 120 return chromeos::StartSession(user_email.c_str(), ""); 121 } 122 123 bool StopSession(const std::string& unique_id /* unused */) { 124 // only pass unique_id through once we use it for something. 125 return chromeos::StopSession(""); 126 } 127 128 bool RestartEntd() { 129 return chromeos::RestartEntd(); 130 } 131 132 bool RestartJob(int pid, const std::string& command_line) { 133 return chromeos::RestartJob(pid, command_line.c_str()); 134 } 135 136 private: 137 static void Handler(void* object, const OwnershipEvent& event) { 138 LoginLibraryImpl* self = static_cast<LoginLibraryImpl*>(object); 139 switch (event) { 140 case SetKeySuccess: 141 self->CompleteSetOwnerKey(true); 142 break; 143 case SetKeyFailure: 144 self->CompleteSetOwnerKey(false); 145 break; 146 case WhitelistOpSuccess: 147 self->CompleteWhitelistOp(true); 148 break; 149 case WhitelistOpFailure: 150 self->CompleteWhitelistOp(false); 151 break; 152 case PropertyOpSuccess: 153 self->CompletePropertyOp(true); 154 break; 155 case PropertyOpFailure: 156 self->CompletePropertyOp(false); 157 break; 158 default: 159 NOTREACHED(); 160 break; 161 } 162 } 163 164 void Init() { 165 session_connection_ = chromeos::MonitorSession(&Handler, this); 166 } 167 168 void CompleteSetOwnerKey(bool value) { 169 VLOG(1) << "Owner key generation: " << (value ? "success" : "fail"); 170 NotificationType result = 171 NotificationType::OWNER_KEY_FETCH_ATTEMPT_SUCCEEDED; 172 if (!value) 173 result = NotificationType::OWNER_KEY_FETCH_ATTEMPT_FAILED; 174 175 // Whether we exported the public key or not, send a notification indicating 176 // that we're done with this attempt. 177 NotificationService::current()->Notify(result, 178 NotificationService::AllSources(), 179 NotificationService::NoDetails()); 180 181 // We stored some settings in transient storage before owner was assigned. 182 // Now owner is assigned and key is generated and we should persist 183 // those settings into signed storage. 184 if (g_browser_process && g_browser_process->local_state()) { 185 SignedSettingsTempStorage::Finalize(g_browser_process->local_state()); 186 } 187 } 188 189 void CompleteWhitelistOp(bool result) { 190 if (whitelist_op_callback_) { 191 whitelist_op_callback_->OnComplete(result); 192 whitelist_op_callback_ = NULL; 193 } 194 } 195 196 void CompletePropertyOp(bool result) { 197 if (property_op_callback_) { 198 property_op_callback_->OnComplete(result); 199 property_op_callback_ = NULL; 200 } 201 } 202 203 chromeos::SessionConnection session_connection_; 204 205 Delegate* set_owner_key_callback_; 206 Delegate* whitelist_op_callback_; 207 Delegate* property_op_callback_; 208 209 DISALLOW_COPY_AND_ASSIGN(LoginLibraryImpl); 210}; 211 212class LoginLibraryStubImpl : public LoginLibrary { 213 public: 214 LoginLibraryStubImpl() {} 215 virtual ~LoginLibraryStubImpl() {} 216 217 bool EmitLoginPromptReady() { return true; } 218 bool CheckWhitelist(const std::string& email, 219 std::vector<uint8>* OUT_signature) { 220 OUT_signature->assign(2, 0); 221 return true; 222 } 223 bool RetrieveProperty(const std::string& name, 224 std::string* OUT_value, 225 std::vector<uint8>* OUT_signature) { 226 OUT_value->assign("stub"); 227 OUT_signature->assign(2, 0); 228 return true; 229 } 230 bool StorePropertyAsync(const std::string& name, 231 const std::string& value, 232 const std::vector<uint8>& signature, 233 Delegate* callback) { 234 BrowserThread::PostTask( 235 BrowserThread::UI, FROM_HERE, 236 NewRunnableFunction(&DoStubCallback, callback)); 237 return true; 238 } 239 bool UnwhitelistAsync(const std::string& email, 240 const std::vector<uint8>& signature, 241 Delegate* callback) { 242 BrowserThread::PostTask( 243 BrowserThread::UI, FROM_HERE, 244 NewRunnableFunction(&DoStubCallback, callback)); 245 return true; 246 } 247 bool WhitelistAsync(const std::string& email, 248 const std::vector<uint8>& signature, 249 Delegate* callback) { 250 BrowserThread::PostTask( 251 BrowserThread::UI, FROM_HERE, 252 NewRunnableFunction(&DoStubCallback, callback)); 253 return true; 254 } 255 bool EnumerateWhitelisted(std::vector<std::string>* whitelisted) { 256 return true; 257 } 258 bool StartSession(const std::string& user_email, 259 const std::string& unique_id /* unused */) { return true; } 260 bool StopSession(const std::string& unique_id /* unused */) { return true; } 261 bool RestartJob(int pid, const std::string& command_line) { return true; } 262 bool RestartEntd() { return true; } 263 264 private: 265 static void DoStubCallback(Delegate* callback) { 266 callback->OnComplete(true); 267 } 268 269 DISALLOW_COPY_AND_ASSIGN(LoginLibraryStubImpl); 270}; 271 272// static 273LoginLibrary* LoginLibrary::GetImpl(bool stub) { 274 if (stub) 275 return new LoginLibraryStubImpl(); 276 else 277 return new LoginLibraryImpl(); 278} 279 280} // namespace chromeos 281