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