blob: 2dd47c6b3aaa6e1a1ab2988ef1067a772f7344f6 [file] [log] [blame]
// Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef LOGIN_MANAGER_POLICY_SERVICE_H_
#define LOGIN_MANAGER_POLICY_SERVICE_H_
#include <string>
#include <vector>
#include <base/basictypes.h>
#include <base/file_path.h>
#include <base/memory/ref_counted.h>
#include <base/memory/scoped_ptr.h>
#include <chromeos/dbus/service_constants.h>
namespace enterprise_management {
class PolicyFetchResponse;
}
namespace base {
class MessageLoopProxy;
class WaitableEvent;
} // namespace base
namespace login_manager {
class OwnerKey;
class PolicyStore;
// Manages policy storage and retrieval from an underlying PolicyStore, thereby
// enforcing policy signatures against a given policy key. Also handles key
// rotations in case a new policy payload comes with an updated policy key.
class PolicyService : public base::RefCountedThreadSafe<PolicyService> {
public:
// Flags determining what do to with new keys in Store().
enum KeyInstallFlags {
KEY_ROTATE = 1, // Existing key may be rotated.
KEY_INSTALL_NEW = 2, // Allow to install a key if none is present.
KEY_CLOBBER = 4, // OK to replace the existing key without any checks.
};
// Wraps a policy service error with code and message.
class Error {
public:
Error();
Error(ChromeOSLoginError code, const std::string& message);
// Sets new error code and message.
void Set(ChromeOSLoginError code, const std::string& message);
ChromeOSLoginError code() const { return code_; }
const std::string& message() const { return message_; }
private:
ChromeOSLoginError code_;
std::string message_;
DISALLOW_COPY_AND_ASSIGN(Error);
};
// Callback interface for asynchronous completion of a Store operation.
class Completion {
public:
virtual ~Completion();
virtual void Success() = 0;
virtual void Failure(const Error& error) = 0;
};
// Delegate for notifications about key and policy getting persisted.
class Delegate {
public:
virtual ~Delegate();
virtual void OnPolicyPersisted(bool success) = 0;
virtual void OnKeyPersisted(bool success) = 0;
};
// Takes ownership of |policy_store| and |policy_key|.
PolicyService(PolicyStore* policy_store,
OwnerKey* policy_key,
const scoped_refptr<base::MessageLoopProxy>& main_loop,
const scoped_refptr<base::MessageLoopProxy>& io_loop);
virtual ~PolicyService();
// Reads policy key and data from disk.
virtual bool Initialize();
// Stores a new policy. Verifies the passed-in policy blob against the policy
// key if it exists, takes care of key rotation if required and persists
// everything to disk. The |flags| parameter determines what to do with a
// new key present in the policy. See KeyInstallFlags for possible values.
//
// Returns false on immediate errors. Otherwise, returns true and reports the
// status of the operation through |completion|.
virtual bool Store(const uint8* policy_blob,
uint32 len,
Completion* completion,
int flags);
// Retrieves the current policy blob. Returns true if successful, false
// otherwise.
virtual bool Retrieve(std::vector<uint8>* policy_blob);
// Policy is persisted to disk on the IO loop. The current thread waits for
// completion and reports back the status afterwards.
virtual bool PersistPolicySync();
// Accessors for the delegate. PolicyService doesn't own the delegate, thus
// client code must make sure that the delegate pointer stays valid.
void set_delegate(Delegate* delegate) { delegate_ = delegate; }
Delegate* delegate() { return delegate_; }
protected:
friend class PolicyServiceTest;
PolicyStore* store() { return policy_store_.get(); }
OwnerKey* key() { return policy_key_.get(); }
const scoped_refptr<base::MessageLoopProxy>& main_loop() {
return main_loop_;
}
// Schedules the key to be persisted.
void PersistKey();
// Schedules the policy to be persisted.
void PersistPolicy();
// Triggers persisting the policy to disk and reports the result to the given
// completion context.
void PersistPolicyWithCompletion(Completion* completion);
// Store a policy blob. This does the heavy lifting for Store(), making the
// signature checks, taking care of key changes and persisting policy and key
// data to disk.
bool StorePolicy(const enterprise_management::PolicyFetchResponse& policy,
Completion* completion,
int flags);
private:
// Takes care of persisting the policy key to disk.
void PersistKeyOnIOLoop();
// Persists policy to disk on the IO thread. If |completion| and |event|,
// respectively, are non-NULL, they will be signaled when done.
void PersistPolicyOnIOLoop(Completion* completion,
base::WaitableEvent* event);
// Completes a key storage operation on the UI thread, reporting the result to
// the delegate.
void OnKeyPersisted(bool status);
// Finishes persisting policy with |status|, notifying the delegate and
// reporting the status through |completion|.
void OnPolicyPersisted(Completion* completion, bool status);
// Takes care of inidicating asynchronous call completion on the UI thread.
// Calls completion->Success() or completion->Failure() depending on |status|,
// and sets the error code and message appropriately.
void CompleteCall(Completion* completion,
bool status,
ChromeOSLoginError code,
const std::string& msg);
private:
scoped_ptr<PolicyStore> policy_store_;
scoped_ptr<OwnerKey> policy_key_;
scoped_refptr<base::MessageLoopProxy> main_loop_;
scoped_refptr<base::MessageLoopProxy> io_loop_;
Delegate* delegate_;
DISALLOW_COPY_AND_ASSIGN(PolicyService);
};
} // namespace login_manager
#endif // LOGIN_MANAGER_POLICY_SERVICE_H_