• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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