diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2020-07-15 17:28:35 +0200 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2020-08-26 17:28:45 +0200 |
commit | 7f217d0345f59917444e7ebf1cecd22ed02e2b1b (patch) | |
tree | ba67b8e8ce04dd19519ab41a933a0e96999a3016 | |
parent | 757fa4711f87bf31f0de47facc4127e8ae915f54 (diff) | |
download | NetworkManager-7f217d0345f59917444e7ebf1cecd22ed02e2b1b.tar.gz |
core: honor the ipv4.dhcp-reject-servers property
-rw-r--r-- | src/devices/nm-device.c | 3 | ||||
-rw-r--r-- | src/dhcp/nm-dhcp-client.c | 53 | ||||
-rw-r--r-- | src/dhcp/nm-dhcp-client.h | 5 | ||||
-rw-r--r-- | src/dhcp/nm-dhcp-dhclient-utils.c | 14 | ||||
-rw-r--r-- | src/dhcp/nm-dhcp-dhclient-utils.h | 1 | ||||
-rw-r--r-- | src/dhcp/nm-dhcp-dhclient.c | 6 | ||||
-rw-r--r-- | src/dhcp/nm-dhcp-manager.c | 5 | ||||
-rw-r--r-- | src/dhcp/nm-dhcp-manager.h | 1 | ||||
-rw-r--r-- | src/dhcp/nm-dhcp-nettools.c | 19 | ||||
-rw-r--r-- | src/dhcp/nm-dhcp-systemd.c | 15 | ||||
-rw-r--r-- | src/dhcp/tests/test-dhcp-dhclient.c | 1 | ||||
-rw-r--r-- | src/nm-iface-helper.c | 1 |
12 files changed, 122 insertions, 2 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 4e8b2bf3c8..c1c2774d6a 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -8876,6 +8876,7 @@ dhcp4_start (NMDevice *self) NMSettingConnection *s_con; GError *error = NULL; const NMPlatformLink *pllink; + const char *const *reject_servers; connection = nm_device_get_applied_connection (self); g_return_val_if_fail (connection, FALSE); @@ -8898,6 +8899,7 @@ dhcp4_start (NMDevice *self) client_id = dhcp4_get_client_id (self, connection, hwaddr); vendor_class_identifier = dhcp4_get_vendor_class_identifier (self, NM_SETTING_IP4_CONFIG (s_ip4)); + reject_servers = nm_setting_ip_config_get_dhcp_reject_servers (s_ip4, NULL); g_warn_if_fail (priv->dhcp_data_4.client == NULL); priv->dhcp_data_4.client = nm_dhcp_manager_start_ip4 (nm_dhcp_manager_get (), @@ -8919,6 +8921,7 @@ dhcp4_start (NMDevice *self) priv->dhcp_anycast_address, NULL, vendor_class_identifier, + reject_servers, &error); if (!priv->dhcp_data_4.client) { _LOGW (LOGD_DHCP4, "failure to start DHCP: %s", error->message); diff --git a/src/dhcp/nm-dhcp-client.c b/src/dhcp/nm-dhcp-client.c index d130a8d4be..b02ff93426 100644 --- a/src/dhcp/nm-dhcp-client.c +++ b/src/dhcp/nm-dhcp-client.c @@ -52,6 +52,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMDhcpClient, PROP_HOSTNAME_FLAGS, PROP_MUD_URL, PROP_VENDOR_CLASS_IDENTIFIER, + PROP_REJECT_SERVERS, ); typedef struct _NMDhcpClientPrivate { @@ -62,6 +63,7 @@ typedef struct _NMDhcpClientPrivate { char * uuid; GBytes * client_id; char * hostname; + const char **reject_servers; char * mud_url; GBytes * vendor_class_identifier; pid_t pid; @@ -332,6 +334,14 @@ nm_dhcp_client_get_vendor_class_identifier (NMDhcpClient *self) return NM_DHCP_CLIENT_GET_PRIVATE (self)->vendor_class_identifier; } +const char *const * +nm_dhcp_client_get_reject_servers (NMDhcpClient *self) +{ + g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), NULL); + + return (const char *const *) NM_DHCP_CLIENT_GET_PRIVATE (self)->reject_servers; +} + /*****************************************************************************/ static const char *state_table[NM_DHCP_STATE_MAX + 1] = { @@ -954,6 +964,38 @@ nm_dhcp_client_handle_event (gpointer unused, return TRUE; } +gboolean +nm_dhcp_client_server_id_is_rejected (NMDhcpClient *self, gconstpointer addr) +{ + NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self); + in_addr_t addr4 = *(in_addr_t *) addr; + guint i; + + /* IPv6 not implemented yet */ + nm_assert (priv->addr_family == AF_INET); + + if (!priv->reject_servers || !priv->reject_servers[0]) + return FALSE; + + for (i = 0; priv->reject_servers[i]; i++) { + in_addr_t r_addr; + in_addr_t mask; + int r_prefix; + + if (!nm_utils_parse_inaddr_prefix_bin (AF_INET, + priv->reject_servers[i], + NULL, + &r_addr, + &r_prefix)) + nm_assert_not_reached (); + mask = _nm_utils_ip4_prefix_to_netmask (r_prefix < 0 ? 32 : r_prefix); + if ((addr4 & mask) == (r_addr & mask)) + return TRUE; + } + + return FALSE; +} + /*****************************************************************************/ static void @@ -1090,6 +1132,10 @@ set_property (GObject *object, guint prop_id, /* construct-only */ priv->vendor_class_identifier = g_value_dup_boxed (value); break; + case PROP_REJECT_SERVERS: + /* construct-only */ + priv->reject_servers = nm_utils_strv_dup_packed (g_value_get_boxed (value), -1); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1131,6 +1177,7 @@ dispose (GObject *object) nm_clear_g_free (&priv->hostname); nm_clear_g_free (&priv->uuid); nm_clear_g_free (&priv->mud_url); + nm_clear_g_free (&priv->reject_servers); nm_clear_pointer (&priv->client_id, g_bytes_unref); nm_clear_pointer (&priv->hwaddr, g_bytes_unref); nm_clear_pointer (&priv->bcast_hwaddr, g_bytes_unref); @@ -1258,6 +1305,12 @@ nm_dhcp_client_class_init (NMDhcpClientClass *client_class) G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_REJECT_SERVERS] = + g_param_spec_boxed (NM_DHCP_CLIENT_REJECT_SERVERS, "", "", + G_TYPE_STRV, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); signals[SIGNAL_STATE_CHANGED] = diff --git a/src/dhcp/nm-dhcp-client.h b/src/dhcp/nm-dhcp-client.h index 11e531999f..b6512d5a7d 100644 --- a/src/dhcp/nm-dhcp-client.h +++ b/src/dhcp/nm-dhcp-client.h @@ -39,6 +39,7 @@ #define NM_DHCP_CLIENT_IAID_EXPLICIT "iaid-explicit" #define NM_DHCP_CLIENT_HOSTNAME_FLAGS "hostname-flags" #define NM_DHCP_CLIENT_VENDOR_CLASS_IDENTIFIER "vendor-class-identifier" +#define NM_DHCP_CLIENT_REJECT_SERVERS "reject-servers" #define NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED "state-changed" #define NM_DHCP_CLIENT_SIGNAL_PREFIX_DELEGATED "prefix-delegated" @@ -144,9 +145,11 @@ GBytes *nm_dhcp_client_get_client_id (NMDhcpClient *self); const char *nm_dhcp_client_get_hostname (NMDhcpClient *self); const char *nm_dhcp_client_get_mud_url (NMDhcpClient *self); +const char *const *nm_dhcp_client_get_reject_servers (NMDhcpClient *self); NMDhcpHostnameFlags nm_dhcp_client_get_hostname_flags (NMDhcpClient *self); + gboolean nm_dhcp_client_get_info_only (NMDhcpClient *self); gboolean nm_dhcp_client_get_use_fqdn (NMDhcpClient *self); @@ -208,6 +211,8 @@ void nm_dhcp_client_set_client_id_bin (NMDhcpClient *self, void nm_dhcp_client_emit_ipv6_prefix_delegated (NMDhcpClient *self, const NMPlatformIP6Address *prefix); +gboolean nm_dhcp_client_server_id_is_rejected (NMDhcpClient *self, gconstpointer addr); + /***************************************************************************** * Client data *****************************************************************************/ diff --git a/src/dhcp/nm-dhcp-dhclient-utils.c b/src/dhcp/nm-dhcp-dhclient-utils.c index 1bd8d0ee71..6f208e96e1 100644 --- a/src/dhcp/nm-dhcp-dhclient-utils.c +++ b/src/dhcp/nm-dhcp-dhclient-utils.c @@ -307,6 +307,7 @@ nm_dhcp_dhclient_create_config (const char *interface, gboolean use_fqdn, NMDhcpHostnameFlags hostname_flags, const char *mud_url, + const char *const *reject_servers, const char *orig_path, const char *orig_contents, GBytes **out_new_client_id) @@ -319,6 +320,7 @@ nm_dhcp_dhclient_create_config (const char *interface, g_return_val_if_fail (!anycast_addr || nm_utils_hwaddr_valid (anycast_addr, ETH_ALEN), NULL); g_return_val_if_fail (NM_IN_SET (addr_family, AF_INET, AF_INET6), NULL); + g_return_val_if_fail (!reject_servers || addr_family == AF_INET, NULL); nm_assert (!out_new_client_id || !*out_new_client_id); new_contents = g_string_new (_("# Created by NetworkManager\n")); @@ -473,6 +475,18 @@ nm_dhcp_dhclient_create_config (const char *interface, } add_mud_url_config (new_contents, mud_url, addr_family); + + if ( reject_servers + && reject_servers[0]) { + g_string_append (new_contents, "reject "); + for (i = 0; reject_servers[i]; i++) { + if (i != 0) + g_string_append (new_contents, ", "); + g_string_append (new_contents, reject_servers[i]); + } + g_string_append (new_contents, ";\n"); + } + if (addr_family == AF_INET) { add_ip4_config (new_contents, client_id, hostname, use_fqdn, hostname_flags); add_request (reqs, "rfc3442-classless-static-routes"); diff --git a/src/dhcp/nm-dhcp-dhclient-utils.h b/src/dhcp/nm-dhcp-dhclient-utils.h index 5094d614e6..57d0a607ad 100644 --- a/src/dhcp/nm-dhcp-dhclient-utils.h +++ b/src/dhcp/nm-dhcp-dhclient-utils.h @@ -18,6 +18,7 @@ char *nm_dhcp_dhclient_create_config (const char *interface, gboolean use_fqdn, NMDhcpHostnameFlags hostname_flags, const char *mud_url, + const char *const *reject_servers, const char *orig_path, const char *orig_contents, GBytes **out_new_client_id); diff --git a/src/dhcp/nm-dhcp-dhclient.c b/src/dhcp/nm-dhcp-dhclient.c index ad8fc57bb1..53d2aa4f4d 100644 --- a/src/dhcp/nm-dhcp-dhclient.c +++ b/src/dhcp/nm-dhcp-dhclient.c @@ -148,6 +148,7 @@ merge_dhclient_config (NMDhcpDhclient *self, gboolean use_fqdn, NMDhcpHostnameFlags hostname_flags, const char *mud_url, + const char *const *reject_servers, const char *orig_path, GBytes **out_new_client_id, GError **error) @@ -178,6 +179,7 @@ merge_dhclient_config (NMDhcpDhclient *self, use_fqdn, hostname_flags, mud_url, + reject_servers, orig_path, orig, out_new_client_id); @@ -271,6 +273,7 @@ create_dhclient_config (NMDhcpDhclient *self, gboolean use_fqdn, NMDhcpHostnameFlags hostname_flags, const char *mud_url, + const char *const *reject_servers, GBytes **out_new_client_id) { gs_free char *orig = NULL; @@ -300,6 +303,7 @@ create_dhclient_config (NMDhcpDhclient *self, use_fqdn, hostname_flags, mud_url, + reject_servers, orig, out_new_client_id, &error)) { @@ -501,6 +505,7 @@ ip4_start (NMDhcpClient *client, nm_dhcp_client_get_use_fqdn (client), nm_dhcp_client_get_hostname_flags (client), nm_dhcp_client_get_mud_url (client), + nm_dhcp_client_get_reject_servers (client), &new_client_id); if (!priv->conf_file) { nm_utils_error_set_literal (error, @@ -546,6 +551,7 @@ ip6_start (NMDhcpClient *client, TRUE, nm_dhcp_client_get_hostname_flags (client), nm_dhcp_client_get_mud_url (client), + NULL, NULL); if (!priv->conf_file) { nm_utils_error_set_literal (error, diff --git a/src/dhcp/nm-dhcp-manager.c b/src/dhcp/nm-dhcp-manager.c index df2261ae0d..5148d641f1 100644 --- a/src/dhcp/nm-dhcp-manager.c +++ b/src/dhcp/nm-dhcp-manager.c @@ -226,6 +226,7 @@ client_start (NMDhcpManager *self, const char *last_ip4_address, guint needed_prefixes, GBytes *vendor_class_identifier, + const char *const *reject_servers, GError **error) { NMDhcpManagerPrivate *priv; @@ -318,6 +319,7 @@ client_start (NMDhcpManager *self, NM_DHCP_CLIENT_TIMEOUT, (guint) timeout, NM_DHCP_CLIENT_HOSTNAME_FLAGS, (guint) hostname_flags, NM_DHCP_CLIENT_VENDOR_CLASS_IDENTIFIER, vendor_class_identifier, + NM_DHCP_CLIENT_REJECT_SERVERS, reject_servers, NM_DHCP_CLIENT_FLAGS, (guint) (0 | (hostname_use_fqdn ? NM_DHCP_CLIENT_FLAGS_USE_FQDN : 0) | (info_only ? NM_DHCP_CLIENT_FLAGS_INFO_ONLY : 0) @@ -399,6 +401,7 @@ nm_dhcp_manager_start_ip4 (NMDhcpManager *self, const char *dhcp_anycast_addr, const char *last_ip_address, GBytes *vendor_class_identifier, + const char *const *reject_servers, GError **error) { NMDhcpManagerPrivate *priv; @@ -459,6 +462,7 @@ nm_dhcp_manager_start_ip4 (NMDhcpManager *self, last_ip_address, 0, vendor_class_identifier, + reject_servers, error); } @@ -523,6 +527,7 @@ nm_dhcp_manager_start_ip6 (NMDhcpManager *self, NULL, needed_prefixes, NULL, + NULL, error); } diff --git a/src/dhcp/nm-dhcp-manager.h b/src/dhcp/nm-dhcp-manager.h index ce3f560470..1bb48ca060 100644 --- a/src/dhcp/nm-dhcp-manager.h +++ b/src/dhcp/nm-dhcp-manager.h @@ -49,6 +49,7 @@ NMDhcpClient * nm_dhcp_manager_start_ip4 (NMDhcpManager *manager, const char *dhcp_anycast_addr, const char *last_ip_address, GBytes *vendor_class_identifier, + const char *const *reject_servers, GError **error); NMDhcpClient * nm_dhcp_manager_start_ip6 (NMDhcpManager *manager, diff --git a/src/dhcp/nm-dhcp-nettools.c b/src/dhcp/nm-dhcp-nettools.c index ec24a77f42..3e6a290f9b 100644 --- a/src/dhcp/nm-dhcp-nettools.c +++ b/src/dhcp/nm-dhcp-nettools.c @@ -1072,16 +1072,31 @@ dhcp4_event_handle (NMDhcpNettools *self, NDhcp4ClientEvent *event) { NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE (self); + struct in_addr server_id; + char addr_str[INET_ADDRSTRLEN]; int r; _LOGT ("client event %d", event->event); switch (event->event) { case N_DHCP4_CLIENT_EVENT_OFFER: - /* always accept the first lease */ + r = n_dhcp4_client_lease_get_server_identifier (event->offer.lease, &server_id); + if (r) { + _LOGW ("selecting lease failed: %d", r); + return TRUE; + } + + if (nm_dhcp_client_server_id_is_rejected (NM_DHCP_CLIENT (self), &server_id)) { + _LOGD ("server-id %s is in the reject-list, ignoring", + nm_utils_inet_ntop (AF_INET, &server_id, addr_str)); + return TRUE; + } + r = n_dhcp4_client_lease_select (event->offer.lease); - if (r) + if (r) { _LOGW ("selecting lease failed: %d", r); + return TRUE; + } break; case N_DHCP4_CLIENT_EVENT_RETRACTED: case N_DHCP4_CLIENT_EVENT_EXPIRED: diff --git a/src/dhcp/nm-dhcp-systemd.c b/src/dhcp/nm-dhcp-systemd.c index 737ccacc48..b657a42118 100644 --- a/src/dhcp/nm-dhcp-systemd.c +++ b/src/dhcp/nm-dhcp-systemd.c @@ -524,6 +524,10 @@ dhcp_event_cb (sd_dhcp_client *client, int event, gpointer user_data) { NMDhcpSystemd *self = NM_DHCP_SYSTEMD (user_data); NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (self); + char addr_str[INET_ADDRSTRLEN]; + sd_dhcp_lease *lease; + struct in_addr addr; + int r; nm_assert (priv->client4 == client); @@ -544,6 +548,17 @@ dhcp_event_cb (sd_dhcp_client *client, int event, gpointer user_data) bound4_handle (self, FALSE); break; case SD_DHCP_CLIENT_EVENT_SELECTING: + r = sd_dhcp_client_get_lease (priv->client4, &lease); + if (r < 0) + return r; + r = sd_dhcp_lease_get_server_identifier (lease, &addr); + if (r < 0) + return r; + if (nm_dhcp_client_server_id_is_rejected (NM_DHCP_CLIENT (user_data), &addr)) { + _LOGD ("server-id %s is in the reject-list, ignoring", + nm_utils_inet_ntop (AF_INET, &addr, addr_str)); + return -ENOMSG; + } break; default: _LOGW ("unhandled DHCP event %d", event); diff --git a/src/dhcp/tests/test-dhcp-dhclient.c b/src/dhcp/tests/test-dhcp-dhclient.c index d51bcae5f8..29cfefc976 100644 --- a/src/dhcp/tests/test-dhcp-dhclient.c +++ b/src/dhcp/tests/test-dhcp-dhclient.c @@ -55,6 +55,7 @@ test_config (const char *orig, use_fqdn, hostname_flags, mud_url, + NULL, "/path/to/dhclient.conf", orig, &new_client_id); diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c index da84640d26..5904e8fc0b 100644 --- a/src/nm-iface-helper.c +++ b/src/nm-iface-helper.c @@ -539,6 +539,7 @@ main (int argc, char *argv[]) NULL, global_opt.dhcp4_address, NULL, + NULL, &error); if (!dhcp4_client) g_error ("failure to start DHCP: %s", error->message); |