Merge lp:~thomas-voss/biometryd/verify-incoming-requests into lp:biometryd
- verify-incoming-requests
- Merge into trunk
Proposed by
Thomas Voß
Status: | Merged |
---|---|
Approved by: | Ken VanDine |
Approved revision: | 29 |
Merged at revision: | 28 |
Proposed branch: | lp:~thomas-voss/biometryd/verify-incoming-requests |
Merge into: | lp:biometryd |
Diff against target: |
1169 lines (+722/-123) 14 files modified
src/biometry/CMakeLists.txt (+5/-0) src/biometry/dbus/interface.h (+24/-13) src/biometry/dbus/skeleton/credentials_resolver.h (+50/-0) src/biometry/dbus/skeleton/daemon_credentials_resolver.cpp (+117/-0) src/biometry/dbus/skeleton/daemon_credentials_resolver.h (+53/-0) src/biometry/dbus/skeleton/device.cpp (+5/-2) src/biometry/dbus/skeleton/device.h (+5/-1) src/biometry/dbus/skeleton/identifier.cpp (+63/-19) src/biometry/dbus/skeleton/identifier.h (+25/-2) src/biometry/dbus/skeleton/request_verifier.cpp (+33/-0) src/biometry/dbus/skeleton/request_verifier.h (+60/-0) src/biometry/dbus/skeleton/template_store.cpp (+239/-83) src/biometry/dbus/skeleton/template_store.h (+42/-3) tests/CMakeLists.txt (+1/-0) |
To merge this branch: | bzr merge lp:~thomas-voss/biometryd/verify-incoming-requests |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ken VanDine | Approve | ||
Review via email: mp+297747@code.launchpad.net |
Commit message
Verify incoming requests.
Description of the change
Verify incoming requests.
To post a comment you must log in.
- 29. By Thomas Voß
-
Make sure that test cases pass if run in virtualized environments without securityfs being mounted.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'src/biometry/CMakeLists.txt' |
2 | --- src/biometry/CMakeLists.txt 2016-06-02 14:17:01 +0000 |
3 | +++ src/biometry/CMakeLists.txt 2016-06-17 10:36:14 +0000 |
4 | @@ -60,6 +60,11 @@ |
5 | dbus/stub/observer.h |
6 | dbus/stub/operation.h |
7 | |
8 | + dbus/skeleton/credentials_resolver.h |
9 | + dbus/skeleton/daemon_credentials_resolver.h |
10 | + dbus/skeleton/daemon_credentials_resolver.cpp |
11 | + dbus/skeleton/request_verifier.h |
12 | + dbus/skeleton/request_verifier.cpp |
13 | dbus/skeleton/service.h |
14 | dbus/skeleton/service.cpp |
15 | dbus/skeleton/device.h |
16 | |
17 | === modified file 'src/biometry/dbus/interface.h' |
18 | --- src/biometry/dbus/interface.h 2016-06-14 20:20:10 +0000 |
19 | +++ src/biometry/dbus/interface.h 2016-06-17 10:36:14 +0000 |
20 | @@ -32,6 +32,17 @@ |
21 | { |
22 | namespace interface |
23 | { |
24 | +struct Errors |
25 | +{ |
26 | + struct NotPermitted |
27 | + { |
28 | + static inline std::string name() |
29 | + { |
30 | + return "com.ubuntu.biometryd.Error.NotPermitted"; |
31 | + } |
32 | + }; |
33 | +}; |
34 | + |
35 | struct Service |
36 | { |
37 | static inline std::string name() |
38 | @@ -42,7 +53,7 @@ |
39 | static inline core::dbus::types::ObjectPath path() |
40 | { |
41 | return core::dbus::types::ObjectPath{"/"}; |
42 | - } |
43 | + } |
44 | |
45 | struct Methods |
46 | { |
47 | @@ -60,7 +71,7 @@ |
48 | |
49 | inline static const std::chrono::milliseconds default_timeout() |
50 | { |
51 | - return std::chrono::seconds{1}; |
52 | + return std::chrono::seconds{5}; |
53 | } |
54 | }; |
55 | }; |
56 | @@ -91,7 +102,7 @@ |
57 | |
58 | inline static const std::chrono::milliseconds default_timeout() |
59 | { |
60 | - return std::chrono::seconds{1}; |
61 | + return std::chrono::seconds{5}; |
62 | } |
63 | }; |
64 | |
65 | @@ -109,7 +120,7 @@ |
66 | |
67 | inline static const std::chrono::milliseconds default_timeout() |
68 | { |
69 | - return std::chrono::seconds{1}; |
70 | + return std::chrono::seconds{5}; |
71 | } |
72 | }; |
73 | |
74 | @@ -127,7 +138,7 @@ |
75 | |
76 | inline static const std::chrono::milliseconds default_timeout() |
77 | { |
78 | - return std::chrono::seconds{1}; |
79 | + return std::chrono::seconds{5}; |
80 | } |
81 | }; |
82 | }; |
83 | @@ -158,7 +169,7 @@ |
84 | |
85 | inline static const std::chrono::milliseconds default_timeout() |
86 | { |
87 | - return std::chrono::seconds{1}; |
88 | + return std::chrono::seconds{5}; |
89 | } |
90 | }; |
91 | }; |
92 | @@ -189,7 +200,7 @@ |
93 | |
94 | inline static const std::chrono::milliseconds default_timeout() |
95 | { |
96 | - return std::chrono::seconds{1}; |
97 | + return std::chrono::seconds{5}; |
98 | } |
99 | }; |
100 | |
101 | @@ -206,7 +217,7 @@ |
102 | |
103 | inline static const std::chrono::milliseconds default_timeout() |
104 | { |
105 | - return std::chrono::seconds{1}; |
106 | + return std::chrono::seconds{5}; |
107 | } |
108 | }; |
109 | |
110 | @@ -224,7 +235,7 @@ |
111 | |
112 | inline static const std::chrono::milliseconds default_timeout() |
113 | { |
114 | - return std::chrono::seconds{1}; |
115 | + return std::chrono::seconds{5}; |
116 | } |
117 | }; |
118 | |
119 | @@ -241,7 +252,7 @@ |
120 | |
121 | inline static const std::chrono::milliseconds default_timeout() |
122 | { |
123 | - return std::chrono::seconds{1}; |
124 | + return std::chrono::seconds{5}; |
125 | } |
126 | }; |
127 | |
128 | @@ -259,7 +270,7 @@ |
129 | |
130 | inline static const std::chrono::milliseconds default_timeout() |
131 | { |
132 | - return std::chrono::seconds{1}; |
133 | + return std::chrono::seconds{5}; |
134 | } |
135 | }; |
136 | }; |
137 | @@ -310,7 +321,7 @@ |
138 | |
139 | inline static const std::chrono::milliseconds default_timeout() |
140 | { |
141 | - return std::chrono::seconds{1}; |
142 | + return std::chrono::seconds{5}; |
143 | } |
144 | }; |
145 | |
146 | @@ -327,7 +338,7 @@ |
147 | |
148 | inline static const std::chrono::milliseconds default_timeout() |
149 | { |
150 | - return std::chrono::seconds{1}; |
151 | + return std::chrono::seconds{5}; |
152 | } |
153 | }; |
154 | }; |
155 | |
156 | === added file 'src/biometry/dbus/skeleton/credentials_resolver.h' |
157 | --- src/biometry/dbus/skeleton/credentials_resolver.h 1970-01-01 00:00:00 +0000 |
158 | +++ src/biometry/dbus/skeleton/credentials_resolver.h 2016-06-17 10:36:14 +0000 |
159 | @@ -0,0 +1,50 @@ |
160 | +/* |
161 | + * Copyright (C) 2016 Canonical, Ltd. |
162 | + * |
163 | + * This program is free software; you can redistribute it and/or modify |
164 | + * it under the terms of the GNU Lesser General Public License as published by |
165 | + * the Free Software Foundation; version 3. |
166 | + * |
167 | + * This program is distributed in the hope that it will be useful, |
168 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
169 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
170 | + * GNU Lesser General Public License for more details. |
171 | + * |
172 | + * You should have received a copy of the GNU Lesser General Public License |
173 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
174 | + * |
175 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
176 | + * |
177 | + */ |
178 | + |
179 | +#ifndef BIOMETRYD_DBUS_SKELETON_CREDENTIALS_RESOLVER_H_ |
180 | +#define BIOMETRYD_DBUS_SKELETON_CREDENTIALS_RESOLVER_H_ |
181 | + |
182 | +#include <biometry/do_not_copy_or_move.h> |
183 | +#include <biometry/optional.h> |
184 | +#include <biometry/dbus/skeleton/request_verifier.h> |
185 | + |
186 | +#include <core/dbus/message.h> |
187 | + |
188 | +#include <functional> |
189 | + |
190 | +namespace biometry |
191 | +{ |
192 | +namespace dbus |
193 | +{ |
194 | +namespace skeleton |
195 | +{ |
196 | +/// @brief CredentialsResolver resolves incoming messages to RequestVerifier::Credentials. |
197 | +class CredentialsResolver : public DoNotCopyOrMove |
198 | +{ |
199 | +public: |
200 | + /// @brief resolve_credentials resolves the credentials of the application that sent msg. |
201 | + virtual void resolve_credentials(const core::dbus::Message::Ptr& msg, |
202 | + const std::function<void(const Optional<RequestVerifier::Credentials>&)>& then) = 0; |
203 | +}; |
204 | +} |
205 | +} |
206 | +} |
207 | + |
208 | +#endif // BIOMETRYD_DBUS_SKELETON_CREDENTIALS_RESOLVER_H_ |
209 | + |
210 | |
211 | === added file 'src/biometry/dbus/skeleton/daemon_credentials_resolver.cpp' |
212 | --- src/biometry/dbus/skeleton/daemon_credentials_resolver.cpp 1970-01-01 00:00:00 +0000 |
213 | +++ src/biometry/dbus/skeleton/daemon_credentials_resolver.cpp 2016-06-17 10:36:14 +0000 |
214 | @@ -0,0 +1,117 @@ |
215 | +/* |
216 | + * Copyright (C) 2016 Canonical, Ltd. |
217 | + * |
218 | + * This program is free software; you can redistribute it and/or modify |
219 | + * it under the terms of the GNU Lesser General Public License as published by |
220 | + * the Free Software Foundation; version 3. |
221 | + * |
222 | + * This program is distributed in the hope that it will be useful, |
223 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
224 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
225 | + * GNU Lesser General Public License for more details. |
226 | + * |
227 | + * You should have received a copy of the GNU Lesser General Public License |
228 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
229 | + * |
230 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
231 | + * |
232 | + */ |
233 | + |
234 | +#include <biometry/dbus/skeleton/daemon_credentials_resolver.h> |
235 | + |
236 | +#include <biometry/application.h> |
237 | +#include <biometry/user.h> |
238 | + |
239 | +#include <core/dbus/macros.h> |
240 | +#include <core/dbus/object.h> |
241 | + |
242 | +#include <core/posix/this_process.h> |
243 | + |
244 | +namespace |
245 | +{ |
246 | +bool is_running_in_a_testing_environment() |
247 | +{ |
248 | + return core::posix::this_process::env::get("BIOMETRYD_DBUS_SKELETON_IS_RUNNING_UNDER_TESTING", "0") == "1"; |
249 | +} |
250 | + |
251 | +struct DBus |
252 | +{ |
253 | + static const std::string& name() |
254 | + { |
255 | + static const std::string s = "org.freedesktop.DBus"; |
256 | + return s; |
257 | + } |
258 | + |
259 | + // Gets the AppArmor confinement string associated with the unique connection name. If |
260 | + // D-Bus is not performing AppArmor mediation, the |
261 | + // org.freedesktop.DBus.Error.AppArmorSecurityContextUnknown error is returned. |
262 | + DBUS_CPP_METHOD_DEF(GetConnectionAppArmorSecurityContext, DBus) |
263 | + |
264 | + // Gets the unix user id of the user that the requesting party is running under. |
265 | + DBUS_CPP_METHOD_DEF(GetConnectionUnixUser, DBus) |
266 | + |
267 | + struct Stub |
268 | + { |
269 | + // Creates a new stub instance for the given object to access |
270 | + // DBus functionality. |
271 | + Stub(const core::dbus::Object::Ptr& object) : object{object} |
272 | + { |
273 | + } |
274 | + |
275 | + // Creates a new stub instance for the given bus connection |
276 | + Stub(const core::dbus::Bus::Ptr& bus) |
277 | + : object |
278 | + { |
279 | + core::dbus::Service::use_service<DBus>(bus) |
280 | + ->object_for_path(core::dbus::types::ObjectPath{"/org/freedesktop/DBus"}) |
281 | + } |
282 | + { |
283 | + } |
284 | + |
285 | + // Gets the AppArmor confinement string associated with the unique connection name. If |
286 | + // D-Bus is not performing AppArmor mediation, the |
287 | + // org.freedesktop.DBus.Error.AppArmorSecurityContextUnknown error is returned. |
288 | + // |
289 | + // Invokes the given handler on completion. |
290 | + void get_connection_app_armor_security_async(const std::string& name, std::function<void(const biometry::Optional<std::string>&)> handler) |
291 | + { |
292 | + object->invoke_method_asynchronously_with_callback<GetConnectionAppArmorSecurityContext, std::string>([handler](const core::dbus::Result<std::string>& result) |
293 | + { |
294 | + biometry::Optional<std::string> label; handler((not result.is_error() ? |
295 | + label = result.value() : |
296 | + is_running_in_a_testing_environment() ? label = "unconfined" : label)); |
297 | + }, name); |
298 | + } |
299 | + |
300 | + // Gets the unix user id of the sender identified by name, invoking handler on completion. |
301 | + void get_connection_unix_user_async(const std::string& name, const std::function<void(biometry::Optional<std::uint32_t>)>& handler) |
302 | + { |
303 | + object->invoke_method_asynchronously_with_callback<GetConnectionUnixUser, std::uint32_t>([handler](const core::dbus::Result<std::uint32_t>& result) |
304 | + { |
305 | + biometry::Optional<std::uint32_t> uid; handler((not result.is_error() ? uid = result.value() : uid)); |
306 | + }, name); |
307 | + } |
308 | + |
309 | + core::dbus::Object::Ptr object; |
310 | + }; |
311 | +}; |
312 | +} |
313 | + |
314 | +biometry::dbus::skeleton::DaemonCredentialsResolver::DaemonCredentialsResolver(const core::dbus::Bus::Ptr& bus) : bus{bus} |
315 | +{ |
316 | +} |
317 | + |
318 | +void biometry::dbus::skeleton::DaemonCredentialsResolver::resolve_credentials( |
319 | + const core::dbus::Message::Ptr& msg, |
320 | + const std::function<void(const Optional<RequestVerifier::Credentials>&)>& then) |
321 | +{ |
322 | + DBus::Stub stub{bus}; |
323 | + stub.get_connection_unix_user_async(msg->sender(), [stub, msg, then](biometry::Optional<std::uint32_t> uid) mutable |
324 | + { |
325 | + stub.get_connection_app_armor_security_async(msg->sender(), [stub, msg, then, uid](const biometry::Optional<std::string>& label) mutable |
326 | + { |
327 | + Optional<RequestVerifier::Credentials> credentials; |
328 | + then((label && uid ? credentials = {biometry::Application{label.get()}, biometry::User{uid.get()}} : credentials)); |
329 | + }); |
330 | + }); |
331 | +} |
332 | |
333 | === added file 'src/biometry/dbus/skeleton/daemon_credentials_resolver.h' |
334 | --- src/biometry/dbus/skeleton/daemon_credentials_resolver.h 1970-01-01 00:00:00 +0000 |
335 | +++ src/biometry/dbus/skeleton/daemon_credentials_resolver.h 2016-06-17 10:36:14 +0000 |
336 | @@ -0,0 +1,53 @@ |
337 | +/* |
338 | + * Copyright (C) 2016 Canonical, Ltd. |
339 | + * |
340 | + * This program is free software; you can redistribute it and/or modify |
341 | + * it under the terms of the GNU Lesser General Public License as published by |
342 | + * the Free Software Foundation; version 3. |
343 | + * |
344 | + * This program is distributed in the hope that it will be useful, |
345 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
346 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
347 | + * GNU Lesser General Public License for more details. |
348 | + * |
349 | + * You should have received a copy of the GNU Lesser General Public License |
350 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
351 | + * |
352 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
353 | + * |
354 | + */ |
355 | + |
356 | +#ifndef BIOMETRYD_DBUS_SKELETON_DAEMON_CREDENTIALS_RESOLVER_H_ |
357 | +#define BIOMETRYD_DBUS_SKELETON_DAEMON_CREDENTIALS_RESOLVER_H_ |
358 | + |
359 | +#include <biometry/dbus/skeleton/credentials_resolver.h> |
360 | + |
361 | +#include <core/dbus/bus.h> |
362 | +#include <core/dbus/message.h> |
363 | + |
364 | +namespace biometry |
365 | +{ |
366 | +namespace dbus |
367 | +{ |
368 | +namespace skeleton |
369 | +{ |
370 | +/// @brief CredentialsResolver resolves incoming messages to RequestVerifier::Credentials. |
371 | +class DaemonCredentialsResolver : public CredentialsResolver |
372 | +{ |
373 | +public: |
374 | + /// @brief Initializes a new instance with the given bus connection. |
375 | + explicit DaemonCredentialsResolver(const core::dbus::Bus::Ptr& bus); |
376 | + |
377 | + /// @brief resolve_credentials resolves the credentials of the application that sent msg. |
378 | + void resolve_credentials(const core::dbus::Message::Ptr& msg, |
379 | + const std::function<void(const Optional<RequestVerifier::Credentials>&)>& then) override; |
380 | + |
381 | +private: |
382 | + core::dbus::Bus::Ptr bus; |
383 | +}; |
384 | +} |
385 | +} |
386 | +} |
387 | + |
388 | +#endif // BIOMETRYD_DBUS_SKELETON_DAEMON_CREDENTIALS_RESOLVER_H_ |
389 | + |
390 | |
391 | === modified file 'src/biometry/dbus/skeleton/device.cpp' |
392 | --- src/biometry/dbus/skeleton/device.cpp 2016-05-02 06:16:01 +0000 |
393 | +++ src/biometry/dbus/skeleton/device.cpp 2016-06-17 10:36:14 +0000 |
394 | @@ -20,6 +20,7 @@ |
395 | #include <biometry/dbus/skeleton/device.h> |
396 | |
397 | #include <biometry/dbus/interface.h> |
398 | +#include <biometry/dbus/skeleton/daemon_credentials_resolver.h> |
399 | #include <biometry/dbus/skeleton/template_store.h> |
400 | |
401 | #include <boost/format.hpp> |
402 | @@ -93,7 +94,8 @@ |
403 | |
404 | template_store_([this, &path]() |
405 | { |
406 | - return TemplateStore::create_for_service_and_object(bus_, service_, service_->add_object_for_path(path), std::ref(template_store())); |
407 | + return TemplateStore::create_for_service_and_object(bus_, service_, service_->add_object_for_path(path), std::ref(template_store()), |
408 | + std::make_shared<TemplateStore::RequestVerifier>(), std::make_shared<DaemonCredentialsResolver>(bus_)); |
409 | }); |
410 | |
411 | auto reply = core::dbus::Message::make_method_return(msg); |
412 | @@ -107,7 +109,8 @@ |
413 | |
414 | identifier_([this, &path]() |
415 | { |
416 | - return Identifier::create_for_service_and_object(bus_, service_, service_->add_object_for_path(path), std::ref(identifier())); |
417 | + return Identifier::create_for_service_and_object(bus_, service_, service_->add_object_for_path(path), std::ref(identifier()), |
418 | + std::make_shared<Identifier::RequestVerifier>(), std::make_shared<DaemonCredentialsResolver>(bus_)); |
419 | }); |
420 | |
421 | auto reply = core::dbus::Message::make_method_return(msg); |
422 | |
423 | === modified file 'src/biometry/dbus/skeleton/device.h' |
424 | --- src/biometry/dbus/skeleton/device.h 2016-05-04 12:17:44 +0000 |
425 | +++ src/biometry/dbus/skeleton/device.h 2016-06-17 10:36:14 +0000 |
426 | @@ -44,7 +44,11 @@ |
427 | typedef std::shared_ptr<Device> Ptr; |
428 | |
429 | /// @brief create_for_bus returns a new skeleton::Device instance connected to bus, forwarding calls to impl. |
430 | - static Ptr create_for_service_and_object(const core::dbus::Bus::Ptr& bus, const core::dbus::Service::Ptr& service, const core::dbus::Object::Ptr& object, const std::shared_ptr<biometry::Device>& impl); |
431 | + static Ptr create_for_service_and_object( |
432 | + const core::dbus::Bus::Ptr& bus, |
433 | + const core::dbus::Service::Ptr& service, |
434 | + const core::dbus::Object::Ptr& object, |
435 | + const std::shared_ptr<biometry::Device>& impl); |
436 | |
437 | /// @brief Frees up resources and removes routes to message handlers. |
438 | ~Device(); |
439 | |
440 | === modified file 'src/biometry/dbus/skeleton/identifier.cpp' |
441 | --- src/biometry/dbus/skeleton/identifier.cpp 2016-05-04 12:17:44 +0000 |
442 | +++ src/biometry/dbus/skeleton/identifier.cpp 2016-06-17 10:36:14 +0000 |
443 | @@ -28,14 +28,34 @@ |
444 | |
445 | #include <boost/format.hpp> |
446 | |
447 | +namespace |
448 | +{ |
449 | +core::dbus::Message::Ptr not_permitted_in_reply_to(const core::dbus::Message::Ptr& msg) |
450 | +{ |
451 | + return core::dbus::Message::make_error(msg, biometry::dbus::interface::Errors::NotPermitted::name(), ""); |
452 | +} |
453 | +} |
454 | + |
455 | +bool biometry::dbus::skeleton::Identifier::RequestVerifier::verify_identify_user_request(const biometry::Application& app, const Credentials& provided) |
456 | +{ |
457 | + // Requests for the same app are fine. |
458 | + if (app == provided.app) |
459 | + return true; |
460 | + |
461 | + // If app ids do not match: we unconditionally trust unconfined apps, and no one else. |
462 | + return provided.app.as_string() == "unconfined"; |
463 | +} |
464 | + |
465 | /// @brief create_for_bus returns a new skeleton::Identifier instance connected to bus, forwarding calls to impl. |
466 | biometry::dbus::skeleton::Identifier::Ptr biometry::dbus::skeleton::Identifier::create_for_service_and_object( |
467 | const core::dbus::Bus::Ptr& bus, |
468 | const core::dbus::Service::Ptr& service, |
469 | const core::dbus::Object::Ptr& object, |
470 | - const std::reference_wrapper<biometry::Identifier>& impl) |
471 | + const std::reference_wrapper<biometry::Identifier>& impl, |
472 | + const std::shared_ptr<RequestVerifier>& request_verifier, |
473 | + const std::shared_ptr<CredentialsResolver>& credentials_resolver) |
474 | { |
475 | - return Ptr{new Identifier{bus, service, object, impl}}; |
476 | + return Ptr{new Identifier{bus, service, object, impl, request_verifier, credentials_resolver}}; |
477 | } |
478 | |
479 | // From biometry::Identifier. |
480 | @@ -48,31 +68,55 @@ |
481 | const core::dbus::Bus::Ptr& bus, |
482 | const core::dbus::Service::Ptr& service, |
483 | const core::dbus::Object::Ptr& object, |
484 | - const std::reference_wrapper<biometry::Identifier>& impl) |
485 | + const std::reference_wrapper<biometry::Identifier>& impl, |
486 | + const std::shared_ptr<RequestVerifier>& request_verifier, |
487 | + const std::shared_ptr<CredentialsResolver>& credentials_resolver) |
488 | : impl{impl}, |
489 | + request_verifier{request_verifier}, |
490 | + credentials_resolver{credentials_resolver}, |
491 | bus{bus}, |
492 | service{service}, |
493 | object{object} |
494 | { |
495 | object->install_method_handler<biometry::dbus::interface::Identifier::Methods::IdentifyUser>([this](const core::dbus::Message::Ptr& msg) |
496 | { |
497 | - biometry::Application app = biometry::Application::system(); biometry::Reason reason = biometry::Reason::unknown(); |
498 | - auto reader = msg->reader(); reader >> app >> reason; |
499 | - auto op = identify_user(app, reason); |
500 | - |
501 | - core::dbus::types::ObjectPath op_path |
502 | - { |
503 | - (boost::format{"%1%/operation/identification/%2%"} % this->object->path().as_string() % util::counter<Identifier>().increment()).str() |
504 | - }; |
505 | - |
506 | - ops.synchronized([this, op_path, op](IdentificationOps::ValueType& ops) |
507 | - { |
508 | - ops[op_path] = skeleton::Operation<Identification>::create_for_object(this->bus, this->service->add_object_for_path(op_path), op); |
509 | + Identifier::credentials_resolver->resolve_credentials(msg, [this, msg](const Optional<RequestVerifier::Credentials>& credentials) |
510 | + { |
511 | + if (not credentials) |
512 | + { |
513 | + this->bus->send(not_permitted_in_reply_to(msg)); |
514 | + return; |
515 | + } |
516 | + |
517 | + biometry::Application app = biometry::Application::system(); biometry::Reason reason = biometry::Reason::unknown(); |
518 | + auto reader = msg->reader(); reader >> app >> reason; |
519 | + |
520 | + if (not this->request_verifier->verify_identify_user_request(app, credentials.get())) |
521 | + { |
522 | + this->bus->send(not_permitted_in_reply_to(msg)); |
523 | + return; |
524 | + } |
525 | + |
526 | + auto op = identify_user(app, reason); |
527 | + |
528 | + core::dbus::types::ObjectPath op_path |
529 | + { |
530 | + (boost::format{"%1%/operation/identification/%2%/%3%/%4%"} |
531 | + % this->object->path().as_string() |
532 | + % credentials.get().app.as_string() |
533 | + % credentials.get().user.id |
534 | + % util::counter<Identifier>().increment()).str() |
535 | + }; |
536 | + |
537 | + ops.synchronized([this, op_path, op](IdentificationOps::ValueType& ops) |
538 | + { |
539 | + ops[op_path] = skeleton::Operation<Identification>::create_for_object(this->bus, this->service->add_object_for_path(op_path), op); |
540 | + }); |
541 | + |
542 | + auto reply = core::dbus::Message::make_method_return(msg); |
543 | + reply->writer() << op_path; |
544 | + this->bus->send(reply); |
545 | }); |
546 | - |
547 | - auto reply = core::dbus::Message::make_method_return(msg); |
548 | - reply->writer() << op_path; |
549 | - this->bus->send(reply); |
550 | }); |
551 | } |
552 | |
553 | |
554 | === modified file 'src/biometry/dbus/skeleton/identifier.h' |
555 | --- src/biometry/dbus/skeleton/identifier.h 2016-05-04 12:17:44 +0000 |
556 | +++ src/biometry/dbus/skeleton/identifier.h 2016-06-17 10:36:14 +0000 |
557 | @@ -22,6 +22,8 @@ |
558 | |
559 | #include <biometry/identifier.h> |
560 | |
561 | +#include <biometry/dbus/skeleton/credentials_resolver.h> |
562 | + |
563 | #include <core/dbus/object.h> |
564 | #include <core/dbus/service.h> |
565 | |
566 | @@ -46,8 +48,22 @@ |
567 | // Safe us some typing. |
568 | typedef std::shared_ptr<Identifier> Ptr; |
569 | |
570 | + /// @brief RequestVerifier models verification of incoming requests. |
571 | + class RequestVerifier : public biometry::dbus::skeleton::RequestVerifier |
572 | + { |
573 | + public: |
574 | + /// @brief verify_identify_user_request returns true if the requesting app identified by provided |
575 | + /// is allowed to run the request described by requested. |
576 | + virtual bool verify_identify_user_request(const Application& requested, const Credentials& provided); |
577 | + }; |
578 | + |
579 | /// @brief create_for_bus returns a new skeleton::Identifier instance connected to bus, forwarding calls to impl. |
580 | - static Ptr create_for_service_and_object(const core::dbus::Bus::Ptr& bus, const core::dbus::Service::Ptr& service, const core::dbus::Object::Ptr& object, const std::reference_wrapper<biometry::Identifier>& impl); |
581 | + static Ptr create_for_service_and_object(const core::dbus::Bus::Ptr& bus, |
582 | + const core::dbus::Service::Ptr& service, |
583 | + const core::dbus::Object::Ptr& object, |
584 | + const std::reference_wrapper<biometry::Identifier>& impl, |
585 | + const std::shared_ptr<RequestVerifier>& request_verifier, |
586 | + const std::shared_ptr<CredentialsResolver>& credentials_resolver); |
587 | |
588 | /// @brief Frees up resources and uninstalls method handlers. |
589 | ~Identifier(); |
590 | @@ -59,9 +75,16 @@ |
591 | typedef biometry::util::Synchronized<std::unordered_map<core::dbus::types::ObjectPath, Operation<Identification>::Ptr>> IdentificationOps; |
592 | |
593 | /// @brief Service creates a new instance for the given remote service and object. |
594 | - Identifier(const core::dbus::Bus::Ptr& bus, const core::dbus::Service::Ptr& service, const core::dbus::Object::Ptr& object, const std::reference_wrapper<biometry::Identifier>& impl); |
595 | + Identifier(const core::dbus::Bus::Ptr& bus, |
596 | + const core::dbus::Service::Ptr& service, |
597 | + const core::dbus::Object::Ptr& object, |
598 | + const std::reference_wrapper<biometry::Identifier>& impl, |
599 | + const std::shared_ptr<RequestVerifier>& request_verifier, |
600 | + const std::shared_ptr<CredentialsResolver>& credentials_resolver); |
601 | |
602 | std::reference_wrapper<biometry::Identifier> impl; |
603 | + std::shared_ptr<RequestVerifier> request_verifier; |
604 | + std::shared_ptr<CredentialsResolver> credentials_resolver; |
605 | |
606 | core::dbus::Bus::Ptr bus; |
607 | core::dbus::Service::Ptr service; |
608 | |
609 | === added file 'src/biometry/dbus/skeleton/request_verifier.cpp' |
610 | --- src/biometry/dbus/skeleton/request_verifier.cpp 1970-01-01 00:00:00 +0000 |
611 | +++ src/biometry/dbus/skeleton/request_verifier.cpp 2016-06-17 10:36:14 +0000 |
612 | @@ -0,0 +1,33 @@ |
613 | +/* |
614 | + * Copyright (C) 2016 Canonical, Ltd. |
615 | + * |
616 | + * This program is free software; you can redistribute it and/or modify |
617 | + * it under the terms of the GNU Lesser General Public License as published by |
618 | + * the Free Software Foundation; version 3. |
619 | + * |
620 | + * This program is distributed in the hope that it will be useful, |
621 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
622 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
623 | + * GNU Lesser General Public License for more details. |
624 | + * |
625 | + * You should have received a copy of the GNU Lesser General Public License |
626 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
627 | + * |
628 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
629 | + * |
630 | + */ |
631 | + |
632 | +#include <biometry/dbus/skeleton/request_verifier.h> |
633 | + |
634 | +#include <iostream> |
635 | +#include <tuple> |
636 | + |
637 | +bool biometry::dbus::skeleton::operator==(const RequestVerifier::Credentials& lhs, const RequestVerifier::Credentials& rhs) |
638 | +{ |
639 | + return std::tie(lhs.app, lhs.user) == std::tie(rhs.app, rhs.user); |
640 | +} |
641 | + |
642 | +std::ostream& biometry::dbus::skeleton::operator<<(std::ostream& out, const RequestVerifier::Credentials& credentials) |
643 | +{ |
644 | + return out << "[" << credentials.app.as_string() << ", " << credentials.user << "]"; |
645 | +} |
646 | |
647 | === added file 'src/biometry/dbus/skeleton/request_verifier.h' |
648 | --- src/biometry/dbus/skeleton/request_verifier.h 1970-01-01 00:00:00 +0000 |
649 | +++ src/biometry/dbus/skeleton/request_verifier.h 2016-06-17 10:36:14 +0000 |
650 | @@ -0,0 +1,60 @@ |
651 | +/* |
652 | + * Copyright (C) 2016 Canonical, Ltd. |
653 | + * |
654 | + * This program is free software; you can redistribute it and/or modify |
655 | + * it under the terms of the GNU Lesser General Public License as published by |
656 | + * the Free Software Foundation; version 3. |
657 | + * |
658 | + * This program is distributed in the hope that it will be useful, |
659 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
660 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
661 | + * GNU Lesser General Public License for more details. |
662 | + * |
663 | + * You should have received a copy of the GNU Lesser General Public License |
664 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
665 | + * |
666 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
667 | + * |
668 | + */ |
669 | + |
670 | +#ifndef BIOMETRYD_DBUS_SKELETON_REQUEST_VERIFIER_H_ |
671 | +#define BIOMETRYD_DBUS_SKELETON_REQUEST_VERIFIER_H_ |
672 | + |
673 | +#include <biometry/application.h> |
674 | +#include <biometry/do_not_copy_or_move.h> |
675 | +#include <biometry/user.h> |
676 | + |
677 | +#include <iosfwd> |
678 | + |
679 | +namespace biometry |
680 | +{ |
681 | +namespace dbus |
682 | +{ |
683 | +namespace skeleton |
684 | +{ |
685 | +/// @brief RequestVerifier is the top-level point of entry to the world |
686 | +/// of verifying incoming requests for different components. |
687 | +/// |
688 | +/// Most importantly, it defines the struct Credentials bundling together |
689 | +/// information about an incoming request. |
690 | +class RequestVerifier : public DoNotCopyOrMove |
691 | +{ |
692 | +public: |
693 | + /// @brief Credentials bundles an app and a user. |
694 | + struct Credentials |
695 | + { |
696 | + Application app; ///< The id of the requesting component. |
697 | + User user; ///< The user under which the requesting component is running. |
698 | + }; |
699 | +}; |
700 | + |
701 | +/// @brief operator== returns true iff lhs and rhs compare equal per component. |
702 | +bool operator==(const RequestVerifier::Credentials& lhs, const RequestVerifier::Credentials& rhs); |
703 | +/// @brief operator<< inserts credentials into out. |
704 | +std::ostream& operator<<(std::ostream& out, const RequestVerifier::Credentials& credentials); |
705 | +} |
706 | +} |
707 | +} |
708 | + |
709 | +#endif // BIOMETRYD_DBUS_SKELETON_REQUEST_VERIFIER_H_ |
710 | + |
711 | |
712 | === modified file 'src/biometry/dbus/skeleton/template_store.cpp' |
713 | --- src/biometry/dbus/skeleton/template_store.cpp 2016-06-14 21:12:44 +0000 |
714 | +++ src/biometry/dbus/skeleton/template_store.cpp 2016-06-17 10:36:14 +0000 |
715 | @@ -30,13 +30,65 @@ |
716 | |
717 | #include <boost/format.hpp> |
718 | |
719 | +namespace |
720 | +{ |
721 | +core::dbus::Message::Ptr not_permitted_in_reply_to(const core::dbus::Message::Ptr& msg) |
722 | +{ |
723 | + return core::dbus::Message::make_error(msg, biometry::dbus::interface::Errors::NotPermitted::name(), ""); |
724 | +} |
725 | + |
726 | +bool verify(const biometry::dbus::skeleton::RequestVerifier::Credentials& requested, const biometry::dbus::skeleton::RequestVerifier::Credentials& provided) |
727 | +{ |
728 | + // In case of a match: good to go. Please note that we |
729 | + // will dispatch to the trust-store in the future, once we |
730 | + // open up the service to all applications. |
731 | + if (requested == provided) |
732 | + return true; |
733 | + |
734 | + // Unconfinded apps are allowed to request operations on behalf of other applications. |
735 | + // We still limit them to their effective uid. |
736 | + if (provided.app.as_string() == "unconfined" && requested.user == provided.user) |
737 | + return true; |
738 | + |
739 | + // All other cases are forbidden. |
740 | + return false; |
741 | +} |
742 | +} |
743 | + |
744 | +bool biometry::dbus::skeleton::TemplateStore::RequestVerifier::verify_size_request(const Credentials& requested, const Credentials& provided) |
745 | +{ |
746 | + return verify(requested, provided); |
747 | +} |
748 | + |
749 | +bool biometry::dbus::skeleton::TemplateStore::RequestVerifier::verify_list_request(const Credentials& requested, const Credentials& provided) |
750 | +{ |
751 | + return verify(requested, provided); |
752 | +} |
753 | + |
754 | +bool biometry::dbus::skeleton::TemplateStore::RequestVerifier::verify_enroll_request(const Credentials& requested, const Credentials& provided) |
755 | +{ |
756 | + return verify(requested, provided); |
757 | +} |
758 | + |
759 | +bool biometry::dbus::skeleton::TemplateStore::RequestVerifier::verify_remove_request(const Credentials& requested, const Credentials& provided) |
760 | +{ |
761 | + return verify(requested, provided); |
762 | +} |
763 | + |
764 | +bool biometry::dbus::skeleton::TemplateStore::RequestVerifier::verify_clear_request(const Credentials& requested, const Credentials& provided) |
765 | +{ |
766 | + return verify(requested, provided); |
767 | +} |
768 | + |
769 | biometry::dbus::skeleton::TemplateStore::Ptr biometry::dbus::skeleton::TemplateStore::create_for_service_and_object( |
770 | const core::dbus::Bus::Ptr& bus, |
771 | const core::dbus::Service::Ptr& service, |
772 | const core::dbus::Object::Ptr& object, |
773 | - const std::reference_wrapper<biometry::TemplateStore>& impl) |
774 | + const std::reference_wrapper<biometry::TemplateStore>& impl, |
775 | + const std::shared_ptr<RequestVerifier>& request_verifier, |
776 | + const std::shared_ptr<CredentialsResolver>& credentials_resolver) |
777 | { |
778 | - return Ptr{new TemplateStore{bus, service, object, impl}}; |
779 | + return Ptr{new TemplateStore{bus, service, object, impl, request_verifier, credentials_resolver}}; |
780 | } |
781 | |
782 | biometry::Operation<biometry::TemplateStore::SizeQuery>::Ptr biometry::dbus::skeleton::TemplateStore::size(const biometry::Application& app, const biometry::User& user) |
783 | @@ -68,115 +120,219 @@ |
784 | const core::dbus::Bus::Ptr& bus, |
785 | const core::dbus::Service::Ptr& service, |
786 | const core::dbus::Object::Ptr& object, |
787 | - const std::reference_wrapper<biometry::TemplateStore>& impl) |
788 | + const std::reference_wrapper<biometry::TemplateStore>& impl, |
789 | + const std::shared_ptr<RequestVerifier>& request_verifier, |
790 | + const std::shared_ptr<CredentialsResolver>& credentials_resolver) |
791 | : impl{impl}, |
792 | + request_verifier{request_verifier}, |
793 | + credentials_resolver{credentials_resolver}, |
794 | bus{bus}, |
795 | service{service}, |
796 | object{object} |
797 | { |
798 | object->install_method_handler<biometry::dbus::interface::TemplateStore::Methods::Size>([this](const core::dbus::Message::Ptr& msg) |
799 | { |
800 | - biometry::User user; biometry::Application app = biometry::Application::system(); |
801 | - auto reader = msg->reader(); reader >> app >> user; |
802 | - auto op = size(app, user); |
803 | - |
804 | - core::dbus::types::ObjectPath op_path |
805 | - { |
806 | - (boost::format{"%1%/operation/size/%2%"} % this->object->path().as_string() % util::counter<TemplateStore>().increment()).str() |
807 | - }; |
808 | - |
809 | - ops.size.synchronized([this, op_path, op](SizeOps::ValueType& ops) |
810 | - { |
811 | - ops[op_path] = skeleton::Operation<SizeQuery>::create_for_object(this->bus, this->service->add_object_for_path(op_path), op); |
812 | + TemplateStore::credentials_resolver->resolve_credentials(msg, [this, msg](const Optional<RequestVerifier::Credentials>& credentials) |
813 | + { |
814 | + if (not credentials) |
815 | + { |
816 | + this->bus->send(not_permitted_in_reply_to(msg)); |
817 | + return; |
818 | + } |
819 | + |
820 | + biometry::User user; biometry::Application app = biometry::Application::system(); |
821 | + auto reader = msg->reader(); reader >> app >> user; |
822 | + |
823 | + if (not this->request_verifier->verify_size_request({app, user}, credentials.get())) |
824 | + { |
825 | + this->bus->send(not_permitted_in_reply_to(msg)); |
826 | + return; |
827 | + } |
828 | + |
829 | + auto op = size(app, user); |
830 | + |
831 | + core::dbus::types::ObjectPath op_path |
832 | + { |
833 | + (boost::format{"%1%/operation/size/%2%/%3%/%4%"} |
834 | + % this->object->path().as_string() |
835 | + % credentials.get().app.as_string() |
836 | + % credentials.get().user.id |
837 | + % util::counter<TemplateStore>().increment()).str() |
838 | + }; |
839 | + |
840 | + ops.size.synchronized([this, op_path, op](SizeOps::ValueType& ops) |
841 | + { |
842 | + ops[op_path] = skeleton::Operation<SizeQuery>::create_for_object(this->bus, this->service->add_object_for_path(op_path), op); |
843 | + }); |
844 | + |
845 | + auto reply = core::dbus::Message::make_method_return(msg); |
846 | + reply->writer() << op_path; |
847 | + this->bus->send(reply); |
848 | }); |
849 | - |
850 | - auto reply = core::dbus::Message::make_method_return(msg); |
851 | - reply->writer() << op_path; |
852 | - this->bus->send(reply); |
853 | }); |
854 | |
855 | object->install_method_handler<biometry::dbus::interface::TemplateStore::Methods::List>([this](const core::dbus::Message::Ptr& msg) |
856 | { |
857 | - biometry::User user; biometry::Application app = biometry::Application::system(); |
858 | - auto reader = msg->reader(); reader >> app >> user; |
859 | - auto op = list(app, user); |
860 | - |
861 | - core::dbus::types::ObjectPath op_path |
862 | - { |
863 | - (boost::format{"%1%/operation/list/%2%"} % this->object->path().as_string() % util::counter<TemplateStore>().increment()).str() |
864 | - }; |
865 | - |
866 | - ops.list.synchronized([this, op_path, op](ListOps::ValueType& ops) |
867 | - { |
868 | - ops[op_path] = skeleton::Operation<List>::create_for_object(this->bus, this->service->add_object_for_path(op_path), op); |
869 | + TemplateStore::credentials_resolver->resolve_credentials(msg, [this, msg](const Optional<RequestVerifier::Credentials>& credentials) |
870 | + { |
871 | + if (not credentials) |
872 | + { |
873 | + this->bus->send(not_permitted_in_reply_to(msg)); |
874 | + return; |
875 | + } |
876 | + |
877 | + biometry::User user; biometry::Application app = biometry::Application::system(); |
878 | + auto reader = msg->reader(); reader >> app >> user; |
879 | + |
880 | + if (not this->request_verifier->verify_list_request({app, user}, credentials.get())) |
881 | + { |
882 | + this->bus->send(not_permitted_in_reply_to(msg)); |
883 | + return; |
884 | + } |
885 | + |
886 | + auto op = list(app, user); |
887 | + |
888 | + core::dbus::types::ObjectPath op_path |
889 | + { |
890 | + (boost::format{"%1%/operation/list/%2%/%3%/%4%"} |
891 | + % this->object->path().as_string() |
892 | + % credentials.get().app.as_string() |
893 | + % credentials.get().user.id |
894 | + % util::counter<TemplateStore>().increment()).str() |
895 | + }; |
896 | + |
897 | + ops.list.synchronized([this, op_path, op](ListOps::ValueType& ops) |
898 | + { |
899 | + ops[op_path] = skeleton::Operation<List>::create_for_object(this->bus, this->service->add_object_for_path(op_path), op); |
900 | + }); |
901 | + |
902 | + auto reply = core::dbus::Message::make_method_return(msg); |
903 | + reply->writer() << op_path; |
904 | + this->bus->send(reply); |
905 | }); |
906 | - |
907 | - auto reply = core::dbus::Message::make_method_return(msg); |
908 | - reply->writer() << op_path; |
909 | - this->bus->send(reply); |
910 | }); |
911 | |
912 | object->install_method_handler<biometry::dbus::interface::TemplateStore::Methods::Enroll>([this](const core::dbus::Message::Ptr& msg) |
913 | { |
914 | - biometry::User user; biometry::Application app = biometry::Application::system(); |
915 | - auto reader = msg->reader(); reader >> app >> user; |
916 | - auto op = enroll(app, user); |
917 | - |
918 | - core::dbus::types::ObjectPath op_path |
919 | - { |
920 | - (boost::format{"%1%/operation/enroll/%2%"} % this->object->path().as_string() % util::counter<TemplateStore>().increment()).str() |
921 | - }; |
922 | - |
923 | - ops.enroll.synchronized([this, op_path, op](EnrollOps::ValueType& ops) |
924 | - { |
925 | - ops[op_path] = skeleton::Operation<Enrollment>::create_for_object(this->bus, this->service->add_object_for_path(op_path), op); |
926 | + TemplateStore::credentials_resolver->resolve_credentials(msg, [this, msg](const Optional<RequestVerifier::Credentials>& credentials) |
927 | + { |
928 | + if (not credentials) |
929 | + { |
930 | + this->bus->send(not_permitted_in_reply_to(msg)); |
931 | + return; |
932 | + } |
933 | + |
934 | + biometry::User user; biometry::Application app = biometry::Application::system(); |
935 | + auto reader = msg->reader(); reader >> app >> user; |
936 | + |
937 | + if (not this->request_verifier->verify_enroll_request({app, user}, credentials.get())) |
938 | + { |
939 | + this->bus->send(not_permitted_in_reply_to(msg)); |
940 | + return; |
941 | + } |
942 | + |
943 | + auto op = enroll(app, user); |
944 | + |
945 | + core::dbus::types::ObjectPath op_path |
946 | + { |
947 | + (boost::format{"%1%/operation/enroll/%2%/%3%/%4%"} |
948 | + % this->object->path().as_string() |
949 | + % credentials.get().app.as_string() |
950 | + % credentials.get().user.id |
951 | + % util::counter<TemplateStore>().increment()).str() |
952 | + }; |
953 | + |
954 | + ops.enroll.synchronized([this, op_path, op](EnrollOps::ValueType& ops) |
955 | + { |
956 | + ops[op_path] = skeleton::Operation<Enrollment>::create_for_object(this->bus, this->service->add_object_for_path(op_path), op); |
957 | + }); |
958 | + |
959 | + auto reply = core::dbus::Message::make_method_return(msg); |
960 | + reply->writer() << op_path; |
961 | + this->bus->send(reply); |
962 | }); |
963 | - |
964 | - auto reply = core::dbus::Message::make_method_return(msg); |
965 | - reply->writer() << op_path; |
966 | - this->bus->send(reply); |
967 | }); |
968 | |
969 | object->install_method_handler<biometry::dbus::interface::TemplateStore::Methods::Remove>([this](const core::dbus::Message::Ptr& msg) |
970 | { |
971 | - biometry::User user; biometry::Application app = biometry::Application::system(); biometry::TemplateStore::TemplateId id{0}; |
972 | - auto reader = msg->reader(); reader >> app >> user >> id; |
973 | - auto op = remove(app, user, id); |
974 | - |
975 | - core::dbus::types::ObjectPath op_path |
976 | - { |
977 | - (boost::format{"%1%/operation/remove/%2%"} % this->object->path().as_string() % util::counter<TemplateStore>().increment()).str() |
978 | - }; |
979 | - |
980 | - ops.remove.synchronized([this, op_path, op](RemoveOps::ValueType& ops) |
981 | - { |
982 | - ops[op_path] = skeleton::Operation<Removal>::create_for_object(this->bus, this->service->add_object_for_path(op_path), op); |
983 | + TemplateStore::credentials_resolver->resolve_credentials(msg, [this, msg](const Optional<RequestVerifier::Credentials>& credentials) |
984 | + { |
985 | + if (not credentials) |
986 | + { |
987 | + this->bus->send(not_permitted_in_reply_to(msg)); |
988 | + return; |
989 | + } |
990 | + |
991 | + biometry::User user; biometry::Application app = biometry::Application::system(); biometry::TemplateStore::TemplateId id{0}; |
992 | + auto reader = msg->reader(); reader >> app >> user >> id; |
993 | + |
994 | + if (not this->request_verifier->verify_remove_request({app, user}, credentials.get())) |
995 | + { |
996 | + this->bus->send(not_permitted_in_reply_to(msg)); |
997 | + return; |
998 | + } |
999 | + |
1000 | + auto op = remove(app, user, id); |
1001 | + |
1002 | + core::dbus::types::ObjectPath op_path |
1003 | + { |
1004 | + (boost::format{"%1%/operation/remove/%2%/%3%/%4%"} |
1005 | + % this->object->path().as_string() |
1006 | + % credentials.get().app.as_string() |
1007 | + % credentials.get().user.id |
1008 | + % util::counter<TemplateStore>().increment()).str() |
1009 | + }; |
1010 | + |
1011 | + ops.remove.synchronized([this, op_path, op](RemoveOps::ValueType& ops) |
1012 | + { |
1013 | + ops[op_path] = skeleton::Operation<Removal>::create_for_object(this->bus, this->service->add_object_for_path(op_path), op); |
1014 | + }); |
1015 | + |
1016 | + auto reply = core::dbus::Message::make_method_return(msg); |
1017 | + reply->writer() << op_path; |
1018 | + this->bus->send(reply); |
1019 | }); |
1020 | - |
1021 | - auto reply = core::dbus::Message::make_method_return(msg); |
1022 | - reply->writer() << op_path; |
1023 | - this->bus->send(reply); |
1024 | }); |
1025 | |
1026 | object->install_method_handler<biometry::dbus::interface::TemplateStore::Methods::Clear>([this](const core::dbus::Message::Ptr& msg) |
1027 | { |
1028 | - biometry::User user; biometry::Application app = biometry::Application::system(); |
1029 | - auto reader = msg->reader(); reader >> app >> user; |
1030 | - auto op = clear(app, user); |
1031 | - |
1032 | - core::dbus::types::ObjectPath op_path |
1033 | - { |
1034 | - (boost::format{"%1%/operation/clear/%2%"} % this->object->path().as_string() % util::counter<TemplateStore>().increment()).str() |
1035 | - }; |
1036 | - |
1037 | - ops.clear.synchronized([this, op_path, op](ClearOps::ValueType& ops) |
1038 | - { |
1039 | - ops[op_path] = skeleton::Operation<Clearance>::create_for_object(this->bus, this->service->add_object_for_path(op_path), op); |
1040 | + TemplateStore::credentials_resolver->resolve_credentials(msg, [this, msg](const Optional<RequestVerifier::Credentials>& credentials) |
1041 | + { |
1042 | + if (not credentials) |
1043 | + { |
1044 | + this->bus->send(not_permitted_in_reply_to(msg)); |
1045 | + return; |
1046 | + } |
1047 | + |
1048 | + biometry::User user; biometry::Application app = biometry::Application::system(); |
1049 | + auto reader = msg->reader(); reader >> app >> user; |
1050 | + |
1051 | + if (not this->request_verifier->verify_clear_request({app, user}, credentials.get())) |
1052 | + { |
1053 | + this->bus->send(not_permitted_in_reply_to(msg)); |
1054 | + return; |
1055 | + } |
1056 | + |
1057 | + auto op = clear(app, user); |
1058 | + |
1059 | + core::dbus::types::ObjectPath op_path |
1060 | + { |
1061 | + (boost::format{"%1%/operation/clear/%2%/%3%/%4%"} |
1062 | + % this->object->path().as_string() |
1063 | + % credentials.get().app.as_string() |
1064 | + % credentials.get().user.id |
1065 | + % util::counter<TemplateStore>().increment()).str() |
1066 | + }; |
1067 | + |
1068 | + ops.clear.synchronized([this, op_path, op](ClearOps::ValueType& ops) |
1069 | + { |
1070 | + ops[op_path] = skeleton::Operation<Clearance>::create_for_object(this->bus, this->service->add_object_for_path(op_path), op); |
1071 | + }); |
1072 | + |
1073 | + auto reply = core::dbus::Message::make_method_return(msg); |
1074 | + reply->writer() << op_path; |
1075 | + this->bus->send(reply); |
1076 | }); |
1077 | - |
1078 | - auto reply = core::dbus::Message::make_method_return(msg); |
1079 | - reply->writer() << op_path; |
1080 | - this->bus->send(reply); |
1081 | }); |
1082 | } |
1083 | |
1084 | |
1085 | === modified file 'src/biometry/dbus/skeleton/template_store.h' |
1086 | --- src/biometry/dbus/skeleton/template_store.h 2016-06-14 21:12:44 +0000 |
1087 | +++ src/biometry/dbus/skeleton/template_store.h 2016-06-17 10:36:14 +0000 |
1088 | @@ -22,6 +22,8 @@ |
1089 | |
1090 | #include <biometry/template_store.h> |
1091 | |
1092 | +#include <biometry/dbus/skeleton/credentials_resolver.h> |
1093 | +#include <biometry/dbus/skeleton/request_verifier.h> |
1094 | #include <biometry/util/synchronized.h> |
1095 | |
1096 | #include <core/dbus/object.h> |
1097 | @@ -46,8 +48,39 @@ |
1098 | // Safe us some typing |
1099 | typedef std::shared_ptr<TemplateStore> Ptr; |
1100 | |
1101 | + /// @brief RequestVerifier models verification of incoming requests. |
1102 | + class RequestVerifier : public biometry::dbus::skeleton::RequestVerifier |
1103 | + { |
1104 | + public: |
1105 | + /// @brief verify_size_request returns true if the application identified by credentials |
1106 | + /// is permitted to query the number of enrolled templates for the app and user bundled in request. |
1107 | + virtual bool verify_size_request(const Credentials& requested, const Credentials& provided); |
1108 | + |
1109 | + /// @brief verify_list_request returns true if the application identified by credentials is |
1110 | + /// allowed to list all templates for the user and app bundled in request. |
1111 | + virtual bool verify_list_request(const Credentials& requested, const Credentials& provided); |
1112 | + |
1113 | + /// @brief verify_enroll_request returns true if the application identified by credentials is |
1114 | + /// allowed to enroll a new template for the app and user bundled in request. |
1115 | + virtual bool verify_enroll_request(const Credentials& requested, const Credentials& provided); |
1116 | + |
1117 | + /// @brief verify_remove_request returns true if the application identified by credentials is |
1118 | + /// allowed to remove a template for the app and user bundled in request. |
1119 | + virtual bool verify_remove_request(const Credentials& requested, const Credentials& provided); |
1120 | + |
1121 | + /// @brief verify_clear_request returns true if the application identified by credentials is |
1122 | + /// allowed to clear all templates for the app and user bundled in request. |
1123 | + virtual bool verify_clear_request(const Credentials& requested, const Credentials& provided); |
1124 | + }; |
1125 | + |
1126 | /// @brief create_for_bus returns a new skeleton::TemplateStore instance connected to bus, forwarding calls to impl. |
1127 | - static Ptr create_for_service_and_object(const core::dbus::Bus::Ptr& bus, const core::dbus::Service::Ptr& service, const core::dbus::Object::Ptr& object, const std::reference_wrapper<biometry::TemplateStore>& impl); |
1128 | + static Ptr create_for_service_and_object( |
1129 | + const core::dbus::Bus::Ptr& bus, |
1130 | + const core::dbus::Service::Ptr& service, |
1131 | + const core::dbus::Object::Ptr& object, |
1132 | + const std::reference_wrapper<biometry::TemplateStore>& impl, |
1133 | + const std::shared_ptr<RequestVerifier>& request_verifier, |
1134 | + const std::shared_ptr<CredentialsResolver>& credentials_resolver); |
1135 | |
1136 | /// @brief Frees up resources and uninstall message handlers. |
1137 | ~TemplateStore(); |
1138 | @@ -68,11 +101,17 @@ |
1139 | typedef util::Synchronized<std::unordered_map<core::dbus::types::ObjectPath, Operation<Clearance>::Ptr>> ClearOps; |
1140 | |
1141 | /// @brief TemplateStore creates a new instance for the given remote service and object. |
1142 | - TemplateStore(const core::dbus::Bus::Ptr& bus, const core::dbus::Service::Ptr& service, const core::dbus::Object::Ptr& object, const std::reference_wrapper<biometry::TemplateStore>& impl); |
1143 | + TemplateStore(const core::dbus::Bus::Ptr& bus, |
1144 | + const core::dbus::Service::Ptr& service, |
1145 | + const core::dbus::Object::Ptr& object, |
1146 | + const std::reference_wrapper<biometry::TemplateStore>& impl, |
1147 | + const std::shared_ptr<RequestVerifier>& request_verifier, |
1148 | + const std::shared_ptr<CredentialsResolver>& credentials_resolver); |
1149 | |
1150 | |
1151 | std::reference_wrapper<biometry::TemplateStore> impl; |
1152 | - |
1153 | + std::shared_ptr<RequestVerifier> request_verifier; |
1154 | + std::shared_ptr<CredentialsResolver> credentials_resolver; |
1155 | core::dbus::Bus::Ptr bus; |
1156 | core::dbus::Service::Ptr service; |
1157 | core::dbus::Object::Ptr object; |
1158 | |
1159 | === modified file 'tests/CMakeLists.txt' |
1160 | --- tests/CMakeLists.txt 2016-05-11 14:39:41 +0000 |
1161 | +++ tests/CMakeLists.txt 2016-06-17 10:36:14 +0000 |
1162 | @@ -44,6 +44,7 @@ |
1163 | gtest_main) |
1164 | |
1165 | add_test(${test_name} ${CMAKE_CURRENT_BINARY_DIR}/${test_name} --gtest_filter=*-*requires*) |
1166 | + set_tests_properties(${test_name} PROPERTIES ENVIRONMENT "BIOMETRYD_DBUS_SKELETON_IS_RUNNING_UNDER_TESTING=1") |
1167 | endmacro(BIOMETRYD_ADD_TEST) |
1168 | |
1169 | add_library(biometryd_devices_plugin_dl SHARED biometryd_devices_plugin_dl.cpp) |
Code looks good