summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancesco Giudici <fgiudici@redhat.com>2018-05-03 18:20:29 +0200
committerFrancesco Giudici <fgiudici@redhat.com>2018-06-07 14:38:02 +0200
commit105d6e4185ad2caab8a32afbe03b7ce1f3d9bb99 (patch)
tree94babed7f037907df33bac83d9aa0a8d094672f5
parentd5798713134050c580e905bcd65c8456abc72c7e (diff)
downloadNetworkManager-105d6e4185ad2caab8a32afbe03b7ce1f3d9bb99.tar.gz
dhcp: remove fallback DUID-UUID generation from dhcp code
This commit centralizes the DUID generation in nm-device.c. As a consequence, a DUID is always provided when starting a DHCPv6 client. The DHCP client can override the passed DUID with the value contained in the client-specific lease file.
-rw-r--r--src/devices/nm-device.c59
-rw-r--r--src/dhcp/nm-dhcp-client.c66
-rw-r--r--src/dhcp/nm-dhcp-dhclient.c3
3 files changed, 55 insertions, 73 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index e779c03e3a..fb96b465b8 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -7747,6 +7747,37 @@ generate_duid_uuid (guint8 *data, gsize data_len)
}
static GBytes *
+generate_duid_from_machine_id (void)
+{
+ gs_free const char *machine_id_s = NULL;
+ uuid_t uuid;
+ GChecksum *sum;
+ guint8 sha256_digest[32];
+ gsize len = sizeof (sha256_digest);
+ static GBytes *global_duid = NULL;
+
+ if (global_duid)
+ return g_bytes_ref (global_duid);
+
+ machine_id_s = nm_utils_machine_id_read ();
+ if (nm_utils_machine_id_parse (machine_id_s, uuid)) {
+ /* Hash the machine ID so it's not leaked to the network */
+ sum = g_checksum_new (G_CHECKSUM_SHA256);
+ g_checksum_update (sum, (const guchar *) &uuid, sizeof (uuid));
+ g_checksum_get_digest (sum, sha256_digest, &len);
+ g_checksum_free (sum);
+ } else {
+ nm_log_warn (LOGD_IP6, "global duid: failed to read " SYSCONFDIR "/machine-id "
+ "or " LOCALSTATEDIR "/lib/dbus/machine-id to generate "
+ "DHCPv6 DUID; creating non-persistent random DUID.");
+ nm_utils_random_bytes (sha256_digest, len);
+ }
+
+ global_duid = generate_duid_uuid (sha256_digest, len);
+ return g_bytes_ref (global_duid);
+}
+
+static GBytes *
dhcp6_get_duid (NMDevice *self, NMConnection *connection, GBytes *hwaddr, NMDhcpDuidEnforce *out_enforce)
{
NMSettingIPConfig *s_ip6;
@@ -7756,8 +7787,8 @@ dhcp6_get_duid (NMDevice *self, NMConnection *connection, GBytes *hwaddr, NMDhcp
GBytes *duid_out = NULL;
guint8 sha256_digest[32];
gsize len = sizeof (sha256_digest);
+ NMDhcpDuidEnforce duid_enforce = NM_DHCP_DUID_ENFORCE_NEVER;
- NM_SET_OUT (out_enforce, NM_DHCP_DUID_ENFORCE_NEVER);
s_ip6 = nm_connection_get_setting_ip6_config (connection);
duid = nm_setting_ip6_config_get_dhcp_duid (NM_SETTING_IP6_CONFIG (s_ip6));
@@ -7769,13 +7800,15 @@ dhcp6_get_duid (NMDevice *self, NMConnection *connection, GBytes *hwaddr, NMDhcp
}
if (!duid || nm_streq (duid, "lease"))
- return NULL;
+ goto end;
- if (!_nm_utils_dhcp_duid_valid (duid, &duid_out))
- return NULL;
+ if (!_nm_utils_dhcp_duid_valid (duid, &duid_out)) {
+ duid_error = "invalid duid";
+ goto end;
+ }
if (duid_out)
- return duid_out;
+ goto end;
if (NM_IN_STRSET (duid, "ll", "llt")) {
if (!hwaddr) {
@@ -7806,7 +7839,7 @@ dhcp6_get_duid (NMDevice *self, NMConnection *connection, GBytes *hwaddr, NMDhcp
g_checksum_free (sum);
}
- NM_SET_OUT (out_enforce, NM_DHCP_DUID_ENFORCE_ALWAYS);
+ duid_enforce = NM_DHCP_DUID_ENFORCE_ALWAYS;
#define EPOCH_DATETIME_200001010000 946684800
#define EPOCH_DATETIME_THREE_YEARS (356 * 24 * 3600 * 3)
@@ -7863,12 +7896,20 @@ dhcp6_get_duid (NMDevice *self, NMConnection *connection, GBytes *hwaddr, NMDhcp
duid_out = generate_duid_uuid (sha256_digest, len);
}
+ duid_error = "generation failed";
end:
if (!duid_out) {
- if (!duid_error)
- duid_error = "generation failed";
- _LOGD (LOGD_IP6, "duid-gen (%s): %s. Fallback to 'lease'.", duid, duid_error);
+ if (duid_error)
+ _LOGD (LOGD_IP6, "duid-gen (%s): %s. Fallback to 'lease'.", duid, duid_error);
+ duid_out = generate_duid_from_machine_id ();
}
+
+ _LOGD (LOGD_IP6, "DUID gen: '%s' (%s)",
+ nm_dhcp_utils_duid_to_string (duid_out),
+ (duid_enforce == NM_DHCP_DUID_ENFORCE_ALWAYS) ? "enforcing" : "fallback");
+
+ NM_SET_OUT (out_enforce, duid_enforce);
+
return duid_out;
}
diff --git a/src/dhcp/nm-dhcp-client.c b/src/dhcp/nm-dhcp-client.c
index 03d5dedbdf..be2b538db6 100644
--- a/src/dhcp/nm-dhcp-client.c
+++ b/src/dhcp/nm-dhcp-client.c
@@ -513,65 +513,9 @@ nm_dhcp_client_start_ip4 (NMDhcpClient *self,
}
static GBytes *
-generate_duid_from_machine_id (void)
-{
- const int DUID_SIZE = 18;
- guint8 *duid_buffer;
- GChecksum *sum;
- guint8 buffer[32]; /* SHA256 digest size */
- gsize sumlen = sizeof (buffer);
- const guint16 duid_type = g_htons (4);
- uuid_t uuid;
- gs_free char *machine_id_s = NULL;
- gs_free char *str = NULL;
- GBytes *duid;
-
- machine_id_s = nm_utils_machine_id_read ();
- if (nm_utils_machine_id_parse (machine_id_s, uuid)) {
- /* Hash the machine ID so it's not leaked to the network */
- sum = g_checksum_new (G_CHECKSUM_SHA256);
- g_checksum_update (sum, (const guchar *) &uuid, sizeof (uuid));
- g_checksum_get_digest (sum, buffer, &sumlen);
- g_checksum_free (sum);
- } else {
- nm_log_warn (LOGD_DHCP, "dhcp: failed to read " SYSCONFDIR "/machine-id "
- "or " LOCALSTATEDIR "/lib/dbus/machine-id to generate "
- "DHCPv6 DUID; creating non-persistent random DUID.");
-
- nm_utils_random_bytes (buffer, sizeof (buffer));
- }
-
- /* Generate a DHCP Unique Identifier for DHCPv6 using the
- * DUID-UUID method (see RFC 6355 section 4). Format is:
- *
- * u16: type (DUID-UUID = 4)
- * u8[16]: UUID bytes
- */
- duid_buffer = g_malloc (DUID_SIZE);
-
- G_STATIC_ASSERT_EXPR (sizeof (duid_type) == 2);
- memcpy (&duid_buffer[0], &duid_type, 2);
-
- /* Since SHA256 is 256 bits, but UUID is 128 bits, we just take the first
- * 128 bits of the SHA256 as the DUID-UUID.
- */
- memcpy (&duid_buffer[2], buffer, 16);
-
- duid = g_bytes_new_take (duid_buffer, DUID_SIZE);
- nm_log_dbg (LOGD_DHCP, "dhcp: generated DUID %s",
- (str = nm_dhcp_utils_duid_to_string (duid)));
- return duid;
-}
-
-static GBytes *
get_duid (NMDhcpClient *self)
{
- static GBytes *duid = NULL;
-
- if (G_UNLIKELY (!duid))
- duid = generate_duid_from_machine_id ();
-
- return g_bytes_ref (duid);
+ return NULL;
}
gboolean
@@ -595,6 +539,7 @@ nm_dhcp_client_start_ip6 (NMDhcpClient *self,
g_return_val_if_fail (priv->uuid != NULL, FALSE);
nm_assert (!priv->duid);
+ nm_assert (client_id);
switch (enforce_duid) {
case NM_DHCP_DUID_ENFORCE_NEVER:
@@ -604,11 +549,8 @@ nm_dhcp_client_start_ip6 (NMDhcpClient *self,
break;
/* fall through */
case NM_DHCP_DUID_ENFORCE_ALWAYS:
- if (client_id) {
- priv->duid = g_bytes_ref (client_id);
- break;
- }
- /* fall through */
+ priv->duid = g_bytes_ref (client_id);
+ break;
default:
nm_assert_not_reached ();
}
diff --git a/src/dhcp/nm-dhcp-dhclient.c b/src/dhcp/nm-dhcp-dhclient.c
index 93306ddd5f..3bd14ebe89 100644
--- a/src/dhcp/nm-dhcp-dhclient.c
+++ b/src/dhcp/nm-dhcp-dhclient.c
@@ -619,8 +619,7 @@ get_duid (NMDhcpClient *client)
}
}
- /* return our DUID, otherwise let the parent class make a default DUID */
- return duid ?: NM_DHCP_CLIENT_CLASS (nm_dhcp_dhclient_parent_class)->get_duid (client);
+ return duid;
}
/*****************************************************************************/