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

// This is the Chaps daemon. It handles calls from multiple processes via D-Bus.
//

#include <grp.h>
#include <pwd.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <memory>
#include <string>

#include <base/command_line.h>
#include <base/location.h>
#include <base/logging.h>
#include <base/memory/ptr_util.h>
#include <base/strings/string_number_conversions.h>
#include <base/synchronization/lock.h>
#include <base/synchronization/waitable_event.h>
#include <base/threading/platform_thread.h>
#include <base/threading/thread.h>
#include <brillo/daemons/dbus_daemon.h>
#include <brillo/syslog_logging.h>
#include <libminijail.h>
#include <scoped_minijail.h>

#include "chaps/chaps_adaptor.h"
#include "chaps/chaps_factory_impl.h"
#include "chaps/chaps_service.h"
#include "chaps/chaps_utility.h"
#include "chaps/dbus_bindings/constants.h"
#include "chaps/platform_globals.h"
#include "chaps/slot_manager_impl.h"

#if USE_TPM2
#include "chaps/tpm2_utility_impl.h"
#else
#include "chaps/tpm_utility_impl.h"
#endif

using base::AutoLock;
using base::Lock;
using base::PlatformThread;
using base::PlatformThreadHandle;
using base::WaitableEvent;
using std::string;

namespace {

const char kTpmThreadName[] = "tpm_background_thread";
const char kInitThreadName[] = "async_init_thread";

void MaskSignals() {
  sigset_t signal_mask;
  CHECK_EQ(0, sigemptyset(&signal_mask));
  for (int signal : {SIGTERM, SIGINT, SIGHUP}) {
    CHECK_EQ(0, sigaddset(&signal_mask, signal));
  }
  CHECK_EQ(0, sigprocmask(SIG_BLOCK, &signal_mask, nullptr));
}

void InitAsync(WaitableEvent* started_event,
               Lock* lock,
               chaps::TPMUtility* tpm,
               chaps::SlotManagerImpl* slot_manager) {
  // It's important that we acquire 'lock' before signaling 'started_event'.
  // This will prevent any D-Bus requests from being processed until we've
  // finished initialization.
  AutoLock auto_lock(*lock);
  started_event->Signal();
  LOG(INFO) << "Starting asynchronous initialization.";
  if (!tpm->Init())
    // Just warn and continue in this case.  The effect will be a functional
    // daemon which handles dbus requests but any attempt to load a token will
    // fail.  To a PKCS #11 client this will look like a library with a few
    // empty slots.
    LOG(WARNING) << "TPM initialization failed (this is expected if no TPM is"
                 << " available).  PKCS #11 tokens will not be available.";
  if (!slot_manager->Init())
    LOG(FATAL) << "Slot initialization failed.";
}

void SetProcessUserAndGroup(const char* user_name,
                            const char* group_name) {
  // Make the umask more restrictive: u + rwx, g + rx.
  umask(0027);

  ScopedMinijail j(minijail_new());
  minijail_change_user(j.get(), user_name);
  minijail_change_group(j.get(), group_name);
  minijail_inherit_usergroups(j.get());
  minijail_no_new_privs(j.get());
  minijail_enter(j.get());
}

}  // namespace

namespace chaps {

class Daemon : public brillo::DBusServiceDaemon {
 public:
  Daemon(const std::string& srk_auth_data, bool auto_load_system_token)
      : DBusServiceDaemon(kChapsServiceName),
        srk_auth_data_(srk_auth_data),
        auto_load_system_token_(auto_load_system_token),
        tpm_background_thread_(kTpmThreadName),
        async_init_thread_(kInitThreadName) {}

 protected:
  int OnInit() override {
#if USE_TPM2
    CHECK(tpm_background_thread_.StartWithOptions(
        base::Thread::Options(base::MessageLoop::TYPE_IO,
                              0 /* use default stack size */)));
    tpm_.reset(new TPM2UtilityImpl(tpm_background_thread_.task_runner()));
#else
    // Instantiate a TPM1.2 Utility.
    tpm_.reset(new TPMUtilityImpl(srk_auth_data_));
#endif

    factory_.reset(new ChapsFactoryImpl);
    slot_manager_.reset(new SlotManagerImpl(
        factory_.get(), tpm_.get(), auto_load_system_token_));
    service_.reset(new ChapsServiceImpl(slot_manager_.get()));

    // Initialize the TPM utility and slot manager asynchronously because
    // we might be able to serve some requests while they are being
    // initialized.
    WaitableEvent init_started(WaitableEvent::ResetPolicy::MANUAL,
                               WaitableEvent::InitialState::NOT_SIGNALED);
    CHECK(async_init_thread_.StartWithOptions(
        base::Thread::Options(base::MessageLoop::TYPE_IO,
                              0 /* use default stack size */)));
    async_init_thread_.task_runner()->PostTask(
        FROM_HERE,
        base::Bind(&InitAsync,
                   &init_started, &lock_, tpm_.get(), slot_manager_.get()));
    // We're not finished with initialization until the initialization thread
    // has had a chance to acquire the lock.
    init_started.Wait();
    // Now we can export D-Bus objects.
    return DBusServiceDaemon::OnInit();
  }

  void RegisterDBusObjectsAsync(
      brillo::dbus_utils::AsyncEventSequencer* sequencer) override {
    adaptor_.reset(
        new ChapsAdaptor(bus_, &lock_, service_.get(), slot_manager_.get()));
    adaptor_->RegisterAsync(
        sequencer->GetHandler("RegisterAsync() failed", true));
  }

 private:
  std::string srk_auth_data_;
  bool auto_load_system_token_;
  base::Thread tpm_background_thread_;
  base::Thread async_init_thread_;
  Lock lock_;

  std::unique_ptr<TPMUtility> tpm_;
  std::unique_ptr<ChapsFactory> factory_;
  std::unique_ptr<SlotManagerImpl> slot_manager_;
  std::unique_ptr<ChapsInterface> service_;
  std::unique_ptr<ChapsAdaptor> adaptor_;

  DISALLOW_COPY_AND_ASSIGN(Daemon);
};

}  // namespace chaps

int main(int argc, char** argv) {
  base::CommandLine::Init(argc, argv);
  base::CommandLine* cl = base::CommandLine::ForCurrentProcess();
  brillo::InitLog(brillo::kLogToSyslog | brillo::kLogToStderr);
  chaps::ScopedOpenSSL openssl;

  LOG(INFO) << "Starting PKCS #11 services.";
  // Run as 'chaps'.
  SetProcessUserAndGroup(chaps::kChapsdProcessUser, chaps::kChapsdProcessGroup);
  // Determine SRK authorization data from the command line.
  string srk_auth_data;
  if (cl->HasSwitch("srk_password")) {
    srk_auth_data = cl->GetSwitchValueASCII("srk_password");
  } else if (cl->HasSwitch("srk_zeros")) {
    int zero_count = 0;
    if (base::StringToInt(cl->GetSwitchValueASCII("srk_zeros"),
                          &zero_count)) {
      srk_auth_data = string(zero_count, 0);
    } else {
      LOG(WARNING) << "Invalid value for srk_zeros: using empty string.";
    }
  }
  bool auto_load_system_token = cl->HasSwitch("auto_load_system_token");
  // Mask signals handled by the daemon thread. This makes sure we
  // won't handle shutdown signals on one of the other threads spawned
  // below.
  MaskSignals();
  LOG(INFO) << "Starting D-Bus dispatcher.";
  chaps::Daemon(srk_auth_data, auto_load_system_token).Run();
  return 0;
}
