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_SIGNED_SETTINGS_H_
6#define CHROME_BROWSER_CHROMEOS_LOGIN_SIGNED_SETTINGS_H_
7#pragma once
8
9#include <string>
10#include <vector>
11
12#include "base/memory/ref_counted.h"
13#include "chrome/browser/chromeos/login/owner_manager.h"
14
15// There are two categories of operations that can be performed on the
16// Chrome OS owner-signed settings store:
17// 1) doing stuff to the whitelist (adding/removing/checking)
18// 2) Storing/Retrieving arbitrary name=value pairs
19//
20// Unfortunately, it is currently a limitation that only one of each
21// category can be in-flight at a time.  You can be doing exactly one thing
22// to the whitelist, and exactly one thing to the property store at a time.
23// I've filed an issue on me to remove that restriction.
24// http://code.google.com/p/chromium-os/issues/detail?id=6415
25
26// The pattern of use here is that the caller instantiates some
27// subclass of SignedSettings by calling one of the create
28// methods. Then, call Execute() on this object from the UI
29// thread. It'll go off and do work (on the FILE thread and over DBus),
30// and then call the appropriate method of the Delegate you passed in
31// -- again, on the UI thread.
32
33namespace enterprise_management {
34class PolicyFetchResponse;
35class PolicyData;
36}  // namespace enterprise_management
37namespace em = enterprise_management;
38
39namespace chromeos {
40class OwnershipService;
41
42class SignedSettings : public base::RefCountedThreadSafe<SignedSettings>,
43                       public OwnerManager::Delegate {
44 public:
45  enum ReturnCode {
46    SUCCESS,
47    NOT_FOUND,         // Email address or property name not found.
48    KEY_UNAVAILABLE,   // Owner key not yet configured.
49    OPERATION_FAILED,  // IPC to signed settings daemon failed.
50    BAD_SIGNATURE      // Signature verification failed.
51  };
52
53  template <class T>
54  class Delegate {
55   public:
56    // This method will be called on the UI thread.
57    virtual void OnSettingsOpCompleted(ReturnCode code, T value) {}
58  };
59
60  SignedSettings();
61  virtual ~SignedSettings();
62
63  // These are both "whitelist" operations, and only one instance of
64  // one type can be in flight at a time.
65  static SignedSettings* CreateCheckWhitelistOp(
66      const std::string& email,
67      SignedSettings::Delegate<bool>* d);
68
69  static SignedSettings* CreateWhitelistOp(const std::string& email,
70                                           bool add_to_whitelist,
71                                           SignedSettings::Delegate<bool>* d);
72
73  // These are both "property" operations, and only one instance of
74  // one type can be in flight at a time.
75  static SignedSettings* CreateStorePropertyOp(
76      const std::string& name,
77      const std::string& value,
78      SignedSettings::Delegate<bool>* d);
79
80  static SignedSettings* CreateRetrievePropertyOp(
81      const std::string& name,
82      SignedSettings::Delegate<std::string>* d);
83
84  // These are both "policy" operations, and only one instance of
85  // one type can be in flight at a time.
86  static SignedSettings* CreateStorePolicyOp(
87      em::PolicyFetchResponse* policy,
88      SignedSettings::Delegate<bool>* d);
89
90  static SignedSettings* CreateRetrievePolicyOp(
91      SignedSettings::Delegate<const em::PolicyFetchResponse&>* d);
92
93  static bool EnumerateWhitelist(std::vector<std::string>* whitelisted);
94
95  static ReturnCode MapKeyOpCode(OwnerManager::KeyOpCode code);
96
97  virtual void Execute() = 0;
98
99  virtual void Fail(ReturnCode code) = 0;
100
101  // Implementation of OwnerManager::Delegate
102  void OnKeyOpComplete(const OwnerManager::KeyOpCode return_code,
103                       const std::vector<uint8>& payload) = 0;
104
105 protected:
106  static bool PolicyIsSane(const em::PolicyFetchResponse& value,
107                           em::PolicyData* poldata);
108
109  void set_service(OwnershipService* service) { service_ = service; }
110
111  void TryToFetchPolicyAndCallBack();
112
113  OwnershipService* service_;
114
115 private:
116  friend class SignedSettingsTest;
117  friend class SignedSettingsHelperTest;
118
119  class Relay
120      : public SignedSettings::Delegate<const em::PolicyFetchResponse&> {
121   public:
122    // |s| must outlive your Relay instance.
123    explicit Relay(SignedSettings* s);
124    virtual ~Relay();
125    // Implementation of SignedSettings::Delegate
126    virtual void OnSettingsOpCompleted(SignedSettings::ReturnCode code,
127                                       const em::PolicyFetchResponse& value);
128   private:
129    SignedSettings* settings_;
130    DISALLOW_COPY_AND_ASSIGN(Relay);
131  };
132
133  // Format of this string is documented in device_management_backend.proto.
134  static const char kDevicePolicyType[];
135
136  scoped_ptr<Relay> relay_;
137  scoped_refptr<SignedSettings> polfetcher_;
138  DISALLOW_COPY_AND_ASSIGN(SignedSettings);
139};
140
141}  // namespace chromeos
142
143#endif  // CHROME_BROWSER_CHROMEOS_LOGIN_SIGNED_SETTINGS_H_
144