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 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 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