libnm: implement special setter for direct string property for ip address
This is a normalization employed by NMSettingIPConfig.gateway. Also rework NMSettingIPConfig.set_property() to no longer assert against valid input. We want to pass there untrusted strings from D-Bus, asserting is a horrible idea. Instead, either normalize the string or keep the invalid text that will be rejected by verify().
This commit is contained in:
@@ -5589,7 +5589,7 @@ test_write_wired_static_ip6_only_gw(gconstpointer user_data)
|
|||||||
|
|
||||||
/* assert that the gateway was written and reloaded as expected */
|
/* assert that the gateway was written and reloaded as expected */
|
||||||
if (!gateway6 || !strcmp(gateway6, "::")) {
|
if (!gateway6 || !strcmp(gateway6, "::")) {
|
||||||
g_assert(nm_setting_ip_config_get_gateway(s_ip6) == NULL);
|
g_assert_cmpstr(nm_setting_ip_config_get_gateway(s_ip6), ==, NULL);
|
||||||
g_assert(written_ifcfg_gateway == NULL);
|
g_assert(written_ifcfg_gateway == NULL);
|
||||||
} else {
|
} else {
|
||||||
g_assert(nm_setting_ip_config_get_gateway(s_ip6) != NULL);
|
g_assert(nm_setting_ip_config_get_gateway(s_ip6) != NULL);
|
||||||
|
@@ -5795,10 +5795,12 @@ ip_gateway_set(const NMSettInfoSetting * sett_info,
|
|||||||
}
|
}
|
||||||
|
|
||||||
GArray *
|
GArray *
|
||||||
_nm_sett_info_property_override_create_array_ip_config(void)
|
_nm_sett_info_property_override_create_array_ip_config(int addr_family)
|
||||||
{
|
{
|
||||||
GArray *properties_override = _nm_sett_info_property_override_create_array();
|
GArray *properties_override = _nm_sett_info_property_override_create_array();
|
||||||
|
|
||||||
|
nm_assert_addr_family(addr_family);
|
||||||
|
|
||||||
_nm_properties_override_gobj(
|
_nm_properties_override_gobj(
|
||||||
properties_override,
|
properties_override,
|
||||||
obj_properties[PROP_METHOD],
|
obj_properties[PROP_METHOD],
|
||||||
@@ -5814,8 +5816,7 @@ _nm_sett_info_property_override_create_array_ip_config(void)
|
|||||||
.to_dbus_fcn = _nm_setting_property_to_dbus_fcn_direct,
|
.to_dbus_fcn = _nm_setting_property_to_dbus_fcn_direct,
|
||||||
.from_dbus_fcn = ip_gateway_set),
|
.from_dbus_fcn = ip_gateway_set),
|
||||||
.direct_offset = NM_STRUCT_OFFSET_ENSURE_TYPE(char *, NMSettingIPConfigPrivate, gateway),
|
.direct_offset = NM_STRUCT_OFFSET_ENSURE_TYPE(char *, NMSettingIPConfigPrivate, gateway),
|
||||||
/* The property setter for the gateway performs some normalization and is special! */
|
.direct_set_string_ip_address_addr_family = addr_family);
|
||||||
.direct_has_special_setter = TRUE);
|
|
||||||
|
|
||||||
_nm_properties_override_gobj(
|
_nm_properties_override_gobj(
|
||||||
properties_override,
|
properties_override,
|
||||||
@@ -5975,7 +5976,6 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps
|
|||||||
{
|
{
|
||||||
NMSettingIPConfig * setting = NM_SETTING_IP_CONFIG(object);
|
NMSettingIPConfig * setting = NM_SETTING_IP_CONFIG(object);
|
||||||
NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting);
|
NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting);
|
||||||
const char * gateway;
|
|
||||||
char ** strv;
|
char ** strv;
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
@@ -6021,12 +6021,10 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps
|
|||||||
(GDestroyNotify) nm_ip_address_unref);
|
(GDestroyNotify) nm_ip_address_unref);
|
||||||
break;
|
break;
|
||||||
case PROP_GATEWAY:
|
case PROP_GATEWAY:
|
||||||
gateway = g_value_get_string(value);
|
|
||||||
g_return_if_fail(
|
|
||||||
!gateway
|
|
||||||
|| nm_utils_ipaddr_is_valid(NM_SETTING_IP_CONFIG_GET_FAMILY(setting), gateway));
|
|
||||||
g_free(priv->gateway);
|
g_free(priv->gateway);
|
||||||
priv->gateway = canonicalize_ip(NM_SETTING_IP_CONFIG_GET_FAMILY(setting), gateway, TRUE);
|
priv->gateway =
|
||||||
|
_nm_utils_ipaddr_canonical_or_invalid(NM_SETTING_IP_CONFIG_GET_FAMILY(setting),
|
||||||
|
g_value_get_string(value));
|
||||||
break;
|
break;
|
||||||
case PROP_ROUTES:
|
case PROP_ROUTES:
|
||||||
g_ptr_array_unref(priv->routes);
|
g_ptr_array_unref(priv->routes);
|
||||||
|
@@ -654,7 +654,7 @@ nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass)
|
|||||||
GObjectClass * object_class = G_OBJECT_CLASS(klass);
|
GObjectClass * object_class = G_OBJECT_CLASS(klass);
|
||||||
NMSettingClass * setting_class = NM_SETTING_CLASS(klass);
|
NMSettingClass * setting_class = NM_SETTING_CLASS(klass);
|
||||||
NMSettingIPConfigClass *setting_ip_config_class = NM_SETTING_IP_CONFIG_CLASS(klass);
|
NMSettingIPConfigClass *setting_ip_config_class = NM_SETTING_IP_CONFIG_CLASS(klass);
|
||||||
GArray *properties_override = _nm_sett_info_property_override_create_array_ip_config();
|
GArray *properties_override = _nm_sett_info_property_override_create_array_ip_config(AF_INET);
|
||||||
|
|
||||||
g_type_class_add_private(klass, sizeof(NMSettingIP4ConfigPrivate));
|
g_type_class_add_private(klass, sizeof(NMSettingIP4ConfigPrivate));
|
||||||
|
|
||||||
|
@@ -650,7 +650,7 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass)
|
|||||||
GObjectClass * object_class = G_OBJECT_CLASS(klass);
|
GObjectClass * object_class = G_OBJECT_CLASS(klass);
|
||||||
NMSettingClass * setting_class = NM_SETTING_CLASS(klass);
|
NMSettingClass * setting_class = NM_SETTING_CLASS(klass);
|
||||||
NMSettingIPConfigClass *setting_ip_config_class = NM_SETTING_IP_CONFIG_CLASS(klass);
|
NMSettingIPConfigClass *setting_ip_config_class = NM_SETTING_IP_CONFIG_CLASS(klass);
|
||||||
GArray *properties_override = _nm_sett_info_property_override_create_array_ip_config();
|
GArray *properties_override = _nm_sett_info_property_override_create_array_ip_config(AF_INET6);
|
||||||
|
|
||||||
g_type_class_add_private(klass, sizeof(NMSettingIP6ConfigPrivate));
|
g_type_class_add_private(klass, sizeof(NMSettingIP6ConfigPrivate));
|
||||||
|
|
||||||
|
@@ -426,7 +426,7 @@ _nm_sett_info_property_override_create_array(void)
|
|||||||
return _nm_sett_info_property_override_create_array_sized(20);
|
return _nm_sett_info_property_override_create_array_sized(20);
|
||||||
}
|
}
|
||||||
|
|
||||||
GArray *_nm_sett_info_property_override_create_array_ip_config(void);
|
GArray *_nm_sett_info_property_override_create_array_ip_config(int addr_family);
|
||||||
|
|
||||||
void _nm_setting_class_commit(NMSettingClass * setting_class,
|
void _nm_setting_class_commit(NMSettingClass * setting_class,
|
||||||
NMMetaSettingType meta_type,
|
NMMetaSettingType meta_type,
|
||||||
|
@@ -685,6 +685,13 @@ _property_direct_set_string(const NMSettInfoProperty *property_info, char **dst,
|
|||||||
src,
|
src,
|
||||||
property_info->direct_set_string_mac_address_len));
|
property_info->direct_set_string_mac_address_len));
|
||||||
}
|
}
|
||||||
|
if (property_info->direct_set_string_ip_address_addr_family != 0) {
|
||||||
|
return nm_utils_strdup_reset_take(
|
||||||
|
dst,
|
||||||
|
_nm_utils_ipaddr_canonical_or_invalid(
|
||||||
|
property_info->direct_set_string_ip_address_addr_family,
|
||||||
|
src));
|
||||||
|
}
|
||||||
return nm_utils_strdup_reset(dst, src);
|
return nm_utils_strdup_reset(dst, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -42,6 +42,8 @@ void _nm_utils_bytes_from_dbus(GVariant *dbus_value, GValue *prop_value);
|
|||||||
|
|
||||||
char *_nm_utils_hwaddr_canonical_or_invalid(const char *mac, gssize length);
|
char *_nm_utils_hwaddr_canonical_or_invalid(const char *mac, gssize length);
|
||||||
|
|
||||||
|
char *_nm_utils_ipaddr_canonical_or_invalid(int addr_family, const char *ip);
|
||||||
|
|
||||||
gboolean _nm_utils_hwaddr_link_local_valid(const char *mac);
|
gboolean _nm_utils_hwaddr_link_local_valid(const char *mac);
|
||||||
|
|
||||||
gboolean _nm_sriov_vf_parse_vlans(NMSriovVF *vf, const char *str, GError **error);
|
gboolean _nm_sriov_vf_parse_vlans(NMSriovVF *vf, const char *str, GError **error);
|
||||||
|
@@ -3880,6 +3880,25 @@ _nm_utils_hwaddr_canonical_or_invalid(const char *mac, gssize length)
|
|||||||
return g_strdup(mac);
|
return g_strdup(mac);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
_nm_utils_ipaddr_canonical_or_invalid(int addr_family, const char *ip)
|
||||||
|
{
|
||||||
|
NMIPAddr addr_bin;
|
||||||
|
|
||||||
|
nm_assert_addr_family(addr_family);
|
||||||
|
|
||||||
|
if (!ip)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!nm_utils_parse_inaddr_bin(addr_family, ip, NULL, &addr_bin))
|
||||||
|
return g_strdup(ip);
|
||||||
|
|
||||||
|
if (nm_ip_addr_is_null(addr_family, &addr_bin))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return nm_utils_inet_ntop_dup(addr_family, &addr_bin);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Determine if given Ethernet address is link-local
|
* Determine if given Ethernet address is link-local
|
||||||
*
|
*
|
||||||
|
@@ -4520,7 +4520,8 @@ test_setting_metadata(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_assert(((sip->direct_set_string_mac_address_len != 0)
|
g_assert(((sip->direct_set_string_mac_address_len != 0)
|
||||||
+ (!!sip->direct_set_string_ascii_strdown))
|
+ (!!sip->direct_set_string_ascii_strdown)
|
||||||
|
+ (sip->direct_set_string_ip_address_addr_family != 0))
|
||||||
<= 1);
|
<= 1);
|
||||||
|
|
||||||
if (!sip->property_type->to_dbus_fcn) {
|
if (!sip->property_type->to_dbus_fcn) {
|
||||||
|
@@ -758,15 +758,9 @@ struct _NMSettInfoProperty {
|
|||||||
* MAC address length. */
|
* MAC address length. */
|
||||||
guint8 direct_set_string_mac_address_len : 5;
|
guint8 direct_set_string_mac_address_len : 5;
|
||||||
|
|
||||||
/* Currently, properties that set property_type->direct_type only have to_dbus_fcn()
|
/* If non-zero, this is the addr-family (AF_INET/AF_INET6) for normalizing an IP
|
||||||
* implemented "the direct way". For the property setter, they still call g_object_set().
|
* address. */
|
||||||
* In the future, also other operations, like from_dbus_fcn() should be implemented
|
guint8 direct_set_string_ip_address_addr_family : 5;
|
||||||
* by direct access (thereby, bypassing g_object_set()).
|
|
||||||
*
|
|
||||||
* A "direct_has_special_setter" property does something unusual, that will require special attention
|
|
||||||
* in the future, when we implement more functionality regarding the setter. It has no effect,
|
|
||||||
* except of marking those properties and serve as a reminder that special care needs to be taken. */
|
|
||||||
bool direct_has_special_setter : 1;
|
|
||||||
|
|
||||||
/* Usually, properties that are set to the default value for the GParamSpec
|
/* Usually, properties that are set to the default value for the GParamSpec
|
||||||
* are not serialized to GVariant (and NULL is returned by to_dbus_data().
|
* are not serialized to GVariant (and NULL is returned by to_dbus_data().
|
||||||
|
Reference in New Issue
Block a user