Commit 54f4907d authored by Zeeshan Ali's avatar Zeeshan Ali

config: Allow whitelisting of applications

Some applications are part of the system and/or ensure that user
location is only queried with their consent. Examples are
gnome-settings-daemon and web browsers. We setup a small list of these
by default and allow system admins/packagers to edit this list through
our config file.

Later we can re-use the same format (or even the file) to add/remove
apps to whitelist based on agents' verdict.
parent a12baaa5
......@@ -7,3 +7,35 @@
# For security reasons, its best to only allow agents that are installed
# in privileged locations, e.g /usr/bin, /usr/sbin, /usr/libexec etc.
whitelist=@demo_agent@/usr/bin/gnome-shell
# Application configuration options
#
# Format:
#
# # Desktop ID of application without .desktop part
# [random-app]
#
# # Allowed access to location information?
# allowed=true|false
#
# # List of UIDs of all users for which this application is allowed location
# # info access, separate by ';'. Keep it empty for allowing it for all users.
# users=
#
# Path of binary
# path=/usr/bin/random-app
[gnome-settings-daemon]
allowed=true
users=
path=/usr/libexec/gnome-settings-daemon
[epiphany]
allowed=true
users=
path=/usr/bin/epiphany
[firefox]
allowed=true
users=
path=/usr/bin/firefox
......@@ -125,3 +125,76 @@ gclue_config_is_agent_allowed (GClueConfig *config,
return allowed;
}
gboolean
gclue_config_is_app_allowed (GClueConfig *config,
const char *desktop_id,
GClueClientInfo *app_info)
{
GClueConfigPrivate *priv = config->priv;
char *expected_app_path = NULL;
const char *app_path;
int* users = NULL;
guint64 uid;
gsize num_users, i;
gboolean allowed = FALSE;
GError *error = NULL;
g_return_val_if_fail (desktop_id != NULL, FALSE);
allowed = g_key_file_get_boolean (priv->key_file,
desktop_id,
"allowed",
&error);
if (error != NULL || !allowed) {
g_debug ("'%s' not in configuration or not allowed", desktop_id);
goto out;
}
expected_app_path = g_key_file_get_string (priv->key_file,
desktop_id,
"path",
&error);
if (error != NULL || expected_app_path == NULL) {
g_warning ("Path not correctly setup for %s in configuration",
desktop_id);
goto out;
}
app_path = gclue_client_info_get_bin_path (app_info);
if (g_strcmp0 (app_path, expected_app_path) != 0) {
g_debug ("Client %s has path '%s' while it should be '%s'",
desktop_id, app_path, expected_app_path);
goto out;
}
uid = gclue_client_info_get_user_id (app_info);
users = g_key_file_get_integer_list (priv->key_file,
desktop_id,
"users",
&num_users,
&error);
if (error != NULL) {
g_warning ("%s", error->message);
goto out;
}
if (num_users == 0) {
allowed = TRUE;
goto out;
}
for (i = 0; i < num_users; i++) {
if (users[i] == uid) {
allowed = TRUE;
break;
}
}
out:
g_clear_pointer (&users, g_free);
g_clear_pointer (&expected_app_path, g_free);
g_clear_error (&error);
return allowed;
}
......@@ -26,6 +26,7 @@
#include <gio/gio.h>
#include "geocode-location.h"
#include "gclue-client-info.h"
#include "gclue-config.h"
G_BEGIN_DECLS
......@@ -59,6 +60,9 @@ GType gclue_config_get_type (void) G_GNUC_CONST;
GClueConfig * gclue_config_get_singleton (void);
gboolean gclue_config_is_agent_allowed (GClueConfig *config,
GClueClientInfo *agent_info);
gboolean gclue_config_is_app_allowed (GClueConfig *config,
const char *desktop_id,
GClueClientInfo *app_info);
G_END_DECLS
......
......@@ -26,6 +26,7 @@
#include "gclue-service-location.h"
#include "gclue-locator.h"
#include "gclue-enum-types.h"
#include "gclue-config.h"
#define DEFAULT_ACCURACY_LEVEL GCLUE_ACCURACY_LEVEL_CITY
......@@ -287,6 +288,7 @@ gclue_service_client_handle_start (GClueClient *client,
GDBusMethodInvocation *invocation)
{
GClueServiceClientPrivate *priv = GCLUE_SERVICE_CLIENT (client)->priv;
GClueConfig *config;
StartData *data;
const char *desktop_id;
GClueAccuracyLevel accuracy_level;
......@@ -308,8 +310,13 @@ gclue_service_client_handle_start (GClueClient *client,
data->client = g_object_ref (client);
data->invocation = g_object_ref (invocation);
if (priv->agent_proxy == NULL) {
/* No agent == No authorization needed */
config = gclue_config_get_singleton ();
/* No agent == No authorization needed */
if (priv->agent_proxy == NULL ||
gclue_config_is_app_allowed (config,
desktop_id,
priv->client_info)) {
priv->location_change_id = g_signal_connect
(priv->locator,
"notify::location",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment