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

#include <dbus/dbus.h>  // C dbus library header. Used in FilterMessage().
#include <stdint.h>

#include <algorithm>
#include <utility>
#include <vector>

#include <base/bind.h>
#include <base/callback.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/scoped_ptr.h>
#include <base/message_loop/message_loop.h>
#include <base/message_loop/message_loop_proxy.h>
#include <base/run_loop.h>
#include <base/strings/string_util.h>
#include <base/time/time.h>
#include <chromeos/dbus/service_constants.h>
#include <chromeos/switches/chrome_switches.h>
#include <dbus/bus.h>
#include <dbus/exported_object.h>
#include <dbus/message.h>
#include <dbus/object_proxy.h>
#include <dbus/scoped_dbus_error.h>

#include "login_manager/browser_job.h"
#include "login_manager/child_exit_handler.h"
#include "login_manager/dbus_signal_emitter.h"
#include "login_manager/key_generator.h"
#include "login_manager/liveness_checker_impl.h"
#include "login_manager/login_metrics.h"
#include "login_manager/nss_util.h"
#include "login_manager/session_manager_dbus_adaptor.h"
#include "login_manager/session_manager_impl.h"
#include "login_manager/system_utils.h"
#include "login_manager/upstart_signal_emitter.h"

namespace em = enterprise_management;
namespace login_manager {

namespace {

const int kSignals[] = {SIGTERM, SIGINT, SIGHUP};
const int kNumSignals = sizeof(kSignals) / sizeof(int);

// I need a do-nothing action for SIGALRM, or using alarm() will kill me.
void DoNothing(int signal) {
}

void FireAndForgetDBusMethodCall(dbus::ObjectProxy* proxy,
                                 const char* interface,
                                 const char* method) {
  dbus::MethodCall call(interface, method);
  proxy->CallMethod(&call,
                    dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
                    dbus::ObjectProxy::EmptyResponseCallback());
}

void FireAndBlockOnDBusMethodCall(dbus::ObjectProxy* proxy,
                                  const char* interface,
                                  const char* method) {
  dbus::MethodCall call(interface, method);
  proxy->CallMethodAndBlock(&call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT);
}

}  // anonymous namespace

// TODO(mkrebs): Remove CollectChrome timeout and file when
// crosbug.com/5872 is fixed.
// When crash-reporter based crash reporting of Chrome is enabled
// (which should only be during test runs) we use
// kKillTimeoutCollectChrome instead of the kill timeout specified at
// the command line.
const int SessionManagerService::kKillTimeoutCollectChrome = 60;
const char SessionManagerService::kCollectChromeFile[] =
    "/mnt/stateful_partition/etc/collect_chrome_crashes";

void SessionManagerService::TestApi::ScheduleChildExit(pid_t pid, int status) {
  siginfo_t info;
  info.si_pid = pid;
  if (WIFEXITED(status)) {
    info.si_code = CLD_EXITED;
    info.si_status = WEXITSTATUS(status);
  } else {
    info.si_status = WTERMSIG(status);
  }
  session_manager_service_->loop_proxy_->PostTask(
      FROM_HERE,
      base::Bind(
          &SessionManagerService::HandleExit, session_manager_service_, info));
}

SessionManagerService::SessionManagerService(
    scoped_ptr<BrowserJobInterface> child_job,
    const base::Closure& quit_closure,
    uid_t uid,
    int kill_timeout,
    bool enable_browser_abort_on_hang,
    base::TimeDelta hang_detection_interval,
    LoginMetrics* metrics,
    SystemUtils* utils)
    : browser_(child_job.Pass()),
      exit_on_child_done_(false),
      kill_timeout_(base::TimeDelta::FromSeconds(kill_timeout)),
      loop_proxy_(base::MessageLoopForIO::current()->message_loop_proxy()),
      quit_closure_(quit_closure),
      match_rule_(base::StringPrintf("type='method_call', interface='%s'",
                                     kSessionManagerInterface)),
      login_metrics_(metrics),
      system_(utils),
      nss_(NssUtil::Create()),
      key_gen_(uid, utils),
      state_key_generator_(utils, metrics),
      enable_browser_abort_on_hang_(enable_browser_abort_on_hang),
      liveness_checking_interval_(hang_detection_interval),
      shutting_down_(false),
      shutdown_already_(false),
      exit_code_(SUCCESS) {
  SetUpHandlers();
}

SessionManagerService::~SessionManagerService() {
  RevertHandlers();
}

bool SessionManagerService::Initialize() {
  LOG(INFO) << "SessionManagerService starting";
  InitializeDBus();

  dbus::ObjectProxy* chrome_dbus_proxy =
      bus_->GetObjectProxy(chromeos::kLibCrosServiceName,
                           dbus::ObjectPath(chromeos::kLibCrosServicePath));

  dbus::ObjectProxy* powerd_dbus_proxy = bus_->GetObjectProxy(
      power_manager::kPowerManagerServiceName,
      dbus::ObjectPath(power_manager::kPowerManagerServicePath));

  dbus::ObjectProxy* upstart_dbus_proxy =
      bus_->GetObjectProxy(UpstartSignalEmitter::kServiceName,
                           dbus::ObjectPath(UpstartSignalEmitter::kPath));

  liveness_checker_.reset(new LivenessCheckerImpl(this,
                                                  chrome_dbus_proxy,
                                                  loop_proxy_,
                                                  enable_browser_abort_on_hang_,
                                                  liveness_checking_interval_));

  // Initially store in derived-type pointer, so that we can initialize
  // appropriately below.
  scoped_ptr<UpstartSignalEmitter> upstart_emitter(
      new UpstartSignalEmitter(upstart_dbus_proxy));

  SessionManagerImpl* impl =
      new SessionManagerImpl(upstart_emitter.Pass(),
                             dbus_emitter_.get(),
                             base::Bind(&FireAndForgetDBusMethodCall,
                                        base::Unretained(chrome_dbus_proxy),
                                        chromeos::kLibCrosServiceInterface,
                                        chromeos::kLockScreen),
                             base::Bind(&FireAndBlockOnDBusMethodCall,
                                        base::Unretained(powerd_dbus_proxy),
                                        power_manager::kPowerManagerInterface,
                                        power_manager::kRequestRestartMethod),
                             &key_gen_,
                             &state_key_generator_,
                             this,
                             login_metrics_,
                             nss_.get(),
                             system_);

  adaptor_.reset(new SessionManagerDBusAdaptor(impl));
  impl_.reset(impl);
  if (!InitializeImpl())
    return false;

  // Set any flags that were specified system-wide.
  browser_->SetExtraArguments(impl_->GetStartUpFlags());

  adaptor_->ExportDBusMethods(session_manager_dbus_object_);
  TakeDBusServiceOwnership();
  return true;
}

void SessionManagerService::Finalize() {
  LOG(INFO) << "SessionManagerService exiting";
  impl_->Finalize();
  ShutDownDBus();
}

void SessionManagerService::ScheduleShutdown() {
  SetExitAndScheduleShutdown(SUCCESS);
}

void SessionManagerService::RunBrowser() {
  browser_->RunInBackground();
  DLOG(INFO) << "Browser is " << browser_->CurrentPid();
  liveness_checker_->Start();
}

void SessionManagerService::AbortBrowser(int signal,
                                         const std::string& message) {
  browser_->Kill(signal, message);
  browser_->WaitAndAbort(GetKillTimeout());
}

void SessionManagerService::RestartBrowserWithArgs(
    const std::vector<std::string>& args,
    bool args_are_extra) {
  // Waiting for Chrome to shutdown takes too much time.
  // We're killing it immediately hoping that data Chrome uses before
  // logging in is not corrupted.
  // TODO(avayvod): Remove RestartJob when crosbug.com/6924 is fixed.
  browser_->KillEverything(SIGKILL, "Restarting browser on-demand.");
  if (args_are_extra)
    browser_->SetExtraArguments(args);
  else
    browser_->SetArguments(args);
  // The browser will be restarted in HandleBrowserExit().
}

void SessionManagerService::SetBrowserSessionForUser(
    const std::string& username,
    const std::string& userhash) {
  browser_->StartSession(username, userhash);
}

void SessionManagerService::SetFlagsForUser(
    const std::string& username,
    const std::vector<std::string>& flags) {
  browser_->SetExtraArguments(flags);
}

bool SessionManagerService::IsBrowser(pid_t pid) {
  return (browser_ && browser_->CurrentPid() > 0 &&
          pid == browser_->CurrentPid());
}

bool SessionManagerService::IsManagedJob(pid_t pid) {
  return IsBrowser(pid);
}

void SessionManagerService::HandleExit(const siginfo_t& ignored) {
  LOG(INFO) << "Exiting process is " << browser_->GetName() << ".";

  // Clears up the whole job's process group.
  browser_->KillEverything(SIGKILL, "Ensuring browser processes are gone.");
  browser_->WaitAndAbort(GetKillTimeout());
  browser_->ClearPid();

  // Do nothing if already shutting down.
  if (shutting_down_)
    return;

  liveness_checker_->Stop();

  if (impl_->ShouldEndSession()) {
    LOG(ERROR) << "Choosing to end session rather than restart browser.";
    SetExitAndScheduleShutdown(CRASH_WHILE_RESTART_DISABLED);
    return;
  }

  DCHECK(browser_.get());
  if (browser_->ShouldStop()) {
    LOG(WARNING) << "Child stopped, shutting down";
    SetExitAndScheduleShutdown(CHILD_EXITING_TOO_FAST);
  } else if (browser_->ShouldRunBrowser()) {
    // TODO(cmasone): deal with fork failing in RunBrowser()
    RunBrowser();
  } else {
    LOG(INFO) << "Should NOT run " << browser_->GetName() << " again.";
    AllowGracefulExitOrRunForever();
  }
}

void SessionManagerService::RequestJobExit() {
  if (browser_ && browser_->CurrentPid() > 0)
    browser_->Kill(SIGTERM, "");
}

void SessionManagerService::EnsureJobExit(base::TimeDelta timeout) {
  if (browser_ && browser_->CurrentPid() > 0)
    browser_->WaitAndAbort(timeout);
}

DBusHandlerResult SessionManagerService::FilterMessage(DBusConnection* conn,
                                                       DBusMessage* message,
                                                       void* data) {
  SessionManagerService* service = static_cast<SessionManagerService*>(data);
  if (::dbus_message_is_method_call(
          message, kSessionManagerInterface, kSessionManagerRestartJob)) {
    const char* sender = ::dbus_message_get_sender(message);
    if (!sender) {
      LOG(ERROR) << "Call to RestartJob has no sender";
      return DBUS_HANDLER_RESULT_HANDLED;
    }
    LOG(INFO) << "Received RestartJob from " << sender;
    DBusMessage* get_pid =
        ::dbus_message_new_method_call("org.freedesktop.DBus",
                                       "/org/freedesktop/DBus",
                                       "org.freedesktop.DBus",
                                       "GetConnectionUnixProcessID");
    CHECK(get_pid);
    ::dbus_message_append_args(
        get_pid, DBUS_TYPE_STRING, &sender, DBUS_TYPE_INVALID);
    DBusMessage* got_pid =
        ::dbus_connection_send_with_reply_and_block(conn, get_pid, -1, NULL);
    ::dbus_message_unref(get_pid);
    if (!got_pid) {
      LOG(ERROR) << "Could not look up sender of RestartJob.";
      return DBUS_HANDLER_RESULT_HANDLED;
    }
    uint32_t pid;
    if (!::dbus_message_get_args(
            got_pid, NULL, DBUS_TYPE_UINT32, &pid, DBUS_TYPE_INVALID)) {
      ::dbus_message_unref(got_pid);
      LOG(ERROR) << "Could not extract pid of sender of RestartJob.";
      return DBUS_HANDLER_RESULT_HANDLED;
    }
    ::dbus_message_unref(got_pid);
    if (!service->IsBrowser(pid)) {
      LOG(WARNING) << "Sender of RestartJob is no child of mine!";
      DBusMessage* denial = dbus_message_new_error(message,
                                                   DBUS_ERROR_ACCESS_DENIED,
                                                   "Sender is not browser.");
      if (!denial || !::dbus_connection_send(conn, denial, NULL))
        LOG(ERROR) << "Could not create error response to RestartJob.";
      return DBUS_HANDLER_RESULT_HANDLED;
    }
  }
  return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}

void SessionManagerService::SetUpHandlers() {
  // I have to ignore SIGUSR1, because Xorg sends it to this process when it's
  // got no clients and is ready for new ones.  If we don't ignore it, we die.
  struct sigaction action;
  memset(&action, 0, sizeof(action));
  action.sa_handler = SIG_IGN;
  CHECK_EQ(sigaction(SIGUSR1, &action, NULL), 0);

  action.sa_handler = DoNothing;
  CHECK_EQ(sigaction(SIGALRM, &action, NULL), 0);

  std::vector<JobManagerInterface*> job_managers;
  job_managers.push_back(this);
  job_managers.push_back(&key_gen_);
  signal_handler_.Init();
  child_exit_handler_.Init(&signal_handler_, job_managers);
  for (int i = 0; i < kNumSignals; ++i) {
    signal_handler_.RegisterHandler(
        kSignals[i],
        base::Bind(&SessionManagerService::OnTerminationSignal,
                   base::Unretained(this)));
  }
}

void SessionManagerService::RevertHandlers() {
  struct sigaction action;
  memset(&action, 0, sizeof(action));
  action.sa_handler = SIG_DFL;
  CHECK_EQ(sigaction(SIGUSR1, &action, NULL), 0);
  CHECK_EQ(sigaction(SIGALRM, &action, NULL), 0);
}

base::TimeDelta SessionManagerService::GetKillTimeout() {
  if (base::PathExists(base::FilePath(kCollectChromeFile)))
    return base::TimeDelta::FromSeconds(kKillTimeoutCollectChrome);
  else
    return kill_timeout_;
}

bool SessionManagerService::InitializeImpl() {
  if (!impl_->Initialize()) {
    LOG(ERROR) << "Policy key is likely corrupt. Initiating device wipe.";
    impl_->InitiateDeviceWipe("bad_policy_key");
    impl_->Finalize();
    exit_code_ = MUST_WIPE_DEVICE;
    return false;
  }
  return true;
}

void SessionManagerService::InitializeDBus() {
  dbus::Bus::Options options;
  options.bus_type = dbus::Bus::SYSTEM;
  bus_ = new dbus::Bus(options);
  CHECK(bus_->Connect());
  CHECK(bus_->SetUpAsyncOperations());

  bus_->AddFilterFunction(&SessionManagerService::FilterMessage, this);
  dbus::ScopedDBusError error;
  bus_->AddMatch(match_rule_, error.get());
  CHECK(!error.is_set()) << "Failed to add match to bus: " << error.name()
                         << ", message="
                         << (error.message() ? error.message() : "unknown.");

  session_manager_dbus_object_ =
      bus_->GetExportedObject(dbus::ObjectPath(kSessionManagerServicePath));

  dbus_emitter_.reset(new DBusSignalEmitter(session_manager_dbus_object_,
                                            kSessionManagerInterface));
}

void SessionManagerService::TakeDBusServiceOwnership() {
  // Note that this needs to happen *after* all methods are exported
  // (http://crbug.com/331431).
  // This should pass dbus::Bus::REQUIRE_PRIMARY once on the new libchrome.
  CHECK(bus_->RequestOwnershipAndBlock(kSessionManagerServiceName,
                                       dbus::Bus::REQUIRE_PRIMARY))
      << "Unable to take ownership of " << kSessionManagerServiceName;
}

void SessionManagerService::ShutDownDBus() {
  dbus::ScopedDBusError error;
  bus_->RemoveMatch(match_rule_, error.get());
  if (error.is_set()) {
    LOG(ERROR) << "Failed to remove match from bus: " << error.name()
               << ", message="
               << (error.message() ? error.message() : "unknown.");
  }
  bus_->RemoveFilterFunction(&SessionManagerService::FilterMessage, this);
  bus_->ShutdownAndBlock();
}

void SessionManagerService::AllowGracefulExitOrRunForever() {
  if (exit_on_child_done_) {
    LOG(INFO) << "SessionManagerService set to exit on child done";
    loop_proxy_->PostTask(
        FROM_HERE,
        base::Bind(base::IgnoreResult(&SessionManagerService::ScheduleShutdown),
                   this));
  } else {
    DLOG(INFO) << "OK, running forever...";
  }
}

void SessionManagerService::SetExitAndScheduleShutdown(ExitCode code) {
  shutting_down_ = true;
  exit_code_ = code;
  impl_->AnnounceSessionStoppingIfNeeded();

  child_exit_handler_.Reset();
  liveness_checker_->Stop();
  CleanupChildren(GetKillTimeout());
  impl_->AnnounceSessionStopped();

  loop_proxy_->PostTask(FROM_HERE, quit_closure_);
  LOG(INFO) << "SessionManagerService quitting run loop";
}

void SessionManagerService::CleanupChildren(base::TimeDelta timeout) {
  RequestJobExit();
  key_gen_.RequestJobExit();
  EnsureJobExit(timeout);
  key_gen_.EnsureJobExit(timeout);
}

bool SessionManagerService::OnTerminationSignal(
    const struct signalfd_siginfo& info) {
  ScheduleShutdown();
  return true;
}

}  // namespace login_manager
