├── .gitignore ├── APPDEBUG.md ├── BUILDING.md ├── COPYING ├── README.md ├── daemon ├── README.md ├── appinfo.c ├── appinfo.h ├── applications.c ├── applications.h ├── appservices.c ├── appservices.h ├── config.c ├── config.h ├── control.c ├── control.h ├── dataflow.dot ├── dbus │ └── sailjaild.conf ├── desktop_data.c ├── later.c ├── later.h ├── logging.c ├── logging.h ├── mainloop.c ├── mainloop.h ├── meson.build ├── migrator.c ├── migrator.h ├── permissions.c ├── permissions.h ├── prompter.c ├── prompter.dot ├── prompter.h ├── sailjailclient.c ├── sailjaild.c ├── sailjaild.dot ├── service.c ├── service.h ├── session.c ├── session.h ├── settings.c ├── settings.h ├── stringset.c ├── stringset.h ├── systemd │ └── sailjaild.service ├── test │ ├── data │ │ ├── keyfile1.ini │ │ ├── keyfile2.ini │ │ └── user-1000.settings │ ├── meson.build │ ├── sailjail │ │ └── applications │ │ │ ├── exec-test1.desktop │ │ │ ├── exec-test2.desktop │ │ │ ├── invalid-app.desktop │ │ │ └── test-app.desktop │ ├── sailjailclient_wrapper.c │ ├── sailjailclient_wrapper.h │ ├── test_appinfo.c │ ├── test_permissions.c │ ├── test_sailjailclient.c │ ├── test_settings.c │ ├── test_stringset.c │ ├── test_util.c │ └── tests.xml.in ├── users.c ├── users.h ├── util.c └── util.h ├── meson.build ├── meson_options.txt ├── rpm └── sailjail.spec └── tools └── measure_launch_time.py /.gitignore: -------------------------------------------------------------------------------- 1 | /_build/ 2 | /build/ 3 | /installroot/ 4 | *.list 5 | /RPMS/ 6 | -------------------------------------------------------------------------------- /APPDEBUG.md: -------------------------------------------------------------------------------- 1 | # Debugging sailjail application sandboxing 2 | 3 | Basically debugging existing saljail application profiles is very 4 | similar to creating and debugging firejail profile in learn mode: enable 5 | sufficiently verbose tracing, reproduce the problem and inspect traces 6 | to find out what is causing the sandboxed application to misbehave. 7 | 8 | The biggest difference is that the process needs to be adjusted to take 9 | into account the fact that all permission mapping and granting 10 | privileges must go through sailjail and other relevant compontents. 11 | 12 | ## 1. Tracing unprivileged applications 13 | 14 | When one is dealing with an application that does not need to be 15 | executed with privileged effective group id, one can simply execute 16 | sailjail from command line. 17 | 18 | As an example of unprivileged application: jolla-calculator. 19 | 20 | ### 1.1. Determining how to launch application 21 | 22 | Locate desktop files coming from the same package as the application 23 | itself. 24 | 25 | [defaultuser@Sailfish ~]$ rpm -qf /usr/bin/jolla-calculator 26 | jolla-calculator-1.0.5-1.12.1.jolla.armv7hl 27 | 28 | [defaultuser@Sailfish ~]$ rpm -ql jolla-calculator 29 | : 30 | /usr/share/applications/jolla-calculator.desktop 31 | : 32 | 33 | [defaultuser@Sailfish ~]$ grep Exec /usr/share/applications/jolla-calculator.desktop 34 | Exec=/usr/bin/sailjail -p jolla-calculator.desktop /usr/bin/jolla-calculator 35 | 36 | ### 1.2. Execute the application 37 | 38 | Use the Exec line from desktop file, with `--trace` added in the 39 | mix. `--trace` takes an existing directory as an argument. 40 | 41 | [defaultuser@Sailfish ~]$ mkdir jolla-calculator-trace 42 | [defaultuser@Sailfish ~]$ /usr/bin/sailjail --trace=jolla-calculator-trace -p jolla-calculator.desktop /usr/bin/jolla-calculator 43 | 44 | After exiting application, log files should be in the directory given 45 | to --trace. 46 | 47 | [defaultuser@Sailfish ~]$ ls -1 jolla-calculator-trace/firejail-*.log* 48 | firejail-dbus.log 49 | firejail-stderr.log 50 | firejail-stderr.log.1 51 | firejail-trace.log 52 | 53 | ## 2. Tracing privileged applications 54 | 55 | When one is dealing with applications that need access to privileged 56 | user data, things are a bit more complicated. 57 | 58 | As an example of privileged application: jolla-notes. 59 | 60 | ### 2.1. Determining application launch files 61 | 62 | Depending on application, one needs to patch application desktop and/or 63 | dbus autolauch configuration files 64 | 65 | [root@Sailfish ~]# rpm -qf /usr/bin/jolla-notes 66 | jolla-notes-1.0.9-1.34.1.jolla.armv7hl 67 | 68 | [root@Sailfish ~]# rpm -ql jolla-notes 69 | : 70 | /usr/share/applications/jolla-notes.desktop 71 | /usr/share/dbus-1/services/com.jolla.notes.service 72 | : 73 | 74 | ### 2.2. Enable sailjail/firejail tracing 75 | 76 | Basically one just needs to add suitable --trace option for sailjail 77 | Exec line. In case several programs need to be traced simultaneously, 78 | it might be better to use application specific target directory. 79 | 80 | In this example we use "/tmp/notest-trace" as destination directory. 81 | 82 | Create trace output directory, make sure it is writable by appropriate 83 | user: 84 | 85 | > Note: Sailjail exits if trace destination directory does not exist 86 | > -> If tmpfs destinations are used, these directories must be 87 | > recreated after each reboot. 88 | 89 | [root@Sailfish ~]# mkdir /tmp/notes-trace 90 | [root@Sailfish ~]# chown defaultuser:defaultuser /tmp/notes-trace 91 | 92 | To make restoring normal state easier, you might want to grab copies of 93 | unmodified launch files, 94 | 95 | [root@Sailfish ~]# cp /usr/share/dbus-1/services/com.jolla.notes.service\ 96 | /usr/share/dbus-1/services/com.jolla.notes.service.original 97 | [root@Sailfish ~]# cp /usr/share/applications/jolla-notes.desktop\ 98 | /usr/share/applications/jolla-notes.desktop.original 99 | 100 | Then modify Exec line so that --trace=/tmp/notes-trace option is passed 101 | to sailjail. 102 | 103 | [root@Sailfish ~]# vim /usr/share/dbus-1/services/com.jolla.notes.service 104 | [root@Sailfish ~]# vim /usr/share/applications/jolla-notes.desktop 105 | 106 | The changes should be something like this 107 | 108 | [root@Sailfish ~]# diff -Naur /usr/share/dbus-1/services/com.jolla.notes.service.original /usr/share/dbus-1/services/com.jolla.notes.service 109 | --- /usr/share/dbus-1/services/com.jolla.notes.service.original 110 | +++ /usr/share/dbus-1/services/com.jolla.notes.service 111 | @@ -1,3 +1,3 @@ 112 | [D-BUS Service] 113 | Name=com.jolla.notes 114 | -Exec=/usr/bin/sailjail -p jolla-notes.desktop /usr/bin/jolla-notes -prestart 115 | +Exec=/usr/bin/sailjail --trace=/tmp/notes-trace -p jolla-notes.desktop /usr/bin/jolla-notes -prestart 116 | 117 | [root@Sailfish ~]# diff -Naur /usr/share/applications/jolla-notes.desktop.original /usr/share/applications/jolla-notes.desktop 118 | --- /usr/share/applications/jolla-notes.desktop.original 119 | +++ /usr/share/applications/jolla-notes.desktop 120 | @@ -2,7 +2,7 @@ 121 | Type=Application 122 | Name=Notes 123 | Icon=icon-launcher-notes 124 | -Exec=/usr/bin/sailjail -p jolla-notes.desktop /usr/bin/jolla-notes 125 | +Exec=/usr/bin/sailjail --trace=/tmp/notes-trace -p jolla-notes.desktop /usr/bin/jolla-notes 126 | X-MeeGo-Logical-Id=notes-de-name 127 | X-MeeGo-Translation-Catalog=notes 128 | X-Maemo-Service=com.jolla.notes 129 | 130 | ### 2.3. Execute the application 131 | 132 | The same way as one usually does, e.g. by clicking icon in the 133 | application launcher grid. 134 | 135 | After potential permissions issue has been reproduced, exit the 136 | application. 137 | 138 | [root@Sailfish ~]# ls -1 /tmp/notes-trace 139 | firejail-dbus.log 140 | firejail-stderr.log 141 | firejail-stderr.log.1 142 | firejail-trace.log 143 | 144 | ## 3. Interpreting the trace files 145 | 146 | After the traced application has exited, the trace directory should 147 | contain following kinds of files: firejail output, listing of libc 148 | function calls trapped via libtrace preload library and dbus traffic 149 | logging from xdg-dbus-proxy instance. 150 | 151 | Brief outline of content is listed below. 152 | 153 | ### 3.1. firejail-stderr.log 154 | 155 | This file contains logging from firejail process itself. 156 | 157 | The output is meant for human consumption, and any serious problems 158 | firejail has should be fairly obvious to spot. 159 | 160 | Additional firejail-stderr.log.N files can exist and contain output from 161 | binaries executed for / within sandboxing. 162 | 163 | ### 3.2. firejail-trace.log 164 | 165 | Output from libtrace.so, which is used for trapping and logging select 166 | syscalls / libc function calls (mostly ones dealing with file i/o) that 167 | the application makes. 168 | 169 | If application is misbehaving but does not clearly log problems it might 170 | be having with fs access, one can go through this log file and look for 171 | signs of problems. 172 | 173 | The format is one line / function call with the following fields: 174 | 175 | :: : 176 | 177 | For example: 178 | 179 | 16:jolla-notes:fopen /property_contexts:(nil) 180 | 16:jolla-notes:fopen /plat_property_contexts:0xf7f1ab8 181 | ^ looking up from various places, eventually succeeds -> ok 182 | 183 | 16:jolla-notes:open /sys/class/timed_output/vibrator/enable:-1 184 | ^ failure to open vibrator device, known cosmetic problem 185 | 186 | 16:jolla-notes:mkdir /run/user/100000/dconf:-1 187 | ^ fails because directory already exists. unfortunately 188 | errno is not logged so it is not always easy to tell 189 | apart false positives from genuine problems 190 | 191 | ### 3.3. firejail-dbus.log 192 | 193 | This file contains logging from xdg-dbus-proxy instance. 194 | 195 | The output is very noisy and ill suited for human consumption, but 196 | obvious problems such missing permission to contact some dbus service / 197 | own a service name should still be relatively easy to spot via 198 | concentrating on hidden/skipped entries: 199 | 200 | grep -B2 -E '\*(HIDDEN|SKIPPED)\*' firejail-dbus.log 201 | 202 | ### 3.4 Tips 203 | 204 | Once problems have been found in the firejail trace logs, quite often 205 | it's easy to locate the missing permissions by grepping the sailjail 206 | and sailjail-permissions repositories. 207 | -------------------------------------------------------------------------------- /BUILDING.md: -------------------------------------------------------------------------------- 1 | Building sailjail 2 | ================= 3 | Sailjail uses [Meson build system](https://mesonbuild.com/). To build it 4 | use the following commands: 5 | 6 | meson setup build 7 | meson compile -C build 8 | 9 | See [the next section](#useful-setup-options) for more tips. 10 | 11 | Useful setup options 12 | -------------------- 13 | Some useful options for `meson setup`: 14 | 15 | | option | explanation | 16 | | -----------------------: | :------------------------------------- | 17 | | -Db\_coverage=true | Build with support for coverage reports | 18 | | -Dlibdbusaccess=disabled | Build without libdbusaccess support | 19 | 20 | Running unit tests 21 | ------------------ 22 | Unit tests can be run with meson: 23 | 24 | meson test -C build 25 | 26 | After that you can also generate a coverage report if you built with 27 | coverage reports support: 28 | 29 | ninja coverage -C build 30 | 31 | It will print you URI to the generated report, assuming that you have 32 | the commands to build the reports in your system. 33 | 34 | Sailjail daemon diagrams 35 | ------------------------ 36 | There is an architecture diagram generated with graphviz and a png 37 | version of it can be generated with `sailjaild.png` target. You can find 38 | it in _build/daemon/_ after building it: 39 | 40 | meson compile sailjaild.png -C build 41 | 42 | Similarly a dataflow diagram can be built with `dataflow.png` target 43 | and prompter state diagram with `prompter.png` target. 44 | 45 | Cheatsheet for make users 46 | ------------------------- 47 | For those that come from the world of makefiles: 48 | 49 | | make command | meson equivalent | 50 | | :------------------------- | :-------------------------------------------- | 51 | | Initial setup | `mkdir build && cd build && meson setup .. .` | 52 | | `make` | `meson compile` | 53 | | `make install` | `meson install` | 54 | | `make install DESTDIR=foo` | `DESTDIR=foo meson install` | 55 | | `make run-tests` | `meson test` | 56 | | `make coverage` | `meson setup .. . -Db_coverage=true`
`meson test`
`ninja coverage` | 57 | 58 | Meson doesn't support building inside source directory. Here we create a 59 | build directory and run the commands inside that. Alternatively you may 60 | use `-C build` argument to specify the build directory. 61 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | Redistribution and use in source and binary forms, with or without 2 | modification, are permitted provided that the following conditions 3 | are met: 4 | 5 | 1. Redistributions of source code must retain the above copyright 6 | notice, this list of conditions and the following disclaimer. 7 | 2. Redistributions in binary form must reproduce the above copyright 8 | notice, this list of conditions and the following disclaimer 9 | in the documentation and/or other materials provided with the 10 | distribution. 11 | 3. Neither the names of the copyright holders nor the names of its 12 | contributors may be used to endorse or promote products derived 13 | from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 | HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | The views and conclusions contained in the software and documentation 28 | are those of the authors and should not be interpreted as representing 29 | any official policies, either expressed or implied. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sailjail 2 | 3 | Sailfish OS application sandboxes are launched through **sailjail** command that is a thin Firejail 4 | wrapper. Sailjail has also a daemon that manages sandboxing permissions and keeps a list of 5 | applications. Firejail documentation can be found [here](https://firejail.wordpress.com/). 6 | 7 | In this document we are following terminology defined by Firejail. 8 | 9 | ## Application permissions 10 | 11 | Application 12 | [permissions](https://github.com/sailfishos/sailjail-permissions#sailfish-os-application-sandboxing-and-permissions) 13 | defined in [sailjail-permissions](https://github.com/sailfishos/sailjail-permissions) are Firejail 14 | profiles. Application developer defines set of required permissions in the application desktop file. 15 | 16 | Application desktop file changes are described in the [Sailjail Permissions 17 | documentation](https://github.com/sailfishos/sailjail-permissions#enable-sandboxing-for-an-application). 18 | 19 | Sailjail parses the desktop file and builds Firejail command line arguments out of the requested 20 | permissions and finally Sailjail executes Firejail with the command line arguments. 21 | 22 | ## Application data structure 23 | 24 | There are three directories that are whitelisted automatically by Sailjail based on desktop file 25 | content. 26 | 27 | $HOME/.local/share// 28 | $HOME/.cache// 29 | $HOME/.config// 30 | 31 | Default user data directories such as [*Pictures*, *Videos*, *Music* and 32 | *Documents*](https://www.freedesktop.org/wiki/Software/xdg-user-dirs/) are not whitelisted by 33 | default rather application developer needs to request access with predefined 34 | [permissions](https://github.com/sailfishos/sailjail-permissions#permissions). 35 | 36 | ## Implicit D-Bus user service ownership 37 | 38 | Based on [*OrganizationName* and 39 | *ApplicationName* values](https://github.com/sailfishos/sailjail-permissions#desktop-file-changes) 40 | application is granted rights to own a D-Bus service name on user session bus. 41 | 42 | Example desktop file 43 | 44 | [Desktop Entry] 45 | Type=Application 46 | Name=My Application 47 | Icon=my-app-icon 48 | Exec=/usr/bin/org.foobar.MyApp 49 | 50 | [X-Sailjail] 51 | Permissions=Internet;Pictures 52 | OrganizationName=org.foobar 53 | ApplicationName=MyApp 54 | ExecDBus=/usr/bin/org.foobar.MyApp -prestart 55 | 56 | With above example application desktop file Firejail command line arguments contain implicitly 57 | **--dbus-user.own=org.foobar.MyApp** when launched through Sailjail. 58 | When application's executable matches desktop file name, it is enough to define it in Exec value. If 59 | the names differ you may define the desktop file with **sailjail** command's **-p** argument: 60 | 61 | Exec=/usr/bin/sailjail -p foobar-myapp.desktop -- /usr/bin/org.foobar.MyApp 62 | 63 | Use of absolute paths is required, except for the desktop file which must be located in 64 | _/usr/share/applications_ or _/etc/sailjail/applications_. 65 | 66 | The ExecDBus value is an optional command line which will be used to auto start the application 67 | to provide the \.\ DBus service. 68 | 69 | ## Sailjail daemon 70 | 71 | Sailjail has a daemon called sailjaild. It keeps track of applications' desktop files in 72 | _/usr/share/applications_ and _/etc/sailjail/applications_. It can be queried over D-Bus for 73 | information regarding these applications, their sandboxing status and permissions. The daemon also 74 | handles prompting user for permissions. 75 | 76 | ## Sailfish OS specific changes to Firejail 77 | 78 | ### Handling privileged user data 79 | 80 | In Sailfish OS portion of user data is considered private and although it resides within user's home 81 | directory the files / directories are owned by _privileged_ user / group and only select 82 | applications are granted access via executing them with effective group id set to _privileged_. For 83 | sandboxed applications _private-data \_ Firejail rule or command line option is used to 84 | provide more fine grained access to privileged data. 85 | 86 | Also noteworthy: sandboxed applications are executed with _no-new-privs_ set. As this makes it 87 | impossible to have effective gid that differs from real gid, privileged applications are running 88 | with real group id set to _privileged_. 89 | 90 | ### General fixes that might be eligible for upstreaming 91 | 92 | - Rule templating. Sailjail defines keywords used in Firejail profiles that Firejail substitutes 93 | automatically while parsing the rules. 94 | - Loading profiles only after parsing arguments instead of loading while parsing. 95 | 96 | ## Debugging sandboxed applications 97 | 98 | See [Application debugging instructions](APPDEBUG.md). 99 | -------------------------------------------------------------------------------- /daemon/README.md: -------------------------------------------------------------------------------- 1 | Sailjail Daemon 2 | =============== 3 | 4 | This document briefly describes internal structure of sailjail daemon 5 | itself, and how / what kinds of clients it is expected to serve. 6 | 7 | Client Behavior 8 | =============== 9 | 10 | Modifying Settings 11 | ------------------ 12 | 13 | Expectation is that direct manipulation of sandboxing related application 14 | data is limited to privileged applications such as Settings UI. This is 15 | enforced by checking credentials of clients making such method calls. 16 | 17 | Tracking known applications can be done by obtaining initial set of 18 | applications via GetApplications() method call and adjusting the active set 19 | when ApplicationAdded or ApplicationRemoved signals are received. 20 | 21 | System wide information about each application can be obtained via 22 | GetAppInfo() method call. This data originates from read-only configuration 23 | / desktop / etc files and can be assumed to be fairly static. Still, if such 24 | information is cached long term, it should be refreshed upon receiving 25 | ApplicationChanged signal. 26 | 27 | User specific application settings can be obtained via: 28 | 29 | - GetLaunchAllowed() 30 | - GetGrantedPermissions() 31 | 32 | Privileged applications can modify these via: 33 | 34 | - SetLaunchAllowed() 35 | - SetGrantedPermissions() 36 | 37 | Also changes in user specific settings are reported via ApplicationChanged 38 | signal. In case of long term caching, client should refresh all settings for 39 | all users that are of interest to the client. 40 | 41 | Launching Applications 42 | ---------------------- 43 | 44 | Launchers are assumed to be fairly simple procedural programs that do not 45 | employ event based mainloop. To facilitate such behavior sailjail daemon has 46 | two helper methods that can be used to obtain launch permissions via a 47 | single blocking D-Bus calls: 48 | 49 | - PromptLaunchPermissions() 50 | - QueryLaunchPermissions() 51 | 52 | QueryLaunchPermissions() basically handles (within sailjail daemon) 53 | obtaining uid of the currently active user session [e.g. sd_seat_get_active()], 54 | checking whether that UID can launch application [GetLaunchAllowed()], and 55 | returns list of permissions the application has been granted 56 | [SetGrantedPermissions()] or error reply. 57 | 58 | PromptLaunchPermissions() behaves similarly, but in case application launch 59 | has not been explicitly allowed or denied, user is first prompted for launch 60 | permission. In such cases reply message is delayed until user responds to 61 | permission prompt and thus client should use either long or infinite timeout 62 | for the D-Bus method call. 63 | 64 | Sandboxed Application 65 | --------------------- 66 | 67 | Expectation is that applications do not need to do IPC with sailjail daemon, 68 | and in case of normal application launch it is not even possible as sailjail 69 | D-Bus service is not visible from within sandbox. 70 | 71 | In case application has been lauched via application specific sandboxed 72 | booster, portion of sailjail D-Bus interface relevant to boosting logic 73 | is available but applications should not rely on that. 74 | 75 | Daemon Internals 76 | ================ 77 | 78 | Existing User Tracking 79 | ---------------------- 80 | 81 | - tracking is done by: 82 | - monitoring /etc/passwd file 83 | 84 | - maintained data: 85 | - minimum UID 86 | - maximum UID 87 | - set of valid UID values 88 | 89 | - UID added: 90 | - no action needed 91 | 92 | - UID removed: 93 | - user must be dropped from settings data 94 | 95 | User Session Tracking 96 | --------------------- 97 | 98 | - tracks UID of current user 99 | 100 | - UID is used for: 101 | - permissions checking/prompting 102 | 103 | - UID changed: 104 | - cancels pending/queued prompts 105 | 106 | Permission File Tracking 107 | ------------------------ 108 | 109 | - tracking is done by: 110 | - monitoring /etc/sailjail/permissions directory 111 | 112 | - maintained data: 113 | - set of PERMISSION names 114 | 115 | - PERMISSION added/removed: 116 | - triggers application data re-evaluation 117 | 118 | Desktop File Tracking 119 | --------------------- 120 | 121 | - tracking is done by monitoring *.desktop files in directories: 122 | - /usr/share/applications 123 | - regular desktop files 124 | - optionally with sailjail specific section 125 | - /etc/sailjail/applications 126 | - uses desktop file format 127 | - can be used for defining permissions for ui-less applications 128 | - or augmenting / overriding values from /usr/share/applications 129 | 130 | - maintained data: 131 | - set of APPLICATION data, each with: 132 | - [Desktop Entry] properties: 133 | - Name 134 | - Type 135 | - Exec 136 | - Icon 137 | - NoDisplay 138 | - X-Maemo-Service 139 | - X-Maemo-Object-Path 140 | - X-Maemo-Method 141 | - [Sailjail] properties: 142 | - Permissions 143 | - OrganizationName 144 | - ApplicationName 145 | - DataDirectory 146 | - Sandboxing 147 | - ExecDBus 148 | 149 | - APPLICATION added: 150 | - broadcast ApplicationAdded signal 151 | - no other actions 152 | 153 | - APPLICATION removed: 154 | - broadcast ApplicationAdded signal 155 | - application settings for each user must be purged 156 | 157 | - APPLICATION changed: 158 | - broadcast ApplicationAdded signal 159 | - triggers settings data re-evaluation 160 | 161 | - dbus ipc: 162 | - method QStringList GetApplications() 163 | -> list of available application names 164 | 165 | - method QVariantMap GetAppInfo(QString application) 166 | -> application names to Name/Type/.. mapping 167 | 168 | - signal void ApplicationAdded(QString application) 169 | - signal void ApplicationRemoved(QString application) 170 | - signal void ApplicationChanged(QString application) 171 | - note that changed signal can occur also due to 172 | - changes in permission data 173 | - changes in user settings data 174 | 175 | User / Application Settings 176 | --------------------------- 177 | 178 | - maintained data: 179 | - tree of: settings(1) -> users(n) -> applications (n) 180 | - leaf node holds: 181 | - launch\_allowed = UNSET|ALWAYS|NEVER 182 | - granted\_permissions: 183 | - subset of: intersection of PERMISSIONS and APPLICATION.permissions 184 | - cleared/filled on launch_allowed changes 185 | - possible to modify while launch_allowed=ALWAYS 186 | - license\_agreed = UNSET|YES|NO 187 | - proof of concept / placeholder (=how to add new data) 188 | 189 | - persistent storage: 190 | - one file / user -> "applications for user" 191 | - when loading / saving: 192 | - data for invalid users / applications is ignored 193 | 194 | - dbus ipc: 195 | - access to application / settings data 196 | - UID / APPLICATION parameters are validated 197 | - even if stale data is still held internally it is not exposed 198 | over dbus interface 199 | 200 | - method int GetLaunchAllowed(uint uid, QString application) 201 | - method void SetLaunchAllowed(uint uid, QString application, int allowed) 202 | - values: UNSET=0|ALWAYS=1|NEVER=2 203 | - setter needs to be under access control 204 | - changing value affects also granted permissions 205 | 206 | - method QStringList GetGrantedPermissions(uint uid, QString application) 207 | - method void SetGrantedPermissions(uint uid, QString application, QStringList permissions) 208 | -> set of permissions granted to UID/APPLICATION 209 | 210 | - method QStringList QueryLaunchPermissions(QString application) 211 | - if application launch is allowed for current UID, returns permissions 212 | 213 | - method QStringList PromptLaunchPermissions(QString application) 214 | - if application launch is not allowed for current UID, 215 | - prompt user and set allowed/granted according to responce 216 | - if application launch is allowed for current UID, returns permissions 217 | 218 | - method int GetLicenseAgreed(uint uid, QString application) 219 | - method void SetLicenseAgreed(uint uid, QString application, int agreed) 220 | - values: UNSET=0|YES=1|NO=2 221 | - used only for: "how to add more data" demonstration 222 | 223 | Autogenerated D-Bus autostart configuration 224 | ------------------------------------------- 225 | 226 | - stored under /run/user/UID/dbus-1/services 227 | - for each application that defines: 228 | - OrganizationName 229 | - ApplicationName 230 | - ExecDBus 231 | - when application configuration data is installed / updated / removed 232 | or current user changes, D-Bus activation configuration files are updated 233 | accordingly and SessionBus daemon (for current user) is instructed to 234 | reload configuration 235 | - ExecDBus allows to tell apart D-Bus autostart and launching from launcher. 236 | It defines the application command line to use. 237 | 238 | Internal Structure 239 | ------------------ 240 | 241 | - names below map directly to source files 242 | - also used in architecture graph 243 | - ref: dot -Tpng sailjaild.dot -o sailjaild.png 244 | 245 | - CONTROL: "root object" 246 | - CONFIG: access to configuration data 247 | - USERS: existing users tracking 248 | - SESSION: user session tracking 249 | - PERMISSIONS: *.permission file tracking, Exec/Permissions/etc properties 250 | - SETTINGS: top level settings api/logic 251 | - USER SETTINGS: persistent storage in user-UID.settings files 252 | - APPLICATION SETTINGS: allowed/granted properties 253 | - SERVICE: dbus service, incoming method calls, outgoing signals 254 | - PROMPTER: session bus connection, queue/execute window prompt ipc 255 | - MIGRATOR: migrates approval files from older sailjail versions 256 | - APPROVAL: approval data from older sailjail versions 257 | - APPSERVICES: maintaining autogenerated D-Bus activation configuration 258 | 259 | Directories Used 260 | ---------------- 261 | 262 | - CONFIG: "/etc/sailjail/config" 263 | - PERMISSIONS: "/etc/sailjail/permissions" 264 | - APPLICATIONS: "/usr/share/applications" and "/etc/sailjail/applications" 265 | - SETTINGS: "/home/.system/var/lib/sailjail/settings" 266 | -------------------------------------------------------------------------------- /daemon/appinfo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Open Mobile Platform LLC. 3 | * 4 | * You may use this file under the terms of the BSD license as follows: 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * 3. Neither the names of the copyright holders nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * The views and conclusions contained in the software and documentation 33 | * are those of the authors and should not be interpreted as representing 34 | * any official policies, either expressed or implied. 35 | */ 36 | 37 | #ifndef APPINFO_H_ 38 | # define APPINFO_H_ 39 | 40 | # include 41 | # include 42 | 43 | G_BEGIN_DECLS 44 | 45 | /* ========================================================================= * 46 | * Types 47 | * ========================================================================= */ 48 | 49 | typedef struct stringset_t stringset_t; 50 | typedef struct applications_t applications_t; 51 | typedef struct appinfo_t appinfo_t; 52 | typedef struct config_t config_t; 53 | typedef struct control_t control_t; 54 | 55 | typedef enum { 56 | APP_MODE_NORMAL, 57 | APP_MODE_COMPATIBILITY, 58 | APP_MODE_NONE, 59 | } app_mode_t; 60 | 61 | /* ========================================================================= * 62 | * Prototypes 63 | * ========================================================================= */ 64 | 65 | /* ------------------------------------------------------------------------- * 66 | * APPINFO 67 | * ------------------------------------------------------------------------- */ 68 | 69 | appinfo_t *appinfo_create (applications_t *applications, const gchar *id); 70 | void appinfo_delete (appinfo_t *self); 71 | void appinfo_delete_cb (void *self); 72 | gboolean appinfo_equal (const appinfo_t *self, const appinfo_t *that); 73 | gboolean appinfo_equal_cb (gconstpointer a, gconstpointer b); 74 | guint appinfo_hash (const appinfo_t *self); 75 | guint appinfo_hash_cb (gconstpointer key); 76 | GVariant *appinfo_to_variant(const appinfo_t *self); 77 | gchar *appinfo_to_string (const appinfo_t *self); 78 | 79 | /* ------------------------------------------------------------------------- * 80 | * APPINFO_ATTRIBUTE 81 | * ------------------------------------------------------------------------- */ 82 | 83 | bool appinfo_valid (const appinfo_t *self); 84 | control_t *appinfo_control (const appinfo_t *self); 85 | const config_t *appinfo_config (const appinfo_t *self); 86 | applications_t *appinfo_applications (const appinfo_t *self); 87 | const gchar *appinfo_id (const appinfo_t *self); 88 | bool appinfo_dbus_auto_start(const appinfo_t *self); 89 | 90 | /* ------------------------------------------------------------------------- * 91 | * APPINFO_PROPERTY 92 | * ------------------------------------------------------------------------- */ 93 | 94 | const gchar *appinfo_get_name (const appinfo_t *self); 95 | const gchar *appinfo_get_type (const appinfo_t *self); 96 | const gchar *appinfo_get_icon (const appinfo_t *self); 97 | const gchar *appinfo_get_exec (const appinfo_t *self); 98 | bool appinfo_get_no_display (const appinfo_t *self); 99 | const gchar *appinfo_get_service (const appinfo_t *self); 100 | const gchar *appinfo_get_object (const appinfo_t *self); 101 | const gchar *appinfo_get_method (const appinfo_t *self); 102 | const gchar *appinfo_get_organization_name(const appinfo_t *self); 103 | const gchar *appinfo_get_application_name (const appinfo_t *self); 104 | const gchar *appinfo_get_exec_dbus (const appinfo_t *self); 105 | const gchar *appinfo_get_data_directory (const appinfo_t *self); 106 | app_mode_t appinfo_get_mode (const appinfo_t *self); 107 | void appinfo_set_name (appinfo_t *self, const gchar *name); 108 | void appinfo_set_type (appinfo_t *self, const gchar *type); 109 | void appinfo_set_icon (appinfo_t *self, const gchar *icon); 110 | void appinfo_set_exec (appinfo_t *self, const gchar *exec); 111 | void appinfo_set_no_display (appinfo_t *self, bool no_display); 112 | void appinfo_set_service (appinfo_t *self, const gchar *service); 113 | void appinfo_set_object (appinfo_t *self, const gchar *object); 114 | void appinfo_set_method (appinfo_t *self, const gchar *method); 115 | void appinfo_set_organization_name(appinfo_t *self, const gchar *organization_name); 116 | void appinfo_set_application_name (appinfo_t *self, const gchar *application_name); 117 | void appinfo_set_exec_dbus (appinfo_t *self, const gchar *exec_dbus); 118 | void appinfo_set_data_directory (appinfo_t *self, const gchar *data_directory); 119 | void appinfo_set_mode (appinfo_t *self, app_mode_t mode); 120 | 121 | /* ------------------------------------------------------------------------- * 122 | * APPINFO_PERMISSIONS 123 | * ------------------------------------------------------------------------- */ 124 | 125 | bool appinfo_has_permission (const appinfo_t *self, const gchar *perm); 126 | stringset_t *appinfo_get_permissions (const appinfo_t *self); 127 | bool appinfo_evaluate_permissions(appinfo_t *self); 128 | void appinfo_set_permissions (appinfo_t *self, const stringset_t *in); 129 | void appinfo_clear_permissions (appinfo_t *self); 130 | 131 | /* ------------------------------------------------------------------------- * 132 | * APPINFO_PARSE 133 | * ------------------------------------------------------------------------- */ 134 | 135 | bool appinfo_parse_desktop(appinfo_t *self); 136 | 137 | G_END_DECLS 138 | 139 | #endif /* APPINFO_H_ */ 140 | -------------------------------------------------------------------------------- /daemon/applications.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Open Mobile Platform LLC. 3 | * 4 | * You may use this file under the terms of the BSD license as follows: 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * 3. Neither the names of the copyright holders nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * The views and conclusions contained in the software and documentation 33 | * are those of the authors and should not be interpreted as representing 34 | * any official policies, either expressed or implied. 35 | */ 36 | 37 | #ifndef APPLICATIONS_H_ 38 | # define APPLICATIONS_H_ 39 | 40 | # include 41 | 42 | G_BEGIN_DECLS 43 | 44 | /* ========================================================================= * 45 | * Types 46 | * ========================================================================= */ 47 | 48 | typedef struct config_t config_t; 49 | typedef struct stringset_t stringset_t; 50 | typedef struct applications_t applications_t; 51 | typedef struct appinfo_t appinfo_t; 52 | typedef struct control_t control_t; 53 | 54 | /* ========================================================================= * 55 | * Prototypes 56 | * ========================================================================= */ 57 | 58 | /* ------------------------------------------------------------------------- * 59 | * APPLICATIONS 60 | * ------------------------------------------------------------------------- */ 61 | 62 | applications_t *applications_create (control_t *control); 63 | void applications_delete (applications_t *self); 64 | void applications_delete_at(applications_t **pself); 65 | void applications_delete_cb(void *self); 66 | void applications_rethink (applications_t *self); 67 | 68 | /* ------------------------------------------------------------------------- * 69 | * APPLICATIONS_ATTRIBUTES 70 | * ------------------------------------------------------------------------- */ 71 | 72 | control_t *applications_control (const applications_t *self); 73 | const stringset_t *applications_available(applications_t *self); 74 | appinfo_t *applications_appinfo (applications_t *self, const char *appname); 75 | const config_t *applications_config (const applications_t *self); 76 | 77 | G_END_DECLS 78 | 79 | #endif /* APPLICATIONS_H_ */ 80 | -------------------------------------------------------------------------------- /daemon/appservices.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Open Mobile Platform LLC. 3 | * 4 | * You may use this file under the terms of the BSD license as follows: 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * 3. Neither the names of the copyright holders nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * The views and conclusions contained in the software and documentation 33 | * are those of the authors and should not be interpreted as representing 34 | * any official policies, either expressed or implied. 35 | */ 36 | 37 | #ifndef APPSERVICES_H_ 38 | # define APPSERVICES_H_ 39 | 40 | # include 41 | 42 | G_BEGIN_DECLS 43 | 44 | /* ========================================================================= * 45 | * Types 46 | * ========================================================================= */ 47 | 48 | typedef struct stringset_t stringset_t; 49 | typedef struct appservices_t appservices_t; 50 | typedef struct appinfo_t appinfo_t; 51 | typedef struct control_t control_t; 52 | 53 | /* ========================================================================= * 54 | * Prototypes 55 | * ========================================================================= */ 56 | 57 | /* ------------------------------------------------------------------------- * 58 | * APPSERVICES 59 | * ------------------------------------------------------------------------- */ 60 | 61 | appservices_t *appservices_create (control_t *control); 62 | void appservices_delete (appservices_t *self); 63 | void appservices_delete_at (appservices_t **pself); 64 | void appservices_delete_cb (void *self); 65 | void appservices_rethink (appservices_t *self); 66 | void appservices_application_changed (appservices_t *self, const char *appname, appinfo_t *appinfo); 67 | void appservices_application_added (appservices_t *self, const char *appname, appinfo_t *appinfo); 68 | void appservices_application_removed (appservices_t *self, const char *appname); 69 | 70 | G_END_DECLS 71 | 72 | #endif /* APPSERVICES_H_ */ 73 | -------------------------------------------------------------------------------- /daemon/config.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Open Mobile Platform LLC. 3 | * 4 | * You may use this file under the terms of the BSD license as follows: 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * 3. Neither the names of the copyright holders nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * The views and conclusions contained in the software and documentation 33 | * are those of the authors and should not be interpreted as representing 34 | * any official policies, either expressed or implied. 35 | */ 36 | 37 | #include "config.h" 38 | 39 | #include "util.h" 40 | #include "stringset.h" 41 | #include "logging.h" 42 | 43 | #include 44 | 45 | /* ========================================================================= * 46 | * Types 47 | * ========================================================================= */ 48 | 49 | typedef struct config_t config_t; 50 | typedef struct stringset_t stringset_t; 51 | 52 | /* ========================================================================= * 53 | * Prototypes 54 | * ========================================================================= */ 55 | 56 | /* ------------------------------------------------------------------------- * 57 | * CONFIG 58 | * ------------------------------------------------------------------------- */ 59 | 60 | static void config_ctor (config_t *self); 61 | static void config_dtor (config_t *self); 62 | config_t *config_create (void); 63 | void config_delete (config_t *self); 64 | void config_delete_at(config_t **pself); 65 | void config_delete_cb(void *self); 66 | 67 | /* ------------------------------------------------------------------------- * 68 | * CONFIG_LOAD 69 | * ------------------------------------------------------------------------- */ 70 | 71 | static void config_unload(config_t *self); 72 | static void config_load (config_t *self); 73 | 74 | /* ------------------------------------------------------------------------- * 75 | * CONFIG_VALUE 76 | * ------------------------------------------------------------------------- */ 77 | 78 | bool config_boolean (const config_t *self, const gchar *sec, const gchar *key, bool def); 79 | gint config_integer (const config_t *self, const gchar *sec, const gchar *key, gint def); 80 | gchar *config_string (const config_t *self, const gchar *sec, const gchar *key, const gchar *def); 81 | stringset_t *config_stringset(const config_t *self, const gchar *sec, const gchar *key); 82 | 83 | /* ========================================================================= * 84 | * CONFIG 85 | * ========================================================================= */ 86 | 87 | struct config_t 88 | { 89 | GKeyFile *cfg_keyfile; 90 | }; 91 | 92 | static void 93 | config_ctor(config_t *self) 94 | { 95 | log_info("config() created"); 96 | self->cfg_keyfile = NULL; 97 | config_load(self); 98 | } 99 | 100 | static void 101 | config_dtor(config_t *self) 102 | { 103 | log_info("config() deleted"); 104 | config_unload(self); 105 | } 106 | 107 | config_t * 108 | config_create(void) 109 | { 110 | config_t *self = g_malloc0(sizeof *self); 111 | config_ctor(self); 112 | return self; 113 | } 114 | 115 | void 116 | config_delete(config_t *self) 117 | { 118 | if( self ) { 119 | config_dtor(self); 120 | g_free(self); 121 | } 122 | } 123 | 124 | void 125 | config_delete_at(config_t **pself) 126 | { 127 | config_delete(*pself), *pself = NULL; 128 | } 129 | 130 | void 131 | config_delete_cb(void *self) 132 | { 133 | config_delete(self); 134 | } 135 | 136 | static void 137 | config_unload(config_t *self) 138 | { 139 | if( self->cfg_keyfile ) { 140 | g_key_file_unref(self->cfg_keyfile), 141 | self->cfg_keyfile = NULL; 142 | } 143 | } 144 | 145 | static void 146 | config_load(config_t *self) 147 | { 148 | glob_t gl = {}; 149 | 150 | config_unload(self); 151 | 152 | self->cfg_keyfile = g_key_file_new(); 153 | 154 | if( glob(CONFIG_DIRECTORY "/" CONFIG_PATTERN, 0, 0, &gl) != 0 ) 155 | goto EXIT; 156 | 157 | for( int i = 0; i < gl.gl_pathc; ++i ) 158 | keyfile_merge(self->cfg_keyfile, gl.gl_pathv[i]); 159 | 160 | EXIT: 161 | globfree(&gl); 162 | } 163 | 164 | bool 165 | config_boolean(const config_t *self, const gchar *sec, const gchar *key, 166 | bool def) 167 | { 168 | return keyfile_get_boolean(self->cfg_keyfile, sec, key, def); 169 | } 170 | 171 | gint 172 | config_integer(const config_t *self, const gchar *sec, const gchar *key, 173 | gint def) 174 | { 175 | return keyfile_get_integer(self->cfg_keyfile, sec, key, def); 176 | } 177 | 178 | gchar * 179 | config_string(const config_t *self, const gchar *sec, const gchar *key, 180 | const gchar *def) 181 | { 182 | return keyfile_get_string(self->cfg_keyfile, sec, key, def); 183 | } 184 | 185 | stringset_t * 186 | config_stringset(const config_t *self, const gchar *sec, const gchar *key) 187 | { 188 | return keyfile_get_stringset(self->cfg_keyfile, sec, key); 189 | } 190 | -------------------------------------------------------------------------------- /daemon/config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Open Mobile Platform LLC. 3 | * 4 | * You may use this file under the terms of the BSD license as follows: 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * 3. Neither the names of the copyright holders nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * The views and conclusions contained in the software and documentation 33 | * are those of the authors and should not be interpreted as representing 34 | * any official policies, either expressed or implied. 35 | */ 36 | 37 | #ifndef CONFIG_H_ 38 | # define CONFIG_H_ 39 | 40 | # include 41 | # include 42 | 43 | G_BEGIN_DECLS 44 | 45 | /* ========================================================================= * 46 | * Types 47 | * ========================================================================= */ 48 | 49 | typedef struct config_t config_t; 50 | typedef struct stringset_t stringset_t; 51 | 52 | /* ========================================================================= * 53 | * Prototypes 54 | * ========================================================================= */ 55 | 56 | /* ------------------------------------------------------------------------- * 57 | * CONFIG 58 | * ------------------------------------------------------------------------- */ 59 | 60 | config_t *config_create (void); 61 | void config_delete (config_t *self); 62 | void config_delete_at(config_t **pself); 63 | void config_delete_cb(void *self); 64 | 65 | /* ------------------------------------------------------------------------- * 66 | * CONFIG_VALUE 67 | * ------------------------------------------------------------------------- */ 68 | 69 | bool config_boolean (const config_t *self, const gchar *sec, const gchar *key, bool def); 70 | gint config_integer (const config_t *self, const gchar *sec, const gchar *key, gint def); 71 | gchar *config_string (const config_t *self, const gchar *sec, const gchar *key, const gchar *def); 72 | stringset_t *config_stringset(const config_t *self, const gchar *sec, const gchar *key); 73 | 74 | G_END_DECLS 75 | 76 | #endif /* CONFIG_H_ */ 77 | -------------------------------------------------------------------------------- /daemon/control.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Open Mobile Platform LLC. 3 | * 4 | * You may use this file under the terms of the BSD license as follows: 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * 3. Neither the names of the copyright holders nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * The views and conclusions contained in the software and documentation 33 | * are those of the authors and should not be interpreted as representing 34 | * any official policies, either expressed or implied. 35 | */ 36 | 37 | #ifndef CONTROL_H_ 38 | # define CONTROL_H_ 39 | 40 | # include 41 | # include 42 | 43 | G_BEGIN_DECLS 44 | 45 | /* ========================================================================= * 46 | * Types 47 | * ========================================================================= */ 48 | 49 | typedef struct stringset_t stringset_t; 50 | typedef struct config_t config_t; 51 | typedef struct users_t users_t; 52 | typedef struct session_t session_t; 53 | typedef struct permissions_t permissions_t; 54 | typedef struct applications_t applications_t; 55 | typedef struct control_t control_t; 56 | typedef struct service_t service_t; 57 | typedef struct appinfo_t appinfo_t; 58 | typedef struct settings_t settings_t; 59 | typedef struct appsettings_t appsettings_t; 60 | typedef struct appservices_t appservices_t; 61 | 62 | /* ========================================================================= * 63 | * Prototypes 64 | * ========================================================================= */ 65 | 66 | /* ------------------------------------------------------------------------- * 67 | * CONTROL 68 | * ------------------------------------------------------------------------- */ 69 | 70 | control_t *control_create (const config_t *config); 71 | void control_delete (control_t *self); 72 | void control_delete_at(control_t **pself); 73 | void control_delete_cb(void *self); 74 | 75 | /* ------------------------------------------------------------------------- * 76 | * CONTROL_ATTRIBUTES 77 | * ------------------------------------------------------------------------- */ 78 | 79 | const config_t *control_config (const control_t *self); 80 | users_t *control_users (const control_t *self); 81 | session_t *control_session (const control_t *self); 82 | permissions_t *control_permissions (const control_t *self); 83 | applications_t *control_applications (const control_t *self); 84 | service_t *control_service (const control_t *self); 85 | settings_t *control_settings (const control_t *self); 86 | appservices_t *control_appservices (const control_t *self); 87 | appsettings_t *control_appsettings (control_t *self, uid_t uid, const char *app); 88 | appinfo_t *control_appinfo (const control_t *self, const char *appname); 89 | uid_t control_current_user (const control_t *self); 90 | bool control_valid_user (const control_t *self, uid_t uid); 91 | uid_t control_min_user (const control_t *self); 92 | uid_t control_max_user (const control_t *self); 93 | bool control_user_is_guest (const control_t *self, uid_t uid); 94 | const stringset_t *control_available_permissions (const control_t *self); 95 | bool control_valid_permission (const control_t *self, const char *perm); 96 | const stringset_t *control_available_applications(const control_t *self); 97 | bool control_valid_application (const control_t *self, const char *appname); 98 | 99 | /* ------------------------------------------------------------------------- * 100 | * CONTROL_SLOTS 101 | * ------------------------------------------------------------------------- */ 102 | 103 | void control_on_users_changed (control_t *self); 104 | void control_on_session_changed (control_t *self); 105 | void control_on_permissions_change(control_t *self); 106 | void control_on_application_change(control_t *self, GHashTable *changed); 107 | void control_on_settings_change (control_t *self, const char *app); 108 | void control_on_appservices_change(control_t *self); 109 | 110 | G_END_DECLS 111 | 112 | #endif /* CONTROL_H_ */ 113 | -------------------------------------------------------------------------------- /daemon/dataflow.dot: -------------------------------------------------------------------------------- 1 | /* -*- mode: c -*- */ 2 | digraph foo { 3 | //rankdir=LR; 4 | node[shape=box]; 5 | node[style=filled] 6 | node[fillcolor=wheat]; 7 | node[width=0.001]; 8 | node[height=0.001]; 9 | node[fontsize=8]; 10 | 11 | edge[fontsize=7]; 12 | edge[color=grey30]; 13 | 14 | /* - - - - - - - - - - - - - - - - - - - * 15 | * SOURCES 16 | * - - - - - - - - - - - - - - - - - - - */ 17 | node[fillcolor=GreenYellow]; 18 | 19 | PERMISSION_FILES [label="Permission\nFiles"]; 20 | DESKTOP_FILES [label="Desktop\nFiles"]; 21 | 22 | /* - - - - - - - - - - - - - - - - - - - * 23 | * STATE DATA 24 | * - - - - - - - - - - - - - - - - - - - */ 25 | node[fillcolor=cyan]; 26 | 27 | ChangedApplications [label="Changed Applications"]; 28 | APPLICATION_DB [label="Application Data"]; 29 | PERMISSION_DB [label="Permission Data"]; 30 | SETTINGS_DB [label="Setting Data"]; 31 | 32 | /* - - - - - - - - - - - - - - - - - - - * 33 | * SIGNALS 34 | * - - - - - - - - - - - - - - - - - - - */ 35 | 36 | node[fillcolor=SlateGray1]; 37 | ApplicationAdded 38 | ApplicationRemoved 39 | ApplicationChanged 40 | 41 | /* - - - - - - - - - - - - - - - - - - - * 42 | * TRIGGERS 43 | * - - - - - - - - - - - - - - - - - - - */ 44 | 45 | node[shape=oval]; 46 | node[fillcolor=yellow]; 47 | 48 | PERMISSION_CHANGE [label="Permission\nChange"]; 49 | APPLICATION_CHANGE [label="Application\nChange"]; 50 | SETTINGS_CHANGE [label="Settings\nChange"]; 51 | 52 | /* - - - - - - - - - - - - - - - - - - - * 53 | * ACTIONS 54 | * - - - - - - - - - - - - - - - - - - - */ 55 | 56 | node[fillcolor=wheat]; 57 | 58 | SETTINGS_RETHINK [label="Settings\nRethink"]; 59 | APPLICATIONS_RETHINK [label="Applications\nRethink"]; 60 | BROADCAST_RETHINK [label="Broadcast\nRethink"]; 61 | 62 | /* - - - - - - - - - - - - - - - - - - - * 63 | * DATAFLOWS (SYNC) 64 | * - - - - - - - - - - - - - - - - - - - */ 65 | 66 | node[fillcolor=pink]; 67 | edge[color=grey30]; 68 | 69 | {ChangedApplications APPLICATION_DB } -> BROADCAST_RETHINK 70 | 71 | SETTINGS_CHANGE -> ChangedApplications; 72 | 73 | APPLICATION_CHANGE -> ChangedApplications; 74 | APPLICATIONS_RETHINK -> APPLICATION_DB; 75 | PERMISSION_CHANGE -> PERMISSION_DB; 76 | 77 | PERMISSION_DB -> SETTINGS_RETHINK; 78 | APPLICATION_DB -> SETTINGS_RETHINK; 79 | PERMISSION_DB -> APPLICATIONS_RETHINK; 80 | SETTINGS_RETHINK -> SETTINGS_DB; 81 | 82 | /* - - - - - - - - - - - - - - - - - - - * 83 | * DATAFLOWS (ASYNC) 84 | * - - - - - - - - - - - - - - - - - - - */ 85 | edge[color=blue, style=dotted]; 86 | 87 | SETTINGS_CHANGE -> BROADCAST_RETHINK; 88 | SETTINGS_RETHINK -> SETTINGS_CHANGE; 89 | PERMISSION_FILES->PERMISSION_CHANGE; 90 | APPLICATION_CHANGE -> SETTINGS_RETHINK; 91 | APPLICATION_CHANGE -> BROADCAST_RETHINK; 92 | DESKTOP_FILES -> APPLICATION_CHANGE; 93 | PERMISSION_CHANGE -> SETTINGS_RETHINK; 94 | PERMISSION_CHANGE -> APPLICATIONS_RETHINK; 95 | 96 | //APPLICATIONS_RETHINK -> APPLICATION_CHANGE; 97 | APPLICATION_CHANGE -> APPLICATIONS_RETHINK; 98 | 99 | BROADCAST_RETHINK -> { 100 | ApplicationAdded 101 | ApplicationRemoved 102 | ApplicationChanged 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /daemon/dbus/sailjaild.conf: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 10 | 11 | 12 | 13 | 15 | 17 | 19 | 20 | 21 | 22 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /daemon/desktop_data.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Open Mobile Platform LLC. 3 | * 4 | * You may use this file under the terms of the BSD license as follows: 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * 3. Neither the names of the copyright holders nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * The views and conclusions contained in the software and documentation 33 | * are those of the authors and should not be interpreted as representing 34 | * any official policies, either expressed or implied. 35 | */ 36 | 37 | #include "util.h" 38 | 39 | #include 40 | 41 | int main(int ac, char **av) 42 | { 43 | if( ac < 2 ) { 44 | fprintf(stderr, 45 | "USAGE:\n" 46 | " %s /usr/share/applications/*.desktop\n" 47 | "\n" 48 | "DESCRIPTION:\n" 49 | " Merges data from all given desktop files and\n" 50 | " outputs the result.\n" 51 | "\n" 52 | " Can be used for quickly checking what kinds of\n" 53 | " Key=Value pairs are used in desktop files\n", 54 | *av); 55 | return EXIT_FAILURE; 56 | } 57 | 58 | GKeyFile *keyfile = g_key_file_new(); 59 | 60 | for( int i = 1; i < ac; ++i ) 61 | keyfile_merge(keyfile, av[i]); 62 | 63 | gchar *text = g_key_file_to_data(keyfile, NULL, NULL); 64 | printf("%s\n", text); 65 | 66 | g_free(text); 67 | g_key_file_unref(keyfile); 68 | 69 | return EXIT_SUCCESS; 70 | } 71 | -------------------------------------------------------------------------------- /daemon/later.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Open Mobile Platform LLC. 3 | * 4 | * You may use this file under the terms of the BSD license as follows: 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * 3. Neither the names of the copyright holders nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * The views and conclusions contained in the software and documentation 33 | * are those of the authors and should not be interpreted as representing 34 | * any official policies, either expressed or implied. 35 | */ 36 | 37 | #include "later.h" 38 | 39 | #include "logging.h" 40 | 41 | /* ========================================================================= * 42 | * Prototypes 43 | * ========================================================================= */ 44 | 45 | /* ------------------------------------------------------------------------- * 46 | * UTILITY 47 | * ------------------------------------------------------------------------- */ 48 | 49 | later_t *later_create (const char *label, gint priority, guint delay, later_func_t func, gpointer aptr); 50 | void later_delete (later_t *self); 51 | void later_delete_at (later_t **pself); 52 | void later_schedule (later_t *self); 53 | void later_cancel (later_t *self); 54 | void later_execute (later_t *self); 55 | static gboolean later_trigger_cb(gpointer aptr); 56 | 57 | /* ========================================================================= * 58 | * LATER 59 | * ========================================================================= */ 60 | 61 | struct later_t 62 | { 63 | const char *label; 64 | gint priority; 65 | guint delay; 66 | later_func_t func; 67 | gpointer aptr; 68 | guint id; 69 | }; 70 | 71 | later_t * 72 | later_create(const char *label, gint priority, guint delay, 73 | later_func_t func, gpointer aptr) 74 | { 75 | later_t *self = g_malloc0(sizeof *self); 76 | 77 | self->label = label; 78 | self->priority = priority; 79 | self->delay = delay; 80 | self->func = func; 81 | self->aptr = aptr; 82 | self->id = 0; 83 | 84 | return self; 85 | } 86 | 87 | void 88 | later_delete(later_t *self) 89 | { 90 | if( self ) { 91 | later_cancel(self); 92 | g_free(self); 93 | } 94 | } 95 | 96 | void 97 | later_delete_at(later_t **pself) 98 | { 99 | later_delete(*pself), *pself = NULL; 100 | } 101 | 102 | void 103 | later_schedule(later_t *self) 104 | { 105 | if( !self->id ) { 106 | log_debug("later(%s) scheduled", self->label); 107 | if( self->delay ) 108 | self->id = g_timeout_add_full(self->priority, 109 | self->delay, 110 | later_trigger_cb, 111 | self, NULL); 112 | else 113 | self->id = g_idle_add_full(self->priority, 114 | later_trigger_cb, 115 | self, NULL); 116 | } 117 | } 118 | 119 | void 120 | later_cancel(later_t *self) 121 | { 122 | if( self->id ) { 123 | log_debug("later(%s) cancelled", self->label); 124 | g_source_remove(self->id), 125 | self->id = 0; 126 | } 127 | } 128 | 129 | void 130 | later_execute(later_t *self) 131 | { 132 | later_cancel(self); 133 | log_debug("later(%s) execute", self->label); 134 | self->func(self->aptr); 135 | } 136 | 137 | static gboolean 138 | later_trigger_cb(gpointer aptr) 139 | { 140 | later_t *self = aptr; 141 | log_debug("later(%s) triggered", self->label); 142 | self->id = 0; 143 | later_execute(self); 144 | return G_SOURCE_REMOVE; 145 | } 146 | -------------------------------------------------------------------------------- /daemon/later.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Open Mobile Platform LLC. 3 | * 4 | * You may use this file under the terms of the BSD license as follows: 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * 3. Neither the names of the copyright holders nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * The views and conclusions contained in the software and documentation 33 | * are those of the authors and should not be interpreted as representing 34 | * any official policies, either expressed or implied. 35 | */ 36 | 37 | #ifndef LATER_H_ 38 | # define LATER_H_ 39 | 40 | # include 41 | 42 | G_BEGIN_DECLS 43 | 44 | /* ========================================================================= * 45 | * Types 46 | * ========================================================================= */ 47 | 48 | typedef struct later_t later_t; 49 | typedef void (*later_func_t)(gpointer aptr); 50 | 51 | /* ========================================================================= * 52 | * Prototypes 53 | * ========================================================================= */ 54 | 55 | /* ------------------------------------------------------------------------- * 56 | * UTILITY 57 | * ------------------------------------------------------------------------- */ 58 | 59 | later_t *later_create (const char *label, gint priority, guint delay, later_func_t func, gpointer aptr); 60 | void later_delete (later_t *self); 61 | void later_delete_at(later_t **pself); 62 | void later_schedule (later_t *self); 63 | void later_cancel (later_t *self); 64 | void later_execute (later_t *self); 65 | 66 | G_END_DECLS 67 | 68 | #endif /* LATER_H_ */ 69 | -------------------------------------------------------------------------------- /daemon/logging.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Open Mobile Platform LLC. 3 | * 4 | * You may use this file under the terms of the BSD license as follows: 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * 3. Neither the names of the copyright holders nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * The views and conclusions contained in the software and documentation 33 | * are those of the authors and should not be interpreted as representing 34 | * any official policies, either expressed or implied. 35 | */ 36 | 37 | #include "logging.h" 38 | 39 | #include "util.h" 40 | 41 | #include 42 | #include 43 | 44 | /* ========================================================================= * 45 | * Prototypes 46 | * ========================================================================= */ 47 | 48 | /* ------------------------------------------------------------------------- * 49 | * LOG 50 | * ------------------------------------------------------------------------- */ 51 | 52 | void log_set_target (log_target_t target); 53 | static int log_normalize_level(int lev); 54 | static const char *log_tag (int lev); 55 | int log_get_level (void); 56 | void log_set_level (int lev); 57 | bool log_p (int lev); 58 | void log_emit_real (const char *file, int line, const char *func, int lev, const char *fmt, ...) __attribute__((format(printf, 5, 6))); 59 | 60 | /* ========================================================================= * 61 | * LOG 62 | * ========================================================================= */ 63 | 64 | static int log_level = LOG_WARNING; 65 | 66 | static log_target_t log_target = LOG_TO_STDERR; 67 | 68 | void 69 | log_set_target(log_target_t target) 70 | { 71 | log_target = target; 72 | } 73 | 74 | static int 75 | log_normalize_level(int lev) 76 | { 77 | return (lev < LOG_CRIT) ? LOG_CRIT : (lev > LOG_TRACE) ? LOG_TRACE : lev; 78 | } 79 | 80 | static const char * 81 | log_tag(int lev) 82 | { 83 | static const char * const tag[] = { 84 | [LOG_EMERG] = "X: ", 85 | [LOG_ALERT] = "A: ", 86 | [LOG_CRIT] = "C: ", 87 | [LOG_ERR] = "E: ", 88 | [LOG_WARNING] = "W: ", 89 | [LOG_NOTICE] = "N: ", 90 | [LOG_INFO] = "I: ", 91 | [LOG_DEBUG] = "D: ", 92 | [LOG_TRACE] = "T: ", 93 | }; 94 | return tag[lev]; 95 | } 96 | 97 | int 98 | log_get_level(void) 99 | { 100 | return log_level; 101 | } 102 | 103 | void 104 | log_set_level(int lev) 105 | { 106 | log_level = log_normalize_level(lev); 107 | } 108 | 109 | bool 110 | log_p(int lev) 111 | { 112 | return log_normalize_level(lev) <= log_level; 113 | } 114 | 115 | void 116 | log_emit_real(const char *file, int line, const char *func, int lev, const char *fmt, ...) 117 | { 118 | (void)file; 119 | (void)line; 120 | (void)func; 121 | 122 | lev = log_normalize_level(lev); 123 | if( lev <= log_level ) { 124 | int saved = errno; 125 | 126 | va_list va; 127 | va_start(va, fmt); 128 | if( log_target == LOG_TO_SYSLOG ) { 129 | vsyslog(lev, fmt, va); 130 | } 131 | else { 132 | char *msg = 0; 133 | if( vasprintf(&msg, fmt, va) < 0 ) 134 | msg = 0; 135 | 136 | #if LOGGING_SHOW_FUNCTION 137 | fprintf(stderr, "%s:%d: %s(): %s%s\n", 138 | file, line, func, log_tag(lev), msg ? strip(msg) : fmt); 139 | #else 140 | fprintf(stderr, "%s%s\n", log_tag(lev), msg ? strip(msg) : fmt); 141 | #endif 142 | fflush(stderr); 143 | free(msg); 144 | } 145 | va_end(va); 146 | 147 | errno = saved; 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /daemon/logging.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Open Mobile Platform LLC. 3 | * 4 | * You may use this file under the terms of the BSD license as follows: 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * 3. Neither the names of the copyright holders nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * The views and conclusions contained in the software and documentation 33 | * are those of the authors and should not be interpreted as representing 34 | * any official policies, either expressed or implied. 35 | */ 36 | 37 | #ifndef LOGGING_H_ 38 | # define LOGGING_H_ 39 | 40 | # include 41 | # include 42 | 43 | # include 44 | 45 | G_BEGIN_DECLS 46 | 47 | /* ========================================================================= * 48 | * Macros 49 | * ========================================================================= */ 50 | 51 | # ifndef LOG_DEBUG 52 | # error foobar 53 | # else 54 | # define LOG_TRACE 8 55 | #endif 56 | 57 | # if 01 58 | # define LOGGING_SHOW_FUNCTION 1 59 | # define LOGGING_LEVEL LOG_DEBUG 60 | # else 61 | # define LOGGING_SHOW_FUNCTION 0 62 | # define LOGGING_LEVEL LOG_INFO 63 | # endif 64 | 65 | # define log_emit(LEV, FMT, ARGS...) do {\ 66 | if( log_p(LEV) ) {\ 67 | log_emit_real(__FILE__, __LINE__, __func__, LEV, FMT, ##ARGS);\ 68 | }\ 69 | } while(0) 70 | 71 | # define log_crit( FMT, ARGS...) log_emit(LOG_CRIT, FMT, ##ARGS) 72 | # define log_err( FMT, ARGS...) log_emit(LOG_ERR, FMT, ##ARGS) 73 | # define log_warning( FMT, ARGS...) log_emit(LOG_WARNING, FMT, ##ARGS) 74 | 75 | # if LOGGING_LEVEL >= LOG_NOTICE 76 | # define log_notice( FMT, ARGS...) log_emit(LOG_NOTICE, FMT, ##ARGS) 77 | # else 78 | # define log_notice( FMT, ARGS...) do{}while(0) 79 | # endif 80 | 81 | # if LOGGING_LEVEL >= LOG_INFO 82 | # define log_info( FMT, ARGS...) log_emit(LOG_INFO, FMT, ##ARGS) 83 | # else 84 | # define log_info( FMT, ARGS...) do{}while(0) 85 | # endif 86 | 87 | # if LOGGING_LEVEL >= LOG_DEBUG 88 | # define log_debug( FMT, ARGS...) log_emit(LOG_DEBUG, FMT, ##ARGS) 89 | # else 90 | # define log_debug( FMT, ARGS...) do{}while(0) 91 | # endif 92 | 93 | # if LOGGING_LEVEL >= LOG_TRACE 94 | # define log_trace( FMT, ARGS...) log_emit(LOG_TRACE, FMT, ##ARGS) 95 | # else 96 | # define log_trace( FMT, ARGS...) do{}while(0) 97 | # endif 98 | 99 | # if 01 100 | # define HERE do{}while(0) 101 | # elif LOGGING_SHOW_FUNCTION 102 | # define HERE log_debug("...") 103 | # else 104 | # define HERE log_debug("%s:%d: %s(): ...", __FILE__, __LINE__, __func__) 105 | # endif 106 | 107 | /* ========================================================================= * 108 | * Types 109 | * ========================================================================= */ 110 | 111 | typedef enum { 112 | LOG_TO_STDERR, 113 | LOG_TO_SYSLOG, 114 | } log_target_t; 115 | 116 | /* ========================================================================= * 117 | * Prototypes 118 | * ========================================================================= */ 119 | 120 | /* ------------------------------------------------------------------------- * 121 | * LOG 122 | * ------------------------------------------------------------------------- */ 123 | 124 | void log_set_target(log_target_t target); 125 | int log_get_level (void); 126 | void log_set_level (int lev); 127 | bool log_p (int lev); 128 | void log_emit_real (const char *file, int line, const char *func, int lev, const char *fmt, ...) __attribute__((format(printf, 5, 6))); 129 | 130 | G_END_DECLS 131 | 132 | #endif /* LOGGING_H_ */ 133 | -------------------------------------------------------------------------------- /daemon/mainloop.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Open Mobile Platform LLC. 3 | * 4 | * You may use this file under the terms of the BSD license as follows: 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * 3. Neither the names of the copyright holders nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * The views and conclusions contained in the software and documentation 33 | * are those of the authors and should not be interpreted as representing 34 | * any official policies, either expressed or implied. 35 | */ 36 | 37 | #include "mainloop.h" 38 | 39 | /* ========================================================================= * 40 | * Prototypes 41 | * ========================================================================= */ 42 | 43 | /* ------------------------------------------------------------------------- * 44 | * UTILITY 45 | * ------------------------------------------------------------------------- */ 46 | 47 | int app_run (void); 48 | void app_exit(int exit_code); 49 | void app_quit(void); 50 | 51 | /* ========================================================================= * 52 | * APP 53 | * ========================================================================= */ 54 | 55 | static GMainLoop *app_mainloop = NULL; 56 | static int app_exitcode = EXIT_FAILURE; 57 | 58 | int 59 | app_run(void) 60 | { 61 | app_exitcode = EXIT_FAILURE; 62 | if( (app_mainloop = g_main_loop_new(NULL, FALSE)) ) { 63 | g_main_loop_run(app_mainloop); 64 | g_main_loop_unref(app_mainloop), 65 | app_mainloop = NULL; 66 | } 67 | return app_exitcode; 68 | } 69 | 70 | void 71 | app_exit(int exit_code) 72 | { 73 | if( !app_mainloop ) 74 | exit(EXIT_FAILURE); 75 | 76 | app_exitcode = exit_code; 77 | g_main_loop_quit(app_mainloop); 78 | } 79 | 80 | void 81 | app_quit(void) 82 | { 83 | app_exit(EXIT_SUCCESS); 84 | } 85 | -------------------------------------------------------------------------------- /daemon/mainloop.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Open Mobile Platform LLC. 3 | * 4 | * You may use this file under the terms of the BSD license as follows: 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * 3. Neither the names of the copyright holders nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * The views and conclusions contained in the software and documentation 33 | * are those of the authors and should not be interpreted as representing 34 | * any official policies, either expressed or implied. 35 | */ 36 | 37 | #ifndef MAINLOOP_H_ 38 | # define MAINLOOP_H_ 39 | 40 | # include 41 | 42 | G_BEGIN_DECLS 43 | 44 | /* ========================================================================= * 45 | * Prototypes 46 | * ========================================================================= */ 47 | 48 | /* ------------------------------------------------------------------------- * 49 | * UTILITY 50 | * ------------------------------------------------------------------------- */ 51 | 52 | int app_run (void); 53 | void app_exit(int exit_code); 54 | void app_quit(void); 55 | 56 | G_END_DECLS 57 | 58 | #endif /* MAINLOOP_H_ */ 59 | -------------------------------------------------------------------------------- /daemon/meson.build: -------------------------------------------------------------------------------- 1 | # ---------------------------------------------------------------------------- 2 | # Common defines 3 | # ---------------------------------------------------------------------------- 4 | common_args = [ 5 | '-DBINDIR="' + bindir + '"', 6 | '-DDATADIR="' + datadir + '"', 7 | '-DSYSCONFDIR="' + sysconfdir + '"', 8 | '-DSHAREDSTATEDIR="' + sharedstatedir + '"', 9 | ] 10 | 11 | # ---------------------------------------------------------------------------- 12 | # Dependencies 13 | # ---------------------------------------------------------------------------- 14 | 15 | # Glib deps are used by daemon and client 16 | glib_deps = [ 17 | dependency('glib-2.0', version : '>= 2.44'), 18 | dependency('gobject-2.0'), 19 | dependency('gio-2.0'), 20 | ] 21 | 22 | # These deps are only used by daemon 23 | libdbusaccess = dependency('libdbusaccess', required : get_option('libdbusaccess')) 24 | libsystemd = dependency('libsystemd') 25 | 26 | # ---------------------------------------------------------------------------- 27 | # Daemon 28 | # ---------------------------------------------------------------------------- 29 | daemon_src = files([ 30 | 'sailjaild.c', 31 | 'appinfo.c', 32 | 'applications.c', 33 | 'appservices.c', 34 | 'config.c', 35 | 'control.c', 36 | 'later.c', 37 | 'logging.c', 38 | 'mainloop.c', 39 | 'migrator.c', 40 | 'permissions.c', 41 | 'prompter.c', 42 | 'service.c', 43 | 'session.c', 44 | 'settings.c', 45 | 'stringset.c', 46 | 'users.c', 47 | 'util.c', 48 | ]) 49 | 50 | if libdbusaccess.found() 51 | daemon_args = [common_args, '-DHAVE_LIBDBUSACCESS'] 52 | else 53 | daemon_args = [common_args] 54 | endif 55 | 56 | executable('sailjaild', 57 | daemon_src, 58 | dependencies : [glib_deps, libsystemd, libdbusaccess], 59 | c_args : daemon_args, 60 | install : true, 61 | install_dir : bindir) 62 | 63 | install_data( 64 | files('systemd/sailjaild.service'), 65 | install_dir : unitdir) 66 | 67 | install_data( 68 | files('dbus/sailjaild.conf'), 69 | install_dir : dbuspolicydir) 70 | 71 | # ---------------------------------------------------------------------------- 72 | # Client 73 | # ---------------------------------------------------------------------------- 74 | client_src = files([ 75 | 'sailjailclient.c', 76 | 'config.c', 77 | 'logging.c', 78 | 'stringset.c', 79 | 'util.c', 80 | ]) 81 | 82 | executable('sailjail', 83 | client_src, 84 | dependencies : glib_deps, 85 | c_args : common_args, 86 | install : true, 87 | install_dir : bindir) 88 | 89 | # ---------------------------------------------------------------------------- 90 | # Diagrams 91 | # ---------------------------------------------------------------------------- 92 | if dot.found() 93 | custom_target('sailjaild.png', 94 | input : files('sailjaild.dot'), 95 | output: 'sailjaild.png', 96 | command: [dot, '-Tpng', '@INPUT@', '-o', '@OUTPUT@'], 97 | install : false) 98 | 99 | custom_target('dataflow.png', 100 | input : files('dataflow.dot'), 101 | output: 'dataflow.png', 102 | command: [dot, '-Tpng', '@INPUT@', '-o', '@OUTPUT@'], 103 | install : false) 104 | 105 | custom_target('prompter.png', 106 | input : files('prompter.dot'), 107 | output: 'prompter.png', 108 | command: [dot, '-Tpng', '@INPUT@', '-o', '@OUTPUT@'], 109 | install : false) 110 | endif 111 | 112 | # ---------------------------------------------------------------------------- 113 | # Desktop data tool 114 | # ---------------------------------------------------------------------------- 115 | executable('desktop_data', 116 | ['desktop_data.c', 'util.c', 'logging.c', 'stringset.c'], 117 | dependencies : glib_deps, 118 | install : false, 119 | build_by_default : false) 120 | 121 | # ---------------------------------------------------------------------------- 122 | # Tests 123 | # ---------------------------------------------------------------------------- 124 | 125 | # Define locations for sources and headers 126 | appinfo = files('appinfo.c') 127 | applications = files('applications.c') 128 | config = files('config.c') 129 | control = files('control.c') 130 | later = files('later.c') 131 | logging = files('logging.c') 132 | mainloop = files('mainloop.c') 133 | migrator = files('migrator.c') 134 | permissions = files('permissions.c') 135 | prompter = files('prompter.c') 136 | sailjailclient = files('sailjailclient.c') 137 | service = files('service.c') 138 | session = files('session.c') 139 | settings = files('settings.c') 140 | stringset = files('stringset.c') 141 | users = files('users.c') 142 | util = files('util.c') 143 | daemon_headers = include_directories('.') 144 | 145 | subdir('test') 146 | 147 | # To make coverage reports work properly, tests must be built in this 148 | # directory. Their definitions are in test/meson.build 149 | 150 | foreach test : tests 151 | executable(test[0], 152 | test[1], 153 | dependencies : glib_deps, 154 | install : true, 155 | install_dir : tests_bindir, 156 | include_directories : daemon_headers, 157 | c_args : test_options, 158 | link_args : test[2]) 159 | endforeach 160 | 161 | foreach test : tests 162 | unit_bins += { 163 | test[0] : executable(test[0] + '_unit', 164 | test[1], 165 | dependencies : glib_deps, 166 | build_by_default : false, 167 | install : false, 168 | include_directories : daemon_headers, 169 | c_args : unit_options, 170 | link_args : test[2]) 171 | } 172 | endforeach 173 | 174 | foreach unit : units 175 | test(unit[0], 176 | unit_bins.get(unit[1]), 177 | args : unit[2], 178 | suite : unit[3], 179 | depends : unit_depends) 180 | endforeach 181 | -------------------------------------------------------------------------------- /daemon/migrator.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Open Mobile Platform LLC. 3 | * 4 | * You may use this file under the terms of the BSD license as follows: 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * 3. Neither the names of the copyright holders nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * The views and conclusions contained in the software and documentation 33 | * are those of the authors and should not be interpreted as representing 34 | * any official policies, either expressed or implied. 35 | */ 36 | 37 | #ifndef MIGRATOR_H_ 38 | # define MIGRATOR_H_ 39 | 40 | # include 41 | # include 42 | 43 | G_BEGIN_DECLS 44 | 45 | /* ========================================================================= * 46 | * Types 47 | * ========================================================================= */ 48 | 49 | typedef struct migrator_t migrator_t; 50 | typedef struct settings_t settings_t; 51 | 52 | /* ========================================================================= * 53 | * Prototypes 54 | * ========================================================================= */ 55 | 56 | /* ------------------------------------------------------------------------- * 57 | * MIGRATOR 58 | * ------------------------------------------------------------------------- */ 59 | 60 | migrator_t *migrator_create (settings_t *settings); 61 | void migrator_delete (migrator_t *self); 62 | void migrator_delete_at(migrator_t **pself); 63 | void migrator_delete_cb(void *self); 64 | 65 | /* ------------------------------------------------------------------------- * 66 | * MIGRATOR_SLOTS 67 | * ------------------------------------------------------------------------- */ 68 | 69 | void migrator_on_settings_saved(migrator_t *self); 70 | 71 | G_END_DECLS 72 | 73 | #endif /* MIGRATOR_H_ */ 74 | -------------------------------------------------------------------------------- /daemon/permissions.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Open Mobile Platform LLC. 3 | * 4 | * You may use this file under the terms of the BSD license as follows: 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * 3. Neither the names of the copyright holders nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * The views and conclusions contained in the software and documentation 33 | * are those of the authors and should not be interpreted as representing 34 | * any official policies, either expressed or implied. 35 | */ 36 | 37 | #ifndef PERMISSIONS_H_ 38 | # define PERMISSIONS_H_ 39 | 40 | # include 41 | 42 | G_BEGIN_DECLS 43 | 44 | /* ========================================================================= * 45 | * Constants 46 | * ========================================================================= */ 47 | 48 | # define PERMISSION_BASE "Base" 49 | # define PERMISSION_PRIVILEGED "Privileged" 50 | # define PERMISSION_COMPATIBILITY "Compatibility" 51 | 52 | /* ========================================================================= * 53 | * Types 54 | * ========================================================================= */ 55 | 56 | typedef struct control_t control_t; 57 | typedef struct config_t config_t; 58 | typedef struct stringset_t stringset_t; 59 | typedef struct permissions_t permissions_t; 60 | 61 | /* ========================================================================= * 62 | * Prototypes 63 | * ========================================================================= */ 64 | 65 | /* ------------------------------------------------------------------------- * 66 | * PERMISSIONS 67 | * ------------------------------------------------------------------------- */ 68 | 69 | permissions_t *permissions_create (control_t *control); 70 | void permissions_delete (permissions_t *self); 71 | void permissions_delete_at(permissions_t **pself); 72 | void permissions_delete_cb(void *self); 73 | 74 | /* ------------------------------------------------------------------------- * 75 | * PERMISSIONS_AVAILABLE 76 | * ------------------------------------------------------------------------- */ 77 | 78 | const stringset_t *permissions_available(permissions_t *self); 79 | 80 | G_END_DECLS 81 | 82 | #endif /* PERMISSIONS_H_ */ 83 | -------------------------------------------------------------------------------- /daemon/prompter.dot: -------------------------------------------------------------------------------- 1 | /* -*- mode: c -*- */ 2 | digraph foo { 3 | node[shape=box]; 4 | node[style=filled] 5 | node[fillcolor=wheat]; 6 | node[width=0.001]; 7 | node[height=0.001]; 8 | node[fontsize=8]; 9 | 10 | edge[fontsize=7]; 11 | edge[color=grey30]; 12 | 13 | /* - - - - - - - - - - - - - - - - - - - * 14 | * STATES 15 | * - - - - - - - - - - - - - - - - - - - */ 16 | 17 | UNDEFINED [label="UNDEFINED"]; 18 | IDLE [label="IDLE"]; 19 | CONNECT [label="CONNECT"]; 20 | PROMPT [label="PROMPT"]; 21 | WAIT [label="WAIT"]; 22 | DISCONNECT [label="DISCONNECT"]; 23 | CONNECTION_FAILURE [label="CONNECTION_FAILURE"]; 24 | PROMPTING_FAILURE [label="PROMPTING_FAILURE"]; 25 | FINAL [label="FINAL"]; 26 | 27 | /* - - - - - - - - - - - - - - - - - - - * 28 | * STATE CHANGES (IN PROMPTER) 29 | * - - - - - - - - - - - - - - - - - - - */ 30 | 31 | node[fillcolor=pink]; 32 | edge[color=grey30]; 33 | 34 | UNDEFINED -> IDLE; 35 | IDLE -> CONNECT; 36 | CONNECT -> CONNECTION_FAILURE; 37 | CONNECT -> PROMPT; 38 | PROMPT -> WAIT; 39 | PROMPT -> DISCONNECT; 40 | PROMPT -> PROMPTING_FAILURE; 41 | WAIT -> PROMPT; 42 | DISCONNECT -> IDLE; 43 | CONNECTION_FAILURE -> IDLE; 44 | PROMPTING_FAILURE -> DISCONNECT; 45 | 46 | /* - - - - - - - - - - - - - - - - - - - * 47 | * STATE CHANGES (FROM OUTSIDE) 48 | * - - - - - - - - - - - - - - - - - - - */ 49 | edge[color=blue, style=dotted]; 50 | 51 | UNDEFINED -> FINAL; 52 | IDLE -> FINAL; 53 | CONNECT -> FINAL; 54 | PROMPT -> FINAL; 55 | WAIT -> FINAL; 56 | DISCONNECT -> FINAL; 57 | CONNECTION_FAILURE -> FINAL; 58 | PROMPTING_FAILURE -> FINAL; 59 | } 60 | -------------------------------------------------------------------------------- /daemon/prompter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Open Mobile Platform LLC. 3 | * 4 | * You may use this file under the terms of the BSD license as follows: 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * 3. Neither the names of the copyright holders nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * The views and conclusions contained in the software and documentation 33 | * are those of the authors and should not be interpreted as representing 34 | * any official policies, either expressed or implied. 35 | */ 36 | 37 | #ifndef PROMPTER_H_ 38 | # define PROMPTER_H_ 39 | 40 | # include 41 | 42 | G_BEGIN_DECLS 43 | 44 | /* ========================================================================= * 45 | * Types 46 | * ========================================================================= */ 47 | 48 | typedef struct appinfo_t appinfo_t; 49 | typedef struct service_t service_t; 50 | typedef struct applications_t applications_t; 51 | typedef struct prompter_t prompter_t; 52 | typedef struct control_t control_t; 53 | typedef struct stringset_t stringset_t; 54 | 55 | /* ========================================================================= * 56 | * Prototypes 57 | * ========================================================================= */ 58 | 59 | /* ------------------------------------------------------------------------- * 60 | * PROMPTER 61 | * ------------------------------------------------------------------------- */ 62 | 63 | prompter_t *prompter_create (service_t *service); 64 | void prompter_delete (prompter_t *self); 65 | void prompter_delete_at (prompter_t **pself); 66 | void prompter_delete_cb (void *self); 67 | void prompter_applications_changed(prompter_t *self, const stringset_t *changed); 68 | void prompter_session_changed (prompter_t *self); 69 | 70 | /* ------------------------------------------------------------------------- * 71 | * PROMPTER_INVOCATION 72 | * ------------------------------------------------------------------------- */ 73 | 74 | void prompter_handle_invocation (prompter_t *self, GDBusMethodInvocation *invocation); 75 | void prompter_dbus_reload_config(prompter_t *self); 76 | 77 | G_END_DECLS 78 | 79 | #endif /* PROMPTER_H_ */ 80 | -------------------------------------------------------------------------------- /daemon/sailjaild.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Open Mobile Platform LLC. 3 | * 4 | * You may use this file under the terms of the BSD license as follows: 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * 3. Neither the names of the copyright holders nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * The views and conclusions contained in the software and documentation 33 | * are those of the authors and should not be interpreted as representing 34 | * any official policies, either expressed or implied. 35 | */ 36 | 37 | #include "config.h" 38 | #include "control.h" 39 | #include "mainloop.h" 40 | #include "logging.h" 41 | #include "util.h" 42 | 43 | #include 44 | 45 | #include 46 | 47 | #include 48 | 49 | /* ========================================================================= * 50 | * Prototypes 51 | * ========================================================================= */ 52 | 53 | /* ------------------------------------------------------------------------- * 54 | * SAILJAILD 55 | * ------------------------------------------------------------------------- */ 56 | 57 | static void sailjaild_filesystem_setup(void); 58 | static int sailjaild_main (int argc, char **argv); 59 | 60 | /* ------------------------------------------------------------------------- * 61 | * MAIN 62 | * ------------------------------------------------------------------------- */ 63 | 64 | int main(int argc, char **argv); 65 | 66 | /* ========================================================================= * 67 | * SAILJAILD 68 | * ========================================================================= */ 69 | 70 | static const struct option long_options[] = { 71 | {"help", no_argument, NULL, 'h'}, 72 | {"verbose", no_argument, NULL, 'v'}, 73 | {"quiet", no_argument, NULL, 'q'}, 74 | {"version", no_argument, NULL, 'V'}, 75 | {"systemd", no_argument, NULL, 'S'}, 76 | {"force-stderr", no_argument, NULL, 'T'}, 77 | {"force-syslog", no_argument, NULL, 's'}, 78 | {0, 0, 0, 0} 79 | }; 80 | static const char short_options[] = "hvqVSTs"; 81 | 82 | static void 83 | sailjaild_filesystem_setup(void) 84 | { 85 | /* Note: Settings are stored in encrypted home partition. As 86 | * home might not be available/mounted at rpm install time, 87 | * data directories must be created during runtime. 88 | */ 89 | 90 | /* Create directories using standard mode bits */ 91 | if( !g_file_test(SETTINGS_DIRECTORY, G_FILE_TEST_IS_DIR) ) { 92 | if( g_mkdir_with_parents(SETTINGS_DIRECTORY, 0755) == -1 ) { 93 | log_err("%s: could not create directory: %m", SETTINGS_DIRECTORY); 94 | 95 | /* Limp onwards instead of possibly breaking everything */ 96 | log_warning("permissions can't be stored persistently"); 97 | } 98 | } 99 | 100 | /* Make settings directory itself accessible by root only */ 101 | if( g_chmod(SETTINGS_DIRECTORY, 0750) == -1 ) { 102 | log_err("%s: could not update permissions: %m", 103 | SETTINGS_DIRECTORY); 104 | } 105 | 106 | /* Settings files must not be world readable. 107 | * As sailjaild writes only to settings files, 108 | * we can just set umask here to accomplish it. 109 | */ 110 | umask(0027); 111 | } 112 | 113 | static int 114 | sailjaild_main(int argc, char **argv) 115 | { 116 | int exit_code = EXIT_FAILURE; 117 | config_t *config = config_create(); 118 | control_t *control = NULL; 119 | bool systemd = false; 120 | 121 | /* Handle options */ 122 | for( ;; ) { 123 | int opt = getopt_long(argc, argv, short_options, long_options, 0); 124 | 125 | if( opt == -1 ) 126 | break; 127 | 128 | switch( opt ) { 129 | case 'h': 130 | printf("usage: TBD\n"); 131 | exit_code = EXIT_SUCCESS; 132 | goto EXIT; 133 | case 'v': 134 | log_set_level(log_get_level() + 1); 135 | break; 136 | case 'q': 137 | log_set_level(log_get_level() - 1); 138 | break; 139 | case 'T': 140 | log_set_target(LOG_TO_STDERR); 141 | break; 142 | case 's': 143 | log_set_target(LOG_TO_SYSLOG); 144 | break; 145 | case 'V': 146 | printf("%s\n", VERSION); 147 | exit_code = EXIT_SUCCESS; 148 | goto EXIT; 149 | case 'S': 150 | systemd = true; 151 | log_set_target(LOG_TO_SYSLOG); 152 | break; 153 | case '?': 154 | fprintf(stderr, "(use --help for instructions)\n"); 155 | goto EXIT; 156 | } 157 | } 158 | 159 | sailjaild_filesystem_setup(); 160 | 161 | control = control_create(config); 162 | 163 | if( systemd ) 164 | sd_notify(0, "READY=1"); 165 | 166 | exit_code = app_run(); 167 | 168 | EXIT: 169 | control_delete_at(&control); 170 | config_delete_at(&config); 171 | 172 | log_debug("exit %d", exit_code); 173 | return exit_code; 174 | } 175 | 176 | /* ========================================================================= * 177 | * MAIN 178 | * ========================================================================= */ 179 | 180 | int 181 | main(int argc, char **argv) 182 | { 183 | return sailjaild_main(argc, argv); 184 | } 185 | -------------------------------------------------------------------------------- /daemon/sailjaild.dot: -------------------------------------------------------------------------------- 1 | /* -*- mode: c -*- */ 2 | digraph foo { 3 | rankdir=LR; 4 | node[shape=box]; 5 | node[style=filled] 6 | node[fillcolor=wheat]; 7 | node[width=0.001]; 8 | node[height=0.001]; 9 | node[fontsize=8]; 10 | 11 | edge[fontsize=7]; 12 | edge[color=grey30]; 13 | 14 | /* - - - - - - - - - - - - - - - - - - - * 15 | * PROCESSES 16 | * - - - - - - - - - - - - - - - - - - - */ 17 | 18 | node[fillcolor=yellow]; 19 | CONTROL; 20 | SETTINGS; 21 | USER_SETTINGS; 22 | APP_SETTINGS; 23 | CONFIG; 24 | MIGRATOR; 25 | APPROVAL; 26 | PROMPTER; 27 | SERVICE; 28 | USERS; 29 | APPLICATIONS; 30 | APPINFO; 31 | APPSERVICES; 32 | PERMISSIONS; 33 | SESSION; 34 | WINDOW_PROMPT [label=" Permission\l Dialog in\l SessionBus\l"] 35 | ANY [label=" (any)\l"] 36 | DBUS_CLIENT [label=" D-Bus\l client in\l SystemBus\l"] 37 | SESSION_BUS [label=" SessionBus\l daemon\l"] 38 | 39 | /* - - - - - - - - - - - - - - - - - - - * 40 | * DATASTORES 41 | * - - - - - - - - - - - - - - - - - - - */ 42 | 43 | node[fillcolor=wheat]; 44 | SETTINGS_FILES [label=" /var/lib/sailjail/userdata/\l USER.settings\l"]; 45 | PASSWD_FILE [label=" /etc/\l passwd\l"]; 46 | PERMISSION_FILES [label=" /etc/sailjail/permissions/\l FEATURE.permission\l"] 47 | DESKTOP_FILES [label=" /usr/share/applications/\l APPLICATION.desktop\l"] 48 | DAEMON_CONFIG [label=" /etc/sailjail/daemon/\l *.config\l"] 49 | SERVICE_STATE [label=" cached\l state\l"] 50 | PROMPTER_QUEUE [label=" request\l queue\l"] 51 | PROMPTER_STM [label=" request\l statemachine\l"] 52 | MIGRATOR_QUEUE [label=" migration\l queue\l"] 53 | MIGRATOR_STM [label=" migration\l statemachine\l"] 54 | REMOVAL_QUEUE [label=" removal\l queue\l"] 55 | APPROVAL_FILES [label=" /var/lib/sailjail-homescreen/**/\l APPLICATION.desktop/X-Sailjail\l"] 56 | SESSION_STATE [label=" /run/systemd/\l sessions\l"]; 57 | ACTIVATION_FILES [label=" /run/user/UID/dbus-1/services/\l DBUSNAME.service\l"] 58 | 59 | /* - - - - - - - - - - - - - - - - - - - * 60 | * DATAFLOWS (SYNC) 61 | * - - - - - - - - - - - - - - - - - - - */ 62 | 63 | edge[color=grey30]; 64 | 65 | SETTINGS -> USER_SETTINGS [label=" get\l set\l"]; 66 | 67 | USER_SETTINGS -> APP_SETTINGS [label=" get\l set\l"]; 68 | USER_SETTINGS -> SETTINGS_FILES [label=" read\l write\l"]; 69 | 70 | APP_SETTINGS -> USER_SETTINGS [label=" dirty\l"]; 71 | USER_SETTINGS -> SETTINGS [label=" dirty\l"]; 72 | 73 | CONTROL -> SETTINGS [label=" save\l load\l remove\l"]; 74 | CONTROL -> SETTINGS [label=" get\l"]; 75 | 76 | CONTROL -> USERS [label=" min\l max\l"]; 77 | CONTROL -> USERS [label=" exists\l"]; 78 | 79 | USERS -> PASSWD_FILE [label=" read\l"]; 80 | 81 | CONTROL -> CONFIG [label=" load\l"]; 82 | ANY -> CONFIG [label=" get\l"]; 83 | CONFIG -> DAEMON_CONFIG [label=" read\l"]; 84 | 85 | CONTROL -> APPLICATIONS [label=" list\l"]; 86 | CONTROL -> APPLICATIONS [label=" get\l"]; 87 | 88 | CONTROL -> PERMISSIONS [label=" list\l"]; 89 | CONTROL -> PERMISSIONS [label=" get\l"]; 90 | PERMISSIONS -> PERMISSION_FILES [label=" read\l"]; 91 | 92 | SERVICE -> CONTROL [label=" fetch data\l"]; 93 | 94 | SERVICE -> SERVICE_STATE; 95 | 96 | PROMPTER -> PROMPTER_QUEUE; 97 | PROMPTER -> PROMPTER_STM; 98 | 99 | CONTROL -> SESSION [label=" get\l"] 100 | 101 | SETTINGS -> MIGRATOR [label=" load\l"]; 102 | 103 | MIGRATOR -> SETTINGS [label=" update\l fetch data\l"]; 104 | 105 | MIGRATOR -> MIGRATOR_QUEUE; 106 | MIGRATOR -> MIGRATOR_STM; 107 | MIGRATOR -> REMOVAL_QUEUE; 108 | 109 | MIGRATOR -> APPROVAL [label=" load\l"]; 110 | APPROVAL -> APPROVAL_FILES [label=" read\l"]; 111 | MIGRATOR -> APPROVAL_FILES [label=" scan\l remove\l"]; 112 | 113 | SESSION -> SESSION_STATE [label=" read\l"] 114 | 115 | APPLICATIONS -> APPINFO [label=" update\l"]; 116 | APPINFO -> DESKTOP_FILES [label=" read\l"]; 117 | APPLICATIONS -> DESKTOP_FILES [label=" scan\l"]; 118 | APPSERVICES -> ACTIVATION_FILES [label=" read\l write\l remove\l"]; 119 | 120 | /* - - - - - - - - - - - - - - - - - - - * 121 | * DATAFLOWS (ASYNC) 122 | * - - - - - - - - - - - - - - - - - - - */ 123 | edge[color=blue]; 124 | 125 | PASSWD_FILE -> USERS [label=" inotify\l"]; 126 | USERS -> CONTROL [label=" changed\l"]; 127 | 128 | DESKTOP_FILES -> APPLICATIONS [label=" inotify\l"]; 129 | APPLICATIONS -> CONTROL [label=" changed\l"]; 130 | 131 | PERMISSION_FILES -> PERMISSIONS [label=" inotify\l"]; 132 | PERMISSIONS -> CONTROL [label=" changed\l"]; 133 | 134 | SETTINGS -> MIGRATOR [label=" saved\l"]; 135 | MIGRATOR -> SETTINGS [label=" finished\l"]; 136 | 137 | CONTROL -> SERVICE [label=" broadcast\l"]; 138 | SERVICE -> DBUS_CLIENT [label=" signal\l"]; 139 | SERVICE -> DBUS_CLIENT [label=" reply\l"]; 140 | DBUS_CLIENT -> SERVICE [label=" request\l"]; 141 | 142 | SERVICE -> PROMPTER [label=" queue\l"]; 143 | PROMPTER -> SERVICE [label=" finished\l"]; 144 | 145 | PROMPTER -> WINDOW_PROMPT [label=" show\l"]; 146 | WINDOW_PROMPT -> PROMPTER [label=" selection\l"]; 147 | 148 | SESSION -> CONTROL [label=" changed\l"] 149 | 150 | SESSION_STATE -> SESSION [label=" inotify\l"] 151 | 152 | SETTINGS -> CONTROL [label=" changed\l"]; 153 | 154 | CONTROL -> APPSERVICES [label=" applications\l changed\l"]; 155 | APPSERVICES -> CONTROL [label=" activation\l changed\l"]; 156 | 157 | CONTROL -> PROMPTER [label=" activation\l changed\l"]; 158 | PROMPTER -> SESSION_BUS [label=" ReloadConfig\l"]; 159 | } 160 | -------------------------------------------------------------------------------- /daemon/service.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Open Mobile Platform LLC. 3 | * Copyright (c) 2021 Jolla Ltd. 4 | * 5 | * You may use this file under the terms of the BSD license as follows: 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer 15 | * in the documentation and/or other materials provided with the 16 | * distribution. 17 | * 3. Neither the names of the copyright holders nor the names of its 18 | * contributors may be used to endorse or promote products derived 19 | * from this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | * 33 | * The views and conclusions contained in the software and documentation 34 | * are those of the authors and should not be interpreted as representing 35 | * any official policies, either expressed or implied. 36 | */ 37 | 38 | #ifndef SERVICE_H_ 39 | # define SERVICE_H_ 40 | 41 | # include 42 | # include 43 | 44 | G_BEGIN_DECLS; 45 | 46 | /* ========================================================================= * 47 | * DBUS 48 | * ========================================================================= */ 49 | 50 | #define DBUS_SERVICE "org.freedesktop.DBus" 51 | #define DBUS_PATH "/" 52 | #define DBUS_INTERFACE "org.freedesktop.DBus" 53 | #define DBUS_METHOD_RELOAD_CONFIG "ReloadConfig" 54 | #define DBUS_METHOD_NAME_HAS_OWNER "NameHasOwner" 55 | 56 | # define WINDOWPROMPT_SERVICE "com.jolla.windowprompt" 57 | # define WINDOWPROMPT_OBJECT "/com/jolla/windowprompt" 58 | # define WINDOWPROMPT_INTERFACE "com.jolla.windowprompt" 59 | # define WINDOWPROMPT_METHOD_PROMPT "newPermissionPrompt" 60 | # define WINDOWPROMPT_PROMPT_INTERFACE "com.jolla.windowprompt.Prompt" 61 | # define WINDOWPROMPT_PROMPT_METHOD_WAIT "wait" 62 | # define WINDOWPROMPT_PROMPT_METHOD_CANCEL "cancel" 63 | 64 | # define PERMISSIONMGR_BUS G_BUS_TYPE_SYSTEM 65 | 66 | # define PERMISSIONMGR_SERVICE "org.sailfishos.sailjaild1" 67 | # define PERMISSIONMGR_INTERFACE "org.sailfishos.sailjaild1" 68 | # define PERMISSIONMGR_OBJECT "/org/sailfishos/sailjaild1" 69 | # define PERMISSIONMGR_METHOD_PROMPT "PromptLaunchPermissions" 70 | # define PERMISSIONMGR_METHOD_QUERY "QueryLaunchPermissions" 71 | # define PERMISSIONMGR_METHOD_GET_APPLICATIONS "GetApplications" 72 | # define PERMISSIONMGR_METHOD_GET_APPINFO "GetAppInfo" 73 | # define PERMISSIONMGR_METHOD_GET_LICENSE "GetLicenseAgreed" 74 | # define PERMISSIONMGR_METHOD_SET_LICENSE "SetLicenseAgreed" 75 | # define PERMISSIONMGR_METHOD_GET_LAUNCHABLE "GetLaunchAllowed" 76 | # define PERMISSIONMGR_METHOD_SET_LAUNCHABLE "SetLaunchAllowed" 77 | # define PERMISSIONMGR_METHOD_GET_GRANTED "GetGrantedPermissions" 78 | # define PERMISSIONMGR_METHOD_SET_GRANTED "SetGrantedPermissions" 79 | # define PERMISSIONMGR_SIGNAL_APP_ADDED "ApplicationAdded" 80 | # define PERMISSIONMGR_SIGNAL_APP_CHANGED "ApplicationChanged" 81 | # define PERMISSIONMGR_SIGNAL_APP_REMOVED "ApplicationRemoved" 82 | 83 | /* Message templates used for error reporting */ 84 | # define SERVICE_MESSAGE_INVALID_APPLICATION "Invalid application name: %s" 85 | # define SERVICE_MESSAGE_INVALID_USER "Invalid user id: %u" 86 | # define SERVICE_MESSAGE_INVALID_PERMISSIONS "Invalid permissions list" 87 | # define SERVICE_MESSAGE_DENIED_PERMANENTLY "Denied permanently" 88 | # define SERVICE_MESSAGE_NOT_ALLOWED "Not allowed" 89 | # define SERVICE_MESSAGE_RESTRICTED_METHOD "%s is not allowed to access %s" 90 | # define SERVICE_MESSAGE_GUEST_NOT_LOGGED_IN "Guest user is not logged in" 91 | # define SERVICE_MESSAGE_DISMISSED "Dismissed" 92 | # define SERVICE_MESSAGE_DISCONNECTED "Disconnected" 93 | 94 | # define PERMISSIONMGR_NOTIFY_DELAY 0 // [ms] 95 | 96 | /* ========================================================================= * 97 | * Types 98 | * ========================================================================= */ 99 | 100 | typedef struct config_t config_t; 101 | typedef struct users_t users_t; 102 | typedef struct session_t session_t; 103 | typedef struct permissions_t permissions_t; 104 | typedef struct applications_t applications_t; 105 | typedef struct control_t control_t; 106 | typedef struct service_t service_t; 107 | typedef struct appinfo_t appinfo_t; 108 | typedef struct stringset_t stringset_t; 109 | typedef struct prompter_t prompter_t; 110 | 111 | /* ========================================================================= * 112 | * Prototypes 113 | * ========================================================================= */ 114 | 115 | /* ------------------------------------------------------------------------- * 116 | * SERVICE 117 | * ------------------------------------------------------------------------- */ 118 | 119 | service_t *service_create (control_t *control); 120 | void service_delete (service_t *self); 121 | void service_delete_at (service_t **pself); 122 | void service_delete_cb (void *self); 123 | void service_applications_changed(service_t *self, const stringset_t *changed); 124 | 125 | /* ------------------------------------------------------------------------- * 126 | * SERVICE_PERMISSIONS 127 | * ------------------------------------------------------------------------- */ 128 | 129 | stringset_t *service_filter_permissions(const service_t *self, const stringset_t *permissions); 130 | 131 | /* ------------------------------------------------------------------------- * 132 | * SERVICE_ATTRIBUTES 133 | * ------------------------------------------------------------------------- */ 134 | 135 | control_t *service_control (const service_t *self); 136 | prompter_t *service_prompter(service_t *self); 137 | 138 | /* ------------------------------------------------------------------------- * 139 | * SERVICE_NAMEOWNER 140 | * ------------------------------------------------------------------------- */ 141 | 142 | bool service_is_nameowner(const service_t *self); 143 | 144 | G_END_DECLS 145 | 146 | #endif /* SERVICE_H_ */ 147 | -------------------------------------------------------------------------------- /daemon/session.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Open Mobile Platform LLC. 3 | * 4 | * You may use this file under the terms of the BSD license as follows: 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * 3. Neither the names of the copyright holders nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * The views and conclusions contained in the software and documentation 33 | * are those of the authors and should not be interpreted as representing 34 | * any official policies, either expressed or implied. 35 | */ 36 | 37 | #ifndef SESSION_H_ 38 | # define SESSION_H_ 39 | 40 | # include 41 | 42 | G_BEGIN_DECLS 43 | 44 | /* ========================================================================= * 45 | * Constants 46 | * ========================================================================= */ 47 | 48 | # define SESSION_UID_UNDEFINED ((uid_t)(-1)) 49 | # define SESSION_GID_UNDEFINED ((gid_t)(-1)) 50 | 51 | /* ========================================================================= * 52 | * Types 53 | * ========================================================================= */ 54 | 55 | typedef struct config_t config_t; 56 | typedef struct session_t session_t; 57 | typedef struct control_t control_t; 58 | 59 | /* ========================================================================= * 60 | * Prototypes 61 | * ========================================================================= */ 62 | 63 | /* ------------------------------------------------------------------------- * 64 | * SESSION 65 | * ------------------------------------------------------------------------- */ 66 | 67 | session_t *session_create (control_t *control); 68 | void session_delete (session_t *self); 69 | void session_delete_at(session_t **pself); 70 | void session_delete_cb(void *self); 71 | 72 | /* ------------------------------------------------------------------------- * 73 | * SESSION_USER 74 | * ------------------------------------------------------------------------- */ 75 | 76 | uid_t session_current_user(const session_t *self); 77 | 78 | G_END_DECLS 79 | 80 | #endif /* SESSION_H_ */ 81 | -------------------------------------------------------------------------------- /daemon/settings.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Open Mobile Platform LLC. 3 | * 4 | * You may use this file under the terms of the BSD license as follows: 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * 3. Neither the names of the copyright holders nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * The views and conclusions contained in the software and documentation 33 | * are those of the authors and should not be interpreted as representing 34 | * any official policies, either expressed or implied. 35 | */ 36 | 37 | #ifndef SETTINGS_H_ 38 | # define SETTINGS_H_ 39 | 40 | # include 41 | # include 42 | 43 | G_BEGIN_DECLS 44 | 45 | /* ========================================================================= * 46 | * Types 47 | * ========================================================================= */ 48 | 49 | typedef struct config_t config_t; 50 | typedef struct settings_t settings_t; 51 | typedef struct usersettings_t usersettings_t; 52 | typedef struct appsettings_t appsettings_t; 53 | typedef struct control_t control_t; 54 | typedef struct stringset_t stringset_t; 55 | typedef struct migrator_t migrator_t; 56 | 57 | typedef enum 58 | { 59 | APP_ALLOWED_UNSET, 60 | APP_ALLOWED_ALWAYS, 61 | APP_ALLOWED_NEVER, 62 | APP_ALLOWED_COUNT 63 | // keep app_allowed_name[] in sync 64 | } app_allowed_t; 65 | 66 | typedef enum 67 | { 68 | APP_AGREED_UNSET, 69 | APP_AGREED_YES, 70 | APP_AGREED_NO, 71 | APP_AGREED_COUNT 72 | // keep app_agreed_name[] in sync 73 | } app_agreed_t; 74 | 75 | typedef enum { 76 | APP_GRANT_DEFAULT, // Take default 77 | APP_GRANT_ALWAYS, // Always allow all permissions 78 | APP_GRANT_LAUNCH, // Allow launching, user may control permissions 79 | APP_GRANT_COUNT 80 | // keep app_grant_name[] in sync 81 | } app_grant_t; 82 | 83 | /* ========================================================================= * 84 | * Prototypes 85 | * ========================================================================= */ 86 | 87 | /* ------------------------------------------------------------------------- * 88 | * SETTINGS 89 | * ------------------------------------------------------------------------- */ 90 | 91 | settings_t *settings_create (const config_t *config, control_t *control); 92 | void settings_delete (settings_t *self); 93 | void settings_delete_at(settings_t **pself); 94 | void settings_delete_cb(void *self); 95 | 96 | /* ------------------------------------------------------------------------- * 97 | * SETTINGS_ATTRIBUTES 98 | * ------------------------------------------------------------------------- */ 99 | 100 | control_t *settings_control (const settings_t *self); 101 | appsettings_t *settings_appsettings(settings_t *self, uid_t uid, const char *app); 102 | 103 | /* ------------------------------------------------------------------------- * 104 | * SETTINGS_USERSETTINGS 105 | * ------------------------------------------------------------------------- */ 106 | 107 | usersettings_t *settings_get_usersettings (const settings_t *self, uid_t uid); 108 | usersettings_t *settings_add_usersettings (settings_t *self, uid_t uid); 109 | bool settings_remove_usersettings(settings_t *self, uid_t uid); 110 | 111 | /* ------------------------------------------------------------------------- * 112 | * SETTINGS_APPSETTING 113 | * ------------------------------------------------------------------------- */ 114 | 115 | appsettings_t *settings_get_appsettings (const settings_t *self, uid_t uid, const char *appname); 116 | appsettings_t *settings_add_appsettings (settings_t *self, uid_t uid, const char *appname); 117 | bool settings_remove_appsettings(settings_t *self, uid_t uid, const char *appname); 118 | 119 | /* ------------------------------------------------------------------------- * 120 | * SETTINGS_STORAGE 121 | * ------------------------------------------------------------------------- */ 122 | 123 | void settings_load_all (settings_t *self); 124 | void settings_save_all (const settings_t *self); 125 | void settings_load_user (settings_t *self, uid_t uid); 126 | void settings_save_user (const settings_t *self, uid_t uid); 127 | void settings_save_later(settings_t *self, uid_t uid); 128 | 129 | /* ------------------------------------------------------------------------- * 130 | * SETTINGS_SLOTS 131 | * ------------------------------------------------------------------------- */ 132 | 133 | void settings_on_migration_finished(settings_t *self); 134 | 135 | /* ------------------------------------------------------------------------- * 136 | * SETTINGS_RETHINK 137 | * ------------------------------------------------------------------------- */ 138 | 139 | void settings_rethink(settings_t *self); 140 | 141 | /* ------------------------------------------------------------------------- * 142 | * USERSETTINGS 143 | * ------------------------------------------------------------------------- */ 144 | 145 | usersettings_t *usersettings_create (settings_t *settings, uid_t uid); 146 | void usersettings_delete (usersettings_t *self); 147 | void usersettings_delete_cb(void *self); 148 | 149 | /* ------------------------------------------------------------------------- * 150 | * USERSETTINGS_APPSETTINGS 151 | * ------------------------------------------------------------------------- */ 152 | 153 | appsettings_t *usersettings_get_appsettings (const usersettings_t *self, const gchar *appname); 154 | appsettings_t *usersettings_add_appsettings (usersettings_t *self, const gchar *appname); 155 | bool usersettings_remove_appsettings(usersettings_t *self, const gchar *appname); 156 | 157 | /* ------------------------------------------------------------------------- * 158 | * USERSETTINGS_STORAGE 159 | * ------------------------------------------------------------------------- */ 160 | 161 | void usersettings_load(usersettings_t *self, const char *path); 162 | void usersettings_save(const usersettings_t *self, const char *path); 163 | 164 | /* ------------------------------------------------------------------------- * 165 | * APPSETTINGS 166 | * ------------------------------------------------------------------------- */ 167 | 168 | appsettings_t *appsettings_create (usersettings_t *usersettings, const char *appname); 169 | void appsettings_delete (appsettings_t *self); 170 | void appsettings_delete_cb(void *self); 171 | 172 | /* ------------------------------------------------------------------------- * 173 | * APPSETTINGS_PROPERTIES 174 | * ------------------------------------------------------------------------- */ 175 | 176 | app_agreed_t appsettings_get_agreed (const appsettings_t *self); 177 | void appsettings_set_agreed (appsettings_t *self, app_agreed_t agreed); 178 | app_allowed_t appsettings_get_allowed (const appsettings_t *self); 179 | bool appsettings_update_allowed(appsettings_t *self, app_allowed_t allowed); 180 | void appsettings_set_allowed (appsettings_t *self, app_allowed_t allowed); 181 | const stringset_t *appsettings_get_granted (appsettings_t *self); 182 | void appsettings_set_granted (appsettings_t *self, const stringset_t *granted); 183 | 184 | G_END_DECLS 185 | 186 | #endif /* SETTINGS_H_ */ 187 | -------------------------------------------------------------------------------- /daemon/stringset.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Open Mobile Platform LLC. 3 | * 4 | * You may use this file under the terms of the BSD license as follows: 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * 3. Neither the names of the copyright holders nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * The views and conclusions contained in the software and documentation 33 | * are those of the authors and should not be interpreted as representing 34 | * any official policies, either expressed or implied. 35 | */ 36 | 37 | #ifndef STRINGSET_H_ 38 | # define STRINGSET_H_ 39 | 40 | # include 41 | # include 42 | 43 | G_BEGIN_DECLS 44 | 45 | /* ========================================================================= * 46 | * Types 47 | * ========================================================================= */ 48 | 49 | typedef struct stringset_t stringset_t; 50 | 51 | /* ========================================================================= * 52 | * Prototypes 53 | * ========================================================================= */ 54 | 55 | /* ------------------------------------------------------------------------- * 56 | * UTILITY 57 | * ------------------------------------------------------------------------- */ 58 | 59 | stringset_t *stringset_create (void); 60 | void stringset_delete (stringset_t *self); 61 | void stringset_delete_at (stringset_t **pself); 62 | void stringset_delete_cb (void *self); 63 | guint stringset_size (const stringset_t *self); 64 | bool stringset_empty (const stringset_t *self); 65 | const GList *stringset_list (const stringset_t *self); 66 | bool stringset_has_item (const stringset_t *self, const gchar *item); 67 | bool stringset_add_item (stringset_t *self, const gchar *item); 68 | bool stringset_add_item_steal(stringset_t *self, gchar *item); 69 | bool stringset_add_item_fmt (stringset_t *self, const char *fmt, ...); 70 | bool stringset_remove_item (stringset_t *self, const gchar *item); 71 | bool stringset_clear (stringset_t *self); 72 | GVariant *stringset_to_variant (const stringset_t *self); 73 | gchar *stringset_to_string (const stringset_t *self); 74 | gchar **stringset_to_strv (const stringset_t *self); 75 | stringset_t *stringset_from_strv (char **vector); 76 | stringset_t *stringset_copy (const stringset_t *self); 77 | void stringset_swap (stringset_t *self, stringset_t *that); 78 | stringset_t *stringset_filter_out (const stringset_t *self, const stringset_t *mask); 79 | stringset_t *stringset_filter_in (const stringset_t *self, const stringset_t *mask); 80 | bool stringset_equal (const stringset_t *self, const stringset_t *that); 81 | bool stringset_extend (stringset_t *self, const stringset_t *that); 82 | bool stringset_assign (stringset_t *self, const stringset_t *that); 83 | 84 | G_END_DECLS 85 | 86 | #endif /* STRINGSET_H_ */ 87 | -------------------------------------------------------------------------------- /daemon/systemd/sailjaild.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Application Permission Management Daemon 3 | Requires=dbus.service 4 | After=dbus.socket 5 | RequiresMountsFor=/home 6 | 7 | [Service] 8 | Type=notify 9 | ExecStart=/usr/bin/sailjaild --systemd 10 | Restart=always 11 | 12 | [Install] 13 | WantedBy=multi-user.target 14 | -------------------------------------------------------------------------------- /daemon/test/data/keyfile1.ini: -------------------------------------------------------------------------------- 1 | [GroupA] 2 | KeyA1=ValueA1 3 | KeyA2=ValueA2 4 | 5 | [GroupB] 6 | KeyB1=ValueB1 7 | KeyB2=ValueB2 8 | -------------------------------------------------------------------------------- /daemon/test/data/keyfile2.ini: -------------------------------------------------------------------------------- 1 | [GroupB] 2 | KeyB1=OverrideB1 3 | KeyB2=ValueB2 4 | 5 | [GroupC] 6 | KeyC1=ValueC1 7 | KeyC2=ValueC2 8 | -------------------------------------------------------------------------------- /daemon/test/data/user-1000.settings: -------------------------------------------------------------------------------- 1 | [test-app] 2 | Allowed=1 3 | Agreed=0 4 | Autogrant=0 5 | Granted=Internet 6 | Permissions=Internet 7 | -------------------------------------------------------------------------------- /daemon/test/meson.build: -------------------------------------------------------------------------------- 1 | # ---------------------------------------------------------------------------- 2 | # Custom directories for tests 3 | # ---------------------------------------------------------------------------- 4 | testsdir = get_option('testsdir') / 'sailjail-daemon' 5 | tests_bindir = testsdir / 'bin' 6 | tests_prefix = testsdir / 'usr' 7 | tests_datadir = tests_prefix / 'share' 8 | 9 | testdatadir = testsdir / 'data' 10 | 11 | testtmpdata = get_option('testtmpdata') 12 | tests_sysconfdir = testtmpdata / 'etc' 13 | tests_sharedstatedir = testtmpdata 14 | 15 | summary({ 16 | 'testsdir' : testsdir, 17 | 'bindir': tests_bindir, 18 | 'testdatadir': testdatadir, 19 | 'sysconfdir': tests_sysconfdir, 20 | 'sharedstatedir' : tests_sharedstatedir 21 | }, 22 | section : 'QA test paths') 23 | 24 | # ---------------------------------------------------------------------------- 25 | # Static data 26 | # ---------------------------------------------------------------------------- 27 | install_subdir('data', 28 | install_dir : testsdir) 29 | 30 | install_subdir('sailjail/applications', 31 | install_dir : tests_datadir) 32 | 33 | custom_target('tests.xml', 34 | input : 'tests.xml.in', 35 | output : 'tests.xml', 36 | capture : true, 37 | command : [sed, 38 | '-e', 's|@TESTTMPDATA@|' + testtmpdata + '|g', 39 | '-e', 's|@TESTSDIR@|' + testsdir + '|g', 40 | '-e', 's|@TESTDATADIR@|' + testdatadir + '|g', 41 | '-e', 's|@SHAREDSTATEDIR@|' + tests_sharedstatedir + '|g', 42 | '-e', 's|@TESTBINDIR@|' + tests_bindir + '|g', 43 | '@INPUT@'], 44 | install : true, 45 | install_dir : testsdir) 46 | 47 | permission_files = [ 48 | 'Audio.permission', 49 | 'Base.permission', 50 | 'Camera.permission', 51 | 'Contacts.permission', 52 | 'some-app.profile', 53 | ] 54 | create_permission_files = custom_target('permissions', 55 | command : [touch, '@OUTPUT@'], 56 | output : permission_files, 57 | install : true, 58 | install_dir : testsdir / 'etc/sailjail/permissions') 59 | 60 | # ---------------------------------------------------------------------------- 61 | # Tests for QA 62 | # ---------------------------------------------------------------------------- 63 | test_options = [ 64 | '-DSYSCONFDIR="' + tests_sysconfdir + '"', 65 | '-DSHAREDSTATEDIR="' + tests_sharedstatedir + '"', 66 | '-DDATADIR="' + tests_datadir + '"', 67 | '-DTESTDATADIR="' + testdatadir + '"', 68 | '-DUNITTEST', 69 | ] 70 | 71 | tests = [ 72 | ['test_appinfo', 73 | [files('test_appinfo.c'), appinfo, stringset, util, logging], 74 | [ 75 | '-Wl,--wrap=applications_control', 76 | '-Wl,--wrap=applications_config', 77 | '-Wl,--wrap=config_stringset', 78 | '-Wl,--wrap=config_boolean', 79 | '-Wl,--wrap=control_available_permissions', 80 | ] 81 | ], 82 | ['test_permissions', 83 | [files('test_permissions.c'), logging, permissions, stringset, util], 84 | [ 85 | '-Wl,--wrap=control_on_permissions_change', 86 | ] 87 | ], 88 | ['test_sailjailclient', 89 | [files(['test_sailjailclient.c']), logging, sailjailclient, stringset, util], 90 | [ 91 | '-Wl,--wrap=config_create', 92 | '-Wl,--wrap=config_delete', 93 | '-Wl,--wrap=main', 94 | ] 95 | ], 96 | ['test_settings', 97 | [files('test_settings.c'), appinfo, logging, settings, stringset, util], 98 | [ 99 | '-Wl,--wrap=control_min_user', 100 | '-Wl,--wrap=control_max_user', 101 | '-Wl,--wrap=control_user_is_guest', 102 | '-Wl,--wrap=control_valid_user', 103 | '-Wl,--wrap=control_valid_application', 104 | '-Wl,--wrap=control_available_permissions', 105 | '-Wl,--wrap=control_appinfo', 106 | '-Wl,--wrap=control_on_settings_change', 107 | '-Wl,--wrap=config_string', 108 | '-Wl,--wrap=config_stringset', 109 | '-Wl,--wrap=config_boolean', 110 | '-Wl,--wrap=applications_control', 111 | '-Wl,--wrap=applications_config', 112 | '-Wl,--wrap=migrator_create', 113 | '-Wl,--wrap=migrator_delete_at', 114 | '-Wl,--wrap=migrator_on_settings_saved', 115 | ] 116 | ], 117 | ['test_stringset', 118 | [files('test_stringset.c'), stringset], 119 | [], 120 | ], 121 | ['test_util', 122 | [files('test_util.c'), logging, stringset, util], 123 | [], 124 | ], 125 | ] 126 | 127 | # ---------------------------------------------------------------------------- 128 | # Tests for unit testing with 'meson test' 129 | # ---------------------------------------------------------------------------- 130 | unit_sharedstatedir = meson.current_build_dir() / 'tmp/sailjail-daemon-tests' 131 | 132 | unit_options = [ 133 | '-DSYSCONFDIR="' + meson.current_build_dir() + '"', 134 | '-DSHAREDSTATEDIR="' + unit_sharedstatedir + '"', 135 | '-DDATADIR="' + meson.current_source_dir() / 'sailjail' + '"', 136 | '-DTESTDATADIR="' + meson.current_source_dir() / 'data' + '"', 137 | '-DUNITTEST', 138 | ] 139 | 140 | unit_bins = {} 141 | 142 | # The same preparation steps as in tests.xml.in 143 | # These are built with custom_target commands to be able to use depends. 144 | 145 | cleanup_test_dir = custom_target('unit_cleanup_test_dir', 146 | command : [rm, '-rf', unit_sharedstatedir], 147 | build_by_default : false, 148 | output : 'bogus_1') 149 | create_test_dir = custom_target('unit_create_test_dir', 150 | depends : cleanup_test_dir, 151 | command : [mkdir, '-p', 152 | unit_sharedstatedir / 'sailjail/settings'], 153 | build_by_default : false, 154 | output : 'bogus_2') 155 | copy_test_data = custom_target('unit_copy_test_dir', 156 | depends : create_test_dir, 157 | command : [cp, 158 | meson.current_source_dir() / 'data/user-1000.settings', 159 | unit_sharedstatedir / 'sailjail/settings/' 160 | ], 161 | build_by_default : false, 162 | output : 'bogus_3') 163 | unit_permissions_dir = meson.current_build_dir() / 'sailjail' / 'permissions' 164 | create_permissions_dir = custom_target('unit_create_permissions_dir', 165 | command : [mkdir, '-p', unit_permissions_dir], 166 | build_by_default : false, 167 | output : 'bogus_4') 168 | permission_files_to_copy = [] 169 | foreach file : permission_files 170 | permission_files_to_copy += meson.current_build_dir() / file 171 | endforeach 172 | copy_permissions = custom_target('unit_copy_permissions', 173 | depends : [create_permission_files, create_permissions_dir], 174 | command : [cp, permission_files_to_copy, unit_permissions_dir], 175 | build_by_default : false, 176 | output : 'bogus_5') 177 | 178 | unit_depends = [copy_test_data, copy_permissions] 179 | 180 | # The same tests as in tests.xml.in 181 | units = [ 182 | ['util_strip', 'test_util', ['-p', '/sailjaild/util/strip'], 'util'], 183 | ['util_path', 'test_util', ['-p', '/sailjaild/util/path'], 'util'], 184 | ['util_change', 'test_util', ['-p', '/sailjaild/util/change'], 'util'], 185 | ['util_keyfile', 'test_util', ['-p', '/sailjaild/util/keyfile'], 'util'], 186 | ['stringset', 'test_stringset', [], 'stringset'], 187 | ['appinfo', 'test_appinfo', [], 'appinfo'], 188 | ['permissions', 'test_permissions', [], 'permissions'], 189 | ['settings', 'test_settings', ['-p', '/sailjaild/settings/settings'], 'settings'], 190 | ['sailjailclient', 'test_sailjailclient', [], 'sailjailclient'], 191 | ] 192 | -------------------------------------------------------------------------------- /daemon/test/sailjail/applications/exec-test1.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=Test Application 3 | Type=Application 4 | Icon=test 5 | Exec=false 6 | 7 | [X-Sailjail] 8 | OrganizationName=org.example 9 | ApplicationName=ExecTest1 10 | Permissions= 11 | ExecDBus=false 12 | -------------------------------------------------------------------------------- /daemon/test/sailjail/applications/exec-test2.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=Test Application 3 | Type=Application 4 | Icon=test 5 | Exec=/usr/libexec/testapp 6 | X-Nemo-Single-Instance=no 7 | 8 | [X-Sailjail] 9 | OrganizationName=org.example 10 | ApplicationName=ExecTest2 11 | Permissions= 12 | ExecDBus=/usr/libexec/testapp --fork --dbus 13 | -------------------------------------------------------------------------------- /daemon/test/sailjail/applications/invalid-app.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=Invalid Application 3 | Exec=/foo/bar 4 | -------------------------------------------------------------------------------- /daemon/test/sailjail/applications/test-app.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=Test Application 3 | Type=Application 4 | Icon=test 5 | Exec=/usr/bin/true 6 | 7 | [X-Sailjail] 8 | OrganizationName=org.example 9 | ApplicationName=TestApplication 10 | Permissions=Internet;NonExistingPermission 11 | -------------------------------------------------------------------------------- /daemon/test/sailjailclient_wrapper.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Open Mobile Platform LLC. 3 | * 4 | * You may use this file under the terms of the BSD license as follows: 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * 3. Neither the names of the copyright holders nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * The views and conclusions contained in the software and documentation 33 | * are those of the authors and should not be interpreted as representing 34 | * any official policies, either expressed or implied. 35 | */ 36 | 37 | /* Wrap static functions for non-static use in tests */ 38 | 39 | #include "sailjailclient_wrapper.h" 40 | 41 | /* ========================================================================= * 42 | * Prototypes for static functions in sailjailclient.c 43 | * ========================================================================= */ 44 | 45 | /* ------------------------------------------------------------------------- * 46 | * SAILJAILCLIENT 47 | * ------------------------------------------------------------------------- */ 48 | 49 | static bool sailjailclient_match_argv (const char **tpl_argv, const char **app_argv); 50 | static bool sailjailclient_validate_argv (const char *exec, const gchar **app_argv, bool use_compatibility); 51 | 52 | /* ========================================================================= * 53 | * Prototypes 54 | * ========================================================================= */ 55 | 56 | /* ------------------------------------------------------------------------- * 57 | * WRAPPERS 58 | * ------------------------------------------------------------------------- */ 59 | 60 | bool sailjailclient_match_argv_wrapper (const char **tpl_argv, const char **app_argv); 61 | bool sailjailclient_validate_argv_wrapper (const char *exec, const gchar **app_argv, bool use_compatibility); 62 | 63 | /* ========================================================================= * 64 | * WRAPPERS 65 | * ========================================================================= */ 66 | 67 | bool 68 | sailjailclient_match_argv_wrapper(const char **tpl_argv, const char **app_argv) 69 | { 70 | return sailjailclient_match_argv(tpl_argv, app_argv); 71 | } 72 | 73 | bool 74 | sailjailclient_validate_argv_wrapper(const char *exec, const gchar **app_argv, bool use_compatibility) 75 | { 76 | return sailjailclient_validate_argv(exec, app_argv, use_compatibility); 77 | } 78 | -------------------------------------------------------------------------------- /daemon/test/sailjailclient_wrapper.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Open Mobile Platform LLC. 3 | * 4 | * You may use this file under the terms of the BSD license as follows: 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * 3. Neither the names of the copyright holders nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * The views and conclusions contained in the software and documentation 33 | * are those of the authors and should not be interpreted as representing 34 | * any official policies, either expressed or implied. 35 | */ 36 | 37 | #ifndef SAILJAILCLIENT_WRAPPER_H_ 38 | # define SAILJAILCLIENT_WRAPPER_H_ 39 | 40 | # include 41 | # include 42 | 43 | G_BEGIN_DECLS 44 | 45 | /* ========================================================================= * 46 | * Prototypes 47 | * ========================================================================= */ 48 | 49 | /* ------------------------------------------------------------------------- * 50 | * WRAPPERS 51 | * ------------------------------------------------------------------------- */ 52 | 53 | bool sailjailclient_match_argv_wrapper (const char **tpl_argv, const char **app_argv); 54 | bool sailjailclient_validate_argv_wrapper (const char *exec, const gchar **app_argv, bool use_compatibility); 55 | 56 | G_END_DECLS 57 | 58 | #endif /* SAILJAILCLIENT_WRAPPER_H_ */ 59 | -------------------------------------------------------------------------------- /daemon/test/test_appinfo.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Open Mobile Platform LLC. 3 | * 4 | * You may use this file under the terms of the BSD license as follows: 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * 3. Neither the names of the copyright holders nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * The views and conclusions contained in the software and documentation 33 | * are those of the authors and should not be interpreted as representing 34 | * any official policies, either expressed or implied. 35 | */ 36 | 37 | #include "appinfo.h" 38 | #include "stringset.h" 39 | 40 | #include 41 | #include 42 | 43 | /* ========================================================================= * 44 | * MOCK DATA 45 | * ========================================================================= */ 46 | 47 | typedef struct { 48 | stringset_t *mck_ctl_available_permissions; 49 | } appinfo_test_mock_t; 50 | 51 | void 52 | appinfo_test_mock_init(appinfo_test_mock_t *mock) 53 | { 54 | mock->mck_ctl_available_permissions = stringset_create(); 55 | stringset_add_item(mock->mck_ctl_available_permissions, "Audio"); 56 | stringset_add_item(mock->mck_ctl_available_permissions, "Internet"); 57 | stringset_add_item(mock->mck_ctl_available_permissions, "Pictures"); 58 | } 59 | 60 | /* ========================================================================= * 61 | * MOCK CONTROL FUNCTIONS 62 | * ========================================================================= */ 63 | 64 | const stringset_t * 65 | __wrap_control_available_permissions(const control_t *self) 66 | { 67 | const appinfo_test_mock_t *mock = (const appinfo_test_mock_t *)self; 68 | return mock->mck_ctl_available_permissions; 69 | } 70 | 71 | /* ========================================================================= * 72 | * MOCK APPLICATIONS FUNCTIONS 73 | * ========================================================================= */ 74 | 75 | control_t * 76 | __wrap_applications_control(const applications_t *self) 77 | { 78 | const appinfo_test_mock_t *mock = (const appinfo_test_mock_t *)self; 79 | return (control_t *)mock; 80 | } 81 | 82 | config_t * 83 | __wrap_applications_config(applications_t *self) 84 | { 85 | const appinfo_test_mock_t *mock = (const appinfo_test_mock_t *)self; 86 | return (config_t *)mock; 87 | } 88 | 89 | /* ========================================================================= * 90 | * MOCK CONFIG_FUNCTIONS 91 | * ========================================================================= */ 92 | 93 | stringset_t * 94 | __wrap_config_stringset(config_t *self, const gchar *sec, const gchar *key) 95 | { 96 | (void)self; // unused 97 | (void)sec; // unused 98 | (void)key; // unused 99 | return stringset_create(); 100 | } 101 | 102 | bool 103 | __wrap_config_boolean(config_t *self, const gchar *sec, const gchar *key, bool def) 104 | { 105 | (void)self; // unused 106 | (void)sec; // unused 107 | (void)key; // unused 108 | return def; 109 | } 110 | 111 | /* ========================================================================= * 112 | * APPINFO TESTS 113 | * ========================================================================= */ 114 | 115 | void test_appinfo_create_missing(gconstpointer user_data) 116 | { 117 | appinfo_t *appinfo = appinfo_create((applications_t *)user_data, "test-not-an-app"); 118 | g_assert_nonnull(appinfo); 119 | g_assert_true(appinfo_parse_desktop(appinfo)); 120 | g_assert_false(appinfo_valid(appinfo)); 121 | appinfo_delete(appinfo); 122 | } 123 | 124 | void test_appinfo_create_invalid(gconstpointer user_data) 125 | { 126 | appinfo_t *appinfo = appinfo_create((applications_t *)user_data, "invalid-app"); 127 | g_assert_nonnull(appinfo); 128 | g_assert_true(appinfo_parse_desktop(appinfo)); 129 | g_assert_false(appinfo_valid(appinfo)); 130 | appinfo_delete(appinfo); 131 | } 132 | 133 | void test_appinfo_read_properties(gconstpointer user_data) 134 | { 135 | appinfo_t *appinfo = appinfo_create((applications_t *)user_data, "test-app"); 136 | g_assert_nonnull(appinfo); 137 | g_assert_true(appinfo_parse_desktop(appinfo)); 138 | g_assert_true(appinfo_valid(appinfo)); 139 | g_assert_cmpstr(appinfo_get_name(appinfo), ==, "Test Application"); 140 | g_assert_cmpstr(appinfo_get_type(appinfo), ==, "Application"); 141 | g_assert_cmpstr(appinfo_get_icon(appinfo), ==, "test"); 142 | g_assert_cmpstr(appinfo_get_exec(appinfo), ==, "/usr/bin/true"); 143 | g_assert_cmpstr(appinfo_get_organization_name(appinfo), ==, "org.example"); 144 | g_assert_cmpstr(appinfo_get_application_name(appinfo), ==, "TestApplication"); 145 | appinfo_delete(appinfo); 146 | } 147 | 148 | void test_appinfo_permissions(gconstpointer user_data) 149 | { 150 | appinfo_t *appinfo = appinfo_create((applications_t *)user_data, "test-app"); 151 | g_assert_nonnull(appinfo); 152 | g_assert_true(appinfo_parse_desktop(appinfo)); 153 | g_assert_true(appinfo_valid(appinfo)); 154 | g_assert_true(appinfo_has_permission(appinfo, "Internet")); 155 | g_assert_false(appinfo_has_permission(appinfo, "Pictures")); 156 | g_assert_false(appinfo_has_permission(appinfo, "NonExistingPermission")); 157 | appinfo_delete(appinfo); 158 | } 159 | 160 | void test_appinfo_exec(gconstpointer user_data) 161 | { 162 | appinfo_t *appinfo = appinfo_create((applications_t *)user_data, "test-app"); 163 | g_assert_nonnull(appinfo); 164 | g_assert_true(appinfo_parse_desktop(appinfo)); 165 | g_assert_true(appinfo_valid(appinfo)); 166 | g_assert_cmpstr(appinfo_get_exec(appinfo), ==, "/usr/bin/true"); 167 | g_assert_cmpstr(appinfo_get_exec_dbus(appinfo), ==, "(undefined)"); 168 | appinfo_delete(appinfo); 169 | 170 | appinfo = appinfo_create((applications_t *)user_data, "exec-test1"); 171 | g_assert_nonnull(appinfo); 172 | g_assert_true(appinfo_parse_desktop(appinfo)); 173 | g_assert_true(appinfo_valid(appinfo)); 174 | g_assert_cmpstr(appinfo_get_exec(appinfo), ==, "false"); 175 | g_assert_cmpstr(appinfo_get_exec_dbus(appinfo), ==, "/usr/bin/invoker --type=generic --id=exec-test1 --single-instance /usr/bin/false"); 176 | appinfo_delete(appinfo); 177 | 178 | appinfo = appinfo_create((applications_t *)user_data, "exec-test2"); 179 | g_assert_nonnull(appinfo); 180 | g_assert_true(appinfo_parse_desktop(appinfo)); 181 | g_assert_true(appinfo_valid(appinfo)); 182 | g_assert_cmpstr(appinfo_get_exec(appinfo), ==, "/usr/libexec/testapp"); 183 | g_assert_cmpstr(appinfo_get_exec_dbus(appinfo), ==, "/usr/bin/invoker --type=generic --id=exec-test2 /usr/libexec/testapp --fork --dbus"); 184 | appinfo_delete(appinfo); 185 | } 186 | 187 | /* ========================================================================= * 188 | * MAIN 189 | * ========================================================================= */ 190 | 191 | int main(int argc, char **argv) 192 | { 193 | appinfo_test_mock_t mock; 194 | appinfo_test_mock_init(&mock); 195 | 196 | setlocale(LC_ALL, ""); 197 | 198 | g_test_init(&argc, &argv, NULL); 199 | 200 | g_test_add_data_func("/sailjaild/appinfo/create_missing", &mock, test_appinfo_create_missing); 201 | g_test_add_data_func("/sailjaild/appinfo/create_invalid", &mock, test_appinfo_create_invalid); 202 | g_test_add_data_func("/sailjaild/appinfo/read_properties", &mock, test_appinfo_read_properties); 203 | g_test_add_data_func("/sailjaild/appinfo/permissions", &mock, test_appinfo_permissions); 204 | g_test_add_data_func("/sailjaild/appinfo/exec", &mock, test_appinfo_exec); 205 | 206 | return g_test_run(); 207 | } 208 | -------------------------------------------------------------------------------- /daemon/test/test_permissions.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Open Mobile Platform LLC. 3 | * 4 | * You may use this file under the terms of the BSD license as follows: 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * 3. Neither the names of the copyright holders nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * The views and conclusions contained in the software and documentation 33 | * are those of the authors and should not be interpreted as representing 34 | * any official policies, either expressed or implied. 35 | */ 36 | 37 | #include "permissions.h" 38 | #include "stringset.h" 39 | #include "util.h" 40 | 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | /* ========================================================================= * 47 | * MOCK DATA 48 | * ========================================================================= */ 49 | 50 | typedef struct { 51 | bool mck_change_signaled; 52 | GMainLoop *main_loop; 53 | } permissions_test_mock_t; 54 | 55 | void 56 | permissions_test_mock_init(permissions_test_mock_t *mock) 57 | { 58 | mock->mck_change_signaled = false; 59 | mock->main_loop = g_main_loop_new(NULL, TRUE); 60 | } 61 | 62 | /* ========================================================================= * 63 | * MOCK CONTROL FUNCTIONS 64 | * ========================================================================= */ 65 | 66 | void 67 | __wrap_control_on_permissions_change(control_t *self) 68 | { 69 | permissions_test_mock_t *mock = (permissions_test_mock_t *)self; 70 | mock->mck_change_signaled = true; 71 | g_main_loop_quit(mock->main_loop); 72 | } 73 | 74 | /* ========================================================================= * 75 | * Utility 76 | * ========================================================================= */ 77 | 78 | gboolean 79 | permissions_test_timeout(gpointer user_data) 80 | { 81 | permissions_test_mock_t *mock = (permissions_test_mock_t *)user_data; 82 | g_main_loop_quit(mock->main_loop); 83 | return G_SOURCE_REMOVE; 84 | } 85 | 86 | void 87 | permissions_test_add_timeout(permissions_test_mock_t *mock) 88 | { 89 | /* Timeout the test after ten seconds and quit main loop 90 | * if the expected signal doesn't fire 91 | */ 92 | static guint timeout = 0; 93 | if( timeout ) 94 | g_source_remove(timeout); 95 | timeout = g_timeout_add_seconds_full(G_PRIORITY_LOW, 10, 96 | permissions_test_timeout, mock, NULL); 97 | } 98 | 99 | /* ========================================================================= * 100 | * PERMISSIONS TESTS 101 | * ========================================================================= */ 102 | 103 | void test_permissions_create_delete() 104 | { 105 | permissions_t *permissions = permissions_create(NULL); 106 | g_assert_nonnull(permissions); 107 | permissions_delete_at(&permissions); 108 | g_assert_null(permissions); 109 | permissions_delete_at(&permissions); 110 | g_assert_null(permissions); 111 | } 112 | 113 | void test_permissions_available() 114 | { 115 | permissions_t *permissions = permissions_create(NULL); 116 | const stringset_t *available = permissions_available(permissions); 117 | g_assert_cmpint(stringset_size(available), ==, 4); 118 | g_assert_true(stringset_has_item(available, "Audio")); 119 | g_assert_false(stringset_has_item(available, "Base")); 120 | g_assert_true(stringset_has_item(available, "Camera")); 121 | g_assert_true(stringset_has_item(available, "Contacts")); 122 | g_assert_true(stringset_has_item(available, "Privileged")); 123 | g_assert_false(stringset_has_item(available, "some-app")); 124 | g_assert_false(stringset_has_item(available, "some-app.profile")); 125 | permissions_delete(permissions); 126 | } 127 | 128 | void test_permissions_changed(gconstpointer user_data) 129 | { 130 | permissions_test_mock_t *mock = (permissions_test_mock_t *)user_data; 131 | permissions_t *permissions = permissions_create((control_t *)mock); 132 | const stringset_t *available = permissions_available(permissions); 133 | g_assert_false(stringset_has_item(available, "Test")); 134 | /* First test adding a permission */ 135 | permissions_test_add_timeout(mock); 136 | FILE *file = fopen(PERMISSIONS_DIRECTORY "/Test.permission", "a"); 137 | g_assert_nonnull(file); 138 | g_assert_cmpint(fclose(file), ==, 0); 139 | g_main_loop_run(mock->main_loop); 140 | g_assert_true(mock->mck_change_signaled); 141 | available = permissions_available(permissions); 142 | g_assert_true(stringset_has_item(available, "Test")); 143 | /* Second test removing a permission */ 144 | permissions_test_add_timeout(mock); 145 | mock->mck_change_signaled = false; 146 | g_assert_cmpint(unlink(PERMISSIONS_DIRECTORY "/Test.permission"), ==, 0); 147 | g_main_loop_run(mock->main_loop); 148 | g_assert_true(mock->mck_change_signaled); 149 | available = permissions_available(permissions); 150 | g_assert_false(stringset_has_item(available, "Test")); 151 | permissions_delete(permissions); 152 | } 153 | 154 | /* ========================================================================= * 155 | * MAIN 156 | * ========================================================================= */ 157 | 158 | int main(int argc, char **argv) 159 | { 160 | permissions_test_mock_t mock; 161 | permissions_test_mock_init(&mock); 162 | 163 | setlocale(LC_ALL, ""); 164 | 165 | g_test_init(&argc, &argv, NULL); 166 | 167 | g_test_add_func("/sailjaild/permissions/create_and_delete", test_permissions_create_delete); 168 | g_test_add_func("/sailjaild/permissions/available", test_permissions_available); 169 | g_test_add_data_func("/sailjaild/permissions/changed", &mock, test_permissions_changed); 170 | 171 | return g_test_run(); 172 | } 173 | -------------------------------------------------------------------------------- /daemon/test/test_sailjailclient.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Open Mobile Platform LLC. 3 | * 4 | * You may use this file under the terms of the BSD license as follows: 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * 3. Neither the names of the copyright holders nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * The views and conclusions contained in the software and documentation 33 | * are those of the authors and should not be interpreted as representing 34 | * any official policies, either expressed or implied. 35 | */ 36 | 37 | #include "sailjailclient_wrapper.h" 38 | #include "config.h" 39 | 40 | #include 41 | #include 42 | 43 | /* ========================================================================= * 44 | * MOCK CONFIG FUNCTIONS 45 | * ========================================================================= */ 46 | 47 | config_t * 48 | __wrap_config_create() 49 | { 50 | return NULL; 51 | } 52 | 53 | void 54 | __wrap_config_delete(config_t *config) 55 | { 56 | (void)config; // unused 57 | } 58 | 59 | /* ========================================================================= * 60 | * SAILJAILCLIENT TESTS 61 | * ========================================================================= */ 62 | 63 | void test_sailjailclient_match_argv() 64 | { 65 | { 66 | const char *tplt[] = {"--image", "%f", NULL}; 67 | const char *args[] = {"--image", "foo.png", NULL}; 68 | g_assert_true(sailjailclient_match_argv_wrapper(tplt, args)); 69 | } 70 | { 71 | const char *tplt[] = {"--image", "%f", NULL}; 72 | const char *args[] = {"--image", NULL}; 73 | g_assert_true(sailjailclient_match_argv_wrapper(tplt, args)); 74 | } 75 | { 76 | const char *tplt[] = {"--convert", "%F", NULL}; 77 | const char *args[] = {"--convert", "foo.png", "bar.png", NULL}; 78 | g_assert_true(sailjailclient_match_argv_wrapper(tplt, args)); 79 | } 80 | { 81 | const char *tplt[] = {"--convert", "%F", NULL}; 82 | const char *args[] = {"--convert", NULL}; 83 | g_assert_true(sailjailclient_match_argv_wrapper(tplt, args)); 84 | } 85 | { 86 | const char *tplt[] = {"%k", NULL}; 87 | const char *args[] = {"foo", NULL}; 88 | g_assert_true(sailjailclient_match_argv_wrapper(tplt, args)); 89 | } 90 | { 91 | const char *tplt[] = {"%k", NULL}; 92 | const char *args[] = {NULL}; 93 | g_assert_false(sailjailclient_match_argv_wrapper(tplt, args)); 94 | } 95 | { 96 | const char *tplt[] = {"%k", NULL}; 97 | const char *args[] = {"foo", "bar", NULL}; 98 | g_assert_false(sailjailclient_match_argv_wrapper(tplt, args)); 99 | } 100 | { 101 | const char *tplt[] = {"%i", NULL}; 102 | const char *args[] = {"--icon", "foo", NULL}; 103 | g_assert_true(sailjailclient_match_argv_wrapper(tplt, args)); 104 | } 105 | { 106 | const char *tplt[] = {"%i", NULL}; 107 | const char *args[] = {"--icon", NULL}; 108 | g_assert_false(sailjailclient_match_argv_wrapper(tplt, args)); 109 | } 110 | { 111 | const char *tplt[] = {"%i", NULL}; 112 | const char *args[] = {"foo", NULL}; 113 | g_assert_false(sailjailclient_match_argv_wrapper(tplt, args)); 114 | } 115 | { 116 | const char *tplt[] = {"%i", NULL}; 117 | const char *args[] = {"foo", "bar", NULL}; 118 | g_assert_false(sailjailclient_match_argv_wrapper(tplt, args)); 119 | } 120 | { 121 | const char *tplt[] = {"%m", NULL}; 122 | const char *args[] = {"foo", NULL}; 123 | g_assert_false(sailjailclient_match_argv_wrapper(tplt, args)); 124 | } 125 | { 126 | const char *tplt[] = {"%x", NULL}; 127 | const char *args[] = {"foo", NULL}; 128 | g_assert_false(sailjailclient_match_argv_wrapper(tplt, args)); 129 | } 130 | } 131 | 132 | void test_sailjailclient_validate_argv() 133 | { 134 | { 135 | const char *argv[] = {"/usr/bin/true", NULL}; 136 | g_assert_true(sailjailclient_validate_argv_wrapper("true", argv, false)); 137 | } 138 | { 139 | const char *argv[] = {"/usr/bin/true", NULL}; 140 | g_assert_true(sailjailclient_validate_argv_wrapper("/usr/bin/true", argv, false)); 141 | } 142 | { 143 | const char *argv[] = {"/usr/bin/false", NULL}; 144 | g_assert_false(sailjailclient_validate_argv_wrapper("true", argv, false)); 145 | } 146 | { 147 | const char *argv[] = {"/usr/bin/true", "--foo", NULL}; 148 | g_assert_true(sailjailclient_validate_argv_wrapper("true --foo", argv, false)); 149 | } 150 | { 151 | const char *argv[] = {"/usr/bin/true", NULL}; 152 | g_assert_false(sailjailclient_validate_argv_wrapper("true --foo", argv, false)); 153 | } 154 | { 155 | const char *argv[] = {"/usr/bin/true", "--bar", NULL}; 156 | g_assert_false(sailjailclient_validate_argv_wrapper("true --foo", argv, false)); 157 | } 158 | { 159 | const char *argv[] = {"/usr/bin/true", "-a", "-b", "-c", NULL}; 160 | g_assert_true(sailjailclient_validate_argv_wrapper("true -a -b -c", argv, false)); 161 | } 162 | { 163 | const char *argv[] = {"/usr/bin/true", "-a", "-b", "-b", NULL}; 164 | g_assert_false(sailjailclient_validate_argv_wrapper("true -a -b -c", argv, false)); 165 | } 166 | } 167 | 168 | void test_sailjailclient_validate_argv_compatibility() 169 | { 170 | { 171 | const char *argv[] = {"/usr/bin/testapp", NULL}; 172 | g_assert_true(sailjailclient_validate_argv_wrapper("testapp", argv, true)); 173 | } 174 | { 175 | const char *argv[] = {"/usr/libexec/testapp", NULL}; 176 | g_assert_false(sailjailclient_validate_argv_wrapper("testapp", argv, false)); 177 | } 178 | { 179 | const char *argv[] = {"/usr/bin/other", NULL}; 180 | g_assert_false(sailjailclient_validate_argv_wrapper("testapp", argv, true)); 181 | } 182 | { 183 | const char *argv[] = {"/usr/bin/testapp", NULL}; 184 | g_assert_true(sailjailclient_validate_argv_wrapper("/usr/bin/testapp", argv, true)); 185 | } 186 | } 187 | 188 | void test_sailjailclient_validate_argv_dbus() 189 | { 190 | { 191 | const char *argv[] = {"/usr/bin/false", NULL}; 192 | g_assert_true(sailjailclient_validate_argv_wrapper("/usr/bin/invoker --type=generic --id=exec-test1 --single-instance /usr/bin/false", argv, false)); 193 | } 194 | { 195 | const char *argv[] = {"/usr/bin/false", "--dbus", NULL}; 196 | g_assert_true(sailjailclient_validate_argv_wrapper("/usr/bin/invoker --type=generic --id=exec-test1 --single-instance /usr/bin/false --dbus", argv, false)); 197 | } 198 | { 199 | const char *argv[] = {"/usr/bin/invoker", NULL}; 200 | g_assert_false(sailjailclient_validate_argv_wrapper("/usr/bin/invoker --type=generic --id=exec-test1 --single-instance /usr/bin/false", argv, false)); 201 | } 202 | { 203 | const char *argv[] = {"/usr/bin/true", "-prestart", NULL}; 204 | g_assert_true(sailjailclient_validate_argv_wrapper("true", argv, false)); 205 | } 206 | { 207 | const char *argv[] = {"/usr/bin/true", NULL}; 208 | g_assert_false(sailjailclient_validate_argv_wrapper(NULL, argv, false)); 209 | } 210 | } 211 | 212 | /* ========================================================================= * 213 | * MAIN 214 | * ========================================================================= */ 215 | 216 | int __wrap_main(int argc, char **argv) 217 | { 218 | setlocale(LC_ALL, ""); 219 | 220 | g_test_init(&argc, &argv, NULL); 221 | 222 | g_test_add_func("/sailjaild/sailjailclient/match_argv", test_sailjailclient_match_argv); 223 | g_test_add_func("/sailjaild/sailjailclient/validate_argv", test_sailjailclient_validate_argv); 224 | g_test_add_func("/sailjaild/sailjailclient/validate_argv_compatibility", test_sailjailclient_validate_argv_compatibility); 225 | g_test_add_func("/sailjaild/sailjailclient/validate_argv_dbus", test_sailjailclient_validate_argv_dbus); 226 | 227 | return g_test_run(); 228 | } 229 | -------------------------------------------------------------------------------- /daemon/test/test_settings.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Open Mobile Platform LLC. 3 | * 4 | * You may use this file under the terms of the BSD license as follows: 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * 3. Neither the names of the copyright holders nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * The views and conclusions contained in the software and documentation 33 | * are those of the authors and should not be interpreted as representing 34 | * any official policies, either expressed or implied. 35 | */ 36 | 37 | #include "settings.h" 38 | #include "appinfo.h" 39 | #include "stringset.h" 40 | 41 | #include 42 | #include 43 | 44 | /* ========================================================================= * 45 | * MOCK DATA 46 | * ========================================================================= */ 47 | 48 | #define MIN_USER 1000 49 | #define MAX_USER 1000 50 | #define GUEST_USER 1050 51 | 52 | typedef struct { 53 | bool mck_guest_valid; 54 | stringset_t *mck_ctl_available_permissions; 55 | stringset_t *mck_ctl_valid_applications; 56 | } settings_test_mock_t; 57 | 58 | void 59 | settings_test_mock_init(settings_test_mock_t *mock) 60 | { 61 | mock->mck_guest_valid = true; 62 | mock->mck_ctl_available_permissions = stringset_create(); 63 | stringset_add_item(mock->mck_ctl_available_permissions, "Audio"); 64 | stringset_add_item(mock->mck_ctl_available_permissions, "Internet"); 65 | stringset_add_item(mock->mck_ctl_available_permissions, "Pictures"); 66 | mock->mck_ctl_valid_applications = stringset_create(); 67 | stringset_add_item(mock->mck_ctl_valid_applications, "test-app"); 68 | } 69 | 70 | /* ========================================================================= * 71 | * MOCK CONTROL FUNCTIONS 72 | * ========================================================================= */ 73 | 74 | uid_t 75 | __wrap_control_min_user(const control_t *self) 76 | { 77 | (void)self; // unused 78 | return MIN_USER; 79 | } 80 | 81 | uid_t 82 | __wrap_control_max_user(const control_t *self) 83 | { 84 | (void)self; // unused 85 | return MAX_USER; 86 | } 87 | 88 | bool 89 | __wrap_control_user_is_guest(const control_t *self, uid_t uid) 90 | { 91 | (void)self; // unused 92 | return uid == GUEST_USER; 93 | } 94 | 95 | bool 96 | __wrap_control_valid_user(const control_t *self, uid_t uid) 97 | { 98 | const settings_test_mock_t *mock = (const settings_test_mock_t *)self; 99 | if( uid == GUEST_USER ) 100 | return mock->mck_guest_valid; 101 | return uid >= MIN_USER && uid <= MAX_USER; 102 | } 103 | 104 | bool 105 | __wrap_control_valid_application(const control_t *self, const char *appname) 106 | { 107 | const settings_test_mock_t *mock = (const settings_test_mock_t *)self; 108 | return stringset_has_item(mock->mck_ctl_valid_applications, appname); 109 | } 110 | 111 | const stringset_t * 112 | __wrap_control_available_permissions(const control_t *self) 113 | { 114 | const settings_test_mock_t *mock = (const settings_test_mock_t *)self; 115 | return mock->mck_ctl_available_permissions; 116 | } 117 | 118 | appinfo_t * 119 | __wrap_control_appinfo(control_t *self, const gchar *appname) 120 | { 121 | settings_test_mock_t *mock = (settings_test_mock_t *)self; 122 | appinfo_t *appinfo = appinfo_create((applications_t *)mock, appname); 123 | appinfo_parse_desktop(appinfo); 124 | return appinfo; 125 | } 126 | 127 | void 128 | __wrap_control_on_settings_change(control_t *self, const gchar *appname) 129 | { 130 | (void)self; // unused 131 | (void)appname; // unused 132 | } 133 | 134 | /* ========================================================================= * 135 | * MOCK CONFIG FUNCTIONS 136 | * ========================================================================= */ 137 | 138 | gchar * 139 | __wrap_config_string(const config_t *self, const gchar *sec, const gchar *key, const gchar *def) 140 | { 141 | (void)self; // unused 142 | (void)sec; // unused 143 | (void)key; // unused 144 | return g_strdup(def); 145 | } 146 | 147 | stringset_t * 148 | __wrap_config_stringset(config_t *self, const gchar *sec, const gchar *key) 149 | { 150 | (void)self; // unused 151 | (void)sec; // unused 152 | (void)key; // unused 153 | return stringset_create(); 154 | } 155 | 156 | bool 157 | __wrap_config_boolean(config_t *self, const gchar *sec, const gchar *key, bool def) 158 | { 159 | (void)self; // unused 160 | (void)sec; // unused 161 | (void)key; // unused 162 | return def; 163 | } 164 | 165 | /* ========================================================================= * 166 | * MOCK APPLICATIONS FUNCTIONS 167 | * ========================================================================= */ 168 | 169 | control_t * 170 | __wrap_applications_control(const applications_t *self) 171 | { 172 | settings_test_mock_t *mock = (settings_test_mock_t *)self; 173 | return (control_t *)mock; 174 | } 175 | 176 | config_t * 177 | __wrap_applications_config(applications_t *self) 178 | { 179 | settings_test_mock_t *mock = (settings_test_mock_t *)self; 180 | return (config_t *)mock; 181 | } 182 | 183 | /* ========================================================================= * 184 | * MOCK MIGRATOR FUNCTIONS 185 | * ========================================================================= */ 186 | 187 | migrator_t * 188 | __wrap_migrator_create(control_t *control) 189 | { 190 | return NULL; 191 | } 192 | 193 | void 194 | __wrap_migrator_delete_at(migrator_t **pself) 195 | { 196 | (void)pself; // unused 197 | } 198 | 199 | void 200 | __wrap_migrator_on_settings_saved(migrator_t *self) 201 | { 202 | (void)self; // unused 203 | } 204 | 205 | /* ========================================================================= * 206 | * SETTINGS TESTS 207 | * ========================================================================= */ 208 | 209 | void test_settings_create_delete(gconstpointer user_data) 210 | { 211 | settings_t *settings = settings_create((config_t *)user_data, (control_t *)user_data); 212 | g_assert_nonnull(settings); 213 | settings_delete_at(&settings); 214 | g_assert_null(settings); 215 | settings_delete_at(&settings); 216 | g_assert_null(settings); 217 | } 218 | 219 | void test_settings_load(gconstpointer user_data) 220 | { 221 | settings_t *settings = settings_create((config_t *)user_data, (control_t *)user_data); 222 | settings_load_user(settings, 1000); 223 | usersettings_t *usersettings = settings_get_usersettings(settings, 1000); 224 | g_assert_nonnull(usersettings); 225 | appsettings_t *appsettings = settings_get_appsettings(settings, 1000, "test-app"); 226 | g_assert_nonnull(appsettings); 227 | g_assert_cmpint(appsettings_get_allowed(appsettings), ==, APP_ALLOWED_ALWAYS); 228 | g_assert_cmpint(appsettings_get_agreed(appsettings), ==, APP_ALLOWED_UNSET); 229 | const stringset_t *granted = appsettings_get_granted(appsettings); 230 | g_assert_cmpint(stringset_size(granted), ==, 1); 231 | g_assert_true(stringset_has_item(granted, "Internet")); 232 | settings_delete(settings); 233 | } 234 | 235 | /* ========================================================================= * 236 | * MAIN 237 | * ========================================================================= */ 238 | 239 | int main(int argc, char **argv) 240 | { 241 | settings_test_mock_t mock; 242 | settings_test_mock_init(&mock); 243 | 244 | setlocale(LC_ALL, ""); 245 | 246 | g_test_init(&argc, &argv, NULL); 247 | 248 | g_test_add_data_func("/sailjaild/settings/settings/create_and_delete", &mock, test_settings_create_delete); 249 | g_test_add_data_func("/sailjaild/settings/settings/load", &mock, test_settings_load); 250 | 251 | return g_test_run(); 252 | } 253 | -------------------------------------------------------------------------------- /daemon/test/tests.xml.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | sailjail daemon tests 5 | 6 | 7 | sailjail daemon tests 8 | 9 | rm -rf @TESTTMPDATA@ 10 | mkdir -p @SHAREDSTATEDIR@/sailjail/settings 11 | cp @TESTDATADIR@/user-1000.settings @SHAREDSTATEDIR@/sailjail/settings/ 12 | cp -r @TESTSDIR@/etc @TESTTMPDATA@/etc 13 | 14 | 15 | @TESTBINDIR@/test_util -p "/sailjaild/util/strip" 16 | 17 | 18 | @TESTBINDIR@/test_util -p "/sailjaild/util/path" 19 | 20 | 21 | @TESTBINDIR@/test_util -p "/sailjaild/util/change" 22 | 23 | 24 | @TESTBINDIR@/test_util -p "/sailjaild/util/keyfile" 25 | 26 | 27 | @TESTBINDIR@/test_stringset 28 | 29 | 30 | @TESTBINDIR@/test_appinfo 31 | 32 | 33 | @TESTBINDIR@/test_permissions 34 | 35 | 36 | @TESTBINDIR@/test_settings -p /sailjaild/settings/settings 37 | 38 | 39 | @TESTBINDIR@/test_sailjailclient -p /sailjaild/sailjailclient 40 | 41 | 42 | rm -rf @TESTTMPDATA@ 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /daemon/users.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Open Mobile Platform LLC. 3 | * 4 | * You may use this file under the terms of the BSD license as follows: 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * 3. Neither the names of the copyright holders nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * The views and conclusions contained in the software and documentation 33 | * are those of the authors and should not be interpreted as representing 34 | * any official policies, either expressed or implied. 35 | */ 36 | 37 | #ifndef USERS_H_ 38 | # define USERS_H_ 39 | 40 | # include 41 | # include 42 | 43 | G_BEGIN_DECLS 44 | 45 | /* ========================================================================= * 46 | * Types 47 | * ========================================================================= */ 48 | 49 | typedef struct control_t control_t; 50 | typedef struct config_t config_t; 51 | typedef struct users_t users_t; 52 | 53 | /* ========================================================================= * 54 | * Prototypes 55 | * ========================================================================= */ 56 | 57 | /* ------------------------------------------------------------------------- * 58 | * USERS 59 | * ------------------------------------------------------------------------- */ 60 | 61 | users_t *users_create (control_t *control); 62 | void users_delete (users_t *self); 63 | void users_delete_at(users_t **pself); 64 | void users_delete_cb(void *self); 65 | 66 | /* ------------------------------------------------------------------------- * 67 | * USERS_USER 68 | * ------------------------------------------------------------------------- */ 69 | 70 | uid_t users_first_user (const users_t *self); 71 | uid_t users_last_user (const users_t *self); 72 | bool users_user_exists (users_t *self, uid_t uid); 73 | bool users_user_is_guest(const users_t *self, uid_t uid); 74 | 75 | G_END_DECLS 76 | 77 | #endif /* USERS_H_ */ 78 | -------------------------------------------------------------------------------- /daemon/util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Open Mobile Platform LLC. 3 | * 4 | * You may use this file under the terms of the BSD license as follows: 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * 3. Neither the names of the copyright holders nor the names of its 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * The views and conclusions contained in the software and documentation 33 | * are those of the authors and should not be interpreted as representing 34 | * any official policies, either expressed or implied. 35 | */ 36 | 37 | #ifndef UTIL_H_ 38 | # define UTIL_H_ 39 | 40 | # include 41 | # include 42 | 43 | G_BEGIN_DECLS 44 | 45 | /* ========================================================================= * 46 | * Constants 47 | * ========================================================================= */ 48 | 49 | /* Expected: We get these from Makefile, or spec during rpm build */ 50 | # ifndef VERSION 51 | # define VERSION "0.0.0" 52 | # endif 53 | 54 | # ifndef BINDIR 55 | # define BINDIR "/usr/bin" 56 | # endif 57 | 58 | # ifndef SYSCONFDIR 59 | # define SYSCONFDIR "/etc" 60 | # endif 61 | 62 | # ifndef SHAREDSTATEDIR 63 | # define SHAREDSTATEDIR "/var/lib" 64 | # endif 65 | 66 | # ifndef DATADIR 67 | # define DATADIR "/usr/share" 68 | # endif 69 | 70 | # define RUNTIME_DATADIR "/run/user" 71 | 72 | # define HOME_LOCALDIR "/.local" 73 | # define HOME_DATADIR HOME_LOCALDIR "/share" 74 | 75 | /* Config from: *.conf */ 76 | # define CONFIG_DIRECTORY SYSCONFDIR "/sailjail/config" 77 | # define CONFIG_EXTENSION ".conf" 78 | # define CONFIG_PATTERN "[0-9][0-9]*" CONFIG_EXTENSION 79 | 80 | /* Users from: passwd */ 81 | # define USERS_DIRECTORY SYSCONFDIR 82 | # define USERS_EXTENSION "" 83 | # define USERS_PATTERN "passwd" USERS_EXTENSION 84 | 85 | /* Permissions from: *.permission */ 86 | # define PERMISSIONS_DIRECTORY SYSCONFDIR "/sailjail/permissions" 87 | # define PERMISSIONS_EXTENSION ".permission" 88 | # define PERMISSIONS_PATTERN "[A-Z]*" PERMISSIONS_EXTENSION 89 | # define PROFILES_EXTENSION ".profile" 90 | 91 | /* Applications from: *.desktop */ 92 | # define APPLICATIONS_DIRECTORY DATADIR "/applications" 93 | # define APPLICATIONS_EXTENSION ".desktop" 94 | # define APPLICATIONS_PATTERN "*" APPLICATIONS_EXTENSION 95 | 96 | /* Sailjail overrides from: *.desktop */ 97 | # define SAILJAIL_APP_DIRECTORY SYSCONFDIR "/sailjail/applications" 98 | 99 | /* Writable DBus services */ 100 | # define DBUS_DIRECTORY "/dbus-1" 101 | # define DBUS_SERVICES_DIRECTORY DBUS_DIRECTORY "/services" 102 | # define DBUS_SERVICES_EXTENSION ".service" 103 | # define DBUS_SERVICES_PATTERN "*" DBUS_SERVICES_EXTENSION 104 | 105 | /* Settings from: *.settings */ 106 | # define SETTINGS_DIRECTORY SHAREDSTATEDIR "/sailjail/settings" 107 | # define SETTINGS_EXTENSION ".settings" 108 | # define SETTINGS_PATTERN "*" SETTINGS_EXTENSION 109 | 110 | /* Booster binaries in: /usr/libexec/mapplauncherd/ */ 111 | # define BOOSTER_DIRECTORY "/usr/libexec/mapplauncherd" 112 | # define BOOSTER_EXTENSION "" 113 | # define BOOSTER_PATTERN "booster-*" 114 | 115 | /* Standard desktop properties */ 116 | # define DESKTOP_SECTION "Desktop Entry" 117 | # define DESKTOP_KEY_NAME "Name" 118 | # define DESKTOP_KEY_TYPE "Type" 119 | # define DESKTOP_KEY_ICON "Icon" 120 | # define DESKTOP_KEY_EXEC "Exec" 121 | # define DESKTOP_KEY_NO_DISPLAY "NoDisplay" 122 | 123 | /* Maemo desktop properties */ 124 | # define MAEMO_SECTION "Desktop Entry" 125 | # define MAEMO_KEY_SERVICE "X-Maemo-Service" 126 | # define MAEMO_KEY_OBJECT "X-Maemo-Object-Path" 127 | # define MAEMO_KEY_METHOD "X-Maemo-Method" 128 | 129 | /* Sharing desktop properties */ 130 | # define SHARE_KEY_METHODS "X-Share-Methods" 131 | 132 | /* Sailjail desktop properties */ 133 | # define SAILJAIL_SECTION_PRIMARY "X-Sailjail" 134 | # define SAILJAIL_SECTION_SECONDARY "Sailjail" 135 | # define SAILJAIL_KEY_ORGANIZATION_NAME "OrganizationName" 136 | # define SAILJAIL_KEY_APPLICATION_NAME "ApplicationName" 137 | # define SAILJAIL_KEY_DATA_DIRECTORY "DataDirectory" 138 | # define SAILJAIL_KEY_PERMISSIONS "Permissions" 139 | # define SAILJAIL_KEY_SANDBOXING "Sandboxing" 140 | # define SAILJAIL_KEY_EXEC_DBUS "ExecDBus" 141 | 142 | # define NEMO_KEY_APPLICATION_TYPE "X-Nemo-Application-Type" 143 | # define NEMO_KEY_SINGLE_INSTANCE "X-Nemo-Single-Instance" 144 | 145 | # define MAEMO_KEY_FIXED_ARGS "X-Maemo-Fixed-Args" 146 | 147 | # define OSSO_KEY_SERVICE "X-Osso-Service" 148 | 149 | /* DBus service file properties */ 150 | # define DBUS_SERVICE_SECTION "D-BUS Service" 151 | # define DBUS_KEY_NAME "Name" 152 | # define DBUS_KEY_EXEC "Exec" 153 | # define DBUS_KEY_APPLICATION "X-Sailjail-Application" 154 | 155 | /* ========================================================================= * 156 | * Types 157 | * ========================================================================= */ 158 | 159 | typedef struct stringset_t stringset_t; 160 | 161 | /* ========================================================================= * 162 | * Prototypes 163 | * ========================================================================= */ 164 | 165 | /* ------------------------------------------------------------------------- * 166 | * UTILITY 167 | * ------------------------------------------------------------------------- */ 168 | 169 | char *strip(char *str); 170 | 171 | /* ------------------------------------------------------------------------- * 172 | * PATH 173 | * ------------------------------------------------------------------------- */ 174 | 175 | const gchar *path_basename (const gchar *path); 176 | gchar *path_construct (const gchar *dir, const gchar *file, const gchar *ext); 177 | const gchar *path_extension (const gchar *path); 178 | gchar *path_dirname (const gchar *path); 179 | gchar *path_to_desktop_name (const gchar *path); 180 | gchar *path_from_desktop_name (const gchar *stem); 181 | gchar *alt_path_from_desktop_name(const gchar *stem); 182 | gchar *path_to_permission_name (const gchar *path); 183 | gchar *path_from_permission_name (const gchar *stem); 184 | gchar *path_from_profile_name (const gchar *stem); 185 | 186 | /* ------------------------------------------------------------------------- * 187 | * GUTIL 188 | * ------------------------------------------------------------------------- */ 189 | 190 | guint gutil_add_watch(int fd, GIOCondition cnd, GIOFunc cb, gpointer aptr); 191 | 192 | /* ------------------------------------------------------------------------- * 193 | * CHANGE 194 | * ------------------------------------------------------------------------- */ 195 | 196 | bool change_uid (uid_t *where, uid_t val); 197 | bool change_boolean (bool *where, bool val); 198 | bool change_string (gchar **pstr, const gchar *val); 199 | bool change_string_steal(gchar **pstr, gchar *val); 200 | bool change_timer (guint *where, guint val); 201 | 202 | /* ------------------------------------------------------------------------- * 203 | * KEYFILE 204 | * ------------------------------------------------------------------------- */ 205 | 206 | bool keyfile_save (GKeyFile *file, const gchar *path); 207 | bool keyfile_load (GKeyFile *file, const gchar *path); 208 | bool keyfile_merge (GKeyFile *file, const gchar *path); 209 | bool keyfile_get_boolean (GKeyFile *file, const gchar *sec, const gchar *key, bool def); 210 | gint keyfile_get_integer (GKeyFile *file, const gchar *sec, const gchar *key, gint def); 211 | gchar *keyfile_get_string (GKeyFile *file, const gchar *sec, const gchar *key, const gchar *def); 212 | stringset_t *keyfile_get_stringset(GKeyFile *file, const gchar *sec, const gchar *key); 213 | void keyfile_set_boolean (GKeyFile *file, const gchar *sec, const gchar *key, bool val); 214 | void keyfile_set_integer (GKeyFile *file, const gchar *sec, const gchar *key, gint val); 215 | void keyfile_set_string (GKeyFile *file, const gchar *sec, const gchar *key, const gchar *val); 216 | void keyfile_set_stringset(GKeyFile *file, const gchar *sec, const gchar *key, const stringset_t *val); 217 | 218 | G_END_DECLS 219 | 220 | #endif /* UTIL_H_ */ 221 | -------------------------------------------------------------------------------- /meson.build: -------------------------------------------------------------------------------- 1 | project('sailjail', 'c', 2 | default_options : ['c_std=c99']) 3 | 4 | # ---------------------------------------------------------------------------- 5 | # Installation directories 6 | # ---------------------------------------------------------------------------- 7 | prefix = get_option('prefix') # /usr 8 | includedir = prefix / get_option('includedir') # /usr/include 9 | bindir = prefix / get_option('bindir') # /usr/bin 10 | sbindir = prefix / get_option('sbindir') # /usr/sbin 11 | libexecdir = prefix / get_option('libexecdir') # /usr/libexec 12 | libdir = prefix / get_option('libdir') # /usr/lib 13 | sysconfdir = get_option('sysconfdir') # etc 14 | datadir = prefix / get_option('datadir') # /usr/share 15 | mandir = prefix / get_option('mandir') # /usr/share/man 16 | infodir = prefix / get_option('infodir') # /usr/share/info 17 | localstatedir = get_option('localstatedir') # /var 18 | sharedstatedir = get_option('sharedstatedir') # /var/lib 19 | unitdir = get_option('unitdir') # /usr/lib/systemd/system 20 | userunitdir = get_option('userunitdir') # /usr/lib/systemd/user 21 | dbuspolicydir = get_option('dbuspolicydir') # /usr/share/dbus-1/system.d 22 | testsdir = get_option('testsdir') # /opt/tests 23 | 24 | summary({ 25 | 'prefix' : prefix, 26 | 'includedir' : includedir, 27 | 'bindir' : bindir, 28 | 'sbindir' : sbindir, 29 | 'libexecdir' : libexecdir, 30 | 'libdir' : libdir, 31 | 'sysconfdir' : sysconfdir, 32 | 'datadir' : datadir, 33 | 'mandir' : mandir, 34 | 'infodir' : infodir, 35 | 'localstatedir' : localstatedir, 36 | 'sharedstatedir' : sharedstatedir, 37 | 'unitdir' : unitdir, 38 | 'userunitdir' : userunitdir, 39 | 'dbuspolicydir' : dbuspolicydir, 40 | 'testsdir' : testsdir, 41 | }, 42 | section : 'Installation directories') 43 | 44 | # ---------------------------------------------------------------------------- 45 | # Common default flags 46 | # ---------------------------------------------------------------------------- 47 | add_project_arguments('-DVERSION="' + get_option('version') + '"', language : 'c') 48 | add_project_arguments('-D_GNU_SOURCE', language : 'c') 49 | add_project_arguments('-D_FILE_OFFSET_BITS=64', language : 'c') 50 | 51 | # ---------------------------------------------------------------------------- 52 | # Utility programs 53 | # ---------------------------------------------------------------------------- 54 | cp = find_program('cp') 55 | mkdir = find_program('mkdir') 56 | rm = find_program('rm') 57 | sed = find_program('sed') 58 | touch = find_program('touch') 59 | dot = find_program('dot', required : false) 60 | 61 | # ---------------------------------------------------------------------------- 62 | # Daemon and client 63 | # ---------------------------------------------------------------------------- 64 | subdir('daemon') 65 | -------------------------------------------------------------------------------- /meson_options.txt: -------------------------------------------------------------------------------- 1 | option('version', type : 'string') 2 | option('libdbusaccess', type : 'feature', value : 'enabled') 3 | option('unitdir', type : 'string', value : '/usr/lib/systemd/system') 4 | option('userunitdir', type : 'string', value : '/usr/lib/systemd/user') 5 | option('dbuspolicydir', type : 'string', value : '/usr/share/dbus-1/system.d') 6 | option('testsdir', type : 'string', value : '/opt/tests') 7 | option('testtmpdata', type : 'string', value : '/tmp/sailjail-daemon-tests') 8 | -------------------------------------------------------------------------------- /rpm/sailjail.spec: -------------------------------------------------------------------------------- 1 | Name: sailjail 2 | Summary: Firejail-based sanboxing tool 3 | Version: 1.1.19 4 | Release: 1 5 | License: BSD 6 | URL: https://github.com/sailfishos/sailjail 7 | Source0: %{name}-%{version}.tar.bz2 8 | 9 | %define glib_version 2.44 10 | 11 | Requires: firejail >= 0.9.64.4+git3 12 | Requires: xdg-dbus-proxy 13 | Requires: sailjail-permissions 14 | Requires(pre): sailfish-setup 15 | 16 | Requires: glib2 >= %{glib_version} 17 | Requires: sailjail-daemon 18 | Provides: sailjail-launch-approval 19 | 20 | BuildRequires: meson 21 | BuildRequires: ccache 22 | BuildRequires: pkgconfig(glib-2.0) >= %{glib_version} 23 | BuildRequires: pkgconfig(gobject-2.0) 24 | BuildRequires: pkgconfig(gio-2.0) 25 | BuildRequires: pkgconfig(libsystemd) 26 | BuildRequires: pkgconfig(libdbusaccess) 27 | BuildRequires: sed 28 | 29 | # Keep settings in encrypted home partition 30 | %define _sharedstatedir /home/.system/var/lib 31 | # Directory for D-Bus policy 32 | %define _dbuspolicydir %{_datadir}/dbus-1/system.d 33 | # Tests directory 34 | %define _testsdir /opt/tests 35 | 36 | %description 37 | Firejail-based sanboxing for Sailfish OS. 38 | 39 | %package tools 40 | Summary: Tools for developing %{name}'d apps 41 | Requires: python3-base 42 | 43 | %description tools 44 | %{summary}. 45 | Contains a script to measure launching time. 46 | 47 | %package daemon 48 | Summary: Daemon for managing application sandboxing permissions 49 | 50 | Requires: mapplauncherd >= 4.2.8 51 | 52 | %description daemon 53 | This package contains daemon that keeps track of: 54 | - defined permissions (under /etc/sailjail/permissions) 55 | - permissions required by applications (under /usr/share/applications) 56 | - what permissions user has granted to each application 57 | 58 | %package daemon-tests 59 | Summary: QA tests for %{name}-daemon 60 | 61 | %description daemon-tests 62 | %{summary}. 63 | 64 | %prep 65 | %setup -q -n %{name}-%{version} 66 | 67 | %build 68 | %meson \ 69 | -Dversion=%{version} \ 70 | -Duserunitdir=%{_userunitdir} \ 71 | -Dunitdir=%{_unitdir} \ 72 | -Ddbuspolicydir=%{_dbuspolicydir} \ 73 | -Dtestsdir=%{_testsdir} \ 74 | 75 | %meson_build 76 | 77 | %install 78 | %meson_install 79 | 80 | install -D -m755 tools/measure_launch_time.py \ 81 | %{buildroot}%{_bindir}/measure_launch_time 82 | 83 | install -d %{buildroot}%{_unitdir}/multi-user.target.wants 84 | ln -s ../sailjaild.service %{buildroot}%{_unitdir}/multi-user.target.wants/ 85 | install -d %{buildroot}%{_sysconfdir}/sailjail/config 86 | install -d %{buildroot}%{_sysconfdir}/sailjail/applications 87 | 88 | %files 89 | %defattr(-,root,root,-) 90 | %license COPYING 91 | %attr(2755,root,privileged) %{_bindir}/sailjail 92 | 93 | %files tools 94 | %defattr(-,root,root,-) 95 | %{_bindir}/measure_launch_time 96 | 97 | %files daemon 98 | %defattr(-,root,root,-) 99 | %license COPYING 100 | %{_bindir}/sailjaild 101 | %{_unitdir}/*.service 102 | %{_unitdir}/multi-user.target.wants/*.service 103 | %{_dbuspolicydir}/sailjaild.conf 104 | %dir %{_sysconfdir}/sailjail 105 | %dir %{_sysconfdir}/sailjail/config 106 | %dir %{_sysconfdir}/sailjail/applications 107 | 108 | %files daemon-tests 109 | %defattr(-,root,root,-) 110 | %license COPYING 111 | %{_testsdir}/%{name}-daemon 112 | --------------------------------------------------------------------------------