summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2018-06-11 11:55:35 +0200
committerThomas Haller <thaller@redhat.com>2018-06-12 13:30:36 +0200
commit5df4c17ba14f8604277aa338f2e26ad264012e1b (patch)
treefd8fca7dd07f599d6dd987fc4de5a5c4424229a7
parentd9488417e76c6d88dd4f97709b8826e1566db829 (diff)
downloadNetworkManager-5df4c17ba14f8604277aa338f2e26ad264012e1b.tar.gz
device: handle failure to generate ipv4.dhcp-client-id by fallback to random client-id
First of all, generating the client-id is not expected to fail. If it fails, something is already very wrong. Maybe, a failure to generate a client-id should result in failing the activation. However, let's not go full measure in this question. Instead: - ensure that we log a warning and a reason why the client-id could not be generated. - fallback to a random client id. Clearly, we were unable to generate the requested client-id, hence, we should fallback to a default value which does not make the host easily identifyable. Of course, that means that the generated DHCP client-id is not at all stable. But note that something is already very wrong, so when handling the error we should do something conservative (that is, protecting the users privacy). This is also what happens for a failure to generate the ipv6.dhcp-duid.
-rw-r--r--src/devices/nm-device.c83
1 files changed, 53 insertions, 30 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 95e56b9cea..ab8565c2dd 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -7018,6 +7018,18 @@ get_dhcp_timeout (NMDevice *self, int addr_family)
}
static GBytes *
+dhcp4_get_client_id_mac (const guint8 *hwaddr /* ETH_ALEN bytes */)
+{
+ guint8 *client_id_buf;
+ guint8 hwaddr_type = ARPHRD_ETHER;
+
+ client_id_buf = g_malloc (ETH_ALEN + 1);
+ client_id_buf[0] = hwaddr_type;
+ memcpy (&client_id_buf[1], hwaddr, ETH_ALEN);
+ return g_bytes_new_take (client_id_buf, ETH_ALEN + 1);
+}
+
+static GBytes *
dhcp4_get_client_id (NMDevice *self,
NMConnection *connection,
GBytes *hwaddr)
@@ -7026,7 +7038,10 @@ dhcp4_get_client_id (NMDevice *self,
const char *client_id;
gs_free char *client_id_default = NULL;
guint8 *client_id_buf;
- gboolean is_mac;
+ const char *fail_reason;
+ guint8 hwaddr_bin_buf[NM_UTILS_HWADDR_LEN_MAX];
+ const guint8 *hwaddr_bin;
+ gsize hwaddr_len;
s_ip4 = nm_connection_get_setting_ip4_config (connection);
client_id = nm_setting_ip4_config_get_dhcp_client_id (NM_SETTING_IP4_CONFIG (s_ip4));
@@ -7041,43 +7056,40 @@ dhcp4_get_client_id (NMDevice *self,
if (!client_id)
return NULL;
- if ( (is_mac = nm_streq (client_id, "mac"))
- || nm_streq (client_id, "perm-mac")) {
- char hwaddr_bin_buf[NM_UTILS_HWADDR_LEN_MAX];
- guint8 hwaddr_type;
- const guint8 *hwaddr_bin;
- gsize hwaddr_len;
-
- if (is_mac) {
- if (!hwaddr)
- return NULL;
- hwaddr_bin = g_bytes_get_data (hwaddr, &hwaddr_len);
- } else {
- const char *hwaddr_str;
+ if (nm_streq (client_id, "mac")) {
+ if (!hwaddr) {
+ fail_reason = "failed to get current MAC address";
+ goto out_fail;
+ }
- hwaddr_str = nm_device_get_permanent_hw_address (self);
- if (!hwaddr_str)
- return NULL;
+ hwaddr_bin = g_bytes_get_data (hwaddr, &hwaddr_len);
+ if (hwaddr_len != ETH_ALEN) {
+ fail_reason = "MAC address is not ethernet";
+ goto out_fail;
+ }
+
+ return dhcp4_get_client_id_mac (hwaddr_bin);
+ }
- if (!_nm_utils_hwaddr_aton (hwaddr_str, hwaddr_bin_buf, sizeof (hwaddr_bin_buf), &hwaddr_len))
- g_return_val_if_reached (NULL);
+ if (nm_streq (client_id, "perm-mac")) {
+ const char *hwaddr_str;
- hwaddr_bin = (const guint8 *) hwaddr_bin_buf;
+ hwaddr_str = nm_device_get_permanent_hw_address (self);
+ if (!hwaddr_str) {
+ fail_reason = "failed to get permanent MAC address";
+ goto out_fail;
}
- switch (hwaddr_len) {
- case ETH_ALEN:
- hwaddr_type = ARPHRD_ETHER;
- break;
- default:
+ if (!_nm_utils_hwaddr_aton (hwaddr_str, hwaddr_bin_buf, sizeof (hwaddr_bin_buf), &hwaddr_len))
+ g_return_val_if_reached (NULL);
+
+ if (hwaddr_len != ETH_ALEN) {
/* unsupported type. */
- return NULL;
+ fail_reason = "MAC address is not ethernet";
+ goto out_fail;
}
- client_id_buf = g_malloc (hwaddr_len + 1);
- client_id_buf[0] = hwaddr_type;
- memcpy (&client_id_buf[1], hwaddr_bin, hwaddr_len);
- return g_bytes_new_take (client_id_buf, hwaddr_len + 1);
+ return dhcp4_get_client_id_mac (hwaddr_bin_buf);
}
if (nm_streq (client_id, "stable")) {
@@ -7117,6 +7129,17 @@ dhcp4_get_client_id (NMDevice *self,
}
return nm_dhcp_utils_client_id_string_to_bytes (client_id);
+
+out_fail:
+ {
+ _LOGW (LOGD_DEVICE | LOGD_DHCP4 | LOGD_IP4,
+ "ipv4.dhcp-client-id: failure to generate client id (%s). Use random client id",
+ fail_reason);
+ client_id_buf = g_malloc (1 + 15);
+ client_id_buf[0] = 0;
+ nm_utils_random_bytes (&client_id_buf[1], 15);
+ return g_bytes_new_take (client_id_buf, 1 + 15);
+ }
}
static NMActStageReturn