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/minijail/minijail.h>
24 #include <brillo/syslog_logging.h>
25 #include <brillo/userdb_utils.h>
26
27 #include "trunks/background_command_transceiver.h"
28 #include "trunks/resource_manager.h"
29 #include "trunks/tpm_handle.h"
30 #include "trunks/tpm_simulator_handle.h"
31 #if defined(USE_BINDER_IPC)
32 #include "trunks/trunks_binder_service.h"
33 #else
34 #include "trunks/trunks_dbus_service.h"
35 #endif
36 #include "trunks/trunks_factory_impl.h"
37 #include "trunks/trunks_ftdi_spi.h"
38
39 namespace {
40
41 const uid_t kRootUID = 0;
42 const char kTrunksUser[] = "trunks";
43 const char kTrunksGroup[] = "trunks";
44 #if defined(__ANDROID__)
45 const char kTrunksSeccompPath[] =
46 "/system/usr/share/policy/trunksd-seccomp.policy";
47 #else
48 const char kTrunksSeccompPath[] = "/usr/share/policy/trunksd-seccomp.policy";
49 #endif
50 const char kBackgroundThreadName[] = "trunksd_background_thread";
51
InitMinijailSandbox()52 void InitMinijailSandbox() {
53 uid_t trunks_uid;
54 gid_t trunks_gid;
55 CHECK(brillo::userdb::GetUserInfo(kTrunksUser, &trunks_uid, &trunks_gid))
56 << "Error getting trunks uid and gid.";
57 CHECK_EQ(getuid(), kRootUID) << "trunksd not initialized as root.";
58 brillo::Minijail* minijail = brillo::Minijail::GetInstance();
59 struct minijail* jail = minijail->New();
60 minijail->DropRoot(jail, kTrunksUser, kTrunksGroup);
61 minijail->UseSeccompFilter(jail, kTrunksSeccompPath);
62 minijail->Enter(jail);
63 minijail->Destroy(jail);
64 CHECK_EQ(getuid(), trunks_uid)
65 << "trunksd was not able to drop user privilege.";
66 CHECK_EQ(getgid(), trunks_gid)
67 << "trunksd was not able to drop group privilege.";
68 }
69
70 } // namespace
71
main(int argc,char ** argv)72 int main(int argc, char** argv) {
73 base::CommandLine::Init(argc, argv);
74 base::CommandLine* cl = base::CommandLine::ForCurrentProcess();
75 int flags = brillo::kLogToSyslog;
76 if (cl->HasSwitch("log_to_stderr")) {
77 flags |= brillo::kLogToStderr;
78 }
79 brillo::InitLog(flags);
80
81 // Create a service instance before anything else so objects like
82 // AtExitManager exist.
83 #if defined(USE_BINDER_IPC)
84 trunks::TrunksBinderService service;
85 #else
86 trunks::TrunksDBusService service;
87 #endif
88
89 // Chain together command transceivers:
90 // [IPC] --> BackgroundCommandTransceiver
91 // --> ResourceManager
92 // --> TpmHandle
93 // --> [TPM]
94 trunks::CommandTransceiver* low_level_transceiver;
95 if (cl->HasSwitch("ftdi")) {
96 LOG(INFO) << "Sending commands to FTDI SPI.";
97 low_level_transceiver = new trunks::TrunksFtdiSpi();
98 } else if (cl->HasSwitch("simulator")) {
99 LOG(INFO) << "Sending commands to simulator.";
100 low_level_transceiver = new trunks::TpmSimulatorHandle();
101 } else {
102 low_level_transceiver = new trunks::TpmHandle();
103 }
104 CHECK(low_level_transceiver->Init())
105 << "Error initializing TPM communication.";
106 // This needs to be *after* opening the TPM handle and *before* starting the
107 // background thread.
108 InitMinijailSandbox();
109 base::Thread background_thread(kBackgroundThreadName);
110 CHECK(background_thread.Start()) << "Failed to start background thread.";
111 trunks::TrunksFactoryImpl factory(low_level_transceiver);
112 CHECK(factory.Initialize()) << "Failed to initialize trunks factory.";
113 trunks::ResourceManager resource_manager(factory, low_level_transceiver);
114 background_thread.task_runner()->PostNonNestableTask(
115 FROM_HERE, base::Bind(&trunks::ResourceManager::Initialize,
116 base::Unretained(&resource_manager)));
117 trunks::BackgroundCommandTransceiver background_transceiver(
118 &resource_manager, background_thread.task_runner());
119 service.set_transceiver(&background_transceiver);
120 LOG(INFO) << "Trunks service started.";
121 return service.Run();
122 }
123