device: handle failure in generate_duid_from_machine_id() in dhcp6_get_duid()

dhcp6_get_duid() already handles failure to generate the DUID in a
sensible manner. No reason to duplicate the error handling in
generate_duid_from_machine_id().

Especially, because generate_duid_from_machine_id() used to cache the
random DUID in memory and reuse it from then on. There is no reason to do
that, /etc/machine-id must be available to NetworkManager. We still
handle such a grave error gracefully by generating a random DUID.
This commit is contained in:
Thomas Haller 2018-06-11 12:27:03 +02:00
parent 8bb1aed2ad
commit 6d06a0e1b0
2 changed files with 19 additions and 27 deletions

View file

@ -7797,18 +7797,14 @@ generate_duid_from_machine_id (void)
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);
}
if (!nm_utils_machine_id_parse (machine_id_s, uuid))
return NULL;
/* 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);
global_duid = generate_duid_uuid (sha256_digest, len);
return g_bytes_ref (global_duid);
@ -7824,7 +7820,7 @@ 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;
NMDhcpDuidEnforce duid_enforce = NM_DHCP_DUID_ENFORCE_ALWAYS;
s_ip6 = nm_connection_get_setting_ip6_config (connection);
duid = nm_setting_ip6_config_get_dhcp_duid (NM_SETTING_IP6_CONFIG (s_ip6));
@ -7836,12 +7832,13 @@ dhcp6_get_duid (NMDevice *self, NMConnection *connection, GBytes *hwaddr, NMDhcp
}
if (!duid || nm_streq (duid, "lease")) {
duid_enforce = NM_DHCP_DUID_ENFORCE_NEVER;
duid_out = generate_duid_from_machine_id ();
if (!duid_out)
duid_error = "failure to read machine-id";
goto end;
}
duid_enforce = NM_DHCP_DUID_ENFORCE_ALWAYS;
if (!_nm_utils_dhcp_duid_valid (duid, &duid_out)) {
duid_error = "invalid duid";
goto end;
@ -7868,11 +7865,8 @@ dhcp6_get_duid (NMDevice *self, NMConnection *connection, GBytes *hwaddr, NMDhcp
gsize secret_key_len;
stable_id = _get_stable_id (self, connection, &stable_type);
if (!stable_id) {
nm_assert_not_reached ();
duid_error = "cannot retrieve the stable id";
goto end;
}
if (!stable_id)
g_return_val_if_reached (NULL);
salted_header = htonl (670531087 + stable_type);
@ -7933,8 +7927,7 @@ end:
if (!duid_out) {
guint8 uuid[16];
if (duid_error)
_LOGW (LOGD_IP6, "duid-gen (%s): %s. Fallback to random DUID-UUID.", duid, 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));
@ -7945,7 +7938,6 @@ end:
(duid_enforce == NM_DHCP_DUID_ENFORCE_ALWAYS) ? "enforcing" : "fallback");
NM_SET_OUT (out_enforce, duid_enforce);
return duid_out;
}
@ -7956,7 +7948,7 @@ dhcp6_start_with_link_ready (NMDevice *self, NMConnection *connection)
NMSettingIPConfig *s_ip6;
gs_unref_bytes GBytes *hwaddr = NULL;
gs_unref_bytes GBytes *duid = NULL;
NMDhcpDuidEnforce enforce_duid;
NMDhcpDuidEnforce enforce_duid = NM_DHCP_DUID_ENFORCE_NEVER;
const NMPlatformIP6Address *ll_addr = NULL;

View file

@ -2521,20 +2521,20 @@ nm_utils_machine_id_read (void)
*/
if ( !g_file_get_contents ("/etc/machine-id", &contents, NULL, NULL)
&& !g_file_get_contents (LOCALSTATEDIR "/lib/dbus/machine-id", &contents, NULL, NULL))
return FALSE;
return NULL;
contents = g_strstrip (contents);
for (i = 0; i < 32; i++) {
if (!g_ascii_isxdigit (contents[i]))
return FALSE;
return NULL;
if (contents[i] >= 'A' && contents[i] <= 'F') {
/* canonicalize to lower-case */
contents[i] = 'a' + (contents[i] - 'A');
}
}
if (contents[i] != '\0')
return FALSE;
return NULL;
return g_steal_pointer (&contents);
}