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
32 namespace tpm_manager {
33
34 using brillo::dbus_utils::DBusObject;
35
DBusService(TpmNvramInterface * nvram_service,TpmOwnershipInterface * ownership_service)36 DBusService::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
DBusService(scoped_refptr<dbus::Bus> bus,TpmNvramInterface * nvram_service,TpmOwnershipInterface * ownership_service)42 DBusService::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
RegisterDBusObjectsAsync(brillo::dbus_utils::AsyncEventSequencer * sequencer)52 void 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
125 template <typename RequestProtobufType,
126 typename ReplyProtobufType,
127 DBusService::HandlerFunction<RequestProtobufType,
128 ReplyProtobufType,
129 TpmNvramInterface> func>
HandleNvramDBusMethod(std::unique_ptr<DBusMethodResponse<const ReplyProtobufType &>> response,const RequestProtobufType & request)130 void 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
147 template <typename RequestProtobufType,
148 typename ReplyProtobufType,
149 DBusService::HandlerFunction<RequestProtobufType,
150 ReplyProtobufType,
151 TpmOwnershipInterface> func>
HandleOwnershipDBusMethod(std::unique_ptr<DBusMethodResponse<const ReplyProtobufType &>> response,const RequestProtobufType & request)152 void 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