diff options
Diffstat (limited to 'libnm-core')
| -rw-r--r-- | libnm-core/nm-keyfile.c | 100 | ||||
| -rw-r--r-- | libnm-core/nm-setting-wired.c | 2 | ||||
| -rw-r--r-- | libnm-core/tests/test-setting.c | 69 |
3 files changed, 131 insertions, 40 deletions
diff --git a/libnm-core/nm-keyfile.c b/libnm-core/nm-keyfile.c index b0c7a134..43253acf 100644 --- a/libnm-core/nm-keyfile.c +++ b/libnm-core/nm-keyfile.c @@ -1359,6 +1359,9 @@ nm_keyfile_detect_unqualified_path_scheme (const char *base_dir, */ path = get_cert_path (base_dir, (const guint8 *) data, data_len); + + /* FIXME(keyfile-parse-in-memory): it is wrong that keyfile reader makes decisions based on + * the file systems content. The serialization/parsing should be entirely in-memory. */ if ( !memchr (data, '/', data_len) && !has_cert_ext (path)) { if (!consider_exists) @@ -1439,6 +1442,10 @@ cert_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key) path2 = path2_free; } + /* FIXME(keyfile-parse-in-memory): keyfile reader must not access the file system and + * (in a first step) only operate in memory-only. If the presence of files should be checked, + * then by invoking a callback (and possibly keyfile settings plugin would + * collect the file names to be checked and check them later). */ if (!g_file_test (path2, G_FILE_TEST_EXISTS)) { handle_warn (info, key, NM_KEYFILE_WARN_SEVERITY_INFO_MISSING_FILE, _("certificate or key file '%s' does not exist"), @@ -2896,41 +2903,48 @@ static const ParseInfoSetting *const parse_infos[_NM_META_SETTING_TYPE_NUM] = { ), }; -static const ParseInfoProperty * +static void _parse_info_find (NMSetting *setting, const char *property_name, - const NMMetaSettingInfo **out_setting_info) + const NMMetaSettingInfo **out_setting_info, + const ParseInfoSetting **out_parse_info_setting, + const ParseInfoProperty **out_parse_info_property) { const NMMetaSettingInfo *setting_info; const ParseInfoSetting *pis; - gssize idx; + const ParseInfoProperty *pip; #if NM_MORE_ASSERTS > 10 { guint i, j; + static int asserted = FALSE; - for (i = 0; i < G_N_ELEMENTS (parse_infos); i++) { - pis = parse_infos[i]; + if (!asserted) { + for (i = 0; i < G_N_ELEMENTS (parse_infos); i++) { + pis = parse_infos[i]; - if (!pis) - continue; + if (!pis) + continue; + if (!pis->properties) + continue; - g_assert (pis->properties); - g_assert (pis->properties[0]); - for (j = 0; pis->properties[j]; j++) { - const ParseInfoProperty *pip0; - const ParseInfoProperty *pip = pis->properties[j]; - - 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); + g_assert (pis->properties[0]); + for (j = 0; pis->properties[j]; j++) { + const ParseInfoProperty *pip0; + const ParseInfoProperty *pipj = pis->properties[j]; + + g_assert (pipj->property_name); + if ( j > 0 + && (pip0 = pis->properties[j - 1]) + && strcmp (pip0->property_name, pipj->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, pipj->property_name); + } } } + asserted = TRUE; } } #endif @@ -2938,16 +2952,25 @@ _parse_info_find (NMSetting *setting, if ( !NM_IS_SETTING (setting) || !(setting_info = NM_SETTING_GET_CLASS (setting)->setting_info)) { /* handle invalid setting objects gracefully. */ - *out_setting_info = NULL; - return NULL; + NM_SET_OUT (out_setting_info, NULL); + NM_SET_OUT (out_parse_info_setting, NULL); + NM_SET_OUT (out_parse_info_property, NULL); + return; } nm_assert (setting_info->setting_name); + nm_assert (_NM_INT_NOT_NEGATIVE (setting_info->meta_type)); + nm_assert (setting_info->meta_type < G_N_ELEMENTS (parse_infos)); + + pis = parse_infos[setting_info->meta_type]; - *out_setting_info = setting_info; + pip = NULL; + if ( pis + && property_name) { + gssize idx; - 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, @@ -2956,10 +2979,12 @@ _parse_info_find (NMSetting *setting, NULL, NULL); if (idx >= 0) - return pis->properties[idx]; + pip = pis->properties[idx]; } - return NULL; + NM_SET_OUT (out_setting_info, setting_info); + NM_SET_OUT (out_parse_info_setting, pis); + NM_SET_OUT (out_parse_info_property, pip); } /*****************************************************************************/ @@ -2985,7 +3010,7 @@ read_one_setting_value (KeyfileReaderInfo *info, key = property_info->name; - pip = _parse_info_find (setting, key, &setting_info); + _parse_info_find (setting, key, &setting_info, NULL, &pip); nm_assert (setting_info); @@ -3603,7 +3628,7 @@ write_setting_value (KeyfileWriterInfo *info, key = property_info->name; - pip = _parse_info_find (setting, key, &setting_info); + _parse_info_find (setting, key, &setting_info, NULL, &pip); if (!pip) { if (!setting_info) { @@ -3840,9 +3865,13 @@ nm_keyfile_write (NMConnection *connection, for (i = 0; i < n_settings; i++) { const NMSettInfoSetting *sett_info; NMSetting *setting = settings[i]; + const char *setting_name; + const char *setting_alias; sett_info = _nm_setting_class_get_sett_info (NM_SETTING_GET_CLASS (setting)); + setting_name = sett_info->setting_class->setting_info->setting_name; + if (sett_info->detail.gendata_info) { guint k, n_keys; const char *const*keys; @@ -3852,7 +3881,6 @@ nm_keyfile_write (NMConnection *connection, 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++) { @@ -3886,6 +3914,18 @@ nm_keyfile_write (NMConnection *connection, goto out_with_info_error; } + setting_alias = nm_keyfile_plugin_get_alias_for_setting_name (setting_name); + if ( ( setting_alias + && g_key_file_has_group (info.keyfile, setting_alias)) + || g_key_file_has_group (info.keyfile, setting_name)) { + /* we have a section for the setting. Nothing to do. */ + } else { + /* ensure the group is present. There is no API for that, so add and remove + * a dummy key. */ + g_key_file_set_value (info.keyfile, setting_alias ?: setting_name, ".X", "1"); + g_key_file_remove_key (info.keyfile, setting_alias ?: setting_name, ".X", NULL); + } + if (NM_IS_SETTING_WIREGUARD (setting)) { _write_setting_wireguard (setting, &info); if (info.error) diff --git a/libnm-core/nm-setting-wired.c b/libnm-core/nm-setting-wired.c index 379bd173..71add938 100644 --- a/libnm-core/nm-setting-wired.c +++ b/libnm-core/nm-setting-wired.c @@ -1237,7 +1237,7 @@ nm_setting_wired_class_init (NMSettingWiredClass *klass) /** * NMSettingWired:speed: * - * When a value grater than 0 is set, configures the device to use + * When a value greater than 0 is set, configures the device to use * the specified speed. If "auto-negotiate" is "yes" the specified * speed will be the only one advertised during link negotiation: * this works only for BASE-T 802.3 specifications and is useful for diff --git a/libnm-core/tests/test-setting.c b/libnm-core/tests/test-setting.c index aa9de5a0..0ddf3e8e 100644 --- a/libnm-core/tests/test-setting.c +++ b/libnm-core/tests/test-setting.c @@ -2581,7 +2581,7 @@ static void test_roundtrip_conversion (gconstpointer test_data) { const int MODE = GPOINTER_TO_INT (test_data); - const char *ID= nm_sprintf_bufa (100, "roundtip-conversion-%d", MODE); + const char *ID= nm_sprintf_bufa (100, "roundtrip-conversion-%d", MODE); const char *UUID= "63376701-b61e-4318-bf7e-664a1c1eeaab"; const char *INTERFACE_NAME = nm_sprintf_bufa (100, "ifname%d", MODE); guint32 ETH_MTU = nmtst_rand_select ((guint32) 0u, @@ -2663,6 +2663,8 @@ test_roundtrip_conversion (gconstpointer test_data) "addr-gen-mode=stable-privacy\n" "dns-search=\n" "method=auto\n" + "\n" + "[proxy]\n" "", ID, UUID, @@ -2722,6 +2724,8 @@ test_roundtrip_conversion (gconstpointer test_data) "interface-name=%s\n" "permissions=\n" "\n" + "[wireguard]\n" + "\n" "[ipv4]\n" "dns-search=\n" "method=disabled\n" @@ -2730,6 +2734,8 @@ test_roundtrip_conversion (gconstpointer test_data) "addr-gen-mode=stable-privacy\n" "dns-search=\n" "method=ignore\n" + "\n" + "[proxy]\n" "", ID, UUID, @@ -2770,7 +2776,8 @@ test_roundtrip_conversion (gconstpointer test_data) "type=wireguard\n" "interface-name=%s\n" "permissions=\n" - "%s" /* [wireguard] */ + "\n" + "[wireguard]\n" "%s" /* fwmark */ "%s" /* listen-port */ "%s" /* private-key-flags */ @@ -2785,17 +2792,12 @@ test_roundtrip_conversion (gconstpointer test_data) "addr-gen-mode=stable-privacy\n" "dns-search=\n" "method=ignore\n" + "\n" + "[proxy]\n" "", ID, UUID, INTERFACE_NAME, - ( ( (WG_FWMARK != 0) - || (WG_LISTEN_PORT != 0) - || (WG_PRIVATE_KEY_FLAGS != NM_SETTING_SECRET_FLAG_NONE) - || ( WG_PRIVATE_KEY - && WG_PRIVATE_KEY_FLAGS == NM_SETTING_SECRET_FLAG_NONE)) - ? "\n[wireguard]\n" - : ""), ( (WG_FWMARK != 0) ? nm_sprintf_bufa (100, "fwmark=%u\n", WG_FWMARK) : ""), @@ -2887,6 +2889,8 @@ test_roundtrip_conversion (gconstpointer test_data) "routing-rule1=priority 1 from ::/0 table 1000\n" "routing-rule2=priority 2 from 1:2:3:b::/65 table 1001\n" "routing-rule3=priority 3 from 1:2:3:c::/66 table 1002\n" + "\n" + "[proxy]\n" "", ID, UUID, @@ -3279,6 +3283,51 @@ test_parse_tc_handle (void) /*****************************************************************************/ +static void +test_empty_setting (void) +{ + gs_unref_object NMConnection *con = NULL; + gs_unref_object NMConnection *con2 = NULL; + NMSettingBluetooth *s_bt; + NMSettingGsm *s_gsm; + gs_unref_keyfile GKeyFile *kf = NULL; + gs_free_error GError *error = NULL; + + con = nmtst_create_minimal_connection ("bt-empty-gsm", "dca3192a-f2dc-48eb-b806-d0ff788f122c", NM_SETTING_BLUETOOTH_SETTING_NAME, NULL); + + s_bt = _nm_connection_get_setting (con, NM_TYPE_SETTING_BLUETOOTH); + g_object_set (s_bt, + NM_SETTING_BLUETOOTH_TYPE, "dun", + NM_SETTING_BLUETOOTH_BDADDR, "aa:bb:cc:dd:ee:ff", + NULL); + + s_gsm = NM_SETTING_GSM (nm_setting_gsm_new ()); + nm_connection_add_setting (con, NM_SETTING (s_gsm)); + + nmtst_connection_normalize (con); + + nmtst_assert_connection_verifies_without_normalization (con); + + kf = nm_keyfile_write (con, NULL, NULL, &error); + nmtst_assert_success (kf, error); + + g_assert (g_key_file_has_group (kf, "gsm")); + g_assert_cmpint (nmtst_keyfile_get_num_keys (kf, "gsm"), ==, 0); + + con2 = nm_keyfile_read (kf, + "/ignored/current/working/directory/for/loading/relative/paths", + NULL, + NULL, + &error); + nmtst_assert_success (con2, error); + + g_assert (nm_connection_get_setting (con2, NM_TYPE_SETTING_GSM)); + + nmtst_assert_connection_verifies_without_normalization (con2); +} + +/*****************************************************************************/ + NMTST_DEFINE (); int @@ -3366,5 +3415,7 @@ main (int argc, char **argv) g_test_add_func ("/libnm/test_team_setting", test_team_setting); + g_test_add_func ("/libnm/test_empty_setting", test_empty_setting); + return g_test_run (); } |