trunksd.cc revision 01f41a46e8a9e0b8d4518aaf7aa757e83f4f938f
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/daemons/dbus_daemon.h> 249f01b702ae6c852cf800a7156b15040b92fad94bAlex Vakulenko#include <brillo/minijail/minijail.h> 259f01b702ae6c852cf800a7156b15040b92fad94bAlex Vakulenko#include <brillo/syslog_logging.h> 269f01b702ae6c852cf800a7156b15040b92fad94bAlex Vakulenko#include <brillo/userdb_utils.h> 27c2be426142cd74b3136b2670f3feb92fb92923cbUtkarsh Sanghi 2880c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn#include "trunks/background_command_transceiver.h" 292e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr#include "trunks/dbus_interface.h" 304ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include "trunks/resource_manager.h" 3180c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn#include "trunks/tpm_handle.h" 32a14c7687bef55291df9d222cc7893f2ac8a16b2eJocelyn Bohr#include "trunks/tpm_simulator_handle.h" 334ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include "trunks/trunks_factory_impl.h" 345ece90471dd12922f9f35ee4bf6bb6a336d4ea92Vadim Bendebury#include "trunks/trunks_ftdi_spi.h" 35c2be426142cd74b3136b2670f3feb92fb92923cbUtkarsh Sanghi#include "trunks/trunks_service.h" 36c2be426142cd74b3136b2670f3feb92fb92923cbUtkarsh Sanghi 379f01b702ae6c852cf800a7156b15040b92fad94bAlex Vakulenkousing brillo::dbus_utils::AsyncEventSequencer; 382e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr 3980c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahnnamespace { 4080c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn 4180c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahnconst uid_t kRootUID = 0; 4280c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahnconst char kTrunksUser[] = "trunks"; 4380c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahnconst char kTrunksGroup[] = "trunks"; 4480c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahnconst char kTrunksSeccompPath[] = "/usr/share/policy/trunksd-seccomp.policy"; 4580c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahnconst char kBackgroundThreadName[] = "trunksd_background_thread"; 4680c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn 4780c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahnvoid InitMinijailSandbox() { 482e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr uid_t trunks_uid; 492e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr gid_t trunks_gid; 509f01b702ae6c852cf800a7156b15040b92fad94bAlex Vakulenko CHECK(brillo::userdb::GetUserInfo(kTrunksUser, &trunks_uid, &trunks_gid)) 512e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr << "Error getting trunks uid and gid."; 5280c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn CHECK_EQ(getuid(), kRootUID) << "Trunks Daemon not initialized as root."; 539f01b702ae6c852cf800a7156b15040b92fad94bAlex Vakulenko brillo::Minijail* minijail = brillo::Minijail::GetInstance(); 5480c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn struct minijail* jail = minijail->New(); 554ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn minijail->DropRoot(jail, kTrunksUser, kTrunksGroup); 562e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr minijail->UseSeccompFilter(jail, kTrunksSeccompPath); 5780c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn minijail->Enter(jail); 5880c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn minijail->Destroy(jail); 592e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr CHECK_EQ(getuid(), trunks_uid) 602e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr << "TrunksDaemon was not able to drop to trunks user."; 612e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr CHECK_EQ(getgid(), trunks_gid) 622e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr << "TrunksDaemon was not able to drop to trunks group."; 6380c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn} 6480c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn 6580c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn} // namespace 66c2be426142cd74b3136b2670f3feb92fb92923cbUtkarsh Sanghi 679f01b702ae6c852cf800a7156b15040b92fad94bAlex Vakulenkoclass TrunksDaemon : public brillo::DBusServiceDaemon { 682e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr public: 69951eb5974a3873720e8b942b270a7bffa89b2ffbUtkarsh Sanghi explicit TrunksDaemon(trunks::CommandTransceiver* transceiver) : 709f01b702ae6c852cf800a7156b15040b92fad94bAlex Vakulenko brillo::DBusServiceDaemon(trunks::kTrunksServiceName) { 71951eb5974a3873720e8b942b270a7bffa89b2ffbUtkarsh Sanghi transceiver_.reset(transceiver); 722e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr background_thread_.reset(new base::Thread(kBackgroundThreadName)); 732e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr CHECK(background_thread_->Start()); 742e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr // Chain together command transceivers: 752e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr // [IPC] --> TrunksService --> BackgroundCommandTransceiver --> 762e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr // ResourceManager --> TpmHandle --> [TPM] 77951eb5974a3873720e8b942b270a7bffa89b2ffbUtkarsh Sanghi factory_.reset(new trunks::TrunksFactoryImpl(transceiver_.get())); 782e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr resource_manager_.reset(new trunks::ResourceManager( 792e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr *factory_, 80951eb5974a3873720e8b942b270a7bffa89b2ffbUtkarsh Sanghi transceiver_.get())); 812e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr background_thread_->message_loop_proxy()->PostNonNestableTask( 822e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr FROM_HERE, 832e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr base::Bind(&trunks::ResourceManager::Initialize, 842e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr base::Unretained(resource_manager_.get()))); 852e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr background_transceiver_.reset( 862e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr new trunks::BackgroundCommandTransceiver( 872e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr resource_manager_.get(), 882e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr background_thread_->message_loop_proxy())); 892e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr } 902e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr 912e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr protected: 922e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr void RegisterDBusObjectsAsync(AsyncEventSequencer* sequencer) override { 932e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr trunks_service_.reset(new trunks::TrunksService( 942e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr bus_, 952e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr background_transceiver_.get())); 962e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr trunks_service_->Register( 972e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr sequencer->GetHandler("Register() failed.", true)); 982e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr } 992e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr 1002e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr 1012e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr private: 1022e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr std::unique_ptr<trunks::TrunksService> trunks_service_; 103951eb5974a3873720e8b942b270a7bffa89b2ffbUtkarsh Sanghi std::unique_ptr<trunks::CommandTransceiver> transceiver_; 1042e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr // Thread for executing TPM comands. 1052e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr std::unique_ptr<base::Thread> background_thread_; 1062e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr std::unique_ptr<trunks::TrunksFactory> factory_; 1072e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr std::unique_ptr<trunks::ResourceManager> resource_manager_; 1082e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr std::unique_ptr<trunks::CommandTransceiver> background_transceiver_; 1092e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr 1102e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr DISALLOW_COPY_AND_ASSIGN(TrunksDaemon); 1112e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr}; 1122e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr 113c2be426142cd74b3136b2670f3feb92fb92923cbUtkarsh Sanghiint main(int argc, char **argv) { 1143978ff0bfabc5f04798851e003d3dc372280a989Alex Vakulenko base::CommandLine::Init(argc, argv); 1155ece90471dd12922f9f35ee4bf6bb6a336d4ea92Vadim Bendebury base::CommandLine *cl = base::CommandLine::ForCurrentProcess(); 11601f41a46e8a9e0b8d4518aaf7aa757e83f4f938fUtkarsh Sanghi int flags = brillo::kLogToSyslog; 11701f41a46e8a9e0b8d4518aaf7aa757e83f4f938fUtkarsh Sanghi if (cl->HasSwitch("log_to_stderr")) { 11801f41a46e8a9e0b8d4518aaf7aa757e83f4f938fUtkarsh Sanghi flags |= brillo::kLogToStderr; 11901f41a46e8a9e0b8d4518aaf7aa757e83f4f938fUtkarsh Sanghi } 12001f41a46e8a9e0b8d4518aaf7aa757e83f4f938fUtkarsh Sanghi brillo::InitLog(flags); 1215ece90471dd12922f9f35ee4bf6bb6a336d4ea92Vadim Bendebury trunks::CommandTransceiver *transceiver; 1225ece90471dd12922f9f35ee4bf6bb6a336d4ea92Vadim Bendebury if (cl->HasSwitch("ftdi")) { 1235ece90471dd12922f9f35ee4bf6bb6a336d4ea92Vadim Bendebury transceiver = new trunks::TrunksFtdiSpi(); 124a14c7687bef55291df9d222cc7893f2ac8a16b2eJocelyn Bohr } else if (cl->HasSwitch("simulator")) { 125a14c7687bef55291df9d222cc7893f2ac8a16b2eJocelyn Bohr transceiver = new trunks::TpmSimulatorHandle(); 1265ece90471dd12922f9f35ee4bf6bb6a336d4ea92Vadim Bendebury } else { 1275ece90471dd12922f9f35ee4bf6bb6a336d4ea92Vadim Bendebury transceiver = new trunks::TpmHandle(); 1285ece90471dd12922f9f35ee4bf6bb6a336d4ea92Vadim Bendebury } 1295ece90471dd12922f9f35ee4bf6bb6a336d4ea92Vadim Bendebury CHECK(transceiver->Init()) << "Error initializing transceiver"; 1305ece90471dd12922f9f35ee4bf6bb6a336d4ea92Vadim Bendebury TrunksDaemon daemon(transceiver); 1314ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn InitMinijailSandbox(); 1322e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr LOG(INFO) << "Trunks Service Started"; 1332e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr return daemon.Run(); 134c2be426142cd74b3136b2670f3feb92fb92923cbUtkarsh Sanghi} 135