Merge lp:~thomas-voss/location-service/fix-1219164 into lp:location-service/trunk

Proposed by Thomas Voß
Status: Merged
Approved by: Thomas Voß
Approved revision: 90
Merged at revision: 82
Proposed branch: lp:~thomas-voss/location-service/fix-1219164
Merge into: lp:location-service/trunk
Diff against target: 1037 lines (+616/-37)
20 files modified
CMakeLists.txt (+7/-1)
data/CMakeLists.txt (+9/-0)
data/com.ubuntu.location.Service.conf (+5/-1)
data/ubuntu-location-service-trust-stored.conf.in (+13/-0)
debian/control (+4/-0)
debian/ubuntu-location-service-bin.install (+1/-0)
examples/service/service.cpp (+1/-1)
include/location_service/com/ubuntu/location/service/interface.h (+1/-1)
src/location_service/com/ubuntu/location/CMakeLists.txt (+7/-0)
src/location_service/com/ubuntu/location/service/config.h.in (+38/-0)
src/location_service/com/ubuntu/location/service/daemon.cpp (+11/-2)
src/location_service/com/ubuntu/location/service/default_configuration.cpp (+3/-10)
src/location_service/com/ubuntu/location/service/default_configuration.h (+18/-13)
src/location_service/com/ubuntu/location/service/session/skeleton.cpp (+3/-3)
src/location_service/com/ubuntu/location/service/trust_store_permission_manager.cpp (+176/-0)
src/location_service/com/ubuntu/location/service/trust_store_permission_manager.h (+85/-0)
tests/CMakeLists.txt (+1/-0)
tests/acceptance_tests.cpp (+26/-5)
tests/app_armor_testing_profile (+3/-0)
tests/trust_store_permission_manager_test.cpp (+204/-0)
To merge this branch: bzr merge lp:~thomas-voss/location-service/fix-1219164
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Needs Fixing
Seth Arnold (community) Approve
Jamie Strandboge Pending
Marc Deslauriers Pending
Manuel de la Peña Pending
Review via email: mp+228861@code.launchpad.net

Commit message

Make the location service a trusted helper.

Description of the change

Make the location-service a trusted helper.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
75. By Thomas Voß

Add missing build dependencies.
Add tests for TrustStorePermissionManager.
Add tests for AppArmorProfileResolver together with testing apparmor profiles.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
76. By Thomas Voß

[ thomas-voss ]
* Make sure that logging directories are created on service startup.
  (LP: #1349704)
* Fix build warnings.
* Add a vanilla gps.conf file and install it to /etc/gps.conf. Make
  sure that expections thrown while trying to download GPS Xtra data
  do not abort the service. (LP: #1347887)
[ Pete Woods ]
* Add libdbus-cpp and libdbus as dependencies on devel package.
* Enable building on arm64, powerpc and ppc64el.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
77. By Thomas Voß

Make sure that acceptance tests do not fail due to missing trust.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
78. By Thomas Voß

Make sure that upstart configuration for trust-stored is shipped with -bin package.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
79. By Thomas Voß

42 as a pid really does not work well, use getpid() instead.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
80. By Thomas Voß

Execute the incoming connection on a pool of 3 threads.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
81. By Thomas Voß

Adjust dispatching policy for service implementation.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
82. By Thomas Voß

Wait at most 60 seconds for creating a session with the location service.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
83. By Thomas Voß

Dispatch updates from providers instead of calling directly into the client.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
84. By Thomas Voß

Revert dispatcher changes.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
85. By Thomas Voß

Adjust timeout for session creation.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Seth Arnold (seth-arnold) wrote :

The AppArmor policies are being looked up by pid which can be a racy interface. Do the races matter to us? Will something else in the system prevent the following chain of events?

A process with pid 4242 running with AppArmor profile Foo makes a location request
A process dies from some event
B process with any pid spawns children until one has pid 4242
C process with pid 4242 running with AppArmor profile Bar receives permission to use location from previous request

It seems fairly unlikely, I'll admit, but if an attacker can chew up enough CPU time, some race conditions can become arbitrarily easy to exploit.

Thanks

review: Needs Information
86. By Thomas Voß

Asynchronously deliver position/heading/velocity updates.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
87. By Thomas Voß

Add trust-store-bin as build- and runtime-dependency.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
88. By Thomas Voß

Finishing touches to the user-session upstart job for starting the trust-stored skeleton.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
89. By Thomas Voß

Adjust description strings.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Thomas Voß (thomas-voss) wrote :

> The AppArmor policies are being looked up by pid which can be a racy
> interface. Do the races matter to us? Will something else in the system
> prevent the following chain of events?
>
> A process with pid 4242 running with AppArmor profile Foo makes a location
> request
> A process dies from some event
> B process with any pid spawns children until one has pid 4242
> C process with pid 4242 running with AppArmor profile Bar receives permission
> to use location from previous request
>
> It seems fairly unlikely, I'll admit, but if an attacker can chew up enough
> CPU time, some race conditions can become arbitrarily easy to exploit.
>

It's a very good point. To address it, I would propose:

  (1.) Query pid*, uid*, apparmor* profile from dbus daemon
  (2.) Query agent
  (3.) Query pid, uid, apparmor and compare to pid*, uid*, apparmor*

Issue and task is captured here: https://bugs.launchpad.net/location-service/+bug/1352978. However, I would think that we should land the MP as is to make sure we have fixed the critical RTM bug.
> Thanks

Revision history for this message
Seth Arnold (seth-arnold) wrote :

Addressing the potential race in an update is fine with me, thanks for already filing the bug.

We may wish to reconsider the "<profile> is trying to access your location" string -- while this is nicely unambiguous, it's also going to be incomprehensible for the average user.

Are there human-legible strings that uniquely identify the application? Say, APP_ID and a publisher id?

review: Approve
90. By Thomas Voß

We really should store the app id, not the service name.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2014-07-29 09:41:24 +0000
3+++ CMakeLists.txt 2014-08-05 19:36:35 +0000
4@@ -6,6 +6,8 @@
5 set(UBUNTU_LOCATION_SERVICE_VERSION_MINOR 0)
6 set(UBUNTU_LOCATION_SERVICE_VERSION_PATCH 0)
7
8+set(UBUNTU_LOCATION_SERVICE_TRUST_STORE_SERVICE_NAME "UbuntuLocationService")
9+
10 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -pedantic -Wextra -fPIC")
11 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -fno-strict-aliasing -pedantic -Wextra -fPIC")
12
13@@ -27,10 +29,11 @@
14 pkg_check_modules(DBUS dbus-1 REQUIRED)
15 pkg_check_modules(DBUS_CPP dbus-cpp REQUIRED)
16 pkg_check_modules(JSON_C json-c REQUIRED)
17-# TODO(tvoss): Re-enable once net-cpp hits the archive.
18+pkg_check_modules(LIBAPPARMOR libapparmor REQUIRED)
19 pkg_check_modules(NET_CPP net-cpp REQUIRED)
20 pkg_check_modules(PROCESS_CPP process-cpp REQUIRED)
21 pkg_check_modules(PROPERTIES_CPP properties-cpp REQUIRED)
22+pkg_check_modules(TRUST_STORE trust-store REQUIRED)
23 #####################################################################
24 # Enable code coverage calculation with gcov/gcovr/lcov
25 # Usage:
26@@ -56,14 +59,17 @@
27 ${DBUS_INCLUDE_DIRS}
28 ${DBUS_CPP_INCLUDE_DIRS}
29 ${JSON_C_INCLUDE_DIRS}
30+ ${LIBAPPARMOR_INCLUDE_DIRS}
31 ${NET_CPP_INCLUDE_DIRS}
32 ${PROPERTIES_CPP_INCLUDE_DIRS}
33 ${PROCESS_CPP_INCLUDE_DIRS}
34+ ${TRUST_STORE_INCLUDE_DIRS}
35 ${GLog_INCLUDE_DIR}
36 ${GFlags_INCLUDE_DIR}
37
38 ${CMAKE_SOURCE_DIR}/include/location_service
39 ${CMAKE_SOURCE_DIR}/src/location_service
40+ ${CMAKE_BINARY_DIR}/src/location_service
41 )
42
43 file(GLOB_RECURSE UBUNTU_LOCATION_SERVICE_PUBLIC_HEADERS ${CMAKE_CURRENT_SOURCE_DIR} *.h)
44
45=== modified file 'data/CMakeLists.txt'
46--- data/CMakeLists.txt 2014-05-19 18:00:57 +0000
47+++ data/CMakeLists.txt 2014-08-05 19:36:35 +0000
48@@ -26,6 +26,10 @@
49 ubuntu-location-service.conf.in ubuntu-location-service.conf @ONLY
50 )
51
52+configure_file(
53+ ubuntu-location-service-trust-stored.conf.in ubuntu-location-service-trust-stored.conf @ONLY
54+)
55+
56 install(
57 FILES ${CMAKE_CURRENT_BINARY_DIR}/ubuntu-location-service.pc
58 DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
59@@ -45,3 +49,8 @@
60 FILES ${CMAKE_CURRENT_BINARY_DIR}/ubuntu-location-service.conf
61 DESTINATION /etc/init/
62 )
63+
64+install(
65+ FILES ${CMAKE_CURRENT_BINARY_DIR}/ubuntu-location-service-trust-stored.conf
66+ DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/upstart/sessions/
67+)
68
69=== modified file 'data/com.ubuntu.location.Service.conf'
70--- data/com.ubuntu.location.Service.conf 2013-05-28 14:20:45 +0000
71+++ data/com.ubuntu.location.Service.conf 2014-08-05 19:36:35 +0000
72@@ -8,13 +8,17 @@
73 <allow send_destination="com.ubuntu.location.Service.Session"/>
74 <allow send_interface="com.ubuntu.location.Service"/>
75 <allow send_interface="com.ubuntu.location.Service.Session"/>
76+ <allow own="core.trust.dbus.Agent.UbuntuLocationService"/>
77+ <allow send_interface="core.trust.dbus.Agent"/>
78+ <allow send_interface="core.trust.dbus.AgentRegistry"/>
79 </policy>
80 <policy context="default">
81- <deny own="com.ubuntu.location.Service"/>
82+ <deny own="com.ubuntu.location.Service"/>
83 <allow own="com.ubuntu.location.Service.Session"/>
84 <allow send_destination="com.ubuntu.location.Service"/>
85 <allow send_destination="com.ubuntu.location.Service.Session"/>
86 <allow send_interface="com.ubuntu.location.Service"/>
87 <allow send_interface="com.ubuntu.location.Service.Session"/>
88+ <allow send_interface="core.trust.dbus.AgentRegistry"/>
89 </policy>
90 </busconfig>
91
92=== added file 'data/ubuntu-location-service-trust-stored.conf.in'
93--- data/ubuntu-location-service-trust-stored.conf.in 1970-01-01 00:00:00 +0000
94+++ data/ubuntu-location-service-trust-stored.conf.in 2014-08-05 19:36:35 +0000
95@@ -0,0 +1,13 @@
96+description "Location Services Trust Store Daemon"
97+
98+start on started JOB=dbus and started JOB=unity8
99+stop on stopping JOB=dbus or (:sys:stopped JOB=ubuntu-location-service)
100+
101+respawn
102+
103+exec /usr/bin/trust-stored-skeleton \
104+ --remote-agent DBusRemoteAgent --bus=system \
105+ --local-agent MirAgent \
106+ --trusted-mir-socket=/var/run/user/$(id -u)/mir_socket_trusted \
107+ --for-service UbuntuLocationService \
108+ --store-bus session
109
110=== modified file 'debian/control'
111--- debian/control 2014-07-30 14:16:29 +0000
112+++ debian/control 2014-08-05 19:36:35 +0000
113@@ -15,6 +15,7 @@
114 # in libstdc++ causing us issues, we explicitly select a G++
115 # version.
116 g++-4.9,
117+ libapparmor-dev,
118 libboost-filesystem-dev,
119 libboost-program-options-dev,
120 libboost-system-dev,
121@@ -26,9 +27,11 @@
122 libjson-c-dev,
123 libnet-cpp-dev,
124 libprocess-cpp-dev,
125+ libtrust-store-dev,
126 libubuntu-platform-hardware-api-headers [!arm64 !ppc64el !powerpc],
127 libubuntu-platform-hardware-api-dev [!arm64 !ppc64el !powerpc],
128 libproperties-cpp-dev,
129+ trust-store-bin,
130 Standards-Version: 3.9.4
131 Homepage: http://launchpad.net/location-service
132 # If you aren't a member of ~phablet-team but need to upload packaging changes,
133@@ -89,6 +92,7 @@
134 Depends: libubuntu-location-service2 (= ${binary:Version}),
135 ${misc:Depends},
136 ${shlibs:Depends},
137+ trust-store-bin,
138 Breaks: ubuntu-location-service-examples (<< 0.0.2),
139 Replaces: ubuntu-location-service-examples (<< 0.0.2),
140 Description: location service aggregating position/velocity/heading
141
142=== modified file 'debian/ubuntu-location-service-bin.install'
143--- debian/ubuntu-location-service-bin.install 2013-12-16 12:37:07 +0000
144+++ debian/ubuntu-location-service-bin.install 2014-08-05 19:36:35 +0000
145@@ -1,4 +1,5 @@
146 etc/dbus-1/system.d/
147 etc/init/*
148+usr/share/upstart/sessions/ubuntu-location-service-trust-stored.conf
149 usr/bin/ubuntu-location-serviced
150 usr/bin/ubuntu-location-serviced-cli
151
152=== modified file 'examples/service/service.cpp'
153--- examples/service/service.cpp 2014-06-23 04:57:59 +0000
154+++ examples/service/service.cpp 2014-08-05 19:36:35 +0000
155@@ -165,7 +165,7 @@
156 incoming,
157 outgoing,
158 config.the_engine(instantiated_providers, config.the_provider_selection_policy()),
159- config.the_permission_manager(),
160+ config.the_permission_manager(incoming),
161 culs::Harvester::Configuration
162 {
163 cul::connectivity::platform_default_manager(),
164
165=== modified file 'include/location_service/com/ubuntu/location/service/interface.h'
166--- include/location_service/com/ubuntu/location/service/interface.h 2014-02-03 13:52:21 +0000
167+++ include/location_service/com/ubuntu/location/service/interface.h 2014-08-05 19:36:35 +0000
168@@ -81,7 +81,7 @@
169
170 inline static const std::chrono::milliseconds default_timeout()
171 {
172- return std::chrono::seconds{1};
173+ return std::chrono::seconds{25};
174 }
175 };
176
177
178=== modified file 'src/location_service/com/ubuntu/location/CMakeLists.txt'
179--- src/location_service/com/ubuntu/location/CMakeLists.txt 2014-07-31 10:18:42 +0000
180+++ src/location_service/com/ubuntu/location/CMakeLists.txt 2014-08-05 19:36:35 +0000
181@@ -6,6 +6,10 @@
182
183 add_subdirectory(providers)
184
185+configure_file(
186+ service/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/service/config.h @ONLY
187+)
188+
189 add_library(
190 ubuntu-location-service SHARED
191
192@@ -25,6 +29,7 @@
193 service/default_configuration.cpp
194 service/default_permission_manager.cpp
195 service/harvester.cpp
196+ service/trust_store_permission_manager.cpp
197
198 service/implementation.cpp
199 service/skeleton.cpp
200@@ -99,7 +104,9 @@
201 ${DBUS_LIBRARIES}
202 ${DBUS_CPP_LDFLAGS}
203 ${JSON_C_LDFLAGS}
204+ ${LIBAPPARMOR_LDFLAGS}
205 ${NET_CPP_LDFLAGS}
206+ ${TRUST_STORE_LDFLAGS}
207 ${GLog_LIBRARY}
208 ${GFlags_LIBRARY}
209 )
210
211=== added file 'src/location_service/com/ubuntu/location/service/config.h.in'
212--- src/location_service/com/ubuntu/location/service/config.h.in 1970-01-01 00:00:00 +0000
213+++ src/location_service/com/ubuntu/location/service/config.h.in 2014-08-05 19:36:35 +0000
214@@ -0,0 +1,38 @@
215+/*
216+ * Copyright © 2012-2013 Canonical Ltd.
217+ *
218+ * This program is free software: you can redistribute it and/or modify it
219+ * under the terms of the GNU Lesser General Public License version 3,
220+ * as published by the Free Software Foundation.
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+#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_CONFIG_H_
233+#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_CONFIG_H_
234+
235+namespace com
236+{
237+namespace ubuntu
238+{
239+namespace location
240+{
241+namespace service
242+{
243+static constexpr const char* trust_store_service_name
244+{
245+ "@UBUNTU_LOCATION_SERVICE_TRUST_STORE_SERVICE_NAME@"
246+};
247+}
248+}
249+}
250+}
251+
252+#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_CONFIG_H_
253
254=== modified file 'src/location_service/com/ubuntu/location/service/daemon.cpp'
255--- src/location_service/com/ubuntu/location/service/daemon.cpp 2014-07-29 10:51:48 +0000
256+++ src/location_service/com/ubuntu/location/service/daemon.cpp 2014-08-05 19:36:35 +0000
257@@ -192,12 +192,13 @@
258 config.outgoing->install_executor(dbus::asio::make_executor(config.outgoing));
259
260 location::service::DefaultConfiguration dc;
261+
262 location::service::Implementation::Configuration configuration
263 {
264 config.incoming,
265 config.outgoing,
266 dc.the_engine(instantiated_providers, dc.the_provider_selection_policy()),
267- dc.the_permission_manager(),
268+ dc.the_permission_manager(config.outgoing),
269 location::service::Harvester::Configuration
270 {
271 location::connectivity::platform_default_manager(),
272@@ -211,7 +212,9 @@
273 };
274
275 std::thread t1{[&config](){config.incoming->run();}};
276- std::thread t2{[&config](){config.outgoing->run();}};
277+ std::thread t2{[&config](){config.incoming->run();}};
278+ std::thread t3{[&config](){config.incoming->run();}};
279+ std::thread t4{[&config](){config.outgoing->run();}};
280
281 trap->run();
282
283@@ -224,6 +227,12 @@
284 if (t2.joinable())
285 t2.join();
286
287+ if (t3.joinable())
288+ t3.join();
289+
290+ if (t4.joinable())
291+ t4.join();
292+
293 return EXIT_SUCCESS;
294 }
295
296
297=== modified file 'src/location_service/com/ubuntu/location/service/default_configuration.cpp'
298--- src/location_service/com/ubuntu/location/service/default_configuration.cpp 2013-12-14 09:10:29 +0000
299+++ src/location_service/com/ubuntu/location/service/default_configuration.cpp 2014-08-05 19:36:35 +0000
300@@ -17,20 +17,13 @@
301 */
302 #include <com/ubuntu/location/service/default_configuration.h>
303 #include <com/ubuntu/location/service/default_permission_manager.h>
304+#include <com/ubuntu/location/service/trust_store_permission_manager.h>
305
306 #include <com/ubuntu/location/default_provider_selection_policy.h>
307
308 namespace cul = com::ubuntu::location;
309 namespace culs = com::ubuntu::location::service;
310
311-culs::DefaultConfiguration::DefaultConfiguration()
312-{
313-}
314-
315-culs::DefaultConfiguration::~DefaultConfiguration() noexcept
316-{
317-}
318-
319 cul::Engine::Ptr culs::DefaultConfiguration::the_engine(
320 const std::set<cul::Provider::Ptr>& provider_set,
321 const cul::ProviderSelectionPolicy::Ptr& provider_selection_policy)
322@@ -53,8 +46,8 @@
323 return std::set<cul::Provider::Ptr>{seed};
324 }
325
326-culs::PermissionManager::Ptr culs::DefaultConfiguration::the_permission_manager()
327+culs::PermissionManager::Ptr culs::DefaultConfiguration::the_permission_manager(const core::dbus::Bus::Ptr& bus)
328 {
329- return DefaultPermissionManager::Ptr(new DefaultPermissionManager());
330+ return culs::TrustStorePermissionManager::create_default_instance_with_bus(bus);
331 }
332
333
334=== renamed file 'include/location_service/com/ubuntu/location/service/default_configuration.h' => 'src/location_service/com/ubuntu/location/service/default_configuration.h'
335--- include/location_service/com/ubuntu/location/service/default_configuration.h 2013-12-10 09:42:54 +0000
336+++ src/location_service/com/ubuntu/location/service/default_configuration.h 2014-08-05 19:36:35 +0000
337@@ -22,6 +22,8 @@
338
339 #include <set>
340
341+#include <core/dbus/bus.h>
342+
343 namespace com
344 {
345 namespace ubuntu
346@@ -30,24 +32,27 @@
347 {
348 namespace service
349 {
350+// A helper class to create dependencies of the service implementation.
351 class DefaultConfiguration
352 {
353 public:
354- DefaultConfiguration();
355- DefaultConfiguration(const DefaultConfiguration&) = delete;
356- DefaultConfiguration& operator=(const DefaultConfiguration&) = delete;
357- ~DefaultConfiguration() noexcept;
358-
359+ DefaultConfiguration() = default;
360+ virtual ~DefaultConfiguration() = default;
361+
362+ // Creates a policy instance for selecting a set of providers given a criteria
363+ // as specified by a client application.
364+ virtual ProviderSelectionPolicy::Ptr the_provider_selection_policy();
365+
366+ // Returns a set of providers, seeded with the seed provider if it is not null.
367+ virtual std::set<Provider::Ptr> the_provider_set(const Provider::Ptr& seed = Provider::Ptr {});
368+
369+ // Creates an engine instance given a set of providers and a provider selection policy.
370 virtual Engine::Ptr the_engine(
371 const std::set<Provider::Ptr>& provider_set,
372- const ProviderSelectionPolicy::Ptr& provider_selection_policy);
373-
374- ProviderSelectionPolicy::Ptr the_provider_selection_policy();
375-
376- std::set<Provider::Ptr> the_provider_set(
377- const Provider::Ptr& seed = Provider::Ptr {});
378-
379- PermissionManager::Ptr the_permission_manager();
380+ const ProviderSelectionPolicy::Ptr& provider_selection_policy);
381+
382+ // Instantiates an instance of the permission manager.
383+ virtual PermissionManager::Ptr the_permission_manager(const std::shared_ptr<core::dbus::Bus>& bus);
384 };
385 }
386 }
387
388=== modified file 'src/location_service/com/ubuntu/location/service/session/skeleton.cpp'
389--- src/location_service/com/ubuntu/location/service/session/skeleton.cpp 2014-06-24 07:56:00 +0000
390+++ src/location_service/com/ubuntu/location/service/session/skeleton.cpp 2014-08-05 19:36:35 +0000
391@@ -283,7 +283,7 @@
392 VLOG(10) << __PRETTY_FUNCTION__;
393 try
394 {
395- configuration.remote.object->invoke_method_synchronously<culs::session::Interface::UpdatePosition, void>(position);
396+ configuration.remote.object->invoke_method_asynchronously<culs::session::Interface::UpdatePosition, void>(position);
397 } catch(const std::exception&)
398 {
399 // We consider the session to be dead once we hit an exception here.
400@@ -300,7 +300,7 @@
401 VLOG(10) << __PRETTY_FUNCTION__;
402 try
403 {
404- configuration.remote.object->invoke_method_synchronously<culs::session::Interface::UpdateHeading, void>(heading);
405+ configuration.remote.object->invoke_method_asynchronously<culs::session::Interface::UpdateHeading, void>(heading);
406 } catch(const std::exception&)
407 {
408 // We consider the session to be dead once we hit an exception here.
409@@ -317,7 +317,7 @@
410 VLOG(10) << __PRETTY_FUNCTION__;
411 try
412 {
413- configuration.remote.object->invoke_method_synchronously<culs::session::Interface::UpdateVelocity, void>(velocity);
414+ configuration.remote.object->invoke_method_asynchronously<culs::session::Interface::UpdateVelocity, void>(velocity);
415 } catch(const std::exception&)
416 {
417 // We consider the session to be dead once we hit an exception here.
418
419=== added file 'src/location_service/com/ubuntu/location/service/trust_store_permission_manager.cpp'
420--- src/location_service/com/ubuntu/location/service/trust_store_permission_manager.cpp 1970-01-01 00:00:00 +0000
421+++ src/location_service/com/ubuntu/location/service/trust_store_permission_manager.cpp 2014-08-05 19:36:35 +0000
422@@ -0,0 +1,176 @@
423+/*
424+ * Copyright © 2012-2013 Canonical Ltd.
425+ *
426+ * This program is free software: you can redistribute it and/or modify it
427+ * under the terms of the GNU Lesser General Public License version 3,
428+ * as published by the Free Software Foundation.
429+ *
430+ * This program is distributed in the hope that it will be useful,
431+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
432+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
433+ * GNU Lesser General Public License for more details.
434+ *
435+ * You should have received a copy of the GNU Lesser General Public License
436+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
437+ *
438+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
439+ */
440+
441+#include <com/ubuntu/location/service/trust_store_permission_manager.h>
442+
443+#include <com/ubuntu/location/logging.h>
444+#include <com/ubuntu/location/service/config.h>
445+
446+#include <core/trust/dbus_agent.h>
447+
448+#include <core/dbus/bus.h>
449+#include <core/dbus/asio/executor.h>
450+
451+#include <core/posix/this_process.h>
452+
453+#include <sys/apparmor.h>
454+
455+namespace location = com::ubuntu::location;
456+namespace service = com::ubuntu::location::service;
457+
458+namespace
459+{
460+bool is_running_under_testing()
461+{
462+ return core::posix::this_process::env::get(
463+ "TRUST_STORE_PERMISSION_MANAGER_IS_RUNNING_UNDER_TESTING",
464+ "0") == "1";
465+
466+}
467+}
468+
469+service::TrustStorePermissionManager::AppArmorProfileResolver service::TrustStorePermissionManager::libapparmor_profile_resolver()
470+{
471+ return [](core::trust::Pid pid)
472+ {
473+ static const int app_armor_error{-1};
474+
475+ // We make sure to clean up the returned string.
476+ struct Scope
477+ {
478+ ~Scope()
479+ {
480+ if (con) ::free(con);
481+ }
482+
483+ char* con{nullptr};
484+ char* mode{nullptr};
485+ } scope;
486+
487+ // Reach out to apparmor
488+ auto rc = aa_gettaskcon(pid.value, &scope.con, &scope.mode);
489+
490+ // From man aa_gettaskcon:
491+ // On success size of data placed in the buffer is returned, this includes the mode if
492+ //present and any terminating characters. On error, -1 is returned, and errno(3) is
493+ //set appropriately.
494+ if (rc == app_armor_error) throw std::system_error
495+ {
496+ errno,
497+ std::system_category()
498+ };
499+
500+ // Safely construct the string
501+ return std::string
502+ {
503+ scope.con ? scope.con : ""
504+ };
505+ };
506+}
507+
508+core::trust::Feature service::TrustStorePermissionManager::default_feature()
509+{
510+ return core::trust::Feature{0};
511+}
512+
513+service::TrustStorePermissionManager::Ptr service::TrustStorePermissionManager::create_default_instance_with_bus(const std::shared_ptr<core::dbus::Bus>& bus)
514+{
515+ return Ptr
516+ {
517+ new TrustStorePermissionManager
518+ {
519+ core::trust::dbus::create_multi_user_agent_for_bus_connection(
520+ bus,
521+ com::ubuntu::location::service::trust_store_service_name),
522+ TrustStorePermissionManager::libapparmor_profile_resolver()
523+ }
524+ };
525+}
526+
527+service::TrustStorePermissionManager::TrustStorePermissionManager(
528+ const std::shared_ptr<core::trust::Agent>& agent,
529+ service::TrustStorePermissionManager::AppArmorProfileResolver app_armor_profile_resolver)
530+ : agent{agent},
531+ app_armor_profile_resolver{app_armor_profile_resolver}
532+{
533+}
534+
535+service::PermissionManager::Result service::TrustStorePermissionManager::check_permission_for_credentials(
536+ const location::Criteria&,
537+ const service::Credentials& credentials)
538+{
539+ // This is ugly and we should get rid of it. Ideally, we would be able
540+ // inject a mocked trust-store into our acceptance testing.
541+ if (is_running_under_testing())
542+ return Result::granted;
543+
544+ std::string profile;
545+ try
546+ {
547+ profile = app_armor_profile_resolver(core::trust::Pid{credentials.pid});
548+ } catch(const std::exception& e)
549+ {
550+ LOG(ERROR) << "Could not resolve PID " << credentials.pid << " to apparmor profile: " << e.what();
551+ return service::PermissionManager::Result::rejected;
552+ } catch(...)
553+ {
554+ LOG(ERROR) << "Could not resolve PID " << credentials.pid << " to apparmor profile.";
555+ return service::PermissionManager::Result::rejected;
556+ }
557+
558+ std::string description;
559+
560+ if (profile == "unconfined")
561+ {
562+ description = "An unconfined application wants to access your current location.";
563+ } else
564+ {
565+ description = profile + " wants to access your current location.";
566+ }
567+
568+ core::trust::Agent::RequestParameters params
569+ {
570+ core::trust::Uid{credentials.uid},
571+ core::trust::Pid{credentials.pid},
572+ profile,
573+ TrustStorePermissionManager::default_feature(),
574+ description
575+ };
576+
577+ Result result{Result::rejected};
578+
579+ try
580+ {
581+ auto answer = agent->authenticate_request_with_parameters(params);
582+ switch(answer)
583+ {
584+ case core::trust::Request::Answer::granted:
585+ result = Result::granted;
586+ break;
587+ case core::trust::Request::Answer::denied:
588+ result = Result::rejected;
589+ break;
590+ }
591+ } catch(...)
592+ {
593+ // We silently drop all issues here and return rejected.
594+ result = Result::rejected;
595+ }
596+
597+ return result;
598+}
599
600=== added file 'src/location_service/com/ubuntu/location/service/trust_store_permission_manager.h'
601--- src/location_service/com/ubuntu/location/service/trust_store_permission_manager.h 1970-01-01 00:00:00 +0000
602+++ src/location_service/com/ubuntu/location/service/trust_store_permission_manager.h 2014-08-05 19:36:35 +0000
603@@ -0,0 +1,85 @@
604+/*
605+ * Copyright © 2012-2013 Canonical Ltd.
606+ *
607+ * This program is free software: you can redistribute it and/or modify it
608+ * under the terms of the GNU Lesser General Public License version 3,
609+ * as published by the Free Software Foundation.
610+ *
611+ * This program is distributed in the hope that it will be useful,
612+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
613+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
614+ * GNU Lesser General Public License for more details.
615+ *
616+ * You should have received a copy of the GNU Lesser General Public License
617+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
618+ *
619+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
620+ */
621+#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_TRUST_STORE_PERMISSION_MANAGER_H_
622+#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_TRUST_STORE_PERMISSION_MANAGER_H_
623+
624+#include <com/ubuntu/location/service/permission_manager.h>
625+
626+#include <core/trust/agent.h>
627+
628+namespace core
629+{
630+namespace dbus
631+{
632+class Bus;
633+}
634+}
635+
636+namespace com
637+{
638+namespace ubuntu
639+{
640+namespace location
641+{
642+namespace service
643+{
644+// A PermmissionManager implementation leveraging the trust-store
645+// infrastructure to cache a user's answer and to dispatch
646+// to user-specific trust-store instances.
647+class TrustStorePermissionManager : public PermissionManager
648+{
649+public:
650+ // Just a convenience typedef.
651+ typedef std::shared_ptr<TrustStorePermissionManager> Ptr;
652+
653+ // Functor for resolving a process id to an app-armor profile name.
654+ typedef std::function<std::string(const core::trust::Pid&)> AppArmorProfileResolver;
655+
656+ // Returns an AppArmorProfileResolver leveraging libapparmor.
657+ static AppArmorProfileResolver libapparmor_profile_resolver();
658+
659+ // The default feature tag we use when calling out to the agent.
660+ static core::trust::Feature default_feature();
661+
662+ // Creates a default instance, initializing the agent and resolver
663+ // fields to sensible default choices.
664+ static Ptr create_default_instance_with_bus(const std::shared_ptr<core::dbus::Bus>& bus);
665+
666+ // Sets up the manager for operation and stores the agent and resolver
667+ // instances given to the ctor.
668+ TrustStorePermissionManager(
669+ const std::shared_ptr<core::trust::Agent>& agent,
670+ AppArmorProfileResolver app_armor_profile_resolver);
671+
672+ // From PermissionManager
673+ Result check_permission_for_credentials(const Criteria&, const Credentials& credentials) override;
674+
675+private:
676+ // The agent instance we leverage to authenticate
677+ // permission requests.
678+ std::shared_ptr<core::trust::Agent> agent;
679+
680+ // Helper to resolve an application's pid to an app-armor profile name.
681+ AppArmorProfileResolver app_armor_profile_resolver;
682+};
683+}
684+}
685+}
686+}
687+
688+#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_SERVICE_TRUST_STORE_PERMISSION_MANAGER_H_
689
690=== modified file 'tests/CMakeLists.txt'
691--- tests/CMakeLists.txt 2014-07-11 12:56:40 +0000
692+++ tests/CMakeLists.txt 2014-08-05 19:36:35 +0000
693@@ -87,6 +87,7 @@
694 LOCATION_SERVICE_ADD_TEST(provider_factory_test provider_factory_test.cpp)
695 LOCATION_SERVICE_ADD_TEST(provider_test provider_test.cpp)
696 LOCATION_SERVICE_ADD_TEST(wgs84_test wgs84_test.cpp)
697+LOCATION_SERVICE_ADD_TEST(trust_store_permission_manager_test trust_store_permission_manager_test.cpp)
698
699 # Provider-specific test-cases go here.
700 if (LOCATION_SERVICE_ENABLE_GPS_PROVIDER)
701
702=== modified file 'tests/acceptance_tests.cpp'
703--- tests/acceptance_tests.cpp 2014-06-23 04:57:59 +0000
704+++ tests/acceptance_tests.cpp 2014-08-05 19:36:35 +0000
705@@ -64,6 +64,15 @@
706
707 namespace
708 {
709+
710+bool setup_trust_store_permission_manager_for_testing()
711+{
712+ core::posix::this_process::env::set_or_throw("TRUST_STORE_PERMISSION_MANAGER_IS_RUNNING_UNDER_TESTING", "1");
713+ return true;
714+}
715+
716+static const bool trust_store_is_set_up_for_testing = setup_trust_store_permission_manager_for_testing();
717+
718 struct NullReporter : public culs::Harvester::Reporter
719 {
720 NullReporter() = default;
721@@ -168,6 +177,8 @@
722
723 TEST_F(LocationServiceStandalone, SessionsReceiveUpdatesViaDBus)
724 {
725+ EXPECT_TRUE(trust_store_is_set_up_for_testing);
726+
727 core::testing::CrossProcessSync sync_start;
728 core::testing::CrossProcessSync sync_session_created;
729
730@@ -199,7 +210,7 @@
731 incoming,
732 outgoing,
733 config.the_engine(config.the_provider_set(helper), config.the_provider_selection_policy()),
734- config.the_permission_manager(),
735+ config.the_permission_manager(incoming),
736 cul::service::Harvester::Configuration
737 {
738 cul::connectivity::platform_default_manager(),
739@@ -293,6 +304,8 @@
740
741 TEST_F(LocationServiceStandalone, EngineStatusCanBeQueriedAndAdjusted)
742 {
743+ EXPECT_TRUE(trust_store_is_set_up_for_testing);
744+
745 core::testing::CrossProcessSync sync_start;
746
747 auto server = [this, &sync_start]()
748@@ -319,7 +332,7 @@
749 incoming,
750 outgoing,
751 config.the_engine(config.the_provider_set(helper), config.the_provider_selection_policy()),
752- config.the_permission_manager(),
753+ config.the_permission_manager(incoming),
754 cul::service::Harvester::Configuration
755 {
756 cul::connectivity::platform_default_manager(),
757@@ -371,6 +384,8 @@
758
759 TEST_F(LocationServiceStandalone, SatellitePositioningStatusCanBeQueriedAndAdjusted)
760 {
761+ EXPECT_TRUE(trust_store_is_set_up_for_testing);
762+
763 core::testing::CrossProcessSync sync_start;
764
765 auto server = [this, &sync_start]()
766@@ -398,7 +413,7 @@
767 incoming,
768 outgoing,
769 config.the_engine(config.the_provider_set(helper), config.the_provider_selection_policy()),
770- config.the_permission_manager(),
771+ config.the_permission_manager(incoming),
772 cul::service::Harvester::Configuration
773 {
774 cul::connectivity::platform_default_manager(),
775@@ -450,6 +465,8 @@
776
777 TEST_F(LocationServiceStandalone, WifiAndCellIdReportingStateCanBeQueriedAndAjdusted)
778 {
779+ EXPECT_TRUE(trust_store_is_set_up_for_testing);
780+
781 core::testing::CrossProcessSync sync_start;
782
783 auto server = [this, &sync_start]()
784@@ -476,7 +493,7 @@
785 incoming,
786 outgoing,
787 config.the_engine(config.the_provider_set(helper), config.the_provider_selection_policy()),
788- config.the_permission_manager(),
789+ config.the_permission_manager(incoming),
790 cul::service::Harvester::Configuration
791 {
792 cul::connectivity::platform_default_manager(),
793@@ -527,6 +544,8 @@
794
795 TEST_F(LocationServiceStandalone, VisibleSpaceVehiclesCanBeQueried)
796 {
797+ EXPECT_TRUE(trust_store_is_set_up_for_testing);
798+
799 core::testing::CrossProcessSync sync_start;
800
801 cul::SpaceVehicle sv;
802@@ -562,7 +581,7 @@
803 incoming,
804 outgoing,
805 config.the_engine(config.the_provider_set(helper), config.the_provider_selection_policy()),
806- config.the_permission_manager(),
807+ config.the_permission_manager(incoming),
808 cul::service::Harvester::Configuration
809 {
810 cul::connectivity::platform_default_manager(),
811@@ -713,6 +732,8 @@
812
813 TEST_F(LocationServiceStandaloneLoad, MultipleClientsConnectingAndDisconnectingWorks)
814 {
815+ EXPECT_TRUE(trust_store_is_set_up_for_testing);
816+
817 options.print(LOG(INFO));
818
819 auto server = core::posix::fork([this]()
820
821=== added file 'tests/app_armor_testing_profile'
822--- tests/app_armor_testing_profile 1970-01-01 00:00:00 +0000
823+++ tests/app_armor_testing_profile 2014-08-05 19:36:35 +0000
824@@ -0,0 +1,3 @@
825+profile an_empty_profile_for_testing_purposes
826+{
827+}
828\ No newline at end of file
829
830=== added file 'tests/trust_store_permission_manager_test.cpp'
831--- tests/trust_store_permission_manager_test.cpp 1970-01-01 00:00:00 +0000
832+++ tests/trust_store_permission_manager_test.cpp 2014-08-05 19:36:35 +0000
833@@ -0,0 +1,204 @@
834+/*
835+ * Copyright © 2012-2013 Canonical Ltd.
836+ *
837+ * This program is free software: you can redistribute it and/or modify it
838+ * under the terms of the GNU Lesser General Public License version 3,
839+ * as published by the Free Software Foundation.
840+ *
841+ * This program is distributed in the hope that it will be useful,
842+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
843+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
844+ * GNU Lesser General Public License for more details.
845+ *
846+ * You should have received a copy of the GNU Lesser General Public License
847+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
848+ *
849+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
850+ */
851+
852+#include <com/ubuntu/location/service/trust_store_permission_manager.h>
853+
854+#include <com/ubuntu/location/criteria.h>
855+
856+#include <core/posix/fork.h>
857+#include <core/testing/cross_process_sync.h>
858+
859+#include <gmock/gmock.h>
860+
861+#include <thread>
862+
863+#include <sys/apparmor.h>
864+
865+namespace location = com::ubuntu::location;
866+namespace service = com::ubuntu::location::service;
867+
868+namespace
869+{
870+struct MockAgent : public core::trust::Agent
871+{
872+ /**
873+ * @brief Presents the given request to the user, returning the user-provided answer.
874+ * @param request The trust request that a user has to answer.
875+ * @param description Extended description of the trust request.
876+ */
877+ MOCK_METHOD1(authenticate_request_with_parameters, core::trust::Request::Answer(const core::trust::Agent::RequestParameters&));
878+};
879+
880+struct MockAppArmorProfileResolver
881+{
882+ MOCK_METHOD1(resolve_pid_to_app_armor_profile, std::string(const core::trust::Pid&));
883+
884+ service::TrustStorePermissionManager::AppArmorProfileResolver to_functional()
885+ {
886+ return [this](const core::trust::Pid& pid)
887+ {
888+ return resolve_pid_to_app_armor_profile(pid);
889+ };
890+ }
891+};
892+
893+location::Criteria default_criteria;
894+}
895+
896+TEST(TrustStorePermissionManager, calls_out_to_agent)
897+{
898+ using namespace ::testing;
899+
900+ auto mock_agent = std::make_shared<MockAgent>();
901+
902+ EXPECT_CALL(*mock_agent, authenticate_request_with_parameters(_))
903+ .Times(1)
904+ .WillRepeatedly(Return(core::trust::Request::Answer::denied));
905+
906+ service::TrustStorePermissionManager pm
907+ {
908+ mock_agent,
909+ service::TrustStorePermissionManager::libapparmor_profile_resolver()
910+ };
911+
912+ EXPECT_EQ(service::PermissionManager::Result::rejected,
913+ pm.check_permission_for_credentials(
914+ default_criteria,
915+ location::service::Credentials{::getpid(), ::getuid()}));
916+}
917+
918+TEST(TrustStorePermissionManager, returns_rejected_for_throwing_agent)
919+{
920+ using namespace ::testing;
921+
922+ auto mock_agent = std::make_shared<MockAgent>();
923+
924+ EXPECT_CALL(*mock_agent, authenticate_request_with_parameters(_))
925+ .Times(1)
926+ .WillRepeatedly(Throw(std::runtime_error{"Thrown from mock agent"}));
927+
928+ service::TrustStorePermissionManager pm{mock_agent, service::TrustStorePermissionManager::libapparmor_profile_resolver()};
929+
930+ EXPECT_EQ(service::PermissionManager::Result::rejected,
931+ pm.check_permission_for_credentials(default_criteria, location::service::Credentials{::getpid(), ::getuid()}));
932+}
933+
934+TEST(TrustStorePermissionManager, resolves_app_id)
935+{
936+ using namespace ::testing;
937+
938+ const pid_t pid = ::getpid();
939+ const uid_t uid = ::getuid();
940+
941+ auto mock_agent = std::make_shared<MockAgent>();
942+
943+ EXPECT_CALL(*mock_agent, authenticate_request_with_parameters(_))
944+ .Times(1)
945+ .WillRepeatedly(Return(core::trust::Request::Answer::denied));
946+
947+ MockAppArmorProfileResolver resolver;
948+ EXPECT_CALL(resolver, resolve_pid_to_app_armor_profile(core::trust::Pid{pid}))
949+ .Times(1)
950+ .WillRepeatedly(Return(std::string{"does.not.exist"}));
951+
952+ service::TrustStorePermissionManager pm
953+ {
954+ mock_agent,
955+ resolver.to_functional()
956+ };
957+
958+ EXPECT_EQ(service::PermissionManager::Result::rejected,
959+ pm.check_permission_for_credentials(default_criteria, location::service::Credentials{pid, uid}));
960+}
961+
962+TEST(TrustStorePermissionManager, returns_rejected_for_throwing_app_id_resolver)
963+{
964+ using namespace ::testing;
965+
966+ const pid_t pid = ::getpid();
967+ const uid_t uid = ::getuid();
968+
969+ auto mock_agent = std::make_shared<MockAgent>();
970+
971+ EXPECT_CALL(*mock_agent, authenticate_request_with_parameters(_))
972+ .Times(0); // This should never be called if we cannot resolve an apparmor profile.
973+
974+ MockAppArmorProfileResolver resolver;
975+ EXPECT_CALL(resolver, resolve_pid_to_app_armor_profile(core::trust::Pid{pid}))
976+ .Times(1)
977+ .WillRepeatedly(Throw(std::runtime_error{"Thrown from MockAppArmorProfileResolver"}));
978+
979+ service::TrustStorePermissionManager pm
980+ {
981+ mock_agent,
982+ resolver.to_functional()
983+ };
984+
985+ EXPECT_EQ(service::PermissionManager::Result::rejected,
986+ pm.check_permission_for_credentials(default_criteria, location::service::Credentials{pid, uid}));
987+}
988+
989+// We should be provided with this kind of functionality by the trust-store.
990+// The respective request is captured here:
991+// https://bugs.launchpad.net/trust-store/+bug/1350736
992+TEST(AppArmorProfileResolver, libapparmor_profile_resolver_returns_correct_profile_for_unconfined_process)
993+{
994+ auto child = core::posix::fork(
995+ []() { while (true); return core::posix::exit::Status::success;},
996+ core::posix::StandardStream::empty);
997+
998+ EXPECT_EQ("unconfined",
999+ service::TrustStorePermissionManager::libapparmor_profile_resolver()(core::trust::Pid{child.pid()}));
1000+}
1001+
1002+TEST(AppArmorProfileResolver, libapparmor_profile_resolver_throws_for_apparmor_error)
1003+{
1004+ // Passing -1 as the pid value results in the underlying apparmor call failing
1005+ // and the implementation translating to a std::system_error.
1006+ EXPECT_THROW(service::TrustStorePermissionManager::libapparmor_profile_resolver()(core::trust::Pid{-1}),
1007+ std::system_error);
1008+}
1009+
1010+// We disabel this test by default as it requires the developer to take some manual preparations.
1011+// Specifically:
1012+// sudo apparmor-parser -n for_testing --add tests/app_armor_testing_profile
1013+namespace for_testing
1014+{
1015+ static constexpr const char* an_empty_profile_for_testing_purposes
1016+ {
1017+ "an_empty_profile_for_testing_purposes"
1018+ };
1019+}
1020+TEST(AppArmorProfileResolver, DISABLED_libapparmor_profile_resolver_returns_correct_profile_for_confined_process)
1021+{
1022+ core::testing::CrossProcessSync cps; // child --| aa_profile_changed |--> parent
1023+ auto child = core::posix::fork(
1024+ [&cps]()
1025+ {
1026+ aa_change_profile(for_testing::an_empty_profile_for_testing_purposes);
1027+ cps.try_signal_ready_for(std::chrono::milliseconds{500});
1028+ while (true);
1029+ return core::posix::exit::Status::success;
1030+ },
1031+ core::posix::StandardStream::empty);
1032+
1033+ cps.wait_for_signal_ready_for(std::chrono::milliseconds{500});
1034+
1035+ EXPECT_EQ(for_testing::an_empty_profile_for_testing_purposes,
1036+ service::TrustStorePermissionManager::libapparmor_profile_resolver()(core::trust::Pid{child.pid()}));
1037+}

Subscribers

People subscribed via source and target branches