// 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 "cryptohome/dbus_service.h"

#include <cstdlib>
#include <string>

#include <base/at_exit.h>
#include <base/command_line.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/memory/ptr_util.h>
#include <base/strings/string_number_conversions.h>
#include <chaps/pkcs11/cryptoki.h>
#include <brillo/syslog_logging.h>
#include <openssl/evp.h>

#include "cryptohome/cleanup/disk_cleanup.h"
#include "cryptohome/crypto/scrypt.h"
#include "cryptohome/cryptohome_metrics.h"
#include "cryptohome/platform.h"
#include "cryptohome/userdataauth.h"

namespace switches {
static const char* kAttestationMode = "attestation_mode";
static const char* kDistributedModeOption = "dbus";
// Keeps std* open for debugging.
static const char* kNoCloseOnDaemonize = "noclose";
static const char* kNoLegacyMount = "nolegacymount";
static const char* kNoDownloadsBindMount = "no_downloads_bind_mount";
static const char* kDirEncryption = "direncryption";
static const char* kFscryptV2 = "fscrypt_v2";
static const char* kNoDaemonize = "nodaemonize";
static const char* kCleanupThreshold = "cleanup_threshold";
static const char* kAggressiveThreshold = "aggressive_cleanup_threshold";
static const char* kTargetFreeSpace = "target_free_space";

}  // namespace switches

uint64_t ReadCleanupThreshold(const base::CommandLine* cl,
                              const char* switch_name,
                              uint64_t default_value) {
  std::string value = cl->GetSwitchValueASCII(switch_name);

  if (value.size() == 0) {
    return default_value;
  }

  uint64_t parsed_value;
  if (!base::StringToUint64(value, &parsed_value)) {
    LOG(ERROR) << "Failed to parse " << switch_name << "; using defaults";
    return default_value;
  }

  return parsed_value;
}

int main(int argc, char** argv) {
  // Initialize command line configuration early, as logging will require
  // command line to be initialized
  base::CommandLine::Init(argc, argv);

  brillo::InitLog(brillo::kLogToSyslog | brillo::kLogToStderr);

  // Read the file before we daemonize so it can be deleted as soon as we exit.
  cryptohome::Platform platform;

  base::CommandLine* cl = base::CommandLine::ForCurrentProcess();
  // Validity check of attestation mode. Historically we had monolithic and
  // distributed mode, and now the monolithic mode has been obsoleted, so we
  // expect either the switch is missing or explicitly set to distributed mode.
  if (cl->HasSwitch(switches::kAttestationMode) &&
      cl->GetSwitchValueASCII(switches::kAttestationMode) !=
          switches::kDistributedModeOption) {
    LOG(FATAL) << "Unrecognized or obsoleted " << switches::kAttestationMode
               << " option: "
               << cl->GetSwitchValueASCII(switches::kAttestationMode);
  }
  int noclose = cl->HasSwitch(switches::kNoCloseOnDaemonize);
  bool nolegacymount = cl->HasSwitch(switches::kNoLegacyMount);
  bool nodownloadsbind = cl->HasSwitch(switches::kNoDownloadsBindMount);
  bool direncryption = cl->HasSwitch(switches::kDirEncryption);
  bool fscryptv2 = cl->HasSwitch(switches::kFscryptV2);
  bool daemonize = !cl->HasSwitch(switches::kNoDaemonize);
  uint64_t cleanup_threshold =
      ReadCleanupThreshold(cl, switches::kCleanupThreshold,
                           cryptohome::kFreeSpaceThresholdToTriggerCleanup);
  uint64_t aggressive_cleanup_threshold = ReadCleanupThreshold(
      cl, switches::kAggressiveThreshold,
      cryptohome::kFreeSpaceThresholdToTriggerAggressiveCleanup);
  uint64_t target_free_space = ReadCleanupThreshold(
      cl, switches::kTargetFreeSpace, cryptohome::kTargetFreeSpaceAfterCleanup);

  if (daemonize) {
    PLOG_IF(FATAL, daemon(0, noclose) == -1) << "Failed to daemonize";
  }

  // Initialize OpenSSL.
  OpenSSL_add_all_algorithms();

  // Initialize cryptohome metrics
  // Because mount thread may use metrics after main scope, don't
  // TearDownMetrics after main finished.
  cryptohome::InitializeMetrics();

  // Make sure scrypt parameters are correct.
  cryptohome::AssertProductionScryptParams();

  // Note that there's an AtExitManager in the constructor of
  // UserDataAuthDaemon
  cryptohome::UserDataAuthDaemon user_data_auth_daemon;

  // Set options on whether we are going to use legacy mount. See comments on
  // Mount::MountLegacyHome() for more information.
  user_data_auth_daemon.GetUserDataAuth()->set_legacy_mount(!nolegacymount);
  user_data_auth_daemon.GetUserDataAuth()->set_bind_mount_downloads(
      !nodownloadsbind);

  // Set options on whether we are going to use ext4 directory encryption or
  // eCryptfs.
  user_data_auth_daemon.GetUserDataAuth()->set_force_ecryptfs(!direncryption);
  user_data_auth_daemon.GetUserDataAuth()->set_fscrypt_v2(fscryptv2);

  // Set automatic cleanup thresholds.
  user_data_auth_daemon.GetUserDataAuth()->set_cleanup_threshold(
      cleanup_threshold);
  user_data_auth_daemon.GetUserDataAuth()->set_aggressive_cleanup_threshold(
      aggressive_cleanup_threshold);
  user_data_auth_daemon.GetUserDataAuth()->set_target_free_space(
      target_free_space);

  // Note the startup sequence is as following:
  // 1. UserDataAuthDaemon constructor => UserDataAuth constructor
  // 2. UserDataAuthDaemon::OnInit() (called by Daemon::Run())
  // 3. UserDataAuthDaemon::RegisterDBusObjectsAsync() (called by 2.)
  // 4. UserDataAuth::Initialize() (called by 3.)
  // 5. UserDataAuth::PostDBusInitialize() (called by 3.)
  // Daemon::OnInit() needs to be called before Initialize(), because
  // Initialize() create threads, and thus mess with Daemon's
  // AsynchronousSignalHandler.

  // Start UserDataAuth daemon if the option is selected
  user_data_auth_daemon.Run();

  // If PKCS #11 was initialized, this will tear it down.
  C_Finalize(NULL);

  return 0;
}
