diff options
author | Francesco Giudici <fgiudici@redhat.com> | 2018-05-03 18:20:29 +0200 |
---|---|---|
committer | Francesco Giudici <fgiudici@redhat.com> | 2018-06-07 14:38:02 +0200 |
commit | 105d6e4185ad2caab8a32afbe03b7ce1f3d9bb99 (patch) | |
tree | 94babed7f037907df33bac83d9aa0a8d094672f5 | |
parent | d5798713134050c580e905bcd65c8456abc72c7e (diff) | |
download | NetworkManager-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.c | 59 | ||||
-rw-r--r-- | src/dhcp/nm-dhcp-client.c | 66 | ||||
-rw-r--r-- | src/dhcp/nm-dhcp-dhclient.c | 3 |
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; } /*****************************************************************************/ |