Commit d05adbc6 authored by Slava Monich's avatar Slava Monich

[mms-engine] D-Bus access control. JB#46060

By default, only privileged and sailfish-mms groups (effective or primary)
are allowed to call most D-Bus methods.

D-Bus access rules can be configured by adding [DBus] section to
/etc/mms-engine.conf config file:

[DBus]
MmsEngineAccess=...
TransferAccess=...
TransferListAccess=...

The default rules are:

MmsEngineAccess:

  (!group(privileged))&(!group(sailfish-mms))&(cancel()|receiveMessage()|
  sendReadReport()|sendMessage()|push()|pushNotify()|setLogLevel()|
  setLogType()|migrateSettings())=deny

TransferAccess:

  (!group(privileged))&(!group(sailfish-mms))&Get()=deny

TransferListAccess:

  (!group(privileged))&(!group(sailfish-mms))&(GetAll()|EnableUpdates()|
  DisableUpdates()|GetSendProgress()|GetReceiveProgress())=deny
parent 4ba66dbf
......@@ -17,7 +17,7 @@ include ../mms-lib/Config.mak
# Required packages
#
PKGS = gio-unix-2.0 gio-2.0 libglibutil
PKGS = gio-unix-2.0 gio-2.0 libdbusaccess libglibutil
LIB_PKGS = libwspcodec gmime-2.6 libgofono libsoup-2.4 dconf
ifdef SAILFISH
......
This diff is collapsed.
TEMPLATE = app
CONFIG += link_pkgconfig
PKGCONFIG += gmime-2.6 gio-unix-2.0 gio-2.0 glib-2.0 libsoup-2.4 dconf
PKGCONFIG += libwspcodec libgofono libglibutil
PKGCONFIG += libwspcodec libgofono libdbusaccess libglibutil
QMAKE_CFLAGS += -Wno-unused-parameter
include(../mms-lib/mms-lib-config.pri)
......
This diff is collapsed.
/*
* Copyright (C) 2013-2016 Jolla Ltd.
* Contact: Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2013-2019 Jolla Ltd.
* Copyright (C) 2013-2019 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2019 Open Mobile Platform LLC.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
......@@ -16,6 +17,8 @@
#define JOLLA_MMS_ENGINE_H
#include <gio/gio.h>
#include <dbusaccess_types.h>
#include "mms_settings.h"
#include "mms_version.h"
......@@ -35,15 +38,42 @@
# define MMS_ENGINE_CONFIG_FILE "/etc/mms-engine.conf"
#endif /* MMS_ENGINE_CONFIG_FILE */
#define MMS_ENGINE_DBUS_METHODS(m) \
m(CANCEL) \
m(RECEIVE_MESSAGE) \
m(SEND_READ_REPORT) \
m(SEND_MESSAGE) \
m(PUSH) \
m(PUSH_NOTIFY) \
m(SET_LOG_LEVEL) \
m(SET_LOG_TYPE) \
m(GET_VERSION) \
m(MIGRATE_SETTINGS)
typedef enum mms_engine_action {
/* Action ids must be non-zero, shift those by one */
MMS_ENGINE_ACTION_NONE = 0,
#define MMS_ENGINE_ACTION_(id) MMS_ENGINE_ACTION_##id,
MMS_ENGINE_DBUS_METHODS(MMS_ENGINE_ACTION_)
#undef MMS_ENGINE_ACTION_
} MMS_ENGINE_ACTION;
typedef struct mms_engine MMSEngine;
typedef struct engine_dbus_config {
GBusType type;
DAPolicy* engine_access;
DAPolicy* tx_list_access;
DAPolicy* tx_access;
} MMSEngineDbusConfig;
MMSEngine*
mms_engine_new(
const MMSConfig* config,
const MMSSettingsSimData* defaults,
unsigned int flags,
MMSLogModule* log_modules[],
int log_count);
const MMSEngineDbusConfig* dbus_config,
MMSLogModule* log_modules[], /* NULL terminated */
unsigned int flags);
MMSEngine*
mms_engine_ref(
......
/*
* Copyright (C) 2014-2018 Jolla Ltd.
* Copyright (C) 2014-2018 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2014-2019 Jolla Ltd.
* Copyright (C) 2014-2019 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2019 Open Mobile Platform LLC.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
......@@ -117,6 +118,12 @@ mms_settings_load_defaults(
MMSSettingsSimDataCopy* simconfig,
GError** error);
void
mms_settings_parse(
GKeyFile* file,
MMSConfigCopy* config,
MMSSettingsSimDataCopy* data);
void
mms_settings_set_sim_defaults(
MMSSettings* settings,
......
/*
* Copyright (C) 2014-2018 Jolla Ltd.
* Copyright (C) 2014-2018 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2014-2019 Jolla Ltd.
* Copyright (C) 2014-2019 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2019 Open Mobile Platform LLC.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
......@@ -187,18 +188,27 @@ mms_settings_load_defaults(
MMSSettingsSimDataCopy* data,
GError** error)
{
gboolean ok = FALSE;
GKeyFile* file = g_key_file_new();
if (g_key_file_load_from_file(file, path, 0, error)) {
gboolean ok = g_key_file_load_from_file(file, path, 0, error);
if (ok) {
GDEBUG("Loading %s", path);
mms_settings_parse_global_config(config, file);
mms_settings_parse_sim_config(data, file);
ok = TRUE;
mms_settings_parse(file, config, data);
}
g_key_file_free(file);
return ok;
}
void
mms_settings_parse(
GKeyFile* file,
MMSConfigCopy* config,
MMSSettingsSimDataCopy* data)
{
mms_settings_parse_global_config(config, file);
mms_settings_parse_sim_config(data, file);
}
void
mms_settings_sim_data_copy(
MMSSettingsSimDataCopy* dest,
......
......@@ -3,7 +3,7 @@
.PHONY: clean all debug release
# Required packages
PKGS = libglibutil glib-2.0 gio-2.0 gio-unix-2.0
PKGS = libdbusaccess libglibutil glib-2.0 gio-2.0 gio-unix-2.0
#
# Default target
......
/*
* Copyright (C) 2016 Jolla Ltd.
* Contact: Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2016-2019 Jolla Ltd.
* Copyright (C) 2016-2019 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2019 Open Mobile Platform LLC.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
......@@ -18,8 +19,39 @@
#include "mms_transfer_list.h"
#include <dbusaccess_types.h>
#define MMS_TRANSFER_LIST_DBUS_METHODS(m) \
m(GET)
typedef enum mms_transfer_list_action {
/* Action ids must be non-zero, shift those by one */
MMS_TRANSFER_LIST_ACTION_NONE = 0,
#define MMS_TRANSFER_LIST_ACTION_(id) MMS_TRANSFER_LIST_ACTION_##id,
MMS_TRANSFER_LIST_DBUS_METHODS(MMS_TRANSFER_LIST_ACTION_)
#undef MMS_TRANSFER_LIST_ACTION_
} MMS_TRANSFER_LIST_ACTION;
#define MMS_TRANSFER_DBUS_METHODS(m) \
m(GET_ALL) \
m(ENABLE_UPDATES) \
m(DISABLE_UPDATES) \
m(GET_INTERFACE_VERSION) \
m(GET_SEND_PROGRESS) \
m(GET_RECEIVE_PROGRESS)
typedef enum mms_transfer_action {
/* Action ids must be non-zero, shift those by one */
MMS_TRANSFER_ACTION_NONE = 0,
#define MMS_TRANSFER_ACTION_(id) MMS_TRANSFER_ACTION_##id,
MMS_TRANSFER_DBUS_METHODS(MMS_TRANSFER_ACTION_)
#undef MMS_TRANSFER_ACTION_
} MMS_TRANSFER_ACTION;
MMSTransferList*
mms_transfer_list_dbus_new(void);
mms_transfer_list_dbus_new(
DAPolicy* tx_list_access,
DAPolicy* tx_access);
#endif /* JOLLA_MMS_TRANSFER_LIST_DBUS_H */
......
......@@ -2,7 +2,7 @@ TEMPLATE = lib
CONFIG += staticlib
CONFIG -= qt
CONFIG += link_pkgconfig
PKGCONFIG += libglibutil glib-2.0 gio-2.0 gio-unix-2.0
PKGCONFIG += libdbusaccess libglibutil glib-2.0 gio-2.0 gio-unix-2.0
DBUS_SPEC_DIR = $$_PRO_FILE_PWD_/spec
INCLUDEPATH += . include
INCLUDEPATH += ../mms-lib/include
......
/*
* Copyright (C) 2016 Jolla Ltd.
* Contact: Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2016-2019 Jolla Ltd.
* Copyright (C) 2016-2019 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2019 Open Mobile Platform LLC.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
......@@ -16,7 +17,7 @@
#ifndef JOLLA_MMS_TRANSFER_DBUS_H
#define JOLLA_MMS_TRANSFER_DBUS_H
#include "mms_lib_types.h"
#include "mms_transfer_list_dbus.h"
#include <gio/gio.h>
......@@ -43,6 +44,8 @@ GType mms_transfer_dbus_get_type(void);
MMSTransferDbus*
mms_transfer_dbus_new(
GDBusConnection* bus,
DA_BUS da_bus,
DAPolicy* access,
const char* id,
const char* type);
......
......@@ -19,6 +19,9 @@
#include <gutil_strv.h>
#include <dbusaccess_peer.h>
#include <dbusaccess_policy.h>
/* Generated code */
#include "org.nemomobile.MmsEngine.TransferList.h"
......@@ -27,12 +30,18 @@
#define MMS_TRANSFER_LIST_SIGNAL_TRANSFER_STARTED "TransferStarted"
#define MMS_TRANSFER_LIST_SIGNAL_TRANSFER_FINISHED "TransferFinished"
#define MMS_TRANSFER_LIST_DBUS_PATH "/"
#define MMS_TRANSFER_LIST_DBUS_BUS G_BUS_TYPE_SYSTEM
#define MMS_TRANSFER_LIST_DA_BUS DA_BUS_SYSTEM
/* Class definition */
typedef MMSTransferListClass MMSTransferListDbusClass;
struct mms_transfer_list_dbus {
MMSTransferList super;
GDBusConnection* bus;
OrgNemomobileMmsEngineTransferList* skeleton;
DAPolicy* tx_list_access;
DAPolicy* tx_access;
gulong list_transfers_id;
GHashTable* transfers;
GHashTable* clients;
......@@ -44,9 +53,6 @@ G_DEFINE_TYPE(MMSTransferListDbus, mms_transfer_list_dbus, \
#define MMS_TRANSFER_LIST_DBUS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
MMS_TYPE_TRANSFER_LIST_DBUS, MMSTransferListDbus))
#define MMS_TRANSFER_LIST_DBUS_PATH "/"
#define MMS_TRANSFER_LIST_DBUS_BUS G_BUS_TYPE_SYSTEM
/*
* Sends signals only to registered clients. That's not much of an overhead
* because there's usually no more than one client (i.e. Messages app).
......@@ -160,10 +166,14 @@ mms_transfer_list_dbus_bus_cb(
}
MMSTransferList*
mms_transfer_list_dbus_new()
mms_transfer_list_dbus_new(
DAPolicy* tx_list_access,
DAPolicy* tx_access)
{
MMSTransferListDbus* self = g_object_new(MMS_TYPE_TRANSFER_LIST_DBUS, 0);
self->tx_list_access = da_policy_ref(tx_list_access);
self->tx_access = da_policy_ref(tx_access);
g_bus_get(MMS_TRANSFER_LIST_DBUS_BUS, NULL, mms_transfer_list_dbus_bus_cb,
g_object_ref(self));
return &self->super;
......@@ -177,7 +187,8 @@ mms_transfer_list_dbus_transfer_started(
char* type) /* Transfer type */
{
MMSTransferListDbus* self = MMS_TRANSFER_LIST_DBUS(list);
MMSTransferDbus* transfer = mms_transfer_dbus_new(self->bus, id, type);
MMSTransferDbus* transfer = mms_transfer_dbus_new(self->bus,
MMS_TRANSFER_LIST_DA_BUS, self->tx_access, id, type);
GDEBUG("Transfer %s started", transfer->path);
transfer->list = self;
......@@ -284,47 +295,62 @@ mms_transfer_list_dbus_handle_get(
MMSTransferListDbus* self)
{
const char* sender = g_dbus_method_invocation_get_sender(call);
const char* null = NULL;
const gchar* const* list = &null;
const gchar** paths = NULL;
guint n = g_hash_table_size(self->transfers);
/* Store the sender's name */
if (!self->clients) {
self->clients = /* sender => watch id */
g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
}
if (!g_hash_table_contains(self->clients, sender)) {
/* New client */
gulong watch_id = g_bus_watch_name_on_connection(self->bus,
sender, G_BUS_NAME_WATCHER_FLAGS_NONE, NULL,
mms_transfer_list_dbus_client_vanished, self, NULL);
g_hash_table_insert(self->clients, g_strdup(sender),
GUINT_TO_POINTER(watch_id));
}
if (n) {
guint i = 0;
gpointer value;
GHashTableIter it;
DAPeer* peer = da_peer_get(MMS_TRANSFER_LIST_DA_BUS, sender);
if (peer && da_policy_check(self->tx_list_access, &peer->cred,
MMS_TRANSFER_LIST_ACTION_GET, 0, DA_ACCESS_ALLOW) ==
DA_ACCESS_ALLOW) {
const char* null = NULL;
const gchar* const* list = &null;
const gchar** paths = NULL;
guint n = g_hash_table_size(self->transfers);
/* Store the sender's name */
if (!self->clients) {
self->clients = /* sender => watch id */
g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
}
if (!g_hash_table_contains(self->clients, sender)) {
/* New client */
gulong watch_id = g_bus_watch_name_on_connection(self->bus,
sender, G_BUS_NAME_WATCHER_FLAGS_NONE, NULL,
mms_transfer_list_dbus_client_vanished, self, NULL);
g_hash_table_insert(self->clients, g_strdup(sender),
GUINT_TO_POINTER(watch_id));
}
g_hash_table_iter_init(&it, self->transfers);
paths = g_new(const char*, n+1);
GVERBOSE("%u transfer(s)", n);
while (i < n && g_hash_table_iter_next(&it, NULL, &value)) {
MMSTransferDbus* transfer = value;
GVERBOSE(" %s", transfer->path);
paths[i++] = transfer->path;
if (n) {
guint i = 0;
gpointer value;
GHashTableIter it;
g_hash_table_iter_init(&it, self->transfers);
paths = g_new(const char*, n+1);
GVERBOSE("%u transfer(s)", n);
while (i < n && g_hash_table_iter_next(&it, NULL, &value)) {
MMSTransferDbus* transfer = value;
GVERBOSE(" %s", transfer->path);
paths[i++] = transfer->path;
}
paths[i++] = NULL;
list = paths;
} else {
GVERBOSE("No transfers");
list = &null;
}
paths[i++] = NULL;
list = paths;
org_nemomobile_mms_engine_transfer_list_complete_get
(skeleton, call, list);
g_free(paths);
} else {
GVERBOSE("No transfers");
list = &null;
const char* iface = g_dbus_method_invocation_get_interface_name(call);
const char* method = g_dbus_method_invocation_get_method_name(call);
GWARN("Client %s is not allowed to call %s.%s", sender, iface, method);
g_dbus_method_invocation_return_error(call, G_DBUS_ERROR,
G_DBUS_ERROR_FAILED, "Client %s is not allowed to call %s.%s",
sender, iface, method);
}
org_nemomobile_mms_engine_transfer_list_complete_get(skeleton, call, list);
g_free(paths);
return TRUE;
}
......@@ -348,6 +374,8 @@ mms_transfer_list_dbus_finalize(
if (self->bus) {
g_object_unref(self->bus);
}
da_policy_unref(self->tx_list_access);
da_policy_unref(self->tx_access);
G_OBJECT_CLASS(mms_transfer_list_dbus_parent_class)->finalize(object);
}
......
......@@ -4,7 +4,7 @@ Version: 1.0.67
Release: 1
Group: Communications/Telephony and IM
License: GPLv2
URL: https://git.merproject.org/mer-core/mms-engine
URL: https://git.sailfishos.org/mer-core/mms-engine
Source0: %{name}-%{version}.tar.bz2
Requires: dbus
Requires: ofono
......@@ -13,6 +13,7 @@ Requires: libwspcodec >= 2.2
Requires: libgofono >= 2.0.0
Requires: libgofonoext >= 1.0.4
Requires: libglibutil >= 1.0.5
Requires: libdbusaccess >= 1.0.10
Requires(post): glib2
Requires(postun): glib2
......@@ -28,6 +29,7 @@ BuildRequires: pkgconfig(libwspcodec) >= 2.2
BuildRequires: pkgconfig(libgofono) >= 2.0.0
BuildRequires: pkgconfig(libgofonoext) >= 1.0.4
BuildRequires: pkgconfig(libglibutil) >= 1.0.11
BuildRequires: pkgconfig(libdbusaccess)
#BuildRequires: pkgconfig(ImageMagick)
BuildRequires: pkgconfig(Qt5Gui)
......
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