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;
42256c12528d3d74c5fb65fea270b45d982ea010adJorge Lucangeli Obesconst char kTrunksUser[] = "trunks";
43256c12528d3d74c5fb65fea270b45d982ea010adJorge Lucangeli Obesconst char kTrunksGroup[] = "trunks";
449caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn#if defined(__ANDROID__)
459caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahnconst char kTrunksSeccompPath[] =
469caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn    "/system/usr/share/policy/trunksd-seccomp.policy";
479caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn#else
4880c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahnconst char kTrunksSeccompPath[] = "/usr/share/policy/trunksd-seccomp.policy";
499caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn#endif
5080c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahnconst char kBackgroundThreadName[] = "trunksd_background_thread";
5180c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn
5280c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahnvoid InitMinijailSandbox() {
532e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr  uid_t trunks_uid;
542e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr  gid_t trunks_gid;
559f01b702ae6c852cf800a7156b15040b92fad94bAlex Vakulenko  CHECK(brillo::userdb::GetUserInfo(kTrunksUser, &trunks_uid, &trunks_gid))
562e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr      << "Error getting trunks uid and gid.";
579caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn  CHECK_EQ(getuid(), kRootUID) << "trunksd not initialized as root.";
589f01b702ae6c852cf800a7156b15040b92fad94bAlex Vakulenko  brillo::Minijail* minijail = brillo::Minijail::GetInstance();
5980c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn  struct minijail* jail = minijail->New();
604ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  minijail->DropRoot(jail, kTrunksUser, kTrunksGroup);
612e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr  minijail->UseSeccompFilter(jail, kTrunksSeccompPath);
6280c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn  minijail->Enter(jail);
6380c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn  minijail->Destroy(jail);
642e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr  CHECK_EQ(getuid(), trunks_uid)
659caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn      << "trunksd was not able to drop user privilege.";
662e77a42d0ff3eb5e98f066749059fa5ee696f313Jocelyn Bohr  CHECK_EQ(getgid(), trunks_gid)
679caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn      << "trunksd was not able to drop group privilege.";
6880c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn}
6980c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn
7080c739e10fd606b24e2656cad6e566c66bb218d4Darren Krahn}  // namespace
71c2be426142cd74b3136b2670f3feb92fb92923cbUtkarsh Sanghi
724dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahnint main(int argc, char** argv) {
733978ff0bfabc5f04798851e003d3dc372280a989Alex Vakulenko  base::CommandLine::Init(argc, argv);
744dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  base::CommandLine* cl = base::CommandLine::ForCurrentProcess();
7501f41a46e8a9e0b8d4518aaf7aa757e83f4f938fUtkarsh Sanghi  int flags = brillo::kLogToSyslog;
7601f41a46e8a9e0b8d4518aaf7aa757e83f4f938fUtkarsh Sanghi  if (cl->HasSwitch("log_to_stderr")) {
7701f41a46e8a9e0b8d4518aaf7aa757e83f4f938fUtkarsh Sanghi    flags |= brillo::kLogToStderr;
7801f41a46e8a9e0b8d4518aaf7aa757e83f4f938fUtkarsh Sanghi  }
7901f41a46e8a9e0b8d4518aaf7aa757e83f4f938fUtkarsh Sanghi  brillo::InitLog(flags);
809caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn
814dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn// Create a service instance before anything else so objects like
824dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn// AtExitManager exist.
839caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn#if defined(USE_BINDER_IPC)
849caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn  trunks::TrunksBinderService service;
859caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn#else
869caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn  trunks::TrunksDBusService service;
879caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn#endif
889caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn
899caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn  // Chain together command transceivers:
909caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn  //   [IPC] --> BackgroundCommandTransceiver
919caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn  //         --> ResourceManager
929caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn  //         --> TpmHandle
939caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn  //         --> [TPM]
944dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn  trunks::CommandTransceiver* low_level_transceiver;
955ece90471dd12922f9f35ee4bf6bb6a336d4ea92Vadim Bendebury  if (cl->HasSwitch("ftdi")) {
969caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn    LOG(INFO) << "Sending commands to FTDI SPI.";
979caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn    low_level_transceiver = new trunks::TrunksFtdiSpi();
98a14c7687bef55291df9d222cc7893f2ac8a16b2eJocelyn Bohr  } else if (cl->HasSwitch("simulator")) {
999caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn    LOG(INFO) << "Sending commands to simulator.";
1009caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn    low_level_transceiver = new trunks::TpmSimulatorHandle();
1015ece90471dd12922f9f35ee4bf6bb6a336d4ea92Vadim Bendebury  } else {
1029caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn    low_level_transceiver = new trunks::TpmHandle();
1035ece90471dd12922f9f35ee4bf6bb6a336d4ea92Vadim Bendebury  }
1049caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn  CHECK(low_level_transceiver->Init())
1059caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn      << "Error initializing TPM communication.";
1069caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn  // This needs to be *after* opening the TPM handle and *before* starting the
1079caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn  // background thread.
1084ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  InitMinijailSandbox();
1099caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn  base::Thread background_thread(kBackgroundThreadName);
1109caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn  CHECK(background_thread.Start()) << "Failed to start background thread.";
1119caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn  trunks::TrunksFactoryImpl factory(low_level_transceiver);
112b180754b429c078cbc99175a6059a8b5d0491002Darren Krahn  CHECK(factory.Initialize()) << "Failed to initialize trunks factory.";
1139caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn  trunks::ResourceManager resource_manager(factory, low_level_transceiver);
1149caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn  background_thread.task_runner()->PostNonNestableTask(
1159caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn      FROM_HERE, base::Bind(&trunks::ResourceManager::Initialize,
1169caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn                            base::Unretained(&resource_manager)));
1179caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn  trunks::BackgroundCommandTransceiver background_transceiver(
1189caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn      &resource_manager, background_thread.task_runner());
1199caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn  service.set_transceiver(&background_transceiver);
1209caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn  LOG(INFO) << "Trunks service started.";
1219caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn  return service.Run();
122c2be426142cd74b3136b2670f3feb92fb92923cbUtkarsh Sanghi}
123