1//
2// Copyright (C) 2015 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 "tpm_manager/server/dbus_service.h"
18
19#include <memory>
20#include <string>
21
22#include <brillo/bind_lambda.h>
23#include <brillo/daemons/dbus_daemon.h>
24#include <brillo/dbus/async_event_sequencer.h>
25#include <dbus/bus.h>
26#include <dbus/object_path.h>
27
28#include "tpm_manager/common/tpm_manager_constants.h"
29#include "tpm_manager/common/tpm_nvram_dbus_interface.h"
30#include "tpm_manager/common/tpm_ownership_dbus_interface.h"
31
32namespace tpm_manager {
33
34using brillo::dbus_utils::DBusObject;
35
36DBusService::DBusService(TpmNvramInterface* nvram_service,
37                         TpmOwnershipInterface* ownership_service)
38    : brillo::DBusServiceDaemon(tpm_manager::kTpmManagerServiceName),
39      nvram_service_(nvram_service),
40      ownership_service_(ownership_service) {}
41
42DBusService::DBusService(scoped_refptr<dbus::Bus> bus,
43                         TpmNvramInterface* nvram_service,
44                         TpmOwnershipInterface* ownership_service)
45    : brillo::DBusServiceDaemon(tpm_manager::kTpmManagerServiceName),
46      dbus_object_(new DBusObject(nullptr,
47                                  bus,
48                                  dbus::ObjectPath(kTpmManagerServicePath))),
49      nvram_service_(nvram_service),
50      ownership_service_(ownership_service) {}
51
52void DBusService::RegisterDBusObjectsAsync(
53    brillo::dbus_utils::AsyncEventSequencer* sequencer) {
54  if (!dbus_object_.get()) {
55    // At this point bus_ should be valid.
56    CHECK(bus_.get());
57    dbus_object_.reset(new DBusObject(
58        nullptr, bus_, dbus::ObjectPath(kTpmManagerServicePath)));
59  }
60  brillo::dbus_utils::DBusInterface* ownership_dbus_interface =
61      dbus_object_->AddOrGetInterface(kTpmOwnershipInterface);
62
63  ownership_dbus_interface->AddMethodHandler(
64      kGetTpmStatus, base::Unretained(this),
65      &DBusService::HandleOwnershipDBusMethod<
66          GetTpmStatusRequest, GetTpmStatusReply,
67          &TpmOwnershipInterface::GetTpmStatus>);
68
69  ownership_dbus_interface->AddMethodHandler(
70      kTakeOwnership, base::Unretained(this),
71      &DBusService::HandleOwnershipDBusMethod<
72          TakeOwnershipRequest, TakeOwnershipReply,
73          &TpmOwnershipInterface::TakeOwnership>);
74
75  ownership_dbus_interface->AddMethodHandler(
76      kRemoveOwnerDependency, base::Unretained(this),
77      &DBusService::HandleOwnershipDBusMethod<
78          RemoveOwnerDependencyRequest, RemoveOwnerDependencyReply,
79          &TpmOwnershipInterface::RemoveOwnerDependency>);
80
81  brillo::dbus_utils::DBusInterface* nvram_dbus_interface =
82      dbus_object_->AddOrGetInterface(kTpmNvramInterface);
83
84  nvram_dbus_interface->AddMethodHandler(
85      kDefineSpace, base::Unretained(this),
86      &DBusService::HandleNvramDBusMethod<DefineSpaceRequest, DefineSpaceReply,
87                                          &TpmNvramInterface::DefineSpace>);
88
89  nvram_dbus_interface->AddMethodHandler(
90      kDestroySpace, base::Unretained(this),
91      &DBusService::HandleNvramDBusMethod<DestroySpaceRequest,
92                                          DestroySpaceReply,
93                                          &TpmNvramInterface::DestroySpace>);
94
95  nvram_dbus_interface->AddMethodHandler(
96      kWriteSpace, base::Unretained(this),
97      &DBusService::HandleNvramDBusMethod<WriteSpaceRequest, WriteSpaceReply,
98                                          &TpmNvramInterface::WriteSpace>);
99
100  nvram_dbus_interface->AddMethodHandler(
101      kReadSpace, base::Unretained(this),
102      &DBusService::HandleNvramDBusMethod<ReadSpaceRequest, ReadSpaceReply,
103                                          &TpmNvramInterface::ReadSpace>);
104
105  nvram_dbus_interface->AddMethodHandler(
106      kLockSpace, base::Unretained(this),
107      &DBusService::HandleNvramDBusMethod<LockSpaceRequest, LockSpaceReply,
108                                          &TpmNvramInterface::LockSpace>);
109
110  nvram_dbus_interface->AddMethodHandler(
111      kListSpaces, base::Unretained(this),
112      &DBusService::HandleNvramDBusMethod<ListSpacesRequest, ListSpacesReply,
113                                          &TpmNvramInterface::ListSpaces>);
114
115  nvram_dbus_interface->AddMethodHandler(
116      kGetSpaceInfo, base::Unretained(this),
117      &DBusService::HandleNvramDBusMethod<GetSpaceInfoRequest,
118                                          GetSpaceInfoReply,
119                                          &TpmNvramInterface::GetSpaceInfo>);
120
121  dbus_object_->RegisterAsync(
122      sequencer->GetHandler("Failed to register D-Bus object.", true));
123}
124
125template <typename RequestProtobufType,
126          typename ReplyProtobufType,
127          DBusService::HandlerFunction<RequestProtobufType,
128                                       ReplyProtobufType,
129                                       TpmNvramInterface> func>
130void DBusService::HandleNvramDBusMethod(
131    std::unique_ptr<DBusMethodResponse<const ReplyProtobufType&>> response,
132    const RequestProtobufType& request) {
133  // Convert |response| to a shared_ptr so |nvram_service_| can safely copy the
134  // callback.
135  using SharedResponsePointer =
136      std::shared_ptr<DBusMethodResponse<const ReplyProtobufType&>>;
137  // A callback that sends off the reply protobuf.
138  auto callback = [](const SharedResponsePointer& response,
139                     const ReplyProtobufType& reply) {
140    response->Return(reply);
141  };
142  (nvram_service_->*func)(
143      request,
144      base::Bind(callback, SharedResponsePointer(std::move(response))));
145}
146
147template <typename RequestProtobufType,
148          typename ReplyProtobufType,
149          DBusService::HandlerFunction<RequestProtobufType,
150                                       ReplyProtobufType,
151                                       TpmOwnershipInterface> func>
152void DBusService::HandleOwnershipDBusMethod(
153    std::unique_ptr<DBusMethodResponse<const ReplyProtobufType&>> response,
154    const RequestProtobufType& request) {
155  // Convert |response| to a shared_ptr so |ownership_service_| can safely
156  // copy the callback.
157  using SharedResponsePointer =
158      std::shared_ptr<DBusMethodResponse<const ReplyProtobufType&>>;
159  // A callback that sends off the reply protobuf.
160  auto callback = [](const SharedResponsePointer& response,
161                     const ReplyProtobufType& reply) {
162    response->Return(reply);
163  };
164  (ownership_service_->*func)(
165      request,
166      base::Bind(callback, SharedResponsePointer(std::move(response))));
167}
168
169}  // namespace tpm_manager
170