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 39namespace { 40 41const uid_t kRootUID = 0; 42const char kTrunksUser[] = "trunks"; 43const char kTrunksGroup[] = "trunks"; 44#if defined(__ANDROID__) 45const char kTrunksSeccompPath[] = 46 "/system/usr/share/policy/trunksd-seccomp.policy"; 47#else 48const char kTrunksSeccompPath[] = "/usr/share/policy/trunksd-seccomp.policy"; 49#endif 50const char kBackgroundThreadName[] = "trunksd_background_thread"; 51 52void 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 72int 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