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

#include <string>

#include <base/command_line.h>
#include <base/logging.h>
#include <base/memory/scoped_ptr.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 <chromeos/syslog_logging.h>
#include <dbus-c++/dbus.h>

#include "chaps/chaps_adaptor.h"
#include "chaps/chaps_factory_impl.h"
#include "chaps/chaps_service.h"
#include "chaps/chaps_service_redirect.h"
#include "chaps/chaps_utility.h"
#include "chaps/platform_globals.h"
#include "chaps/slot_manager_impl.h"
#include "chaps/tpm_utility_impl.h"

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

namespace chaps {

class AsyncInitThread : public PlatformThread::Delegate {
 public:
  AsyncInitThread(Lock* lock,
                  TPMUtilityImpl* tpm,
                  SlotManagerImpl* slot_manager,
                  ChapsServiceImpl* service)
      : started_event_(true, false),
        lock_(lock),
        tpm_(tpm),
        slot_manager_(slot_manager),
        service_(service) {}
  void ThreadMain() {
    // 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 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.";
    if (!service_->Init())
      LOG(FATAL) << "Service initialization failed.";
  }
  void WaitUntilStarted() {
    started_event_.Wait();
  }

 private:
  WaitableEvent started_event_;
  Lock* lock_;
  TPMUtilityImpl* tpm_;
  SlotManagerImpl* slot_manager_;
  ChapsServiceImpl* service_;
};

scoped_ptr<DBus::BusDispatcher> g_dispatcher;

void RunDispatcher(Lock* lock,
                   chaps::ChapsInterface* service,
                   chaps::TokenManagerInterface* token_manager) {
  CHECK(service) << "Failed to initialize service.";
  try {
    ChapsAdaptor adaptor(lock, service, token_manager);
    g_dispatcher->enter();
  } catch (DBus::Error err) {
    LOG(FATAL) << "DBus::Error - " << err.what();
  }
}

}  // namespace chaps

int main(int argc, char** argv) {
  CommandLine::Init(argc, argv);
  CommandLine* cl = CommandLine::ForCurrentProcess();
  chromeos::InitLog(chromeos::kLogToSyslog | chromeos::kLogToStderr);
  chaps::ScopedOpenSSL openssl;
  chaps::g_dispatcher.reset(new DBus::BusDispatcher());
  CHECK(chaps::g_dispatcher.get());
  DBus::default_dispatcher = chaps::g_dispatcher.get();
  Lock lock;
  if (!cl->HasSwitch("lib")) {
    // We're using chaps (i.e. not passing through to another PKCS #11 library).
    LOG(INFO) << "Starting PKCS #11 services.";
    // Run as 'chaps'.
    chaps::SetProcessUserAndGroup(chaps::kChapsdProcessUser,
                                  chaps::kChapsdProcessGroup,
                                  true);
    // 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.";
      }
    }
    chaps::TPMUtilityImpl tpm(srk_auth_data);
    chaps::ChapsFactoryImpl factory;
    chaps::SlotManagerImpl slot_manager(
        &factory, &tpm, cl->HasSwitch("auto_load_system_token"));
    chaps::ChapsServiceImpl service(&slot_manager);
    chaps::AsyncInitThread init_thread(&lock, &tpm, &slot_manager, &service);
    PlatformThreadHandle init_thread_handle;
    if (!PlatformThread::Create(0, &init_thread, &init_thread_handle))
      LOG(FATAL) << "Failed to create initialization thread.";
    // We don't want to start the dispatcher until the initialization thread has
    // had a chance to acquire the lock.
    init_thread.WaitUntilStarted();
    LOG(INFO) << "Starting D-Bus dispatcher.";
    RunDispatcher(&lock, &service, &slot_manager);
    PlatformThread::Join(init_thread_handle);
  } else {
    // We're passing through to another PKCS #11 library.
    string lib = cl->GetSwitchValueASCII("lib");
    LOG(INFO) << "Starting PKCS #11 services with " << lib << ".";
    chaps::ChapsServiceRedirect service(lib.c_str());
    if (!service.Init())
      LOG(FATAL) << "Failed to initialize PKCS #11 library: " << lib;
    RunDispatcher(&lock, &service, NULL);
  }

  return 0;
}
