// 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.

#include "login_manager/user_policy_service.h"

#include <stdint.h>
#include <sys/stat.h>

#include <string>
#include <utility>
#include <vector>

#include <base/files/file_util.h>
#include <base/logging.h>

#include "bindings/device_management_backend.pb.h"
#include "login_manager/dbus_error_types.h"
#include "login_manager/policy_key.h"
#include "login_manager/policy_store.h"
#include "login_manager/system_utils.h"

namespace em = enterprise_management;

namespace login_manager {

UserPolicyService::UserPolicyService(
    std::unique_ptr<PolicyStore> policy_store,
    std::unique_ptr<PolicyKey> policy_key,
    const base::FilePath& key_copy_path,
    SystemUtils* system_utils)
    : PolicyService(std::move(policy_store), policy_key.get()),
      scoped_policy_key_(std::move(policy_key)),
      key_copy_path_(key_copy_path),
      system_utils_(system_utils) {
}

UserPolicyService::~UserPolicyService() {
}

void UserPolicyService::PersistKeyCopy() {
  // Create a copy at |key_copy_path_| that is readable by chronos.
  if (key_copy_path_.empty())
    return;
  if (scoped_policy_key_->IsPopulated()) {
    base::FilePath dir(key_copy_path_.DirName());
    base::CreateDirectory(dir);
    mode_t mode = S_IRWXU | S_IXGRP | S_IXOTH;
    chmod(dir.value().c_str(), mode);

    const std::vector<uint8_t>& key = scoped_policy_key_->public_key_der();
    system_utils_->AtomicFileWrite(key_copy_path_,
                                   std::string(key.begin(), key.end()));
    mode = S_IRUSR | S_IRGRP | S_IROTH;
    chmod(key_copy_path_.value().c_str(), mode);
  } else {
    // Remove the key if it has been cleared.
    system_utils_->RemoveFile(key_copy_path_);
  }
}

bool UserPolicyService::Store(const uint8_t* policy_blob,
                              uint32_t len,
                              const Completion& completion,
                              int key_flags,
                              SignatureCheck signature_check) {
  em::PolicyFetchResponse policy;
  em::PolicyData policy_data;
  if (!policy.ParseFromArray(policy_blob, len) || !policy.has_policy_data() ||
      !policy_data.ParseFromString(policy.policy_data())) {
    static const char msg[] = "Unable to parse policy protobuf.";
    LOG(ERROR) << msg;
    Error error(dbus_error::kSigDecodeFail, msg);
    completion.Run(error);
    return false;
  }

  // Allow to switch to unmanaged state even if no signature is present.
  if (policy_data.state() == em::PolicyData::UNMANAGED &&
      !policy.has_policy_data_signature()) {
    // Also clear the key.
    if (key()->IsPopulated()) {
      key()->ClobberCompromisedKey(std::vector<uint8_t>());
      PersistKey();
    }

    store()->Set(policy);
    PersistPolicyWithCompletion(completion);
    return true;
  }

  return PolicyService::StorePolicy(policy, completion, key_flags,
                                    signature_check);
}

void UserPolicyService::OnKeyPersisted(bool status) {
  if (status)
    PersistKeyCopy();
  // Only notify the delegate after writing the copy, so that chrome can find
  // the file after being notified that the key is ready.
  PolicyService::OnKeyPersisted(status);
}

}  // namespace login_manager
