// Copyright 2014 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 "debugd/src/dev_mode_no_owner_restriction.h"

#include <vector>

#include <chromeos/dbus/service_constants.h>
#include <google/protobuf/message_lite.h>

#include "debugd/src/process_with_output.h"

#include "rpc.pb.h"  // NOLINT(build/include)

namespace debugd {

namespace {

// Time in milliseconds to wait for a D-Bus response from cryptohome.
const int kDbusTimeoutMs = 5000;

const char kAccessDeniedErrorString[] =
    "org.chromium.debugd.error.AccessDenied";
const char kDevModeAccessErrorString[] =
    "Use of this tool is restricted to dev mode.";
const char kOwnerAccessErrorString[] =
    "Unavailable after device has an owner or boot lockbox is finalized.";
const char kOwnerQueryErrorString[] =
    "Error encountered when querying D-Bus, cryptohome may be busy.";

using cryptohome::BaseReply;
using cryptohome::GetLoginStatusRequest;
using cryptohome::GetLoginStatusReply;

// Queries the cryptohome GetLoginStatus D-Bus interface.
//
// Handles lower-level logic for dbus-c++ methods and the cryptohome protobuf
// classes. Cryptohome protobuf responses work by extending the BaseReply class,
// so if an error occurs it's possible to get a reply that does not contain the
// GetLoginStatusReply extension.
//
// |reply| will be filled if a response was received regardless of extension,
// but the function will only return true if reply is filled and has the
// correct GetLoginStatusReply extension.
bool CryptohomeGetLoginStatus(DBus::Connection* system_dbus, BaseReply* reply) {
  GetLoginStatusRequest request;
  DBus::CallMessage msg;
  std::vector<uint8_t> bytes(request.ByteSize(), 0);

  // Set up the message target and protobuf bytes to send.
  if (request.SerializeToArray(bytes.data(), bytes.size()) &&
      msg.destination(cryptohome::kCryptohomeServiceName) &&
      msg.path(cryptohome::kCryptohomeServicePath) &&
      msg.interface(cryptohome::kCryptohomeInterface) &&
      msg.member(cryptohome::kCryptohomeGetLoginStatus)) {
    try {
      DBus::MessageIter write_iter = msg.writer();
      write_iter << bytes;
      // Send the D-Bus message. This can return/throw an error on failure.
      DBus::Message response = system_dbus->send_blocking(msg, kDbusTimeoutMs);
      if (!response.is_error()) {
        const uint8_t* response_bytes;
        size_t response_size =
            response.reader().recurse().get_array(&response_bytes);
        // Return true only if we can parse the reply successfully and it
        // has the proper GetLoginStatusReply extension.
        return reply->ParseFromArray(response_bytes, response_size) &&
               reply->HasExtension(GetLoginStatusReply::reply);
      }
    } catch (...) {
    }
  }
  return false;
}

// Sets a DBus::Error message if the error is non-NULL and hasn't been set yet.
void SetErrorIfNotSet(DBus::Error* error, const char* message) {
  if (error && !error->is_set()) {
    error->set(kAccessDeniedErrorString, message);
  }
}

}  // namespace

DevModeNoOwnerRestriction::DevModeNoOwnerRestriction(
    DBus::Connection* system_dbus)
    : system_dbus_(system_dbus) {
}

bool DevModeNoOwnerRestriction::AllowToolUse(DBus::Error* error) {
  // Check dev mode first to avoid unnecessary cryptohome query delays.
  if (InDevMode()) {
    bool owner_exists, boot_lockbox_finalized;
    if (GetOwnerAndLockboxStatus(&owner_exists, &boot_lockbox_finalized)) {
      if (!(owner_exists || boot_lockbox_finalized)) {
        return true;
      }
      SetErrorIfNotSet(error, kOwnerAccessErrorString);
    }
    // We want to specifically indicate when the query failed  since it may
    // mean that cryptohome is busy and could be tried again later.
    SetErrorIfNotSet(error, kOwnerQueryErrorString);
  }
  SetErrorIfNotSet(error, kDevModeAccessErrorString);
  return false;
}

bool DevModeNoOwnerRestriction::InDevMode() const {
  // The is_developer_end_user script provides a common way to access this
  // information rather than duplicating logic here.
  return ProcessWithOutput::RunProcess("/usr/sbin/is_developer_end_user",
                                       ProcessWithOutput::ArgList{},
                                       true,  // needs root to run properly.
                                       nullptr,  // no stdin.
                                       nullptr,  // no stdout.
                                       nullptr,  // no stderr.
                                       nullptr) == 0;  // no D-Bus error.
}

// Checks for owner user and boot lockbox status.
//
// This function handles the high-level code of checking the cryptohome
// protocol buffer response. Lower-level details of sending the D-Bus function
// and parsing the protocol buffer are handled in CryptohomeGetLoginStatus().
//
// If cryptohome was queried successfully, returns true and |owner_user_exists|
// and |boot_lockbox_finalized| are updated.
bool DevModeNoOwnerRestriction::GetOwnerAndLockboxStatus(
    bool* owner_user_exists,
    bool* boot_lockbox_finalized) {
  BaseReply base_reply;
  if (CryptohomeGetLoginStatus(system_dbus_, &base_reply)) {
    GetLoginStatusReply reply =
        base_reply.GetExtension(GetLoginStatusReply::reply);
    if (reply.has_owner_user_exists() && reply.has_boot_lockbox_finalized()) {
      *owner_user_exists = reply.owner_user_exists();
      *boot_lockbox_finalized = reply.boot_lockbox_finalized();
      return true;
    }
  }
  return false;
}

}  // namespace debugd
