trunksd.cc revision 7e763a9434e12c7980529980de5f8eced22b310a
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/daemons/dbus_daemon.h> 24#include <brillo/minijail/minijail.h> 25#include <brillo/syslog_logging.h> 26#include <brillo/userdb_utils.h> 27 28#include "trunks/background_command_transceiver.h" 29#include "trunks/dbus_interface.h" 30#include "trunks/resource_manager.h" 31#include "trunks/tpm_handle.h" 32#include "trunks/tpm_simulator_handle.h" 33#include "trunks/trunks_factory_impl.h" 34#include "trunks/trunks_ftdi_spi.h" 35#include "trunks/trunks_service.h" 36 37using brillo::dbus_utils::AsyncEventSequencer; 38 39namespace { 40 41const uid_t kRootUID = 0; 42const char kTrunksUser[] = "trunks"; 43const char kTrunksGroup[] = "trunks"; 44const char kTrunksSeccompPath[] = "/usr/share/policy/trunksd-seccomp.policy"; 45const char kBackgroundThreadName[] = "trunksd_background_thread"; 46 47void InitMinijailSandbox() { 48 uid_t trunks_uid; 49 gid_t trunks_gid; 50 CHECK(brillo::userdb::GetUserInfo(kTrunksUser, &trunks_uid, &trunks_gid)) 51 << "Error getting trunks uid and gid."; 52 CHECK_EQ(getuid(), kRootUID) << "Trunks Daemon not initialized as root."; 53 brillo::Minijail* minijail = brillo::Minijail::GetInstance(); 54 struct minijail* jail = minijail->New(); 55 minijail->DropRoot(jail, kTrunksUser, kTrunksGroup); 56 minijail->UseSeccompFilter(jail, kTrunksSeccompPath); 57 minijail->Enter(jail); 58 minijail->Destroy(jail); 59 CHECK_EQ(getuid(), trunks_uid) 60 << "TrunksDaemon was not able to drop to trunks user."; 61 CHECK_EQ(getgid(), trunks_gid) 62 << "TrunksDaemon was not able to drop to trunks group."; 63} 64 65} // namespace 66 67class TrunksDaemon : public brillo::DBusServiceDaemon { 68 public: 69 explicit TrunksDaemon(trunks::CommandTransceiver* transceiver) : 70 brillo::DBusServiceDaemon(trunks::kTrunksServiceName) { 71 transceiver_.reset(transceiver); 72 background_thread_.reset(new base::Thread(kBackgroundThreadName)); 73 CHECK(background_thread_->Start()); 74 // Chain together command transceivers: 75 // [IPC] --> TrunksService --> BackgroundCommandTransceiver --> 76 // ResourceManager --> TpmHandle --> [TPM] 77 factory_.reset(new trunks::TrunksFactoryImpl(transceiver_.get())); 78 resource_manager_.reset(new trunks::ResourceManager( 79 *factory_, 80 transceiver_.get())); 81 background_thread_->task_runner()->PostNonNestableTask( 82 FROM_HERE, 83 base::Bind(&trunks::ResourceManager::Initialize, 84 base::Unretained(resource_manager_.get()))); 85 background_transceiver_.reset( 86 new trunks::BackgroundCommandTransceiver( 87 resource_manager_.get(), 88 background_thread_->task_runner())); 89 } 90 91 protected: 92 void RegisterDBusObjectsAsync(AsyncEventSequencer* sequencer) override { 93 trunks_service_.reset(new trunks::TrunksService( 94 bus_, 95 background_transceiver_.get())); 96 trunks_service_->Register( 97 sequencer->GetHandler("Register() failed.", true)); 98 } 99 100 101 private: 102 std::unique_ptr<trunks::TrunksService> trunks_service_; 103 std::unique_ptr<trunks::CommandTransceiver> transceiver_; 104 // Thread for executing TPM comands. 105 std::unique_ptr<base::Thread> background_thread_; 106 std::unique_ptr<trunks::TrunksFactory> factory_; 107 std::unique_ptr<trunks::ResourceManager> resource_manager_; 108 std::unique_ptr<trunks::CommandTransceiver> background_transceiver_; 109 110 DISALLOW_COPY_AND_ASSIGN(TrunksDaemon); 111}; 112 113int main(int argc, char **argv) { 114 base::CommandLine::Init(argc, argv); 115 base::CommandLine *cl = base::CommandLine::ForCurrentProcess(); 116 int flags = brillo::kLogToSyslog; 117 if (cl->HasSwitch("log_to_stderr")) { 118 flags |= brillo::kLogToStderr; 119 } 120 brillo::InitLog(flags); 121 trunks::CommandTransceiver *transceiver; 122 if (cl->HasSwitch("ftdi")) { 123 transceiver = new trunks::TrunksFtdiSpi(); 124 } else if (cl->HasSwitch("simulator")) { 125 transceiver = new trunks::TpmSimulatorHandle(); 126 } else { 127 transceiver = new trunks::TpmHandle(); 128 } 129 CHECK(transceiver->Init()) << "Error initializing transceiver"; 130 TrunksDaemon daemon(transceiver); 131 InitMinijailSandbox(); 132 LOG(INFO) << "Trunks Service Started"; 133 return daemon.Run(); 134} 135