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