// 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_DEVICE_POLICY_SERVICE_H_
#define LOGIN_MANAGER_DEVICE_POLICY_SERVICE_H_

#include <stdint.h>

#include <string>
#include <vector>

#include <dbus/dbus-glib-lowlevel.h>

#include <base/macros.h>
#include <base/memory/ref_counted.h>
#include <base/memory/scoped_ptr.h>
#include <crypto/scoped_nss_types.h>

#include "login_manager/owner_key_loss_mitigator.h"
#include "login_manager/policy_service.h"

namespace crypto {
class RSAPrivateKey;
}

namespace enterprise_management {
class PolicyFetchResponse;
class ChromeDeviceSettingsProto;
}

namespace login_manager {
class KeyGenerator;
class LoginMetrics;
class NssUtil;
class OwnerKeyLossMitigator;
// Forward declaration.
typedef struct PK11SlotInfoStr PK11SlotInfo;

// A policy service specifically for device policy, adding in a few helpers for
// generating a new key for the device owner, handling key loss mitigation,
// storing owner properties etc.
class DevicePolicyService : public PolicyService {
 public:
  virtual ~DevicePolicyService();

  // Instantiates a regular (non-testing) device policy service instance.
  static DevicePolicyService* Create(
      LoginMetrics* metrics,
      PolicyKey* owner_key,
      OwnerKeyLossMitigator* mitigator,
      NssUtil* nss,
      const scoped_refptr<base::MessageLoopProxy>& main_loop);

  // Checks whether the given |current_user| is the device owner. The result of
  // the check is returned in |is_owner|. If so, it is validated that the device
  // policy settings are set up appropriately:
  // - If |current_user| has the owner key, put her on the login white list.
  // - If policy claims |current_user| is the device owner but she doesn't
  //   appear to have the owner key, run key mitigation.
  // Returns true on success. Fills in |error| upon encountering an error.
  virtual bool CheckAndHandleOwnerLogin(const std::string& current_user,
                                        PK11SlotInfo* module,
                                        bool* is_owner,
                                        Error* error);

  // Ensures that the public key in |buf| is legitimately paired with a private
  // key held by the current user, signs and stores some ownership-related
  // metadata, and then stores this key off as the new device owner key. Returns
  // true if successful, false otherwise
  virtual bool ValidateAndStoreOwnerKey(const std::string& current_user,
                                        const std::string& buf,
                                        PK11SlotInfo* module);

  // Checks whether the key is missing.
  virtual bool KeyMissing();

  // Checks whether key loss is being mitigated.
  virtual bool Mitigating();

  // Loads policy key and policy blob from disk. Returns true if at least the
  // key can be loaded (policy may not be present yet, which is OK).
  virtual bool Initialize();

  // Given info about whether we were able to load the Owner key and the
  // device policy, report the state of these files via |metrics_|.
  virtual void ReportPolicyFileMetrics(bool key_success, bool policy_success);

  // Gets the value of the StartUpFlags policy as a vector of strings to be
  // supplied to Chrome when it is started.
  virtual std::vector<std::string> GetStartUpFlags();

  // Returns the currently active device settings.
  virtual const enterprise_management::ChromeDeviceSettingsProto& GetSettings();

  // PolicyService:
  bool Store(const uint8_t* policy_blob,
             uint32_t len,
             Completion* completion,
             int flags) override;

  static const char kPolicyPath[];
  static const char kSerialRecoveryFlagFile[];

  // Format of this string is documented in device_management_backend.proto.
  static const char kDevicePolicyType[];

  // These are defined in Chromium source at
  // chrome/browser/chromeos/policy/enterprise_install_attributes.cc.  Sadly,
  // the protobuf contains a trailing zero after kEnterpriseDeviceMode.
  static const char kAttrEnterpriseMode[];
  static const char kEnterpriseDeviceMode[];

 private:
  friend class DevicePolicyServiceTest;
  friend class MockDevicePolicyService;

  // Takes ownership of |policy_store| and |mitigator|.
  DevicePolicyService(const base::FilePath& serial_recovery_flag_file,
                      const base::FilePath& policy_file,
                      const base::FilePath& install_attributes_file,
                      scoped_ptr<PolicyStore> policy_store,
                      PolicyKey* owner_key,
                      const scoped_refptr<base::MessageLoopProxy>& main_loop,
                      LoginMetrics* metrics,
                      OwnerKeyLossMitigator* mitigator,
                      NssUtil* nss);

  // Returns true if |policy| allows arbitrary new users to sign in.
  // Only exposed for testing.
  static bool PolicyAllowsNewUsers(
      const enterprise_management::PolicyFetchResponse& policy);

  // Given the private half of the owner keypair, this call whitelists
  // |current_user| and sets a property indicating
  // |current_user| is the owner in the current policy and schedules a
  // PersistPolicy().
  // Returns false on failure, with |error| set appropriately. |error| can be
  // NULL, should you wish to ignore the particulars.
  bool StoreOwnerProperties(const std::string& current_user,
                            crypto::RSAPrivateKey* signing_key,
                            Error* error);

  // Checks the user's NSS database to see if she has the private key.
  // Returns a pointer to it if so.
  crypto::RSAPrivateKey* GetOwnerKeyForGivenUser(
      const std::vector<uint8_t>& key,
      PK11SlotInfo* module,
      Error* error);

  // Returns true if the |current_user| is listed in |policy_| as the
  // device owner.  Returns false if not, or if that cannot be determined.
  bool GivenUserIsOwner(const std::string& current_user);

  // Checks the serial number recovery flag and updates the flag file.
  // TODO(mnissler): Remove once bogus enterprise serials are fixed.
  void UpdateSerialNumberRecoveryFlagFile();

  const base::FilePath serial_recovery_flag_file_;
  const base::FilePath policy_file_;
  const base::FilePath install_attributes_file_;
  LoginMetrics* metrics_;
  OwnerKeyLossMitigator* mitigator_;
  NssUtil* nss_;

  // Cached copy of the decoded device settings. Decoding happens on first
  // access, the cache is cleared whenever a new policy gets installed via
  // Store().
  scoped_ptr<enterprise_management::ChromeDeviceSettingsProto> settings_;

  DISALLOW_COPY_AND_ASSIGN(DevicePolicyService);
};

}  // namespace login_manager

#endif  // LOGIN_MANAGER_DEVICE_POLICY_SERVICE_H_
