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