diff options
author | Thomas Haller <thaller@redhat.com> | 2020-09-10 12:46:53 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2020-09-11 16:18:36 +0200 |
commit | ed8d7ae26438867dd74dfebe1ffd5caf417f4896 (patch) | |
tree | e0927cd84c5b0fc9816a6252538180663745da81 | |
parent | b23825f457bc922aea7fd3cf4f8a5fa4ef3ac415 (diff) | |
download | NetworkManager-ed8d7ae26438867dd74dfebe1ffd5caf417f4896.tar.gz |
core: move nm_utils_generate_duid_from_machine_id() to "nm-core-utils.c"
-rw-r--r-- | src/devices/nm-device.c | 127 | ||||
-rw-r--r-- | src/nm-core-utils.c | 107 | ||||
-rw-r--r-- | src/nm-core-utils.h | 20 |
3 files changed, 138 insertions, 116 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index b7a9df1103..a063b6b31f 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -9662,111 +9662,6 @@ dhcp6_prefix_delegated (NMDhcpClient *client, /*****************************************************************************/ -/* RFC 3315 defines the epoch for the DUID-LLT time field on Jan 1st 2000. */ -#define EPOCH_DATETIME_200001010000 946684800 - -static GBytes * -generate_duid_llt (int arp_type, - const guint8 *hwaddr, - gsize hwaddr_len, - gint64 time) -{ - guint8 *arr; - const guint16 duid_type = htons (1); - const guint16 hw_type = htons (arp_type); - const guint32 duid_time = htonl (NM_MAX (0, time - EPOCH_DATETIME_200001010000)); - - if (!nm_utils_arp_type_get_hwaddr_relevant_part (arp_type, &hwaddr, &hwaddr_len)) - nm_assert_not_reached (); - - arr = g_new (guint8, 2 + 2 + 4 + hwaddr_len); - - memcpy (&arr[0], &duid_type, 2); - memcpy (&arr[2], &hw_type, 2); - memcpy (&arr[4], &duid_time, 4); - memcpy (&arr[8], hwaddr, hwaddr_len); - - return g_bytes_new_take (arr, 2 + 2 + 4 + hwaddr_len); -} - -static GBytes * -generate_duid_ll (int arp_type, - const guint8 *hwaddr, - gsize hwaddr_len) -{ - guint8 *arr; - const guint16 duid_type = htons (3); - const guint16 hw_type = htons (arp_type); - - if (!nm_utils_arp_type_get_hwaddr_relevant_part (arp_type, &hwaddr, &hwaddr_len)) - nm_assert_not_reached (); - - arr = g_new (guint8, 2 + 2 + hwaddr_len); - - memcpy (&arr[0], &duid_type, 2); - memcpy (&arr[2], &hw_type, 2); - memcpy (&arr[4], hwaddr, hwaddr_len); - - return g_bytes_new_take (arr, 2 + 2 + hwaddr_len); -} - -static GBytes * -generate_duid_uuid (const NMUuid *uuid) -{ - const guint16 duid_type = htons (4); - guint8 *duid_buffer; - - nm_assert (uuid); - - /* 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 - */ - G_STATIC_ASSERT_EXPR (sizeof (duid_type) == 2); - G_STATIC_ASSERT_EXPR (sizeof (*uuid) == 16); - duid_buffer = g_malloc (18); - memcpy (&duid_buffer[0], &duid_type, 2); - memcpy (&duid_buffer[2], uuid, 16); - return g_bytes_new_take (duid_buffer, 18); -} - -static GBytes * -generate_duid_from_machine_id (void) -{ - static GBytes *volatile global_duid = NULL; - GBytes *p; - -again: - p = g_atomic_pointer_get (&global_duid); - if (G_UNLIKELY (!p)) { - nm_auto_free_checksum GChecksum *sum = NULL; - const NMUuid *machine_id; - union { - guint8 sha256[NM_UTILS_CHECKSUM_LENGTH_SHA256]; - NMUuid uuid; - } digest; - - machine_id = nm_utils_machine_id_bin (); - - /* 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 *) machine_id, sizeof (*machine_id)); - nm_utils_checksum_get_digest (sum, digest.sha256); - - G_STATIC_ASSERT_EXPR (sizeof (digest.sha256) > sizeof (digest.uuid)); - p = generate_duid_uuid (&digest.uuid); - - if (!g_atomic_pointer_compare_and_exchange (&global_duid, NULL, p)) { - g_bytes_unref (p); - goto again; - } - } - - return g_bytes_ref (p); -} - static GBytes * dhcp6_get_duid (NMDevice *self, NMConnection *connection, GBytes *hwaddr, gboolean *out_enforce) { @@ -9795,7 +9690,7 @@ dhcp6_get_duid (NMDevice *self, NMConnection *connection, GBytes *hwaddr, gboole if (nm_streq (duid, "lease")) { duid_enforce = FALSE; - duid_out = generate_duid_from_machine_id (); + duid_out = nm_utils_generate_duid_from_machine_id (); goto out_good; } @@ -9821,10 +9716,10 @@ dhcp6_get_duid (NMDevice *self, NMConnection *connection, GBytes *hwaddr, gboole } if (nm_streq (duid, "ll")) - duid_out = generate_duid_ll (arp_type, hwaddr_bin, hwaddr_len); + duid_out = nm_utils_generate_duid_ll (arp_type, hwaddr_bin, hwaddr_len); else { - duid_out = generate_duid_llt (arp_type, hwaddr_bin, hwaddr_len, - nm_utils_host_id_get_timestamp_ns () / NM_UTILS_NSEC_PER_SEC); + duid_out = nm_utils_generate_duid_llt (arp_type, hwaddr_bin, hwaddr_len, + nm_utils_host_id_get_timestamp_ns () / NM_UTILS_NSEC_PER_SEC); } goto out_good; @@ -9901,10 +9796,10 @@ dhcp6_get_duid (NMDevice *self, NMConnection *connection, GBytes *hwaddr, gboole if (nm_streq (duid, "stable-ll")) { switch (arp_type) { case ARPHRD_ETHER: - duid_out = generate_duid_ll (arp_type, digest.hwaddr_eth, sizeof (digest.hwaddr_eth)); + duid_out = nm_utils_generate_duid_ll (arp_type, digest.hwaddr_eth, sizeof (digest.hwaddr_eth)); break; case ARPHRD_INFINIBAND: - duid_out = generate_duid_ll (arp_type, digest.hwaddr_infiniband, sizeof (digest.hwaddr_infiniband)); + duid_out = nm_utils_generate_duid_ll (arp_type, digest.hwaddr_infiniband, sizeof (digest.hwaddr_infiniband)); break; default: g_return_val_if_reached (NULL); @@ -9923,25 +9818,25 @@ dhcp6_get_duid (NMDevice *self, NMConnection *connection, GBytes *hwaddr, gboole /* don't use too old timestamps. They cannot be expressed in DUID-LLT and * would all be truncated to zero. */ - time = NM_MAX (time, EPOCH_DATETIME_200001010000 + EPOCH_DATETIME_THREE_YEARS); + time = NM_MAX (time, NM_UTILS_EPOCH_DATETIME_200001010000 + EPOCH_DATETIME_THREE_YEARS); switch (arp_type) { case ARPHRD_ETHER: timestamp = unaligned_read_be32 (&digest.llt_eth.timestamp); time -= timestamp % EPOCH_DATETIME_THREE_YEARS; - duid_out = generate_duid_llt (arp_type, digest.llt_eth.hwaddr, sizeof (digest.llt_eth.hwaddr), time); + duid_out = nm_utils_generate_duid_llt (arp_type, digest.llt_eth.hwaddr, sizeof (digest.llt_eth.hwaddr), time); break; case ARPHRD_INFINIBAND: timestamp = unaligned_read_be32 (&digest.llt_infiniband.timestamp); time -= timestamp % EPOCH_DATETIME_THREE_YEARS; - duid_out = generate_duid_llt (arp_type, digest.llt_infiniband.hwaddr, sizeof (digest.llt_infiniband.hwaddr), time); + duid_out = nm_utils_generate_duid_llt (arp_type, digest.llt_infiniband.hwaddr, sizeof (digest.llt_infiniband.hwaddr), time); break; default: g_return_val_if_reached (NULL); } } else { nm_assert (nm_streq (duid, "stable-uuid")); - duid_out = generate_duid_uuid (&digest.uuid); + duid_out = nm_utils_generate_duid_uuid (&digest.uuid); } goto out_good; @@ -9959,7 +9854,7 @@ out_fail: duid, duid_error); nm_utils_random_bytes (&uuid, sizeof (uuid)); - duid_out = generate_duid_uuid (&uuid); + duid_out = nm_utils_generate_duid_uuid (&uuid); } out_good: diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c index 1f976f2c30..3e785c38a5 100644 --- a/src/nm-core-utils.c +++ b/src/nm-core-utils.c @@ -3757,6 +3757,113 @@ nm_utils_dhcp_client_id_systemd_node_specific (guint32 iaid) /*****************************************************************************/ +GBytes * +nm_utils_generate_duid_llt (int arp_type, + const guint8 *hwaddr, + gsize hwaddr_len, + gint64 time) +{ + guint8 *arr; + const guint16 duid_type = htons (1); + const guint16 hw_type = htons (arp_type); + const guint32 duid_time = htonl (NM_MAX (0, time - NM_UTILS_EPOCH_DATETIME_200001010000)); + + if (!nm_utils_arp_type_get_hwaddr_relevant_part (arp_type, &hwaddr, &hwaddr_len)) + nm_assert_not_reached (); + + arr = g_new (guint8, (2u + 2u + 4u) + hwaddr_len); + + memcpy (&arr[0], &duid_type, 2); + memcpy (&arr[2], &hw_type, 2); + memcpy (&arr[4], &duid_time, 4); + memcpy (&arr[8], hwaddr, hwaddr_len); + + return g_bytes_new_take (arr, (2u + 2u + 4u) + hwaddr_len); +} + +GBytes * +nm_utils_generate_duid_ll (int arp_type, + const guint8 *hwaddr, + gsize hwaddr_len) +{ + guint8 *arr; + const guint16 duid_type = htons (3); + const guint16 hw_type = htons (arp_type); + + if (!nm_utils_arp_type_get_hwaddr_relevant_part (arp_type, &hwaddr, &hwaddr_len)) + nm_assert_not_reached (); + + arr = g_new (guint8, (2u + 2u) + hwaddr_len); + + memcpy (&arr[0], &duid_type, 2); + memcpy (&arr[2], &hw_type, 2); + memcpy (&arr[4], hwaddr, hwaddr_len); + + return g_bytes_new_take (arr, (2u + 2u) + hwaddr_len); +} + +GBytes * +nm_utils_generate_duid_uuid (const NMUuid *uuid) +{ + const guint16 duid_type = htons (4); + guint8 *duid_buffer; + + nm_assert (uuid); + + /* 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 + */ + G_STATIC_ASSERT_EXPR (sizeof (duid_type) == 2); + G_STATIC_ASSERT_EXPR (sizeof (*uuid) == 16); + duid_buffer = g_malloc (18); + memcpy (&duid_buffer[0], &duid_type, 2); + memcpy (&duid_buffer[2], uuid, 16); + return g_bytes_new_take (duid_buffer, 18); +} + +GBytes * +nm_utils_generate_duid_from_machine_id (void) +{ + static GBytes *volatile global_duid = NULL; + GBytes *p; + +again: + p = g_atomic_pointer_get (&global_duid); + if (G_UNLIKELY (!p)) { + nm_auto_free_checksum GChecksum *sum = NULL; + const NMUuid *machine_id; + union { + guint8 sha256[NM_UTILS_CHECKSUM_LENGTH_SHA256]; + NMUuid uuid; + } digest; + + machine_id = nm_utils_machine_id_bin (); + + /* Hash the machine ID so it's not leaked to the network. + * + * Optimally, we would choose an use case specific seed, but for historic + * reasons we didn't. */ + sum = g_checksum_new (G_CHECKSUM_SHA256); + g_checksum_update (sum, (const guchar *) machine_id, sizeof (*machine_id)); + nm_utils_checksum_get_digest (sum, digest.sha256); + + G_STATIC_ASSERT_EXPR (sizeof (digest.sha256) > sizeof (digest.uuid)); + p = nm_utils_generate_duid_uuid (&digest.uuid); + + if (!g_atomic_pointer_compare_and_exchange (&global_duid, NULL, p)) { + g_bytes_unref (p); + goto again; + } + } + + return g_bytes_ref (p); +} + +/*****************************************************************************/ + /** * nm_utils_setpgid: * @unused: unused diff --git a/src/nm-core-utils.h b/src/nm-core-utils.h index 8b5e69916d..0ac95e285e 100644 --- a/src/nm-core-utils.h +++ b/src/nm-core-utils.h @@ -430,6 +430,26 @@ GBytes *nm_utils_dhcp_client_id_systemd_node_specific (guint32 iaid); /*****************************************************************************/ +/* RFC 3315 defines the epoch for the DUID-LLT time field on Jan 1st 2000. */ +#define NM_UTILS_EPOCH_DATETIME_200001010000 946684800 + +struct _NMUuid; + +GBytes *nm_utils_generate_duid_llt (int arp_type, + const guint8 *hwaddr, + gsize hwaddr_len, + gint64 time); + +GBytes *nm_utils_generate_duid_ll (int arp_type, + const guint8 *hwaddr, + gsize hwaddr_len); + +GBytes *nm_utils_generate_duid_uuid (const struct _NMUuid *uuid); + +GBytes *nm_utils_generate_duid_from_machine_id (void); + +/*****************************************************************************/ + void nm_utils_array_remove_at_indexes (GArray *array, const guint *indexes_to_delete, gsize len); void nm_utils_setpgid (gpointer unused); |