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#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_OWNERSHIP_SERVICE_H_
6#define CHROME_BROWSER_CHROMEOS_LOGIN_OWNERSHIP_SERVICE_H_
7#pragma once
8
9#include <string>
10#include <vector>
11
12#include "base/callback.h"
13#include "base/synchronization/lock.h"
14#include "chrome/browser/chromeos/login/owner_key_utils.h"
15#include "chrome/browser/chromeos/login/owner_manager.h"
16#include "chrome/browser/policy/proto/device_management_backend.pb.h"
17#include "content/browser/browser_thread.h"
18#include "content/common/notification_observer.h"
19#include "content/common/notification_registrar.h"
20#include "content/common/notification_service.h"
21
22namespace base {
23template <typename T> struct DefaultLazyInstanceTraits;
24}
25
26namespace em = enterprise_management;
27namespace chromeos {
28
29class OwnershipService : public NotificationObserver {
30 public:
31  enum Status {
32    // Listed in upgrade order.
33    OWNERSHIP_UNKNOWN = 0,
34    OWNERSHIP_NONE,
35    OWNERSHIP_TAKEN
36  };
37
38  // Returns the singleton instance of the OwnershipService.
39  static OwnershipService* GetSharedInstance();
40  virtual ~OwnershipService();
41
42  // Called after FILE thread is created to prefetch ownership status and avoid
43  // blocking on UI thread.
44  void Prewarm();
45
46  // Owner settings are being re-implemented as a single, signed protobuf
47  // that is stored by the session manager.  Thus, to write a setting, you
48  // need to have the existing policy, update it, re-sign it, and then have
49  // it stored.  This could be done by requesting the policy every time, or
50  // by caching it and updating it upon every successful store.
51  // Caching is faster and easier, so we'll do that.  These are the
52  // getters/setters for the cached policy.
53  virtual void set_cached_policy(const em::PolicyData& pol);
54  virtual bool has_cached_policy();
55  virtual const em::PolicyData& cached_policy();
56
57  // Sets a new owner key. This will _not_ load the key material from disk, but
58  // rather update Chrome's in-memory copy of the key. |callback| will be
59  // invoked once the operation completes.
60  virtual void StartUpdateOwnerKey(const std::vector<uint8>& new_key,
61                                   OwnerManager::KeyUpdateDelegate* d);
62
63  // If the device has been owned already, posts a task to the FILE thread to
64  // fetch the public key off disk.
65  //
66  // Sends out a OWNER_KEY_FETCH_ATTEMPT_SUCCESS notification on success,
67  // OWNER_KEY_FETCH_ATTEMPT_FAILED on failure.
68  virtual void StartLoadOwnerKeyAttempt();
69
70  // Initiate an attempt to sign |data| with |private_key_|.  Will call
71  // d->OnKeyOpComplete() when done.  Upon success, the signature will be passed
72  // as the |payload| argument to d->OnKeyOpComplete().
73  //
74  // If you call this on a well-known thread, you'll be called back on that
75  // thread.  Otherwise, you'll get called back on the UI thread.
76  virtual void StartSigningAttempt(const std::string& data,
77                                   OwnerManager::Delegate* d);
78
79  // Initiate an attempt to verify that |signature| is valid over |data| with
80  // |public_key_|.  When the attempt is completed, an appropriate KeyOpCode
81  // will be passed to d->OnKeyOpComplete().
82  //
83  // If you call this on a well-known thread, you'll be called back on that
84  // thread.  Otherwise, you'll get called back on the UI thread.
85  virtual void StartVerifyAttempt(const std::string& data,
86                                  const std::vector<uint8>& signature,
87                                  OwnerManager::Delegate* d);
88
89  // This method must be run on the FILE thread.
90  virtual bool CurrentUserIsOwner();
91
92  // This method should be run on FILE thread.
93  // Note: not static, for better mocking.
94  virtual bool IsAlreadyOwned();
95
96  // This method can be run either on FILE or UI threads.  If |blocking| flag
97  // is specified then it is guaranteed to return either OWNERSHIP_NONE or
98  // OWNERSHIP_TAKEN (and not OWNERSHIP_UNKNOWN), however in this case it may
99  // occasionally block doing i/o.
100  virtual Status GetStatus(bool blocking);
101
102 protected:
103  OwnershipService();
104
105  // NotificationObserver implementation.
106  virtual void Observe(NotificationType type,
107                       const NotificationSource& source,
108                       const NotificationDetails& details);
109
110 private:
111  friend struct base::DefaultLazyInstanceTraits<OwnershipService>;
112  friend class OwnershipServiceTest;
113
114  // Task posted on FILE thread on startup to prefetch ownership status.
115  void FetchStatus();
116
117  // Sets ownership status. May be called on either thread.
118  void SetStatus(Status new_status);
119
120  static void UpdateOwnerKey(OwnershipService* service,
121                             const BrowserThread::ID thread_id,
122                             const std::vector<uint8>& new_key,
123                             OwnerManager::KeyUpdateDelegate* d);
124  static void TryLoadOwnerKeyAttempt(OwnershipService* service);
125  static void TrySigningAttempt(OwnershipService* service,
126                                const BrowserThread::ID thread_id,
127                                const std::string& data,
128                                OwnerManager::Delegate* d);
129  static void TryVerifyAttempt(OwnershipService* service,
130                               const BrowserThread::ID thread_id,
131                               const std::string& data,
132                               const std::vector<uint8>& signature,
133                               OwnerManager::Delegate* d);
134  static void FailAttempt(OwnerManager::Delegate* d);
135
136  OwnerManager* manager() { return manager_.get(); }
137
138  scoped_refptr<OwnerManager> manager_;
139  scoped_refptr<OwnerKeyUtils> utils_;
140  scoped_ptr<em::PolicyData> policy_;
141  NotificationRegistrar notification_registrar_;
142  volatile Status ownership_status_;
143  base::Lock ownership_status_lock_;
144};
145
146}  // namespace chromeos
147
148#endif  // CHROME_BROWSER_CHROMEOS_LOGIN_OWNERSHIP_SERVICE_H_
149