diff options
Diffstat (limited to 'libnm-core/nm-keyfile.c')
| -rw-r--r-- | libnm-core/nm-keyfile.c | 453 |
1 files changed, 111 insertions, 342 deletions
diff --git a/libnm-core/nm-keyfile.c b/libnm-core/nm-keyfile.c index c7d87869..c894e250 100644 --- a/libnm-core/nm-keyfile.c +++ b/libnm-core/nm-keyfile.c @@ -33,7 +33,6 @@ #include <string.h> #include <linux/pkt_sched.h> -#include "nm-utils/nm-secret-utils.h" #include "nm-common-macros.h" #include "nm-core-internal.h" #include "nm-keyfile-utils.h" @@ -120,49 +119,6 @@ setting_alias_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *k } static void -sriov_vfs_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key) -{ - const char *setting_name = nm_setting_get_name (setting); - gs_unref_ptrarray GPtrArray *vfs = NULL; - gs_strfreev char **keys = NULL; - gsize n_keys = 0; - int i; - - keys = nm_keyfile_plugin_kf_get_keys (info->keyfile, setting_name, &n_keys, NULL); - if (!keys || n_keys == 0) - return; - - vfs = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_sriov_vf_unref); - - for (i = 0; i < n_keys; i++) { - gs_free char *value = NULL; - NMSriovVF *vf; - const char *rest; - - if (!g_str_has_prefix (keys[i], "vf.")) - continue; - - rest = &keys[i][3]; - - if (!NM_STRCHAR_ALL (rest, ch, g_ascii_isdigit (ch))) - continue; - - value = nm_keyfile_plugin_kf_get_string (info->keyfile, - setting_name, - keys[i], - NULL); - - vf = _nm_utils_sriov_vf_from_strparts (rest, value, NULL); - if (vf) - g_ptr_array_add (vfs, vf); - } - - g_object_set (G_OBJECT (setting), - key, vfs, - NULL); -} - -static void read_array_of_uint (GKeyFile *file, NMSetting *setting, const char *key) @@ -775,7 +731,7 @@ ip6_addr_gen_mode_parser (KeyfileReaderInfo *info, NMSetting *setting, const cha } else addr_gen_mode = NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64; - g_object_set (G_OBJECT (setting), key, (int) addr_gen_mode, NULL); + g_object_set (G_OBJECT (setting), key, (gint) addr_gen_mode, NULL); } static void @@ -940,7 +896,7 @@ unescape_semicolons (char *str) i++; str[j++] = str[i++];; } - nm_explicit_bzero (&str[j], i - j); + str[j] = '\0'; return j; } @@ -951,10 +907,9 @@ get_bytes (KeyfileReaderInfo *info, gboolean zero_terminate, gboolean unescape_semicolon) { - nm_auto_free_secret char *tmp_string = NULL; + gs_free char *tmp_string = NULL; gboolean may_be_int_list = TRUE; gsize length; - GBytes *result; /* New format: just a string * Old format: integer list; e.g. 11;25;38; @@ -988,11 +943,12 @@ get_bytes (KeyfileReaderInfo *info, /* Try to parse the string as a integer list. */ if (may_be_int_list && length > 0) { - nm_auto_free_secret_buf NMSecretBuf *bin = NULL; + gs_free guint8 *bin_data = NULL; const char *const s = tmp_string; gsize i, d; + const gsize BIN_DATA_LEN = (length / 2 + 3); - bin = nm_secret_buf_new (length / 2 + 3); + bin_data = g_malloc (BIN_DATA_LEN); #define DIGIT(c) ((c) - '0') i = 0; @@ -1025,8 +981,8 @@ get_bytes (KeyfileReaderInfo *info, break; } - nm_assert (d < bin->len); - bin->bin[d++] = n; + bin_data[d++] = n; + nm_assert (d < BIN_DATA_LEN); /* allow whitespace after the digit. */ while (g_ascii_isspace (s[i])) @@ -1044,23 +1000,16 @@ get_bytes (KeyfileReaderInfo *info, * string format before. We expect that this conversion cannot fail. */ if (d > 0) { /* note that @zero_terminate does not add a terminating '\0' to - * binary data as an integer list. If the bytes are expressed as - * an integer list, all potential NUL characters are supposed to - * be included there explicitly. + * binary data as an integer list. * - * However, in the spirit of defensive programming, we do append a - * NUL character to the buffer, although this character is hidden - * and only a mitigation for bugs. */ - - if (d + 10 < bin->len) { - /* hm, too much unused memory. Copy the memory to a suitable - * sized buffer. */ - return nm_secret_copy_to_gbytes (bin->bin, d); - } - - nm_assert (d < bin->len); - bin->bin[d] = '\0'; - return nm_secret_buf_to_gbytes_take (g_steal_pointer (&bin), d); + * But we add a '\0' to the bin_data pointer, just to avoid somebody + * (erronously!) reading the binary data as C-string. + * + * @d itself does not entail the '\0'. */ + nm_assert (d + 1 <= BIN_DATA_LEN); + bin_data = g_realloc (bin_data, d + 1); + bin_data[d] = '\0'; + return g_bytes_new_take (g_steal_pointer (&bin_data), d); } } @@ -1071,13 +1020,8 @@ get_bytes (KeyfileReaderInfo *info, length++; if (length == 0) return NULL; - - result = g_bytes_new_with_free_func (tmp_string, - length, - (GDestroyNotify) nm_free_secret, - tmp_string); - tmp_string = NULL; - return result; + tmp_string = g_realloc (tmp_string, length + (zero_terminate ? 0 : 1)); + return g_bytes_new_take (g_steal_pointer (&tmp_string), length); } static void @@ -1121,12 +1065,12 @@ get_cert_path (const char *base_dir, const guint8 *cert_path, gsize cert_path_le g_return_val_if_fail (base_dir != NULL, NULL); g_return_val_if_fail (cert_path != NULL, NULL); - path = g_strndup ((char *) cert_path, cert_path_len); + base = path = g_malloc0 (cert_path_len + 1); + memcpy (path, cert_path, cert_path_len); if (path[0] == '/') return path; - base = path; p = strrchr (path, '/'); if (p) base = p + 1; @@ -1160,9 +1104,8 @@ nm_keyfile_detect_unqualified_path_scheme (const char *base_dir, const char *data = pdata; gboolean exists = FALSE; gsize validate_len; - gsize path_len, pathuri_len; gs_free char *path = NULL; - gs_free char *pathuri = NULL; + GByteArray *tmp; g_return_val_if_fail (base_dir && base_dir[0] == '/', NULL); @@ -1205,16 +1148,18 @@ nm_keyfile_detect_unqualified_path_scheme (const char *base_dir, * When returning TRUE, we must also be sure that @data_len does not look like * the deprecated format of list of integers. With this implementation that is the * case, as long as @consider_exists is FALSE. */ - path_len = strlen (path); - pathuri_len = (NM_STRLEN (NM_KEYFILE_CERT_SCHEME_PREFIX_PATH) + 1) + path_len; - pathuri = g_new (char, pathuri_len); - memcpy (pathuri, NM_KEYFILE_CERT_SCHEME_PREFIX_PATH, NM_STRLEN (NM_KEYFILE_CERT_SCHEME_PREFIX_PATH)); - memcpy (&pathuri[NM_STRLEN (NM_KEYFILE_CERT_SCHEME_PREFIX_PATH)], path, path_len + 1); - if (nm_setting_802_1x_check_cert_scheme (pathuri, pathuri_len, NULL) != NM_SETTING_802_1X_CK_SCHEME_PATH) + tmp = g_byte_array_sized_new (strlen (NM_KEYFILE_CERT_SCHEME_PREFIX_PATH) + strlen (path) + 1); + g_byte_array_append (tmp, (const guint8 *) NM_KEYFILE_CERT_SCHEME_PREFIX_PATH, strlen (NM_KEYFILE_CERT_SCHEME_PREFIX_PATH)); + g_byte_array_append (tmp, (const guint8 *) path, strlen (path) + 1); + if (nm_setting_802_1x_check_cert_scheme (tmp->data, tmp->len, NULL) != NM_SETTING_802_1X_CK_SCHEME_PATH) { + g_byte_array_unref (tmp); return NULL; + } + g_free (path); + path = (char *) g_byte_array_free (tmp, FALSE); NM_SET_OUT (out_exists, exists); - return g_steal_pointer (&pathuri); + return g_steal_pointer (&path); } #define HAS_SCHEME_PREFIX(bin, bin_len, scheme) \ @@ -1448,7 +1393,7 @@ qdisc_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key) { const char *setting_name = nm_setting_get_name (setting); GPtrArray *qdiscs; - gs_strfreev char **keys = NULL; + gs_strfreev gchar **keys = NULL; gsize n_keys = 0; int i; @@ -1496,7 +1441,7 @@ tfilter_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key) { const char *setting_name = nm_setting_get_name (setting); GPtrArray *tfilters; - gs_strfreev char **keys = NULL; + gs_strfreev gchar **keys = NULL; gsize n_keys = 0; int i; @@ -1565,37 +1510,6 @@ setting_alias_writer (KeyfileWriterInfo *info, } static void -sriov_vfs_writer (KeyfileWriterInfo *info, - NMSetting *setting, - const char *key, - const GValue *value) -{ - GPtrArray *vfs; - guint i; - - vfs = g_value_get_boxed (value); - if (!vfs) - return; - - for (i = 0; i < vfs->len; i++) { - const NMSriovVF *vf = vfs->pdata[i]; - gs_free char *kf_value = NULL; - char kf_key[32]; - - kf_value = nm_utils_sriov_vf_to_str (vf, TRUE, NULL); - if (!kf_value) - continue; - - nm_sprintf_buf (kf_key, "vf.%u", nm_sriov_vf_get_index (vf)); - - nm_keyfile_plugin_kf_set_string (info->keyfile, - nm_setting_get_name (setting), - kf_key, - kf_value); - } -} - -static void write_array_of_uint (GKeyFile *file, NMSetting *setting, const char *key, @@ -1611,7 +1525,7 @@ write_array_of_uint (GKeyFile *file, g_return_if_fail (g_array_get_element_size (array) == sizeof (guint)); - tmp_array = g_new (int, array->len); + tmp_array = g_new (gint, array->len); for (i = 0; i < array->len; i++) { guint v = g_array_index (array, guint, i); @@ -2108,16 +2022,18 @@ typedef struct { }) typedef struct { + const char *setting_name; const ParseInfoProperty*const*properties; } ParseInfoSetting; -#define PARSE_INFO_SETTING(setting_type, ...) \ - [setting_type] = (&((const ParseInfoSetting) { \ +#define PARSE_INFO_SETTING(_setting_name, ...) \ + { \ + .setting_name = _setting_name, \ __VA_ARGS__ \ - })) + } -static const ParseInfoSetting *const parse_infos[_NM_META_SETTING_TYPE_NUM] = { - PARSE_INFO_SETTING (NM_META_SETTING_TYPE_WIRELESS, +static const ParseInfoSetting parse_infos[] = { + PARSE_INFO_SETTING (NM_SETTING_WIRELESS_SETTING_NAME, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_WIRELESS_BSSID, .parser = mac_address_parser_ETHER, @@ -2134,7 +2050,7 @@ static const ParseInfoSetting *const parse_infos[_NM_META_SETTING_TYPE_NUM] = { ), ), ), - PARSE_INFO_SETTING (NM_META_SETTING_TYPE_802_1X, + PARSE_INFO_SETTING (NM_SETTING_802_1X_SETTING_NAME, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_802_1X_CA_CERT, .parser = cert_parser, @@ -2166,7 +2082,7 @@ static const ParseInfoSetting *const parse_infos[_NM_META_SETTING_TYPE_NUM] = { ), ), ), - PARSE_INFO_SETTING (NM_META_SETTING_TYPE_WIRED, + PARSE_INFO_SETTING (NM_SETTING_WIRED_SETTING_NAME, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_WIRED_CLONED_MAC_ADDRESS, .parser = mac_address_parser_ETHER_cloned, @@ -2176,28 +2092,28 @@ static const ParseInfoSetting *const parse_infos[_NM_META_SETTING_TYPE_NUM] = { ), ), ), - PARSE_INFO_SETTING (NM_META_SETTING_TYPE_BLUETOOTH, + PARSE_INFO_SETTING (NM_SETTING_BLUETOOTH_SETTING_NAME, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_BLUETOOTH_BDADDR, .parser = mac_address_parser_ETHER, ), ), ), - PARSE_INFO_SETTING (NM_META_SETTING_TYPE_BOND, + PARSE_INFO_SETTING (NM_SETTING_BOND_SETTING_NAME, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_BOND_OPTIONS, .parser_no_check_key = TRUE, ), ), ), - PARSE_INFO_SETTING (NM_META_SETTING_TYPE_BRIDGE, + PARSE_INFO_SETTING (NM_SETTING_BRIDGE_SETTING_NAME, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_BRIDGE_MAC_ADDRESS, .parser = mac_address_parser_ETHER, ), ), ), - PARSE_INFO_SETTING (NM_META_SETTING_TYPE_CONNECTION, + PARSE_INFO_SETTING (NM_SETTING_CONNECTION_SETTING_NAME, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_CONNECTION_READ_ONLY, .parser_skip = TRUE, @@ -2209,14 +2125,14 @@ static const ParseInfoSetting *const parse_infos[_NM_META_SETTING_TYPE_NUM] = { ), ), ), - PARSE_INFO_SETTING (NM_META_SETTING_TYPE_INFINIBAND, + PARSE_INFO_SETTING (NM_SETTING_INFINIBAND_SETTING_NAME, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_INFINIBAND_MAC_ADDRESS, .parser = mac_address_parser_INFINIBAND, ), ), ), - PARSE_INFO_SETTING (NM_META_SETTING_TYPE_IP4_CONFIG, + PARSE_INFO_SETTING (NM_SETTING_IP4_CONFIG_SETTING_NAME, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_IP_CONFIG_ADDRESSES, .parser_no_check_key = TRUE, @@ -2238,7 +2154,7 @@ static const ParseInfoSetting *const parse_infos[_NM_META_SETTING_TYPE_NUM] = { ), ), ), - PARSE_INFO_SETTING (NM_META_SETTING_TYPE_IP6_CONFIG, + PARSE_INFO_SETTING (NM_SETTING_IP6_CONFIG_SETTING_NAME, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE, .parser_no_check_key = TRUE, @@ -2266,23 +2182,14 @@ static const ParseInfoSetting *const parse_infos[_NM_META_SETTING_TYPE_NUM] = { ), ), ), - PARSE_INFO_SETTING (NM_META_SETTING_TYPE_SERIAL, + PARSE_INFO_SETTING (NM_SETTING_SERIAL_SETTING_NAME, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_SERIAL_PARITY, .parser = parity_parser, ), ), ), - PARSE_INFO_SETTING (NM_META_SETTING_TYPE_SRIOV, - PARSE_INFO_PROPERTIES ( - PARSE_INFO_PROPERTY (NM_SETTING_SRIOV_VFS, - .parser_no_check_key = TRUE, - .parser = sriov_vfs_parser, - .writer = sriov_vfs_writer, - ), - ), - ), - PARSE_INFO_SETTING (NM_META_SETTING_TYPE_TC_CONFIG, + PARSE_INFO_SETTING (NM_SETTING_TC_CONFIG_SETTING_NAME, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_TC_CONFIG_QDISCS, .parser_no_check_key = TRUE, @@ -2296,7 +2203,7 @@ static const ParseInfoSetting *const parse_infos[_NM_META_SETTING_TYPE_NUM] = { ), ), ), - PARSE_INFO_SETTING (NM_META_SETTING_TYPE_TEAM, + PARSE_INFO_SETTING (NM_SETTING_TEAM_SETTING_NAME, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_TEAM_CONFIG, .parser = team_config_parser, @@ -2363,7 +2270,7 @@ static const ParseInfoSetting *const parse_infos[_NM_META_SETTING_TYPE_NUM] = { ), ), ), - PARSE_INFO_SETTING (NM_META_SETTING_TYPE_TEAM_PORT, + PARSE_INFO_SETTING (NM_SETTING_TEAM_PORT_SETTING_NAME, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_TEAM_CONFIG, .parser = team_config_parser, @@ -2394,21 +2301,21 @@ static const ParseInfoSetting *const parse_infos[_NM_META_SETTING_TYPE_NUM] = { ), ), ), - PARSE_INFO_SETTING (NM_META_SETTING_TYPE_USER, + PARSE_INFO_SETTING (NM_SETTING_USER_SETTING_NAME, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_USER_DATA, .parser_no_check_key = TRUE, ), ), ), - PARSE_INFO_SETTING (NM_META_SETTING_TYPE_VLAN, + PARSE_INFO_SETTING (NM_SETTING_VLAN_SETTING_NAME, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_VLAN_FLAGS, .writer_persist_default = TRUE, ), ), ), - PARSE_INFO_SETTING (NM_META_SETTING_TYPE_VPN, + PARSE_INFO_SETTING (NM_SETTING_VPN_SETTING_NAME, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_VPN_DATA, .parser_no_check_key = TRUE, @@ -2430,7 +2337,7 @@ static const ParseInfoSetting *const parse_infos[_NM_META_SETTING_TYPE_NUM] = { ), ), ), - PARSE_INFO_SETTING (NM_META_SETTING_TYPE_WIMAX, + PARSE_INFO_SETTING (NM_SETTING_WIMAX_SETTING_NAME, PARSE_INFO_PROPERTIES ( PARSE_INFO_PROPERTY (NM_SETTING_WIMAX_MAC_ADDRESS, .parser = mac_address_parser_ETHER, @@ -2440,24 +2347,21 @@ static const ParseInfoSetting *const parse_infos[_NM_META_SETTING_TYPE_NUM] = { }; static const ParseInfoProperty * -_parse_info_find (NMSetting *setting, - const char *property_name, - const char **out_setting_name) +_parse_info_find (const char *setting_name, const char *property_name) { - const NMMetaSettingInfo *setting_info; - const ParseInfoSetting *pis; gssize idx; -#if NM_MORE_ASSERTS > 10 +#if NM_MORE_ASSERTS > 5 { guint i, j; for (i = 0; i < G_N_ELEMENTS (parse_infos); i++) { - pis = parse_infos[i]; - - if (!pis) - continue; + const ParseInfoSetting *pis = &parse_infos[i]; + g_assert (pis->setting_name); + if ( i > 0 + && strcmp (pis[-1].setting_name, pis->setting_name) >= 0) + g_error ("Wrong order at index #%d: \"%s\" before \"%s\"", i - 1, pis[-1].setting_name, pis->setting_name); g_assert (pis->properties); g_assert (pis->properties[0]); for (j = 0; pis->properties[j]; j++) { @@ -2467,35 +2371,31 @@ _parse_info_find (NMSetting *setting, g_assert (pip->property_name); if ( j > 0 && (pip0 = pis->properties[j - 1]) - && strcmp (pip0->property_name, pip->property_name) >= 0) { - g_error ("Wrong order at index #%d.%d: \"%s.%s\" before \"%s.%s\"", - i, j - 1, - nm_meta_setting_infos[i].setting_name, pip0->property_name, - nm_meta_setting_infos[i].setting_name, pip->property_name); - } + && strcmp (pip0->property_name, pip->property_name) >= 0) + g_error ("Wrong order at index #%d.%d: \"%s.%s\" before \"%s.%s\"", i, j - 1, pis->setting_name, pip0->property_name, pis->setting_name, pip->property_name); } } } #endif - if ( !NM_IS_SETTING (setting) - || !(setting_info = NM_SETTING_GET_CLASS (setting)->setting_info)) { - /* handle invalid setting objects gracefully. */ - *out_setting_name = NULL; - return NULL; - } - - *out_setting_name = setting_info->setting_name; - - if ((pis = parse_infos[setting_info->meta_type])) { - G_STATIC_ASSERT_EXPR (G_STRUCT_OFFSET (ParseInfoProperty, property_name) == 0); - idx = nm_utils_ptrarray_find_binary_search ((gconstpointer *) pis->properties, - NM_PTRARRAY_LEN (pis->properties), - &property_name, - nm_strcmp_p_with_data, - NULL, - NULL, - NULL); + G_STATIC_ASSERT_EXPR (G_STRUCT_OFFSET (ParseInfoSetting, setting_name) == 0); + idx = _nm_utils_array_find_binary_search (parse_infos, + sizeof (ParseInfoSetting), + G_N_ELEMENTS (parse_infos), + &setting_name, + nm_strcmp_p_with_data, + NULL); + if (idx >= 0) { + const ParseInfoSetting *pis = &parse_infos[idx]; + + nm_assert (nm_streq (pis->setting_name, setting_name)); + idx = _nm_utils_ptrarray_find_binary_search ((gconstpointer *) pis->properties, + NM_PTRARRAY_LEN (pis->properties), + &property_name, + nm_strcmp_p_with_data, + NULL, + NULL, + NULL); if (idx >= 0) return pis->properties[idx]; } @@ -2526,9 +2426,9 @@ read_one_setting_value (NMSetting *setting, if (!(flags & G_PARAM_WRITABLE)) return; - pip = _parse_info_find (setting, key, &setting_name); + setting_name = nm_setting_get_name (setting); - nm_assert (setting_name); + pip = _parse_info_find (setting_name, key); if ( !pip && nm_streq (key, NM_SETTING_NAME)) @@ -2621,7 +2521,7 @@ read_one_setting_value (NMSetting *setting, } else g_object_set (setting, key, int_val, NULL); } else if (type == G_TYPE_BYTES) { - int *tmp; + gint *tmp; GByteArray *array; GBytes *bytes; gsize length; @@ -2654,7 +2554,7 @@ read_one_setting_value (NMSetting *setting, g_bytes_unref (bytes); g_free (tmp); } else if (type == G_TYPE_STRV) { - char **sa; + gchar **sa; gsize length; sa = nm_keyfile_plugin_kf_get_string_list (keyfile, setting_name, key, &length, NULL); @@ -2680,11 +2580,11 @@ read_one_setting_value (NMSetting *setting, } } } else if (G_VALUE_HOLDS_ENUM (value)) { - int int_val; + gint int_val; int_val = nm_keyfile_plugin_kf_get_integer (keyfile, setting_name, key, &err); if (!err) - g_object_set (setting, key, (int) int_val, NULL); + g_object_set (setting, key, (gint) int_val, NULL); } else { if (!handle_warn (info, key, NM_KEYFILE_WARN_SEVERITY_WARN, _("unhandled setting property type '%s'"), @@ -2696,8 +2596,6 @@ read_one_setting_value (NMSetting *setting, static NMSetting * read_setting (KeyfileReaderInfo *info) { - const NMSettInfoSetting *sett_info; - gs_unref_object NMSetting *setting = NULL; const char *alias; GType type; @@ -2706,92 +2604,22 @@ read_setting (KeyfileReaderInfo *info) alias = info->group; type = nm_setting_lookup_type (alias); - if (!type) { - handle_warn (info, NULL, NM_KEYFILE_WARN_SEVERITY_WARN, - _("invalid setting name '%s'"), info->group); - return NULL; - } + if (type) { + NMSetting *setting = g_object_new (type, NULL); - setting = g_object_new (type, NULL); - - info->setting = setting; - - sett_info = _nm_sett_info_setting_get (NM_SETTING_GET_CLASS (setting)); - - if (sett_info->detail.gendata_info) { - gs_free char **keys = NULL; - gsize i, n_keys; - - keys = g_key_file_get_keys (info->keyfile, info->group, &n_keys, NULL); - if (n_keys > 0) { - GHashTable *h = _nm_setting_gendata_hash (setting, TRUE); - - nm_utils_strv_sort (keys, n_keys); - for (i = 0; i < n_keys; i++) { - gs_free char *key = keys[i]; - gs_free_error GError *local = NULL; - const GVariantType *variant_type; - GVariant *variant; - - /* a GKeyfile can return duplicate keys, there is just no API to make sense - * of them. Skip them. */ - if ( i + 1 < n_keys - && nm_streq (key, keys[i + 1])) - continue; - - /* currently, the API is very simple. The setting class just returns - * the desired variant type, and keyfile reader will try to parse - * it accordingly. Note, that this does currently not allow, that - * a particular key can contain different variant types, nor is it - * very flexible in general. - * - * We add flexibility when we need it. Keep it simple for now. */ - variant_type = sett_info->detail.gendata_info->get_variant_type (sett_info, - key, - &local); - if (!variant_type) { - if (!handle_warn (info, key, NM_KEYFILE_WARN_SEVERITY_WARN, - _("invalid key '%s.%s'"), - info->group, key)) - break; - continue; - } - - if (g_variant_type_equal (variant_type, G_VARIANT_TYPE_BOOLEAN)) { - gboolean v; - - v = g_key_file_get_boolean (info->keyfile, - info->group, - key, - &local); - if (local) { - if (!handle_warn (info, key, NM_KEYFILE_WARN_SEVERITY_WARN, - _("key '%s.%s' is not boolean"), - info->group, key)) - break; - continue; - } - variant = g_variant_new_boolean (v); - } else { - nm_assert_not_reached (); - continue; - } - - g_hash_table_insert (h, - g_steal_pointer (&key), - g_variant_take_ref (variant)); - } - for (; i < n_keys; i++) - g_free (keys[i]); - } - } else + info->setting = setting; nm_setting_enumerate_values (setting, read_one_setting_value, info); + info->setting = NULL; + if (!info->error) + return setting; - info->setting = NULL; + g_object_unref (setting); + } else { + handle_warn (info, NULL, NM_KEYFILE_WARN_SEVERITY_WARN, + _("invalid setting name '%s'"), info->group); + } - if (info->error) - return NULL; - return g_steal_pointer (&setting); + return NULL; } static void @@ -2846,7 +2674,7 @@ nm_keyfile_read (GKeyFile *keyfile, gs_unref_object NMConnection *connection = NULL; NMSettingConnection *s_con; NMSetting *setting; - char **groups; + gchar **groups; gsize length; int i; gboolean vpn_secrets = FALSE; @@ -2866,7 +2694,7 @@ nm_keyfile_read (GKeyFile *keyfile, base_dir = base_dir_free = g_get_current_dir (); } } else - g_return_val_if_fail (base_dir[0] == '/', NULL); + g_return_val_if_fail ("/", NULL); connection = nm_simple_connection_new (); @@ -2972,22 +2800,12 @@ write_setting_value (NMSetting *setting, if (info->error) return; + setting_name = nm_setting_get_name (setting); + pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), key); nm_assert (pspec); - pip = _parse_info_find (setting, key, &setting_name); - - if (!setting_name) { - /* the setting type is unknown. That is highly unexpected - * (and as this is currently only called from NetworkManager - * daemon, not possible). - * - * Still, handle it gracefully, because later keyfile writer will become - * public API of libnm, where @setting is (untrusted) user input. - * - * Gracefully here just means: ignore the setting. */ - return; - } + pip = _parse_info_find (setting_name, key); if ( !pip && nm_streq (key, NM_SETTING_NAME)) @@ -3061,7 +2879,7 @@ write_setting_value (NMSetting *setting, char **array; array = (char **) g_value_get_boxed (value); - nm_keyfile_plugin_kf_set_string_list (info->keyfile, setting_name, key, (const char **const) array, g_strv_length (array)); + nm_keyfile_plugin_kf_set_string_list (info->keyfile, setting_name, key, (const gchar **const) array, g_strv_length (array)); } else if (type == G_TYPE_HASH_TABLE) { write_hash_of_string (info->keyfile, setting, key, value); } else if (type == G_TYPE_ARRAY) { @@ -3070,7 +2888,7 @@ write_setting_value (NMSetting *setting, /* Flags are guint but GKeyFile has no uint reader, just uint64 */ nm_keyfile_plugin_kf_set_uint64 (info->keyfile, setting_name, key, (guint64) g_value_get_flags (value)); } else if (G_VALUE_HOLDS_ENUM (value)) - nm_keyfile_plugin_kf_set_integer (info->keyfile, setting_name, key, (int) g_value_get_enum (value)); + nm_keyfile_plugin_kf_set_integer (info->keyfile, setting_name, key, (gint) g_value_get_enum (value)); else g_warn_if_reached (); } @@ -3082,8 +2900,6 @@ nm_keyfile_write (NMConnection *connection, GError **error) { KeyfileWriterInfo info = { 0 }; - gs_free NMSetting **settings = NULL; - guint i, length = 0; g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); g_return_val_if_fail (!error || !*error, NULL); @@ -3096,59 +2912,12 @@ nm_keyfile_write (NMConnection *connection, info.error = NULL; info.handler = handler; info.user_data = user_data; - - settings = nm_connection_get_settings (connection, &length); - for (i = 0; i < length; i++) { - const NMSettInfoSetting *sett_info; - NMSetting *setting = settings[i]; - - sett_info = _nm_sett_info_setting_get (NM_SETTING_GET_CLASS (setting)); - - if (sett_info->detail.gendata_info) { - guint k, n_keys; - const char *const*keys; - - nm_assert (!nm_keyfile_plugin_get_alias_for_setting_name (sett_info->setting_class->setting_info->setting_name)); - - n_keys = _nm_setting_gendata_get_all (setting, &keys, NULL); - - if (n_keys > 0) { - const char *setting_name = sett_info->setting_class->setting_info->setting_name; - GHashTable *h = _nm_setting_gendata_hash (setting, FALSE); - - for (k = 0; k < n_keys; k++) { - const char *key = keys[k]; - GVariant *v; - - v = g_hash_table_lookup (h, key); - - if (g_variant_is_of_type (v, G_VARIANT_TYPE_BOOLEAN)) { - g_key_file_set_boolean (info.keyfile, - setting_name, - key, - g_variant_get_boolean (v)); - } else { - /* BUG: The variant type is not implemented. Since the connection - * verifies, this can only mean we either wrongly didn't reject - * the connection as invalid, or we didn't properly implement the - * variant type. */ - nm_assert_not_reached (); - continue; - } - } - } - } else - nm_setting_enumerate_values (setting, write_setting_value, &info); - - if (info.error) - break; - } + nm_connection_for_each_setting_value (connection, write_setting_value, &info); if (info.error) { g_propagate_error (error, info.error); g_key_file_unref (info.keyfile); return NULL; } - return info.keyfile; } |