dns: ensure that no wrong separators are used for DNS search domains

If wrong separators are used in they keyfile, like commas, the whole
line is considered as a single domain string, like "a.org,b.org".
Obviously this is invalid.

Ideally we should validate that the string is a valid domain, but this
gets quite complex if we want to support unicode characters, which are
valid for many top domains. For now, validate at least that no wrong
separators have been used.

Fixes https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/1740
This commit is contained in:
Íñigo Huguet 2025-04-25 09:19:55 +02:00 committed by Íñigo Huguet
parent 21bbe24fee
commit 3266203bf1
2 changed files with 61 additions and 0 deletions

View file

@ -5671,6 +5671,28 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
}
}
/* Validate DNS search domains */
if (nm_strvarray_get_strv_notempty(priv->dns_search.arr, NULL)) {
for (i = 0; i < priv->dns_search.arr->len; i++) {
const char *dns_search = nm_strvarray_get_idx(priv->dns_search.arr, i);
/* TODO: currently we only check that no wrong list separators have
* been used by mistake. Proper domain name validation would be better. */
if (strpbrk(dns_search, ",; ")) {
g_set_error(error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("DNS search domain '%s' is invalid"),
dns_search);
g_prefix_error(error,
"%s.%s: ",
nm_setting_get_name(setting),
NM_SETTING_IP_CONFIG_DNS_SEARCH);
return FALSE;
}
}
}
/* Validate addresses */
for (i = 0; i < priv->addresses->len; i++) {
NMIPAddress *addr = (NMIPAddress *) priv->addresses->pdata[i];

View file

@ -5460,6 +5460,44 @@ test_settings_dns(void)
}
}
static void
_assert_dns_searches(gboolean valid, ...)
{
NMConnection *con;
NMSettingIPConfig *ip4, *ip6;
const char *dns_search;
va_list args;
con = nmtst_create_minimal_connection("test-dns-search",
NULL,
NM_SETTING_WIRED_SETTING_NAME,
NULL);
nmtst_connection_normalize(con);
ip4 = nm_connection_get_setting_ip4_config(con);
ip6 = nm_connection_get_setting_ip6_config(con);
va_start(args, valid);
while ((dns_search = va_arg(args, const char *))) {
nm_setting_ip_config_add_dns_search(ip4, dns_search);
nm_setting_ip_config_add_dns_search(ip6, dns_search);
}
va_end(args);
g_assert(valid == nm_setting_verify((NMSetting *) ip4, con, NULL));
g_assert(valid == nm_setting_verify((NMSetting *) ip6, con, NULL));
}
static void
test_settings_dns_search_domains(void)
{
_assert_dns_searches(TRUE, "example.com", NULL);
_assert_dns_searches(TRUE, "sub.example.com", NULL);
_assert_dns_searches(TRUE, "example.com", "sub.example.com", NULL);
_assert_dns_searches(FALSE, "example.com,sub.example.com", NULL);
_assert_dns_searches(FALSE, "example.com;sub.example.com", NULL);
_assert_dns_searches(FALSE, "example.com sub.example.com", NULL);
}
/*****************************************************************************/
static void
@ -5570,6 +5608,7 @@ main(int argc, char **argv)
g_test_add_func("/libnm/settings/6lowpan/1", test_6lowpan_1);
g_test_add_func("/libnm/settings/dns", test_settings_dns);
g_test_add_func("/libnm/settings/dns_search_domain", test_settings_dns_search_domains);
g_test_add_func("/libnm/settings/sriov/vf", test_sriov_vf);
g_test_add_func("/libnm/settings/sriov/vf-dup", test_sriov_vf_dup);