mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-05 15:48:06 +02:00
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.
This commit is contained in:
parent
7a0b6b17bb
commit
0d841e7471
3 changed files with 62 additions and 74 deletions
|
|
@ -7750,6 +7750,37 @@ generate_duid_uuid (guint8 *data, gsize data_len)
|
|||
return g_bytes_new_take (duid_buffer, DUID_SIZE);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
@ -7760,8 +7791,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));
|
||||
|
|
@ -7772,14 +7803,18 @@ dhcp6_get_duid (NMDevice *self, NMConnection *connection, GBytes *hwaddr, NMDhcp
|
|||
duid = duid_default;
|
||||
}
|
||||
|
||||
if (!duid || nm_streq (duid, "lease"))
|
||||
return NULL;
|
||||
if (!duid || nm_streq (duid, "lease")) {
|
||||
duid_out = generate_duid_from_machine_id ();
|
||||
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) {
|
||||
|
|
@ -7819,7 +7854,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_THREE_YEARS (356 * 24 * 3600 * 3)
|
||||
if (nm_streq0 (duid, "ll")) {
|
||||
|
|
@ -7861,12 +7896,24 @@ 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);
|
||||
guint8 uuid[16];
|
||||
|
||||
if (duid_error)
|
||||
_LOGW (LOGD_IP6, "duid-gen (%s): %s. Fallback to random DUID-UUID.", duid, duid_error);
|
||||
|
||||
nm_utils_random_bytes (uuid, sizeof (uuid));
|
||||
duid_out = generate_duid_uuid (uuid, sizeof (uuid));
|
||||
}
|
||||
|
||||
_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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -512,66 +512,10 @@ nm_dhcp_client_start_ip4 (NMDhcpClient *self,
|
|||
return NM_DHCP_CLIENT_GET_CLASS (self)->ip4_start (self, dhcp_anycast_addr, last_ip4_address);
|
||||
}
|
||||
|
||||
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 ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue