blob: 97eac7cda1d2b700248d16970bfff49507180390 [file] [log] [blame]
// Copyright (c) 2012 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/files/file_path.h>
#include <base/memory/ref_counted.h>
#include <base/memory/scoped_ptr.h>
#include <base/memory/weak_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 PolicyKey;
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:
// 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(const std::string& code, const std::string& message);
// Sets new error code and message.
void Set(const std::string& code, const std::string& message);
const std::string& code() const { return code_; }
const std::string& message() const { return message_; }
private:
std::string 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 ReportSuccess() = 0;
virtual void ReportFailure(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;
};
PolicyService(scoped_ptr<PolicyStore> policy_store,
PolicyKey* policy_key,
const scoped_refptr<base::MessageLoopProxy>& main_loop);
virtual ~PolicyService();
// 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(); }
PolicyKey* key() { return policy_key_; }
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);
// Completes a key storage operation on the UI thread, reporting the result to
// the delegate.
virtual void OnKeyPersisted(bool status);
private:
// Takes care of persisting the policy key to disk.
void PersistKeyOnLoop();
// Persists policy to disk on the main thread. If |completion| is non-NULL
// it will be signaled when done.
void PersistPolicyOnLoop(Completion* completion);
// Finishes persisting policy with |status|, notifying the delegate and
// reporting the status through |completion|.
void OnPolicyPersisted(Completion* completion, bool status);
private:
scoped_ptr<PolicyStore> policy_store_;
PolicyKey* policy_key_;
scoped_refptr<base::MessageLoopProxy> main_loop_;
Delegate* delegate_;
base::WeakPtrFactory<PolicyService> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(PolicyService);
};
} // namespace login_manager
#endif // LOGIN_MANAGER_POLICY_SERVICE_H_