Merge lp:~attente/ubuntu-system-settings/session-settings-service into lp:ubuntu-system-settings

Proposed by William Hua
Status: Work in progress
Proposed branch: lp:~attente/ubuntu-system-settings/session-settings-service
Merge into: lp:ubuntu-system-settings
Diff against target: 291 lines (+201/-2)
10 files modified
CMakeLists.txt (+6/-0)
data/CMakeLists.txt (+2/-0)
data/session-settings-service.conf.in (+9/-0)
debian/control (+3/-0)
debian/ubuntu-system-settings.install (+1/-0)
lib/SystemSettings/CMakeLists.txt (+8/-2)
lib/SystemSettings/com.ubuntu.Settings.xml (+17/-0)
src/CMakeLists.txt (+1/-0)
src/service/CMakeLists.txt (+10/-0)
src/service/server.vala (+144/-0)
To merge this branch: bzr merge lp:~attente/ubuntu-system-settings/session-settings-service
Reviewer Review Type Date Requested Status
Thomas Voß (community) Disapprove
PS Jenkins bot continuous-integration Approve
Ubuntu Touch System Settings Pending
Review via email: mp+228121@code.launchpad.net

Commit message

Add a session-settings-service.

Providing confined apps with direct access to AccountsService is too dangerous. There's too much sensitive information such as LoginHistory, PasswordHint, etc. Also, because object paths for users are dynamic (e.g. /org/freedesktop/Accounts/User1000), we cannot write AppArmor policy to restrict calls for other users' data.

We propose a service that allows confined apps to read-only access for a limited subset of non-sensitive AccountsService data (language and locale). The service lives on the session bus and provides explicit getters and change notification signals. The service does not provide D-Bus properties since that requires AppArmor policy that opens up the org.freedesktop.DBus.Properties interface.

Compare the following policies. The first is what's needed for direct AccountsService access, the second is what's needed using the proposed session service:

dbus bus=system
     path=/org/freedesktop/Accounts
     interface=org.freedesktop.DBus.Properties
     member=GetAll,
dbus bus=system
     path=/org/freedesktop/Accounts
     interface=org.freedesktop.Accounts
     member=ListCachedUsers,
dbus bus=system
     path=/org/freedesktop/Accounts
     interface=org.freedesktop.Accounts
     member=FindUserByName,
dbus bus=system
     interface=org.freedesktop.DBus.Properties
     member=GetAll,
dbus bus=system
     interface=org.freedesktop.Accounts.User
     member=Changed,

vs.

dbus (send)
     bus=session
     path=/com/canonical/UbuntuSystemSettings
     interface=com.ubuntu.Settings
     member=GetLanguage,
dbus (send)
     bus=session
     path=/com/canonical/UbuntuSystemSettings
     interface=com.ubuntu.Settings
     member=GetLocale,
dbus (receive)
     bus=session
     path=/com/canonical/UbuntuSystemSettings
     interface=com.ubuntu.Settings
     member=LanguageChanged,
dbus (receive)
     bus=session
     path=/com/canonical/UbuntuSystemSettings
     interface=com.ubuntu.Settings
     member=LocaleChanged,

Description of the change

Add a session-settings-service.

Providing confined apps with direct access to AccountsService is too dangerous. There's too much sensitive information such as LoginHistory, PasswordHint, etc. Also, because object paths for users are dynamic (e.g. /org/freedesktop/Accounts/User1000), we cannot write AppArmor policy to restrict calls for other users' data.

We propose a service that allows confined apps to read-only access for a limited subset of non-sensitive AccountsService data (language and locale). The service lives on the session bus and provides explicit getters and change notification signals. The service does not provide D-Bus properties since that requires AppArmor policy that opens up the org.freedesktop.DBus.Properties interface.

Compare the following policies. The first is what's needed for direct AccountsService access, the second is what's needed using the proposed session service:

dbus bus=system
     path=/org/freedesktop/Accounts
     interface=org.freedesktop.DBus.Properties
     member=GetAll,
dbus bus=system
     path=/org/freedesktop/Accounts
     interface=org.freedesktop.Accounts
     member=ListCachedUsers,
dbus bus=system
     path=/org/freedesktop/Accounts
     interface=org.freedesktop.Accounts
     member=FindUserByName,
dbus bus=system
     interface=org.freedesktop.DBus.Properties
     member=GetAll,
dbus bus=system
     interface=org.freedesktop.Accounts.User
     member=Changed,

vs.

dbus (send)
     bus=session
     path=/com/canonical/UbuntuSystemSettings
     interface=com.ubuntu.Settings
     member=GetLanguage,
dbus (send)
     bus=session
     path=/com/canonical/UbuntuSystemSettings
     interface=com.ubuntu.Settings
     member=GetLocale,
dbus (receive)
     bus=session
     path=/com/canonical/UbuntuSystemSettings
     interface=com.ubuntu.Settings
     member=LanguageChanged,
dbus (receive)
     bus=session
     path=/com/canonical/UbuntuSystemSettings
     interface=com.ubuntu.Settings
     member=LocaleChanged,

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

Merge trunk.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:816
http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-ci/1054/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-utopic-touch/2458
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-utopic/1993
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-amd64-ci/246
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/246
        deb: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-armhf-ci/246/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/ubuntu-system-settings-utopic-i386-ci/246
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-mako/2620
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/3699
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/3699/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/10375
    SUCCESS: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-utopic/1666
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/2243
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/2243/artifact/work/output/*zip*/output.zip

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/ubuntu-system-settings-ci/1054/rebuild

review: Approve (continuous-integration)
Revision history for this message
Thomas Voß (thomas-voss) wrote :

First of all thanks for the changes. Two things, though:

  * Our general policy for any new code is to avoid Vala. C, C++/QML or Go is fine, please consider C++ as it is the implementation language of Ubuntu System Settings.

  * It would be quite helpful if you could provide reviewers with an arch document detailing the rationale behind your proposed changes. I appreciate your summary on the MP, but would like to have all stakeholders involved here. Exposing certain types of settings via a service is a feature requested across the board and we should make sure that we have requirements captured properly.

Thanks again for the changes, but I'm still disapproving for the reasons mentioned before.

review: Disapprove

Unmerged revisions

816. By William Hua

Merge trunk.

815. By William Hua

Update com.ubuntu.Settings interface.

814. By William Hua

Use explicit getters and change signals.

813. By William Hua

Rename system-settings-service to session-settings-service.

812. By William Hua

Use dash instead of underscore.

811. By William Hua

Capitalize property names.

810. By William Hua

Add missing build dependencies.

809. By William Hua

Add copyright header.

808. By William Hua

Remove Service header.

807. By William Hua

System settings service.

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-06-19 13:32:47 +0000
3+++ CMakeLists.txt 2014-07-24 17:28:32 +0000
4@@ -56,9 +56,15 @@
5 set(PLUGIN_PRIVATE_MODULE_DIR "${CMAKE_INSTALL_PREFIX}/${LIBDIR}/${PLUGIN_PRIVATE_MODULE_DIR_BASE}")
6 set(SETTINGS_SHARE_DIR "${CMAKE_INSTALL_PREFIX}/${PLUGIN_MANIFEST_DIR_BASE}")
7
8+set(SERVICE_INSTALL_DIR_BASE ubuntu-system-settings)
9+set(SERVICE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/${LIBDIR}/${SERVICE_INSTALL_DIR_BASE}")
10+set(UPSTART_INSTALL_DIR_BASE share/upstart/sessions)
11+set(UPSTART_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/${UPSTART_INSTALL_DIR_BASE}")
12+
13 SET(CMAKE_INSTALL_RPATH "${PLUGIN_MODULE_DIR}")
14
15 add_subdirectory(po)
16+add_subdirectory(data)
17 add_subdirectory(schema)
18 add_subdirectory(lib)
19 include_directories(lib)
20
21=== added directory 'data'
22=== added file 'data/CMakeLists.txt'
23--- data/CMakeLists.txt 1970-01-01 00:00:00 +0000
24+++ data/CMakeLists.txt 2014-07-24 17:28:32 +0000
25@@ -0,0 +1,2 @@
26+configure_file(session-settings-service.conf.in session-settings-service.conf @ONLY)
27+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/session-settings-service.conf DESTINATION ${UPSTART_INSTALL_DIR})
28
29=== added file 'data/session-settings-service.conf.in'
30--- data/session-settings-service.conf.in 1970-01-01 00:00:00 +0000
31+++ data/session-settings-service.conf.in 2014-07-24 17:28:32 +0000
32@@ -0,0 +1,9 @@
33+description "Session settings service"
34+author "William Hua <william.hua@canonical.com>"
35+
36+start on started dbus
37+stop on stopping dbus
38+
39+respawn
40+
41+exec @SERVICE_INSTALL_DIR@/session-settings-service
42
43=== modified file 'debian/control'
44--- debian/control 2014-07-21 14:50:32 +0000
45+++ debian/control 2014-07-24 17:28:32 +0000
46@@ -32,6 +32,9 @@
47 pep8,
48 python3-pep8,
49 pyflakes,
50+ dh-apparmor,
51+ libgirepository1.0-dev,
52+ valac,
53 Standards-Version: 3.9.4
54 Homepage: https://launchpad.net/ubuntu-system-settings
55 # If you aren't a member of ~system-settings-touch but need to upload packaging
56
57=== modified file 'debian/ubuntu-system-settings.install'
58--- debian/ubuntu-system-settings.install 2014-07-17 16:25:10 +0000
59+++ debian/ubuntu-system-settings.install 2014-07-24 17:28:32 +0000
60@@ -4,4 +4,5 @@
61 usr/share/glib-2.0
62 usr/share/locale
63 usr/share/ubuntu/settings/system
64+usr/share/upstart/sessions/session-settings-service.conf
65 usr/share/url-dispatcher
66
67=== modified file 'lib/SystemSettings/CMakeLists.txt'
68--- lib/SystemSettings/CMakeLists.txt 2013-09-30 11:11:20 +0000
69+++ lib/SystemSettings/CMakeLists.txt 2014-07-24 17:28:32 +0000
70@@ -1,4 +1,8 @@
71-add_library(SystemSettings SHARED item-base.cpp item-base.h)
72+include_directories(SYSTEM ${GIO_INCLUDE_DIRS})
73+link_directories(${GIO_LIBRARY_DIRS})
74+
75+add_library(SystemSettings SHARED item-base.cpp item-base.h service.c)
76+target_link_libraries(SystemSettings ${GIO_LIBRARIES})
77 set_target_properties(SystemSettings PROPERTIES
78 VERSION 1.0.0
79 SOVERSION 1
80@@ -7,9 +11,11 @@
81 qt5_use_modules(SystemSettings Core Gui Quick Qml)
82
83 install(TARGETS SystemSettings LIBRARY DESTINATION ${LIBDIR})
84-install(FILES item-base.h ItemBase plugin-interface.h PluginInterface
85+install(FILES item-base.h ItemBase plugin-interface.h PluginInterface ${CMAKE_CURRENT_BINARY_DIR}/service.h
86 DESTINATION include/SystemSettings)
87
88 set(SYSTEMSETTINGS_LIB SystemSettings)
89 configure_file(SystemSettings.pc.in SystemSettings.pc @ONLY)
90 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/SystemSettings.pc DESTINATION ${LIBDIR}/pkgconfig)
91+
92+add_custom_command(OUTPUT service.h service.c COMMAND gdbus-codegen --interface-prefix com.ubuntu --generate-c-code service --c-namespace USS ${CMAKE_CURRENT_SOURCE_DIR}/com.ubuntu.Settings.xml DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/com.ubuntu.Settings.xml)
93
94=== added file 'lib/SystemSettings/com.ubuntu.Settings.xml'
95--- lib/SystemSettings/com.ubuntu.Settings.xml 1970-01-01 00:00:00 +0000
96+++ lib/SystemSettings/com.ubuntu.Settings.xml 2014-07-24 17:28:32 +0000
97@@ -0,0 +1,17 @@
98+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
99+<node>
100+ <interface name="com.ubuntu.Settings">
101+ <method name="GetLanguage">
102+ <arg name="language" type="s" direction="out" />
103+ </method>
104+ <method name="GetLocale">
105+ <arg name="locale" type="s" direction="out" />
106+ </method>
107+ <signal name="LanguageChanged">
108+ <arg name="language" type="s" />
109+ </signal>
110+ <signal name="LocaleChanged">
111+ <arg name="locale" type="s" />
112+ </signal>
113+ </interface>
114+</node>
115
116=== modified file 'src/CMakeLists.txt'
117--- src/CMakeLists.txt 2014-02-13 15:27:47 +0000
118+++ src/CMakeLists.txt 2014-07-24 17:28:32 +0000
119@@ -6,6 +6,7 @@
120 add_definitions(-DPLUGIN_MODULE_DIR="${PLUGIN_MODULE_DIR}")
121
122 add_subdirectory(SystemSettings)
123+add_subdirectory(service)
124
125 set(USS_SOURCES
126 debug.cpp
127
128=== added directory 'src/service'
129=== added file 'src/service/CMakeLists.txt'
130--- src/service/CMakeLists.txt 1970-01-01 00:00:00 +0000
131+++ src/service/CMakeLists.txt 2014-07-24 17:28:32 +0000
132@@ -0,0 +1,10 @@
133+include_directories(SYSTEM ${GIO_INCLUDE_DIRS} ${ACCOUNTSSERVICE_INCLUDE_DIRS})
134+link_directories(${GIO_LIBRARY_DIRS} ${ACCOUNTSSERVICE_LIBRARY_DIRS})
135+
136+add_executable(service-bin server.c)
137+set_target_properties(service-bin PROPERTIES OUTPUT_NAME session-settings-service)
138+target_link_libraries(service-bin ${GIO_LIBRARIES} ${ACCOUNTSSERVICE_LIBRARIES})
139+install(TARGETS service-bin RUNTIME DESTINATION ${SERVICE_INSTALL_DIR})
140+
141+add_custom_command(OUTPUT server.c COMMAND valac -C --enable-experimental-non-null --vapidir=. --pkg gio-2.0 --pkg posix --pkg accountsservice ${CMAKE_CURRENT_SOURCE_DIR}/server.vala DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/server.vala accountsservice.vapi)
142+add_custom_command(OUTPUT accountsservice.vapi COMMAND vapigen --pkg gio-2.0 --library accountsservice /usr/share/gir-1.0/AccountsService-1.0.gir)
143
144=== added file 'src/service/server.vala'
145--- src/service/server.vala 1970-01-01 00:00:00 +0000
146+++ src/service/server.vala 2014-07-24 17:28:32 +0000
147@@ -0,0 +1,144 @@
148+/*
149+ * Copyright (C) 2014 Canonical Ltd.
150+ *
151+ * Contact: William Hua <william.hua@canonical.com>
152+ *
153+ * This program is free software: you can redistribute it and/or modify it
154+ * under the terms of the GNU General Public License version 3, as published
155+ * by the Free Software Foundation.
156+ *
157+ * This program is distributed in the hope that it will be useful, but
158+ * WITHOUT ANY WARRANTY; without even the implied warranties of
159+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
160+ * PURPOSE. See the GNU General Public License for more details.
161+ *
162+ * You should have received a copy of the GNU General Public License along
163+ * with this program. If not, see <http://www.gnu.org/licenses/>.
164+ */
165+
166+[DBus (name = "com.ubuntu.Settings")]
167+public class Server : Object {
168+
169+ private string? _language;
170+ private string? _locale;
171+
172+ private DBusConnection _connection;
173+
174+ private Act.UserManager? _accountsservice_manager;
175+ private ulong _accountsservice_manager_id;
176+ private Act.User? _accountsservice_user;
177+ private ulong _accountsservice_user_id[2];
178+
179+ public Server (DBusConnection connection) {
180+ _connection = connection;
181+
182+ load_accountsservice_manager ();
183+ }
184+
185+ ~Server () {
186+ if (_accountsservice_user != null) {
187+ if (_accountsservice_user_id[1] > 0) {
188+ ((!) _accountsservice_user).disconnect (_accountsservice_user_id[1]);
189+ }
190+
191+ if (_accountsservice_user_id[0] > 0) {
192+ ((!) _accountsservice_user).disconnect (_accountsservice_user_id[0]);
193+ }
194+ }
195+
196+ if (_accountsservice_manager != null && _accountsservice_manager_id > 0) {
197+ ((!) _accountsservice_manager).disconnect (_accountsservice_manager_id);
198+ }
199+ }
200+
201+ public string get_language () {
202+ return _language != null ? (!) _language : "";
203+ }
204+
205+ public string get_locale () {
206+ return _locale != null ? (!) _locale : "";
207+ }
208+
209+ public signal void language_changed (string language);
210+ public signal void locale_changed (string locale);
211+
212+ private void set_language (string language) {
213+ if (language != _language) {
214+ _language = language;
215+ language_changed (language);
216+ }
217+ }
218+
219+ private void set_locale (string locale) {
220+ if (locale != _locale) {
221+ _locale = locale;
222+ locale_changed (locale);
223+ }
224+ }
225+
226+ private void load_accountsservice_manager () {
227+ _accountsservice_manager = Act.UserManager.get_default ();
228+
229+ if (((!) _accountsservice_manager).is_loaded) {
230+ load_accountsservice_user ((!) _accountsservice_manager);
231+ } else {
232+ _accountsservice_manager_id = ((!) _accountsservice_manager).notify["is-loaded"].connect (() => {
233+ if (((!) _accountsservice_manager).is_loaded) {
234+ ((!) _accountsservice_manager).disconnect (_accountsservice_manager_id);
235+ _accountsservice_manager_id = 0;
236+ load_accountsservice_user ((!) _accountsservice_manager);
237+ }
238+ });
239+ }
240+ }
241+
242+ private void load_accountsservice_user (Act.UserManager manager) {
243+ _accountsservice_user = manager.get_user (Environment.get_user_name ());
244+
245+ if (_accountsservice_user != null) {
246+ if (((!) _accountsservice_user).is_loaded) {
247+ watch_accountsservice_user ((!) _accountsservice_user);
248+ } else {
249+ _accountsservice_user_id[0] = ((!) _accountsservice_user).notify["is-loaded"].connect (() => {
250+ if (((!) _accountsservice_user).is_loaded) {
251+ ((!) _accountsservice_user).disconnect (_accountsservice_user_id[0]);
252+ _accountsservice_user_id[0] = 0;
253+ watch_accountsservice_user ((!) _accountsservice_user);
254+ }
255+ });
256+ }
257+ }
258+ }
259+
260+ private void watch_accountsservice_user (Act.User user) {
261+ _accountsservice_user_id[0] = user.notify["language"].connect (() => { set_language (user.language); });
262+ _accountsservice_user_id[1] = user.notify["formats-locale"].connect (() => { set_locale (user.formats_locale); });
263+ _language = user.language;
264+ _locale = user.formats_locale;
265+ }
266+}
267+
268+private static MainLoop loop;
269+
270+private static int main (string[] args) {
271+ Bus.own_name (BusType.SESSION,
272+ "com.canonical.UbuntuSystemSettings",
273+ BusNameOwnerFlags.ALLOW_REPLACEMENT | BusNameOwnerFlags.REPLACE,
274+ (connection, name) => {
275+ try {
276+ connection.register_object ("/com/canonical/UbuntuSystemSettings", new Server (connection));
277+ } catch (IOError error) {
278+ warning ("Object registration failed: %s", error.message);
279+ }
280+ },
281+ null,
282+ null);
283+
284+ loop = new MainLoop ();
285+ Posix.sigaction_t action = { () => { loop.quit (); } };
286+ Posix.sigaction (Posix.SIGINT, action, null);
287+ Posix.sigaction (Posix.SIGTERM, action, null);
288+ loop.run ();
289+
290+ return 0;
291+}

Subscribers

People subscribed via source and target branches