// Copyright (c) 2011 The Chromium 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 CHROME_BROWSER_CHROMEOS_LOGIN_OWNERSHIP_SERVICE_H_ #define CHROME_BROWSER_CHROMEOS_LOGIN_OWNERSHIP_SERVICE_H_ #pragma once #include <string> #include <vector> #include "base/callback.h" #include "base/synchronization/lock.h" #include "chrome/browser/chromeos/login/owner_key_utils.h" #include "chrome/browser/chromeos/login/owner_manager.h" #include "chrome/browser/policy/proto/device_management_backend.pb.h" #include "content/browser/browser_thread.h" #include "content/common/notification_observer.h" #include "content/common/notification_registrar.h" #include "content/common/notification_service.h" namespace base { template <typename T> struct DefaultLazyInstanceTraits; } namespace em = enterprise_management; namespace chromeos { class OwnershipService : public NotificationObserver { public: enum Status { // Listed in upgrade order. OWNERSHIP_UNKNOWN = 0, OWNERSHIP_NONE, OWNERSHIP_TAKEN }; // Returns the singleton instance of the OwnershipService. static OwnershipService* GetSharedInstance(); virtual ~OwnershipService(); // Called after FILE thread is created to prefetch ownership status and avoid // blocking on UI thread. void Prewarm(); // Owner settings are being re-implemented as a single, signed protobuf // that is stored by the session manager. Thus, to write a setting, you // need to have the existing policy, update it, re-sign it, and then have // it stored. This could be done by requesting the policy every time, or // by caching it and updating it upon every successful store. // Caching is faster and easier, so we'll do that. These are the // getters/setters for the cached policy. virtual void set_cached_policy(const em::PolicyData& pol); virtual bool has_cached_policy(); virtual const em::PolicyData& cached_policy(); // Sets a new owner key. This will _not_ load the key material from disk, but // rather update Chrome's in-memory copy of the key. |callback| will be // invoked once the operation completes. virtual void StartUpdateOwnerKey(const std::vector<uint8>& new_key, OwnerManager::KeyUpdateDelegate* d); // If the device has been owned already, posts a task to the FILE thread to // fetch the public key off disk. // // Sends out a OWNER_KEY_FETCH_ATTEMPT_SUCCESS notification on success, // OWNER_KEY_FETCH_ATTEMPT_FAILED on failure. virtual void StartLoadOwnerKeyAttempt(); // Initiate an attempt to sign |data| with |private_key_|. Will call // d->OnKeyOpComplete() when done. Upon success, the signature will be passed // as the |payload| argument to d->OnKeyOpComplete(). // // If you call this on a well-known thread, you'll be called back on that // thread. Otherwise, you'll get called back on the UI thread. virtual void StartSigningAttempt(const std::string& data, OwnerManager::Delegate* d); // Initiate an attempt to verify that |signature| is valid over |data| with // |public_key_|. When the attempt is completed, an appropriate KeyOpCode // will be passed to d->OnKeyOpComplete(). // // If you call this on a well-known thread, you'll be called back on that // thread. Otherwise, you'll get called back on the UI thread. virtual void StartVerifyAttempt(const std::string& data, const std::vector<uint8>& signature, OwnerManager::Delegate* d); // This method must be run on the FILE thread. virtual bool CurrentUserIsOwner(); // This method should be run on FILE thread. // Note: not static, for better mocking. virtual bool IsAlreadyOwned(); // This method can be run either on FILE or UI threads. If |blocking| flag // is specified then it is guaranteed to return either OWNERSHIP_NONE or // OWNERSHIP_TAKEN (and not OWNERSHIP_UNKNOWN), however in this case it may // occasionally block doing i/o. virtual Status GetStatus(bool blocking); protected: OwnershipService(); // NotificationObserver implementation. virtual void Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details); private: friend struct base::DefaultLazyInstanceTraits<OwnershipService>; friend class OwnershipServiceTest; // Task posted on FILE thread on startup to prefetch ownership status. void FetchStatus(); // Sets ownership status. May be called on either thread. void SetStatus(Status new_status); static void UpdateOwnerKey(OwnershipService* service, const BrowserThread::ID thread_id, const std::vector<uint8>& new_key, OwnerManager::KeyUpdateDelegate* d); static void TryLoadOwnerKeyAttempt(OwnershipService* service); static void TrySigningAttempt(OwnershipService* service, const BrowserThread::ID thread_id, const std::string& data, OwnerManager::Delegate* d); static void TryVerifyAttempt(OwnershipService* service, const BrowserThread::ID thread_id, const std::string& data, const std::vector<uint8>& signature, OwnerManager::Delegate* d); static void FailAttempt(OwnerManager::Delegate* d); OwnerManager* manager() { return manager_.get(); } scoped_refptr<OwnerManager> manager_; scoped_refptr<OwnerKeyUtils> utils_; scoped_ptr<em::PolicyData> policy_; NotificationRegistrar notification_registrar_; volatile Status ownership_status_; base::Lock ownership_status_lock_; }; } // namespace chromeos #endif // CHROME_BROWSER_CHROMEOS_LOGIN_OWNERSHIP_SERVICE_H_