Skip to content

Commit

Permalink
[usb] Add a whitelist property specifying allowed USB modes. Contribu…
Browse files Browse the repository at this point in the history
…tes to JB#33745

If the whitelist property exists in the conf file only modes that
appear in the list can be used or set as the default.  If a current
mode is removed from the whitelist the device will be put into charging
mode and if the default is removed that will be changed to ask.
  • Loading branch information
adenexter committed Aug 11, 2017
1 parent 31c104d commit 2fc6363
Show file tree
Hide file tree
Showing 11 changed files with 341 additions and 63 deletions.
4 changes: 4 additions & 0 deletions debian/usb_moded.conf
Expand Up @@ -25,6 +25,10 @@
send_interface="com.meego.usb_moded" send_member="get_net_config"/>
<allow send_destination="com.meego.usb_moded"
send_interface="com.meego.usb_moded" send_member="rescue_off"/>
<deny send_destination="com.meego.usb_moded"
send_interface="com.meego.usb_moded" send_member="set_whitelist"/>
<deny send_destination="com.meego.usb_moded"
send_interface="com.meego.usb_moded" send_member="set_in_whitelist"/>
<allow send_interface="org.freedesktop.DBus.Introspectable" />
<allow send_destination="com.meego.usb_moded" />
<deny own="com.meego.usb_moded"/>
Expand Down
19 changes: 19 additions & 0 deletions src/com.meego.usb_moded.xml
Expand Up @@ -30,6 +30,9 @@
<method name="get_modes">
<arg name="modes" type="s" direction="out"/>
</method>
<method name="get_available_modes">
<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"/>
Expand All @@ -41,6 +44,16 @@
<method name="get_hidden">
<arg name="modes" type="s" direction="out"/>
</method>
<method name="get_whitelisted_modes">
<arg name="modes" type="s" direction="out"/>
</method>
<method name="set_whitelisted_modes">
<arg name="modes" type="s" direction="in"/>
</method>
<method name="set_whitelisted">
<arg name="mode" type="s" direction="in"/>
<arg name="whitelisted" type="b" direction="in"/>
</method>
<method name="rescue_off"/>
<signal name="sig_usb_state_ind">
<arg name="mode" type="s"/>
Expand All @@ -51,6 +64,9 @@
<signal name="sig_usb_supported_modes_ind">
<arg name="modes" type="s"/>
</signal>
<signal name="sig_usb_available_modes_ind">
<arg name="modes" type="s"/>
</signal>
<signal name="sig_usb_config_ind">
<arg name="section" type="s"/>
<arg name="key" type="s"/>
Expand All @@ -59,5 +75,8 @@
<signal name="sig_usb_hidden_modes_ind">
<arg name="modes" type="s"/>
</signal>
<signal name="sig_usb_whitelisted_modes_ind">
<arg name="modes" type="s"/>
</signal>
</interface>
</node>
4 changes: 4 additions & 0 deletions src/usb_moded-config-private.h
Expand Up @@ -30,3 +30,7 @@ set_config_result_t set_hide_mode_setting(const char *mode);
set_config_result_t set_unhide_mode_setting(const char *mode);
char * get_hidden_modes(void);
set_config_result_t set_network_setting(const char *config, const char *setting);
char * get_mode_whitelist(void);
set_config_result_t set_mode_whitelist(const char *whitelist);
set_config_result_t set_mode_in_whitelist(const char *mode, int allowed);

106 changes: 78 additions & 28 deletions src/usb_moded-config.c
Expand Up @@ -41,6 +41,7 @@
#include "usb_moded-config-private.h"
#include "usb_moded-log.h"
#include "usb_moded-modes.h"
#include "usb_moded-modesetting.h"

#ifdef USE_MER_SSU
# include "usb_moded-ssu.h"
Expand Down Expand Up @@ -403,75 +404,77 @@ set_config_result_t set_config_setting(const char *entry, const char *key, const

set_config_result_t set_mode_setting(const char *mode)
{
if (strcmp(mode, MODE_ASK) && valid_mode(mode))
return SET_CONFIG_ERROR;
return (set_config_setting(MODE_SETTING_ENTRY, MODE_SETTING_KEY, mode));
}

/* Builds the string used for hidden modes, when hide set to one builds the
new string of hidden modes when adding one, otherwise it will remove one */
static char * make_hidden_modes_string(const char *mode_name, int hide)
static char * make_modes_string(const char *key, const char *mode_name, int include)
{
char *hidden_new = 0;
char *hidden_old = 0;
gchar **hidden_arr = 0;
GString *hidden_tmp = 0;
char *modes_new = 0;
char *modes_old = 0;
gchar **modes_arr = 0;
GString *modes_tmp = 0;
int i;

/* Get current comma separated list of hidden modes */
hidden_old = get_hidden_modes();
if(!hidden_old)
modes_old = get_conf_string(MODE_SETTING_ENTRY, key);
if(!modes_old)
{
hidden_old = g_strdup("");
modes_old = g_strdup("");
}

hidden_arr = g_strsplit(hidden_old, ",", 0);
modes_arr = g_strsplit(modes_old, ",", 0);

hidden_tmp = g_string_new(NULL);
modes_tmp = g_string_new(NULL);

for(i = 0; hidden_arr[i] != NULL; i++)
for(i = 0; modes_arr[i] != NULL; i++)
{
if(strlen(hidden_arr[i]) == 0)
if(strlen(modes_arr[i]) == 0)
{
/* Skip any empty strings */
continue;
}

if(!strcmp(hidden_arr[i], mode_name))
if(!strcmp(modes_arr[i], mode_name))
{
/* When unhiding, just skip all matching entries */
if(!hide)
if(!include)
continue;

/* When hiding, keep the 1st match and ignore the rest */
hide = 0;
include = 0;
}

if(hidden_tmp->len > 0)
hidden_tmp = g_string_append(hidden_tmp, ",");
hidden_tmp = g_string_append(hidden_tmp, hidden_arr[i]);
if(modes_tmp->len > 0)
modes_tmp = g_string_append(modes_tmp, ",");
modes_tmp = g_string_append(modes_tmp, modes_arr[i]);
}

if(hide)
if(include)
{
/* Adding a hidden mode and no matching entry was found */
if(hidden_tmp->len > 0)
hidden_tmp = g_string_append(hidden_tmp, ",");
hidden_tmp = g_string_append(hidden_tmp, mode_name);
if(modes_tmp->len > 0)
modes_tmp = g_string_append(modes_tmp, ",");
modes_tmp = g_string_append(modes_tmp, mode_name);
}

hidden_new = g_string_free(hidden_tmp, FALSE), hidden_tmp = 0;
modes_new = g_string_free(modes_tmp, FALSE), modes_tmp = 0;

g_strfreev(hidden_arr), hidden_arr = 0;
g_strfreev(modes_arr), modes_arr = 0;

g_free(hidden_old), hidden_old = 0;
g_free(modes_old), modes_old = 0;

return hidden_new;
return modes_new;
}

set_config_result_t set_hide_mode_setting(const char *mode)
{
set_config_result_t ret = SET_CONFIG_UNCHANGED;

char *hidden_modes = make_hidden_modes_string(mode, 1);
char *hidden_modes = make_modes_string(MODE_HIDE_KEY, mode, 1);

if( hidden_modes ) {
ret = set_config_setting(MODE_SETTING_ENTRY, MODE_HIDE_KEY, hidden_modes);
Expand All @@ -480,6 +483,7 @@ set_config_result_t set_hide_mode_setting(const char *mode)
if(ret == SET_CONFIG_UPDATED) {
send_hidden_modes_signal();
send_supported_modes_signal();
send_available_modes_signal();
}

g_free(hidden_modes);
Expand All @@ -491,7 +495,7 @@ set_config_result_t set_unhide_mode_setting(const char *mode)
{
set_config_result_t ret = SET_CONFIG_UNCHANGED;

char *hidden_modes = make_hidden_modes_string(mode, 0);
char *hidden_modes = make_modes_string(MODE_HIDE_KEY, mode, 0);

if( hidden_modes ) {
ret = set_config_setting(MODE_SETTING_ENTRY, MODE_HIDE_KEY, hidden_modes);
Expand All @@ -500,13 +504,55 @@ set_config_result_t set_unhide_mode_setting(const char *mode)
if(ret == SET_CONFIG_UPDATED) {
send_hidden_modes_signal();
send_supported_modes_signal();
send_available_modes_signal();
}

g_free(hidden_modes);

return(ret);
}

set_config_result_t set_mode_whitelist(const char *whitelist)
{
set_config_result_t ret = set_config_setting(MODE_SETTING_ENTRY, MODE_WHITELIST_KEY, whitelist);

if(ret == SET_CONFIG_UPDATED) {
char *mode_setting;
const char *current_mode;

mode_setting = get_mode_setting();
if (strcmp(mode_setting, MODE_ASK) && valid_mode(mode_setting))
set_mode_setting(MODE_ASK);
g_free(mode_setting);

current_mode = get_usb_mode();
if (strcmp(current_mode, MODE_CHARGING_FALLBACK) && strcmp(current_mode, MODE_ASK) && valid_mode(current_mode)) {
usb_moded_mode_cleanup(get_usb_module());
set_usb_mode(MODE_CHARGING_FALLBACK);
}

usb_moded_send_whitelisted_modes_signal(whitelist);
send_available_modes_signal();
}

return ret;
}

set_config_result_t set_mode_in_whitelist(const char *mode, int allowed)
{
set_config_result_t ret = SET_CONFIG_UNCHANGED;

char *whitelist = make_modes_string(MODE_WHITELIST_KEY, mode, allowed);

if (whitelist) {
ret = set_mode_whitelist(whitelist);
}

g_free(whitelist);

return(ret);
}

/*
* @param config : the key to be set
* @param setting : The value to be set
Expand Down Expand Up @@ -808,6 +854,10 @@ char * get_hidden_modes(void)
{
return(get_conf_string(MODE_SETTING_ENTRY, MODE_HIDE_KEY));
}
char * get_mode_whitelist(void)
{
return(get_conf_string(MODE_SETTING_ENTRY, MODE_WHITELIST_KEY));
}

int check_android_section(void)
{
Expand Down
2 changes: 2 additions & 0 deletions src/usb_moded-config.h
Expand Up @@ -58,6 +58,7 @@
#define ANDROID_PRODUCT_KEY "iProduct"
#define ANDROID_PRODUCT_ID_KEY "idProduct"
#define MODE_HIDE_KEY "hide"
#define MODE_WHITELIST_KEY "whitelist"

char * find_mounts(void);
int find_sync(void);
Expand All @@ -80,6 +81,7 @@ char * get_android_product(void);
char * get_android_product_id(void);

char * get_hidden_modes(void);
char * get_mode_whitelist(void);

int check_android_section(void);

Expand Down
6 changes: 6 additions & 0 deletions src/usb_moded-dbus-private.h
Expand Up @@ -50,9 +50,15 @@ int usb_moded_send_error_signal(const char *error);
/* send supported modes signal system bus */
int usb_moded_send_supported_modes_signal(const char *supported_modes);

/* send available modes signal system bus */
int usb_moded_send_available_modes_signal(const char *available_modes);

/* send hidden modes signal system bus */
int usb_moded_send_hidden_modes_signal(const char *hidden_modes);

/* send whitelisted modes signal system bus */
int usb_moded_send_whitelisted_modes_signal(const char *hidden_modes);

/* Callback function type used with usb_moded_get_name_owner_async() */
typedef void (*usb_moded_get_name_owner_fn)(const char *owner);

Expand Down

0 comments on commit 2fc6363

Please sign in to comment.