Commit 6e98e56b authored by Tomi Leppänen's avatar Tomi Leppänen

[dbus] Check sender uid for mode restrictions. Fixes JB#48441

Check sender uid to deny access for modes that are restricted. Prevent
non-owner users from hiding or unhiding modes. Add
get_allowed_modes_for_user method that lists only those methods that
user may choose.

Set last seen user based on uid that has called
get_allowed_modes_for_user last. This is not a perfect solution by any
means since it can be easily confused by calling it from command line as
root but generally no user other than the active one should call it.
Later when there is a proper way to get the active user this can be
improved.
Signed-off-by: Tomi Leppänen's avatarTomi Leppänen <tomi.leppanen@jolla.com>
parent 8abafa0d
......@@ -36,6 +36,9 @@
<method name="get_available_modes">
<arg name="modes" type="s" direction="out"/>
</method>
<method name="get_available_modes_for_user">
<arg name="modes" type="s" direction="out"/>
</method>
<method name="hide_mode">
<arg name="mode" type="s" direction="in"/>
<arg name="mode" type="s" direction="out"/>
......
......@@ -163,6 +163,9 @@ static const char umdbus_introspect_usbmoded[] =
" <method name=\"" USB_MODE_AVAILABLE_MODES_GET "\">\n"
" <arg name=\"modes\" type=\"s\" direction=\"out\"/>\n"
" </method>\n"
" <method name=\"" USB_MODE_AVAILABLE_MODES_FOR_USER "\">\n"
" <arg name=\"modes\" type=\"s\" direction=\"out\"/>\n"
" </method>\n"
" <method name=\"" USB_MODE_HIDE "\">\n"
" <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n"
" <arg name=\"mode\" type=\"s\" direction=\"out\"/>\n"
......@@ -286,6 +289,7 @@ static DBusHandlerResult umdbus_msg_handler(DBusConnection *const connection, DB
const char *member = dbus_message_get_member(msg);
const char *object = dbus_message_get_path(msg);
int type = dbus_message_get_type(msg);
const char *sender = dbus_message_get_sender(msg);
(void)user_data;
......@@ -342,11 +346,17 @@ static DBusHandlerResult umdbus_msg_handler(DBusConnection *const connection, DB
const char *mode = control_get_external_mode();
char *use = 0;
DBusError err = DBUS_ERROR_INIT;
uid_t uid = umdbus_get_sender_uid(sender);
if(!dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &use, DBUS_TYPE_INVALID)) {
log_err("parse error: %s: %s", err.name, err.message);
reply = dbus_message_new_error(msg, DBUS_ERROR_INVALID_ARGS, member);
}
else if( !usbmoded_is_mode_permitted(use, uid) ) {
/* Insufficient permissions */
log_warning("Mode '%s' is not allowed for uid %d", use, uid);
reply = dbus_message_new_error(msg, DBUS_ERROR_ACCESS_DENIED, member);
}
else if( control_get_cable_state() != CABLE_STATE_PC_CONNECTED ) {
/* Mode change makes no sence unless we have a PC connection */
log_warning("Mode '%s' requested while not connected to pc", use);
......@@ -403,6 +413,11 @@ static DBusHandlerResult umdbus_msg_handler(DBusConnection *const connection, DB
if(!dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &config, DBUS_TYPE_INVALID))
reply = dbus_message_new_error(msg, DBUS_ERROR_INVALID_ARGS, member);
#ifdef SAILFISH_ACCESS_CONTROL
/* do not let non-owner user hide modes */
else if (!sailfish_access_control_hasgroup(umdbus_get_sender_uid(sender), "sailfish-system"))
reply = dbus_message_new_error(msg, DBUS_ERROR_ACCESS_DENIED, member);
#endif
else
{
/* error checking is done when setting configuration */
......@@ -424,6 +439,11 @@ static DBusHandlerResult umdbus_msg_handler(DBusConnection *const connection, DB
if(!dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &config, DBUS_TYPE_INVALID))
reply = dbus_message_new_error(msg, DBUS_ERROR_INVALID_ARGS, member);
#ifdef SAILFISH_ACCESS_CONTROL
/* do not let non-owner user unhide modes */
else if (!sailfish_access_control_hasgroup(umdbus_get_sender_uid(sender), "sailfish-system"))
reply = dbus_message_new_error(msg, DBUS_ERROR_ACCESS_DENIED, member);
#endif
else
{
/* error checking is done when setting configuration */
......@@ -516,6 +536,17 @@ static DBusHandlerResult umdbus_msg_handler(DBusConnection *const connection, DB
dbus_message_append_args (reply, DBUS_TYPE_STRING, (const char *) &mode_list, DBUS_TYPE_INVALID);
g_free(mode_list);
}
else if(!strcmp(member, USB_MODE_AVAILABLE_MODES_FOR_USER))
{
uid_t uid = umdbus_get_sender_uid(sender);
gchar *mode_list = common_get_mode_list(AVAILABLE_MODES_LIST, uid);
if((reply = dbus_message_new_method_return(msg)))
dbus_message_append_args (reply, DBUS_TYPE_STRING, (const char *) &mode_list, DBUS_TYPE_INVALID);
g_free(mode_list);
control_set_last_seen_user(uid);
}
else if(!strcmp(member, USB_MODE_RESCUE_OFF))
{
usbmoded_set_rescue_mode(false);
......@@ -1366,7 +1397,7 @@ uid_t umdbus_get_sender_uid(const char *name)
/* Synchronous D-Bus call */
rsp = dbus_connection_send_with_reply_and_block(umdbus_connection, req, -1, &err);
if( rsp == NULL && dbus_error_is_set(&err) ) {
if( !rsp && dbus_error_is_set(&err) ) {
log_err("could not get sender pid for %s: %s: %s", name, err.name, err.message);
goto EXIT;
}
......@@ -1380,7 +1411,7 @@ uid_t umdbus_get_sender_uid(const char *name)
snprintf(path, sizeof path, "/proc/%d", (int)pid);
memset(&st, 0, sizeof st);
if( stat(path, &st) == 0 ) {
if( stat(path, &st) != -1 ) {
uid = st.st_uid;
}
......
......@@ -59,23 +59,24 @@
# define USB_MODE_TARGET_CONFIG_SIGNAL_NAME "sig_usb_taget_mode_config_ind"
/* supported methods */
# define USB_MODE_STATE_REQUEST "mode_request" /* returns the current mode */
# define USB_MODE_TARGET_STATE_GET "get_target_state" /* returns the target mode */
# define USB_MODE_RESCUE_OFF "rescue_off" /* turns rescue mode off so normal mode selection is restored */
# define USB_MODE_CONFIG_GET "get_config" /* returns the mode set in the config */
# define USB_MODE_LIST "get_modes" /* returns a comma-separated list of supported modes for ui's */
# define USB_MODE_HIDE "hide_mode" /* hide a mode */
# define USB_MODE_UNHIDE "unhide_mode" /* unhide a mode */
# define USB_MODE_HIDDEN_GET "get_hidden" /* return the hidden modes */
# define USB_MODE_STATE_SET "set_mode" /* set a mode (only works when connected) */
# define USB_MODE_CONFIG_SET "set_config" /* set the mode that needs to be activated in the config file */
# define USB_MODE_NETWORK_SET "net_config" /* set the network config in the config file */
# define USB_MODE_NETWORK_GET "get_net_config" /* get the network config from the config file */
# define USB_MODE_WHITELISTED_MODES_GET "get_whitelisted_modes" /* get the list of whitelisted modes */
# define USB_MODE_WHITELISTED_MODES_SET "set_whitelisted_modes" /* set the list of whitelisted modes */
# define USB_MODE_WHITELISTED_SET "set_whitelisted" /* sets whether an specific mode is in the whitelist */
# define USB_MODE_AVAILABLE_MODES_GET "get_available_modes" /* returns a comma separated list of modes which are currently available for selection */
# define USB_MODE_TARGET_CONFIG_GET "get_target_mode_config" /* returns current target mode configuration */
# define USB_MODE_STATE_REQUEST "mode_request" /* returns the current mode */
# define USB_MODE_TARGET_STATE_GET "get_target_state" /* returns the target mode */
# define USB_MODE_RESCUE_OFF "rescue_off" /* turns rescue mode off so normal mode selection is restored */
# define USB_MODE_CONFIG_GET "get_config" /* returns the mode set in the config */
# define USB_MODE_LIST "get_modes" /* returns a comma-separated list of supported modes for ui's */
# define USB_MODE_HIDE "hide_mode" /* hide a mode */
# define USB_MODE_UNHIDE "unhide_mode" /* unhide a mode */
# define USB_MODE_HIDDEN_GET "get_hidden" /* return the hidden modes */
# define USB_MODE_STATE_SET "set_mode" /* set a mode (only works when connected) */
# define USB_MODE_CONFIG_SET "set_config" /* set the mode that needs to be activated in the config file */
# define USB_MODE_NETWORK_SET "net_config" /* set the network config in the config file */
# define USB_MODE_NETWORK_GET "get_net_config" /* get the network config from the config file */
# define USB_MODE_WHITELISTED_MODES_GET "get_whitelisted_modes" /* get the list of whitelisted modes */
# define USB_MODE_WHITELISTED_MODES_SET "set_whitelisted_modes" /* set the list of whitelisted modes */
# define USB_MODE_WHITELISTED_SET "set_whitelisted" /* sets whether an specific mode is in the whitelist */
# define USB_MODE_AVAILABLE_MODES_GET "get_available_modes" /* returns a comma separated list of modes which are currently available for selection */
# define USB_MODE_AVAILABLE_MODES_FOR_USER "get_available_modes_for_user" /* returns a comma separated list of modes which are currently available and permitted for user to select */
# define USB_MODE_TARGET_CONFIG_GET "get_target_mode_config" /* returns current target mode configuration */
/**
* (Transient) states reported by "sig_usb_state_ind" that are not modes.
......
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