trunksd.cc revision 7e763a9434e12c7980529980de5f8eced22b310a
1//
2// Copyright (C) 2014 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//      http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17#include <sysexits.h>
18
19#include <base/at_exit.h>
20#include <base/bind.h>
21#include <base/command_line.h>
22#include <base/threading/thread.h>
23#include <brillo/daemons/dbus_daemon.h>
24#include <brillo/minijail/minijail.h>
25#include <brillo/syslog_logging.h>
26#include <brillo/userdb_utils.h>
27
28#include "trunks/background_command_transceiver.h"
29#include "trunks/dbus_interface.h"
30#include "trunks/resource_manager.h"
31#include "trunks/tpm_handle.h"
32#include "trunks/tpm_simulator_handle.h"
33#include "trunks/trunks_factory_impl.h"
34#include "trunks/trunks_ftdi_spi.h"
35#include "trunks/trunks_service.h"
36
37using brillo::dbus_utils::AsyncEventSequencer;
38
39namespace {
40
41const uid_t kRootUID = 0;
42const char kTrunksUser[] = "trunks";
43const char kTrunksGroup[] = "trunks";
44const char kTrunksSeccompPath[] = "/usr/share/policy/trunksd-seccomp.policy";
45const char kBackgroundThreadName[] = "trunksd_background_thread";
46
47void InitMinijailSandbox() {
48  uid_t trunks_uid;
49  gid_t trunks_gid;
50  CHECK(brillo::userdb::GetUserInfo(kTrunksUser, &trunks_uid, &trunks_gid))
51      << "Error getting trunks uid and gid.";
52  CHECK_EQ(getuid(), kRootUID) << "Trunks Daemon not initialized as root.";
53  brillo::Minijail* minijail = brillo::Minijail::GetInstance();
54  struct minijail* jail = minijail->New();
55  minijail->DropRoot(jail, kTrunksUser, kTrunksGroup);
56  minijail->UseSeccompFilter(jail, kTrunksSeccompPath);
57  minijail->Enter(jail);
58  minijail->Destroy(jail);
59  CHECK_EQ(getuid(), trunks_uid)
60      << "TrunksDaemon was not able to drop to trunks user.";
61  CHECK_EQ(getgid(), trunks_gid)
62      << "TrunksDaemon was not able to drop to trunks group.";
63}
64
65}  // namespace
66
67class TrunksDaemon : public brillo::DBusServiceDaemon {
68 public:
69  explicit TrunksDaemon(trunks::CommandTransceiver* transceiver) :
70      brillo::DBusServiceDaemon(trunks::kTrunksServiceName) {
71    transceiver_.reset(transceiver);
72    background_thread_.reset(new base::Thread(kBackgroundThreadName));
73    CHECK(background_thread_->Start());
74    // Chain together command transceivers:
75    //   [IPC] --> TrunksService --> BackgroundCommandTransceiver -->
76    //       ResourceManager --> TpmHandle --> [TPM]
77    factory_.reset(new trunks::TrunksFactoryImpl(transceiver_.get()));
78    resource_manager_.reset(new trunks::ResourceManager(
79        *factory_,
80        transceiver_.get()));
81    background_thread_->task_runner()->PostNonNestableTask(
82        FROM_HERE,
83        base::Bind(&trunks::ResourceManager::Initialize,
84        base::Unretained(resource_manager_.get())));
85    background_transceiver_.reset(
86        new trunks::BackgroundCommandTransceiver(
87            resource_manager_.get(),
88            background_thread_->task_runner()));
89  }
90
91 protected:
92  void RegisterDBusObjectsAsync(AsyncEventSequencer* sequencer) override {
93    trunks_service_.reset(new trunks::TrunksService(
94        bus_,
95        background_transceiver_.get()));
96    trunks_service_->Register(
97        sequencer->GetHandler("Register() failed.", true));
98  }
99
100
101 private:
102  std::unique_ptr<trunks::TrunksService> trunks_service_;
103  std::unique_ptr<trunks::CommandTransceiver> transceiver_;
104  // Thread for executing TPM comands.
105  std::unique_ptr<base::Thread> background_thread_;
106  std::unique_ptr<trunks::TrunksFactory> factory_;
107  std::unique_ptr<trunks::ResourceManager> resource_manager_;
108  std::unique_ptr<trunks::CommandTransceiver> background_transceiver_;
109
110  DISALLOW_COPY_AND_ASSIGN(TrunksDaemon);
111};
112
113int main(int argc, char **argv) {
114  base::CommandLine::Init(argc, argv);
115  base::CommandLine *cl = base::CommandLine::ForCurrentProcess();
116  int flags = brillo::kLogToSyslog;
117  if (cl->HasSwitch("log_to_stderr")) {
118    flags |= brillo::kLogToStderr;
119  }
120  brillo::InitLog(flags);
121  trunks::CommandTransceiver *transceiver;
122  if (cl->HasSwitch("ftdi")) {
123    transceiver = new trunks::TrunksFtdiSpi();
124  } else if (cl->HasSwitch("simulator")) {
125    transceiver = new trunks::TpmSimulatorHandle();
126  } else {
127    transceiver = new trunks::TpmHandle();
128  }
129  CHECK(transceiver->Init()) << "Error initializing transceiver";
130  TrunksDaemon daemon(transceiver);
131  InitMinijailSandbox();
132  LOG(INFO) << "Trunks Service Started";
133  return daemon.Run();
134}
135