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