1bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// 2bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// Copyright (C) 2014 The Android Open Source Project 3bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// 4bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// Licensed under the Apache License, Version 2.0 (the "License"); 5bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// you may not use this file except in compliance with the License. 6bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// You may obtain a copy of the License at 7bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// 8bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// http://www.apache.org/licenses/LICENSE-2.0 9bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// 10bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// Unless required by applicable law or agreed to in writing, software 11bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// distributed under the License is distributed on an "AS IS" BASIS, 12bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// See the License for the specific language governing permissions and 14bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// limitations under the License. 15bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// 16c2be426142cd74b3136b2670f3feb92fb92923cbUtkarsh Sanghi 172e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr#include <sysexits.h> 182e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr 19c2be426142cd74b3136b2670f3feb92fb92923cbUtkarsh Sanghi#include <base/at_exit.h> 204ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include <base/bind.h> 21c2be426142cd74b3136b2670f3feb92fb92923cbUtkarsh Sanghi#include <base/command_line.h> 2280c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn#include <base/threading/thread.h> 239f01b702ae6c852cf800a7156b15040b92fad94bAlex Vakulenko#include <brillo/minijail/minijail.h> 249f01b702ae6c852cf800a7156b15040b92fad94bAlex Vakulenko#include <brillo/syslog_logging.h> 259f01b702ae6c852cf800a7156b15040b92fad94bAlex Vakulenko#include <brillo/userdb_utils.h> 26c2be426142cd74b3136b2670f3feb92fb92923cbUtkarsh Sanghi 2780c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn#include "trunks/background_command_transceiver.h" 284ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include "trunks/resource_manager.h" 2980c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn#include "trunks/tpm_handle.h" 30a14c7687bef55291df9d222cc7893f2ac8a16b2eJocelyn Bohr#include "trunks/tpm_simulator_handle.h" 319caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn#if defined(USE_BINDER_IPC) 329caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn#include "trunks/trunks_binder_service.h" 339caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn#else 349caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn#include "trunks/trunks_dbus_service.h" 359caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn#endif 364ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include "trunks/trunks_factory_impl.h" 375ece90471dd12922f9f35ee4bf6bb6a336d4ea92Vadim Bendebury#include "trunks/trunks_ftdi_spi.h" 382e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr 3980c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahnnamespace { 4080c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn 4180c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahnconst uid_t kRootUID = 0; 429caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn#if defined(__ANDROID__) 439caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahnconst char kTrunksUser[] = "system"; 449caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahnconst char kTrunksGroup[] = "system"; 459caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahnconst char kTrunksSeccompPath[] = 469caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn "/system/usr/share/policy/trunksd-seccomp.policy"; 479caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn#else 4880c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahnconst char kTrunksUser[] = "trunks"; 4980c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahnconst char kTrunksGroup[] = "trunks"; 5080c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahnconst char kTrunksSeccompPath[] = "/usr/share/policy/trunksd-seccomp.policy"; 519caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn#endif 5280c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahnconst char kBackgroundThreadName[] = "trunksd_background_thread"; 5380c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn 5480c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahnvoid InitMinijailSandbox() { 552e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr uid_t trunks_uid; 562e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr gid_t trunks_gid; 579f01b702ae6c852cf800a7156b15040b92fad94bAlex Vakulenko CHECK(brillo::userdb::GetUserInfo(kTrunksUser, &trunks_uid, &trunks_gid)) 582e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr << "Error getting trunks uid and gid."; 599caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn CHECK_EQ(getuid(), kRootUID) << "trunksd not initialized as root."; 609f01b702ae6c852cf800a7156b15040b92fad94bAlex Vakulenko brillo::Minijail* minijail = brillo::Minijail::GetInstance(); 6180c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn struct minijail* jail = minijail->New(); 624ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn minijail->DropRoot(jail, kTrunksUser, kTrunksGroup); 632e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr minijail->UseSeccompFilter(jail, kTrunksSeccompPath); 6480c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn minijail->Enter(jail); 6580c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn minijail->Destroy(jail); 662e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr CHECK_EQ(getuid(), trunks_uid) 679caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn << "trunksd was not able to drop user privilege."; 682e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr CHECK_EQ(getgid(), trunks_gid) 699caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn << "trunksd was not able to drop group privilege."; 7080c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn} 7180c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn 7280c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn} // namespace 73c2be426142cd74b3136b2670f3feb92fb92923cbUtkarsh Sanghi 74c2be426142cd74b3136b2670f3feb92fb92923cbUtkarsh Sanghiint main(int argc, char **argv) { 753978ff0bfabc5f04798851e003d3dc372280a989Alex Vakulenko base::CommandLine::Init(argc, argv); 765ece90471dd12922f9f35ee4bf6bb6a336d4ea92Vadim Bendebury base::CommandLine *cl = base::CommandLine::ForCurrentProcess(); 7701f41a46e8a9e0b8d4518aaf7aa757e83f4f938fUtkarsh Sanghi int flags = brillo::kLogToSyslog; 7801f41a46e8a9e0b8d4518aaf7aa757e83f4f938fUtkarsh Sanghi if (cl->HasSwitch("log_to_stderr")) { 7901f41a46e8a9e0b8d4518aaf7aa757e83f4f938fUtkarsh Sanghi flags |= brillo::kLogToStderr; 8001f41a46e8a9e0b8d4518aaf7aa757e83f4f938fUtkarsh Sanghi } 8101f41a46e8a9e0b8d4518aaf7aa757e83f4f938fUtkarsh Sanghi brillo::InitLog(flags); 829caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn 839caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn // Create a service instance before anything else so objects like 849caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn // AtExitManager exist. 859caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn#if defined(USE_BINDER_IPC) 869caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn trunks::TrunksBinderService service; 879caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn#else 889caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn trunks::TrunksDBusService service; 899caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn#endif 909caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn 919caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn // Chain together command transceivers: 929caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn // [IPC] --> BackgroundCommandTransceiver 939caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn // --> ResourceManager 949caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn // --> TpmHandle 959caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn // --> [TPM] 969caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn trunks::CommandTransceiver *low_level_transceiver; 975ece90471dd12922f9f35ee4bf6bb6a336d4ea92Vadim Bendebury if (cl->HasSwitch("ftdi")) { 989caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn LOG(INFO) << "Sending commands to FTDI SPI."; 999caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn low_level_transceiver = new trunks::TrunksFtdiSpi(); 100a14c7687bef55291df9d222cc7893f2ac8a16b2eJocelyn Bohr } else if (cl->HasSwitch("simulator")) { 1019caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn LOG(INFO) << "Sending commands to simulator."; 1029caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn low_level_transceiver = new trunks::TpmSimulatorHandle(); 1035ece90471dd12922f9f35ee4bf6bb6a336d4ea92Vadim Bendebury } else { 1049caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn low_level_transceiver = new trunks::TpmHandle(); 1055ece90471dd12922f9f35ee4bf6bb6a336d4ea92Vadim Bendebury } 1069caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn CHECK(low_level_transceiver->Init()) 1079caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn << "Error initializing TPM communication."; 1089caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn // This needs to be *after* opening the TPM handle and *before* starting the 1099caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn // background thread. 1104ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn InitMinijailSandbox(); 1119caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn base::Thread background_thread(kBackgroundThreadName); 1129caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn CHECK(background_thread.Start()) << "Failed to start background thread."; 1139caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn trunks::TrunksFactoryImpl factory(low_level_transceiver); 1149caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn trunks::ResourceManager resource_manager(factory, low_level_transceiver); 1159caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn background_thread.task_runner()->PostNonNestableTask( 1169caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn FROM_HERE, base::Bind(&trunks::ResourceManager::Initialize, 1179caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn base::Unretained(&resource_manager))); 1189caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn trunks::BackgroundCommandTransceiver background_transceiver( 1199caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn &resource_manager, background_thread.task_runner()); 1209caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn service.set_transceiver(&background_transceiver); 1219caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn LOG(INFO) << "Trunks service started."; 1229caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn return service.Run(); 123c2be426142cd74b3136b2670f3feb92fb92923cbUtkarsh Sanghi} 124