62 static int config_validate_ip (
const char *ipadd);
63 char *config_find_mounts (
void);
64 int config_find_sync (
void);
65 char *config_find_alt_mount (
void);
66 char *config_find_udev_path (
void);
67 char *config_find_udev_subsystem (
void);
68 char *config_check_trigger (
void);
69 char *config_get_trigger_subsystem (
void);
70 char *config_get_trigger_mode (
void);
71 char *config_get_trigger_property (
void);
72 char *config_get_trigger_value (
void);
73 static char *config_get_network_ip (
void);
74 static char *config_get_network_interface (
void);
75 static char *config_get_network_gateway (
void);
76 static char *config_get_network_netmask (
void);
77 static char *config_get_network_nat_interface(
void);
78 static int config_get_conf_int (
const gchar *entry,
const gchar *key);
79 char *config_get_conf_string (
const gchar *entry,
const gchar *key);
80 static gchar *config_make_user_key_string (
const gchar *base_key, uid_t uid);
81 gchar *config_get_user_conf_string (
const gchar *entry,
const gchar *base_key, uid_t uid);
82 static char *config_get_kcmdline_string (
const char *entry);
83 char *config_get_mode_setting (uid_t uid);
84 set_config_result_t config_set_config_setting (
const char *entry,
const char *key,
const char *value);
85 set_config_result_t config_set_user_config_setting (
const char *entry,
const char *base_key,
const char *value, uid_t uid);
87 static char *config_make_modes_string (
const char *key,
const char *mode_name,
int include);
92 #ifdef SAILFISH_ACCESS_CONTROL
93 char *config_get_group_for_mode (
const char *mode);
96 char *config_get_network_setting (
const char *config);
97 static void config_merge_key (GKeyFile *dest, GKeyFile *srce,
const char *grp,
const char *key);
98 static void config_merge_group (GKeyFile *dest, GKeyFile *srce,
const char *grp);
99 static void config_merge_data (GKeyFile *dest, GKeyFile *srce);
100 static void config_purge_data (GKeyFile *dest, GKeyFile *srce);
101 static void config_purge_empty_groups (GKeyFile *dest);
102 static int config_glob_error_cb (
const char *path,
int err);
103 static bool config_merge_from_file (GKeyFile *ini,
const char *path);
104 static void config_load_static_config (GKeyFile *ini);
105 static bool config_load_legacy_config (GKeyFile *ini);
106 static void config_remove_legacy_config (
void);
107 static void config_load_dynamic_config (GKeyFile *ini);
108 static void config_save_dynamic_config (GKeyFile *ini);
110 static GKeyFile *config_get_settings (
void);
111 char *config_get_android_manufacturer (
void);
112 char *config_get_android_vendor_id (
void);
113 char *config_get_android_product (
void);
114 char *config_get_android_product_id (
void);
115 char *config_get_hidden_modes (
void);
116 char *config_get_mode_whitelist (
void);
117 int config_is_roaming_not_allowed (
void);
124 static int config_validate_ip(
const char *ipadd)
126 LOG_REGISTER_CONTEXT;
128 unsigned int b1, b2, b3, b4;
131 if (sscanf(ipadd,
"%3u.%3u.%3u.%3u%c", &b1, &b2, &b3, &b4, &c) != 4)
134 if ((b1 | b2 | b3 | b4) > 255)
136 if (strspn(ipadd,
"0123456789.") < strlen(ipadd))
142 char *config_find_mounts(
void)
144 LOG_REGISTER_CONTEXT;
148 ret = config_get_conf_string(FS_MOUNT_ENTRY, FS_MOUNT_KEY);
151 ret = g_strdup(FS_MOUNT_DEFAULT);
157 int config_find_sync(
void)
159 LOG_REGISTER_CONTEXT;
161 return config_get_conf_int(FS_SYNC_ENTRY, FS_SYNC_KEY);
164 char * config_find_alt_mount(
void)
166 LOG_REGISTER_CONTEXT;
168 return config_get_conf_string(ALT_MOUNT_ENTRY, ALT_MOUNT_KEY);
171 char * config_find_udev_path(
void)
173 LOG_REGISTER_CONTEXT;
175 return config_get_conf_string(UDEV_PATH_ENTRY, UDEV_PATH_KEY);
178 char * config_find_udev_subsystem(
void)
180 LOG_REGISTER_CONTEXT;
182 return config_get_conf_string(UDEV_PATH_ENTRY, UDEV_SUBSYSTEM_KEY);
185 char * config_check_trigger(
void)
187 LOG_REGISTER_CONTEXT;
189 return config_get_conf_string(TRIGGER_ENTRY, TRIGGER_PATH_KEY);
192 char * config_get_trigger_subsystem(
void)
194 LOG_REGISTER_CONTEXT;
196 return config_get_conf_string(TRIGGER_ENTRY, TRIGGER_UDEV_SUBSYSTEM);
199 char * config_get_trigger_mode(
void)
201 LOG_REGISTER_CONTEXT;
203 return config_get_conf_string(TRIGGER_ENTRY, TRIGGER_MODE_KEY);
206 char * config_get_trigger_property(
void)
208 LOG_REGISTER_CONTEXT;
210 return config_get_conf_string(TRIGGER_ENTRY, TRIGGER_PROPERTY_KEY);
213 char * config_get_trigger_value(
void)
215 LOG_REGISTER_CONTEXT;
217 return config_get_conf_string(TRIGGER_ENTRY, TRIGGER_PROPERTY_VALUE_KEY);
220 static char * config_get_network_ip(
void)
222 LOG_REGISTER_CONTEXT;
224 char * ip = config_get_kcmdline_string(NETWORK_IP_KEY);
226 if(!config_validate_ip(ip))
229 return config_get_conf_string(NETWORK_ENTRY, NETWORK_IP_KEY);
232 static char * config_get_network_interface(
void)
234 LOG_REGISTER_CONTEXT;
236 return config_get_conf_string(NETWORK_ENTRY, NETWORK_INTERFACE_KEY);
239 static char * config_get_network_gateway(
void)
241 LOG_REGISTER_CONTEXT;
243 char * gw = config_get_kcmdline_string(NETWORK_GATEWAY_KEY);
247 return config_get_conf_string(NETWORK_ENTRY, NETWORK_GATEWAY_KEY);
250 static char * config_get_network_netmask(
void)
252 LOG_REGISTER_CONTEXT;
254 char * netmask = config_get_kcmdline_string(NETWORK_NETMASK_KEY);
258 return config_get_conf_string(NETWORK_ENTRY, NETWORK_NETMASK_KEY);
261 static char * config_get_network_nat_interface(
void)
263 LOG_REGISTER_CONTEXT;
265 return config_get_conf_string(NETWORK_ENTRY, NETWORK_NAT_INTERFACE_KEY);
268 static int config_get_conf_int(
const gchar *entry,
const gchar *key)
270 LOG_REGISTER_CONTEXT;
273 GKeyFile *ini = config_get_settings();
275 gint val = g_key_file_get_integer(ini, entry, key, 0);
276 g_key_file_free(ini);
281 char *config_get_conf_string(
const gchar *entry,
const gchar *key)
283 LOG_REGISTER_CONTEXT;
286 GKeyFile *ini = config_get_settings();
288 gchar *val = g_key_file_get_string(ini, entry, key, 0);
289 g_key_file_free(ini);
294 static gchar *config_make_user_key_string(
const gchar *base_key, uid_t uid)
296 LOG_REGISTER_CONTEXT;
299 #ifdef SAILFISH_ACCESS_CONTROL
301 if( uid >= MIN_ADDITIONAL_USER && uid <= MAX_ADDITIONAL_USER )
302 key = g_strdup_printf(
"%s_%d", base_key, (
int)uid);
307 gchar *config_get_user_conf_string(
const gchar *entry,
const gchar *base_key, uid_t uid)
309 LOG_REGISTER_CONTEXT;
312 gchar *key = config_make_user_key_string(base_key, uid);
314 value = config_get_conf_string(entry, key);
317 value = config_get_conf_string(entry, base_key);
322 static char * config_get_kcmdline_string(
const char *entry)
324 LOG_REGISTER_CONTEXT;
332 gchar **arg_tokens = NULL, **network_tokens = NULL;
333 GError *optErr = NULL;
336 if ((fd = open(
"/proc/cmdline", O_RDONLY)) < 0)
338 log_debug(
"could not read /proc/cmdline");
342 len = read(fd, cmdLine,
sizeof cmdLine - 1);
347 log_debug(
"kernel command line was empty");
355 if (!g_shell_parse_argv(cmdLine, &argc, &argv, &optErr))
357 g_error_free(optErr);
362 for (i=0; i < argc; i++)
364 arg_tokens = g_strsplit(argv[i],
"=", 2);
365 if (!g_ascii_strcasecmp(arg_tokens[0],
"usb_moded_ip"))
367 network_tokens = g_strsplit(arg_tokens[1],
":", 7);
369 if(g_strrstr(network_tokens[5],
"usb")|| (g_strrstr(network_tokens[5],
"rndis")))
371 if(!strcmp(entry, NETWORK_IP_KEY))
373 g_free(ret), ret = g_strdup(network_tokens[0]);
374 log_debug(
"Command line ip = %s\n", ret);
376 if(!strcmp(entry, NETWORK_GATEWAY_KEY))
379 if(strlen(network_tokens[2]) > 2)
381 g_free(ret), ret = g_strdup(network_tokens[2]);
382 log_debug(
"Command line gateway = %s\n", ret);
385 if(!strcmp(entry, NETWORK_NETMASK_KEY))
387 g_free(ret), ret = g_strdup(network_tokens[3]);
388 log_debug(
"Command line netmask = %s\n", ret);
392 g_strfreev(arg_tokens);
395 g_strfreev(network_tokens);
400 char * config_get_mode_setting(uid_t uid)
402 LOG_REGISTER_CONTEXT;
407 if( (mode = config_get_kcmdline_string(MODE_SETTING_KEY)) )
410 mode = config_get_user_conf_string(MODE_SETTING_ENTRY, MODE_SETTING_KEY, uid);
417 log_warning(
"default mode '%s' is not valid for uid '%d', reset to '%s'",
419 g_free(mode), mode = g_strdup(
MODE_ASK);
420 config_set_mode_setting(mode, uid);
427 set_config_result_t config_set_config_setting(
const char *entry,
const char *key,
const char *value)
429 LOG_REGISTER_CONTEXT;
433 GKeyFile *static_ini = g_key_file_new();
434 GKeyFile *active_ini = g_key_file_new();
439 config_load_static_config(static_ini);
442 config_merge_data(active_ini, static_ini);
443 config_load_dynamic_config(active_ini);
445 prev = g_key_file_get_string(active_ini, entry, key, 0);
446 if( g_strcmp0(prev, value) ) {
447 g_key_file_set_string(active_ini, entry, key, value);
453 config_purge_data(active_ini, static_ini);
456 config_save_dynamic_config(active_ini);
459 g_key_file_free(active_ini);
460 g_key_file_free(static_ini);
465 set_config_result_t config_set_user_config_setting(
const char *entry,
const char *base_key,
const char *value, uid_t uid)
467 LOG_REGISTER_CONTEXT;
469 gchar *key = config_make_user_key_string(base_key, uid);
477 LOG_REGISTER_CONTEXT;
484 if (!usbmoded_is_mode_permitted(mode, uid))
487 return config_set_user_config_setting(MODE_SETTING_ENTRY,
488 MODE_SETTING_KEY, mode, uid);
493 static char * config_make_modes_string(
const char *key,
const char *mode_name,
int include)
495 LOG_REGISTER_CONTEXT;
499 gchar **modes_arr = 0;
500 GString *modes_tmp = 0;
504 modes_old = config_get_conf_string(MODE_SETTING_ENTRY, key);
507 modes_old = g_strdup(
"");
510 modes_arr = g_strsplit(modes_old,
",", 0);
512 modes_tmp = g_string_new(NULL);
514 for(i = 0; modes_arr[i] != NULL; i++)
516 if(strlen(modes_arr[i]) == 0)
522 if(!strcmp(modes_arr[i], mode_name))
532 if(modes_tmp->len > 0)
533 modes_tmp = g_string_append(modes_tmp,
",");
534 modes_tmp = g_string_append(modes_tmp, modes_arr[i]);
540 if(modes_tmp->len > 0)
541 modes_tmp = g_string_append(modes_tmp,
",");
542 modes_tmp = g_string_append(modes_tmp, mode_name);
545 modes_new = g_string_free(modes_tmp, FALSE), modes_tmp = 0;
547 g_strfreev(modes_arr), modes_arr = 0;
549 g_free(modes_old), modes_old = 0;
556 LOG_REGISTER_CONTEXT;
560 char *hidden_modes = config_make_modes_string(MODE_HIDE_KEY, mode, 1);
563 ret = config_set_config_setting(MODE_SETTING_ENTRY, MODE_HIDE_KEY, hidden_modes);
572 g_free(hidden_modes);
579 LOG_REGISTER_CONTEXT;
583 char *hidden_modes = config_make_modes_string(MODE_HIDE_KEY, mode, 0);
586 ret = config_set_config_setting(MODE_SETTING_ENTRY, MODE_HIDE_KEY, hidden_modes);
595 g_free(hidden_modes);
602 LOG_REGISTER_CONTEXT;
604 set_config_result_t ret = config_set_config_setting(MODE_SETTING_ENTRY, MODE_WHITELIST_KEY, whitelist);
608 char *mode_setting = config_get_mode_setting(current_user);
610 config_set_mode_setting(
MODE_ASK, current_user);
611 g_free(mode_setting);
624 LOG_REGISTER_CONTEXT;
628 char *whitelist = config_make_modes_string(MODE_WHITELIST_KEY, mode, allowed);
630 ret = config_set_mode_whitelist(whitelist ?:
"");
637 #ifdef SAILFISH_ACCESS_CONTROL
638 char *config_get_group_for_mode(
const char *mode)
640 LOG_REGISTER_CONTEXT;
642 char *group = config_get_conf_string(MODE_GROUP_ENTRY, mode);
645 group = g_strdup(
"sailfish-system");
657 LOG_REGISTER_CONTEXT;
659 if(!strcmp(config, NETWORK_IP_KEY) || !strcmp(config, NETWORK_GATEWAY_KEY))
660 if(config_validate_ip(setting) != 0)
663 if(!strcmp(config, NETWORK_IP_KEY) || !strcmp(config, NETWORK_INTERFACE_KEY) || !strcmp(config, NETWORK_GATEWAY_KEY))
665 return config_set_config_setting(NETWORK_ENTRY, config, setting);
671 char *config_get_network_setting(
const char *config)
673 LOG_REGISTER_CONTEXT;
679 if( !g_strcmp0(config, NETWORK_IP_KEY) ) {
680 if( !(ret = config_get_network_ip()) )
681 ret = g_strdup(
"192.168.2.15");
683 else if( !g_strcmp0(config, NETWORK_INTERFACE_KEY)) {
686 if( (ret = config_get_network_interface()) )
696 ret = g_strdup(
"usb0");
698 else if( !g_strcmp0(config, NETWORK_GATEWAY_KEY) ) {
699 ret = config_get_network_gateway();
701 else if( !g_strcmp0(config, NETWORK_NETMASK_KEY) ) {
702 if( !(ret = config_get_network_netmask()) )
703 ret = g_strdup(
"255.255.255.0");
705 else if( !g_strcmp0(config, NETWORK_NAT_INTERFACE_KEY) ) {
706 ret = config_get_network_nat_interface();
728 static void config_merge_key(GKeyFile *dest, GKeyFile *srce,
729 const char *grp,
const char *key)
731 LOG_REGISTER_CONTEXT;
733 gchar *val = g_key_file_get_value(srce, grp, key, 0);
736 g_key_file_set_value(dest, grp, key, val);
748 static void config_merge_group(GKeyFile *dest, GKeyFile *srce,
751 LOG_REGISTER_CONTEXT;
753 gchar **key = g_key_file_get_keys(srce, grp, 0, 0);
755 for(
size_t i = 0; key[i]; ++i )
756 config_merge_key(dest, srce, grp, key[i]);
767 static void config_merge_data(GKeyFile *dest, GKeyFile *srce)
769 LOG_REGISTER_CONTEXT;
771 gchar **grp = g_key_file_get_groups(srce, 0);
774 for(
size_t i = 0; grp[i]; ++i )
775 config_merge_group(dest, srce, grp[i]);
780 static void config_purge_data(GKeyFile *dest, GKeyFile *srce)
782 LOG_REGISTER_CONTEXT;
785 gchar **group = g_key_file_get_groups(srce, &groups);
786 for( gsize g = 0; g < groups; ++g ) {
788 gchar **key = g_key_file_get_keys(srce, group[g], &keys, 0);
789 for( gsize k = 0; k < keys; ++k ) {
790 gchar *cur_val = g_key_file_get_value(dest, group[g], key[k], 0);
794 gchar *def_val = g_key_file_get_value(srce, group[g], key[k], 0);
796 if( !g_strcmp0(cur_val, def_val) ) {
797 log_debug(
"purge redundant: [%s] %s = %s",
798 group[g], key[k], cur_val);
799 g_key_file_remove_key(dest, group[g], key[k], 0);
809 static void config_purge_empty_groups(GKeyFile *dest)
811 LOG_REGISTER_CONTEXT;
814 gchar **group = g_key_file_get_groups(dest, &groups);
815 for( gsize g = 0; g < groups; ++g ) {
817 gchar **key = g_key_file_get_keys(dest, group[g], &keys, 0);
819 log_debug(
"purge redundant group: [%s]", group[g]);
820 g_key_file_remove_group(dest, group[g], 0);
835 static int config_glob_error_cb(
const char *path,
int err)
837 LOG_REGISTER_CONTEXT;
839 log_debug(
"%s: glob: %s", path, g_strerror(err));
843 static bool config_merge_from_file(GKeyFile *ini,
const char *path)
845 LOG_REGISTER_CONTEXT;
849 GKeyFile *tmp = g_key_file_new();
851 if( !g_key_file_load_from_file(tmp, path, 0, &err) ) {
852 log_debug(
"%s: can't load: %s", path, err->message);
855 config_merge_data(ini, tmp);
859 g_key_file_free(tmp);
863 static void config_load_static_config(GKeyFile *ini)
865 LOG_REGISTER_CONTEXT;
867 static const char pattern[] = USB_MODED_STATIC_CONFIG_DIR
"/*.ini";
871 if( glob(pattern, 0, config_glob_error_cb, &gb) != 0 )
872 log_debug(
"no configuration ini-files found");
875 g_key_file_set_string(ini, MODE_SETTING_ENTRY, MODE_SETTING_KEY,
MODE_ASK);
878 for(
size_t i = 0; i < gb.gl_pathc; ++i ) {
879 const char *path = gb.gl_pathv[i];
880 if( strcmp(path, USB_MODED_STATIC_CONFIG_FILE) )
881 config_merge_from_file(ini, path);
887 static bool config_load_legacy_config(GKeyFile *ini)
889 LOG_REGISTER_CONTEXT;
896 if( access(USB_MODED_STATIC_CONFIG_FILE, F_OK) == -1 )
911 if( access(USB_MODED_DYNAMIC_CONFIG_FILE, F_OK) == 0 ) {
912 log_warning(
"%s: has reappeared after settings migration",
913 USB_MODED_STATIC_CONFIG_FILE);
917 if( !config_merge_from_file(ini, USB_MODED_STATIC_CONFIG_FILE) )
926 gchar *val = g_key_file_get_value(ini, MODE_SETTING_ENTRY,
927 MODE_SETTING_KEY, 0);
930 g_key_file_remove_key(ini, MODE_SETTING_ENTRY,
931 MODE_SETTING_KEY, 0);
942 static void config_remove_legacy_config(
void)
944 LOG_REGISTER_CONTEXT;
951 if( access(USB_MODED_STATIC_CONFIG_FILE, F_OK) == -1 && errno == ENOENT ) {
954 else if( unlink(USB_MODED_STATIC_CONFIG_FILE) == -1 && errno != ENOENT ) {
955 log_warning(
"%s: can't remove stale config file: %m",
956 USB_MODED_STATIC_CONFIG_FILE);
960 static void config_load_dynamic_config(GKeyFile *ini)
962 LOG_REGISTER_CONTEXT;
964 config_merge_from_file(ini, USB_MODED_DYNAMIC_CONFIG_FILE);
967 static void config_save_dynamic_config(GKeyFile *ini)
969 LOG_REGISTER_CONTEXT;
971 gchar *current_dta = 0;
972 gchar *previous_dta = 0;
974 config_purge_empty_groups(ini);
975 current_dta = g_key_file_to_data(ini, 0, 0);
977 g_file_get_contents(USB_MODED_DYNAMIC_CONFIG_FILE, &previous_dta, 0, 0);
978 if( g_strcmp0(previous_dta, current_dta) ) {
980 if( mkdir(USB_MODED_DYNAMIC_CONFIG_DIR, 0755) == -1 && errno != EEXIST ) {
981 log_err(
"%s: can't create dir: %m", USB_MODED_DYNAMIC_CONFIG_DIR);
983 else if( !g_file_set_contents(USB_MODED_DYNAMIC_CONFIG_FILE,
984 current_dta, -1, &err) ) {
985 log_err(
"%s: can't save: %s", USB_MODED_DYNAMIC_CONFIG_FILE,
989 log_debug(
"%s: updated", USB_MODED_DYNAMIC_CONFIG_FILE);
992 config_remove_legacy_config();
998 g_free(previous_dta);
1009 LOG_REGISTER_CONTEXT;
1013 GKeyFile *legacy_ini = g_key_file_new();
1014 GKeyFile *static_ini = g_key_file_new();
1015 GKeyFile *active_ini = g_key_file_new();
1018 config_load_static_config(static_ini);
1021 if( config_load_legacy_config(legacy_ini) ) {
1022 config_purge_data(legacy_ini, static_ini);
1023 config_merge_data(active_ini, legacy_ini);
1027 config_load_dynamic_config(active_ini);
1030 config_purge_data(active_ini, static_ini);
1033 config_save_dynamic_config(active_ini);
1035 g_key_file_free(active_ini);
1036 g_key_file_free(static_ini);
1037 g_key_file_free(legacy_ini);
1042 static GKeyFile *config_get_settings(
void)
1044 LOG_REGISTER_CONTEXT;
1046 GKeyFile *ini = g_key_file_new();
1047 config_load_static_config(ini);
1048 config_load_dynamic_config(ini);
1052 char * config_get_android_manufacturer(
void)
1054 LOG_REGISTER_CONTEXT;
1066 return config_get_conf_string(ANDROID_ENTRY, ANDROID_MANUFACTURER_KEY);
1069 char * config_get_android_vendor_id(
void)
1071 LOG_REGISTER_CONTEXT;
1073 return config_get_conf_string(ANDROID_ENTRY, ANDROID_VENDOR_ID_KEY);
1076 char * config_get_android_product(
void)
1078 LOG_REGISTER_CONTEXT;
1090 return config_get_conf_string(ANDROID_ENTRY, ANDROID_PRODUCT_KEY);
1093 char * config_get_android_product_id(
void)
1095 LOG_REGISTER_CONTEXT;
1097 return config_get_conf_string(ANDROID_ENTRY, ANDROID_PRODUCT_ID_KEY);
1100 char * config_get_hidden_modes(
void)
1102 LOG_REGISTER_CONTEXT;
1104 return config_get_conf_string(MODE_SETTING_ENTRY, MODE_HIDE_KEY);
1106 char * config_get_mode_whitelist(
void)
1108 LOG_REGISTER_CONTEXT;
1110 return config_get_conf_string(MODE_SETTING_ENTRY, MODE_WHITELIST_KEY);
1113 int config_is_roaming_not_allowed(
void)
1115 LOG_REGISTER_CONTEXT;
1117 return config_get_conf_int(NETWORK_ENTRY, NO_ROAMING_KEY);
1125 #ifdef SAILFISH_ACCESS_CONTROL
1126 if (uid < MIN_ADDITIONAL_USER || uid > MAX_ADDITIONAL_USER) {
1127 log_err(
"Invalid uid value: %d\n", uid);
1132 GKeyFile *active_ini = g_key_file_new();
1133 config_load_dynamic_config(active_ini);
1135 char *key = config_make_user_key_string(MODE_SETTING_KEY, uid);
1137 if (g_key_file_remove_key(active_ini, MODE_SETTING_ENTRY, key, NULL))
1138 config_save_dynamic_config(active_ini);
1142 g_key_file_free(active_ini);