diff options
Diffstat (limited to 'src/core/nm-core-utils.c')
| -rw-r--r-- | src/core/nm-core-utils.c | 193 |
1 files changed, 128 insertions, 65 deletions
diff --git a/src/core/nm-core-utils.c b/src/core/nm-core-utils.c index 8fdc7379..747e1c09 100644 --- a/src/core/nm-core-utils.c +++ b/src/core/nm-core-utils.c @@ -39,8 +39,8 @@ #include "nm-setting-wireless-security.h" #ifdef __NM_SD_UTILS_H__ - #error \ - "nm-core-utils.c should stay independent of systemd utils. Are you looking for NetworkMangerUtils.c? " +#error \ + "nm-core-utils.c should stay independent of systemd utils. Are you looking for NetworkMangerUtils.c? " #endif G_STATIC_ASSERT(sizeof(NMUtilsTestFlags) <= sizeof(int)); @@ -458,7 +458,7 @@ _kc_invoke_callback(pid_t pid, data->sync.success = success; data->sync.child_status = child_status; - g_idle_add(_kc_invoke_callback_idle, data); + nm_g_idle_add(_kc_invoke_callback_idle, data); } /* nm_utils_kill_child_async: @@ -2484,8 +2484,6 @@ out: typedef struct { NMUuid bin; - char - _nul_sentinel; /* just for safety, if somebody accidentally uses the binary in a string context. */ /* depending on whether the string is packed or not (with/without hyphens), * it's 32 or 36 characters long (plus the trailing NUL). @@ -2503,9 +2501,8 @@ _uuid_data_init(UuidData *uuid_data, gboolean packed, gboolean is_fake, const NM nm_assert(uuid_data); nm_assert(uuid); - uuid_data->bin = *uuid; - uuid_data->_nul_sentinel = '\0'; - uuid_data->is_fake = is_fake; + uuid_data->bin = *uuid; + uuid_data->is_fake = is_fake; if (packed) { G_STATIC_ASSERT_EXPR(sizeof(uuid_data->str) >= (sizeof(*uuid) * 2 + 1)); nm_utils_bin2hexstr_full(uuid, sizeof(*uuid), '\0', FALSE, uuid_data->str); @@ -2573,7 +2570,7 @@ again: if (is_fake) { const guint8 *seed_bin; - const char * hash_seed; + const NMUuid *hash_seed; gsize seed_len; if (!allow_fake) { @@ -2583,6 +2580,9 @@ again: } if (nm_utils_host_id_get(&seed_bin, &seed_len)) { + static const NMUuid u = + NM_UUID_INIT(ab, 08, 5f, 06, b6, 29, 46, d1, a5, 53, 84, ee, ba, 56, 83, b6); + /* We have no valid machine-id but we have a valid secrey_key. * Generate a fake machine ID by hashing the secret-key. The secret_key * is commonly persisted, so it should be stable across reboots (despite @@ -2595,8 +2595,11 @@ again: * will call _machine_id_get(FALSE), so it won't allow accessing a fake * machine-id, thus avoiding the problem. */ fake_type = "secret-key"; - hash_seed = "ab085f06-b629-46d1-a553-84eeba5683b6"; + hash_seed = &u; } else { + static const NMUuid u = + NM_UUID_INIT(7f, f0, c8, f5, 53, 99, 49, 01, ab, 63, 61, bf, 59, 4a, be, 8b); + /* the secret-key is not valid/persistent either. That happens when we fail * to read/write the secret-key to disk. Fallback to boot-id. The boot-id * itself may be fake and randomly generated ad-hoc, but that is as best @@ -2604,7 +2607,7 @@ again: seed_bin = (const guint8 *) nm_utils_boot_id_bin(); seed_len = sizeof(NMUuid); fake_type = "boot-id"; - hash_seed = "7ff0c8f5-5399-4901-ab63-61bf594abe8b"; + hash_seed = &u; } /* the fake machine-id is based on secret-key/boot-id, but we hash it @@ -2613,7 +2616,7 @@ again: (const char *) seed_bin, seed_len, NM_UUID_TYPE_VERSION5, - (gpointer) hash_seed); + hash_seed); } if (!g_once_init_enter(&lock)) @@ -2874,10 +2877,11 @@ typedef struct { bool timestamp_is_good : 1; } HostIdData; +static const HostIdData *volatile host_id_static; + static const HostIdData * _host_id_get(void) { - static const HostIdData *volatile host_id_static; const HostIdData *host_id; again: @@ -2938,6 +2942,78 @@ nm_utils_host_id_get_timestamp_ns(void) return _host_id_get()->timestamp_ns; } +static GArray * nmtst_host_id_stack = NULL; +static GMutex nmtst_host_id_lock; +const HostIdData *nmtst_host_id_static_0 = NULL; + +void +nmtst_utils_host_id_push(const guint8 *host_id, + gssize host_id_len, + gboolean is_good, + const gint64 *timestamp_ns) +{ + NM_G_MUTEX_LOCKED(&nmtst_host_id_lock); + gs_free char *str1_to_free = NULL; + HostIdData * h; + + g_assert(host_id_len >= -1); + + if (host_id_len < 0) + host_id_len = host_id ? strlen((const char *) host_id) : 0; + + nm_log_dbg(LOGD_CORE, + "nmtst: host-id push: \"%s\" (%zu), is-good=%d, timestamp=%" G_GINT64_FORMAT "%s", + nm_utils_buf_utf8safe_escape(host_id, + host_id_len, + NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL, + &str1_to_free), + (gsize) host_id_len, + !!is_good, + timestamp_ns ? *timestamp_ns : 0, + timestamp_ns ? "" : " (not-good)"); + + if (!nmtst_host_id_stack) { + nmtst_host_id_stack = g_array_new(FALSE, FALSE, sizeof(HostIdData)); + nmtst_host_id_static_0 = g_atomic_pointer_get(&host_id_static); + } + + h = nm_g_array_append_new(nmtst_host_id_stack, HostIdData); + + *h = (HostIdData){ + .host_id = nm_memdup(host_id, host_id_len), + .host_id_len = host_id_len, + .timestamp_ns = timestamp_ns ? *timestamp_ns : 0, + .is_good = is_good, + .timestamp_is_good = !!timestamp_ns, + }; + + g_atomic_pointer_set(&host_id_static, h); +} + +void +nmtst_utils_host_id_pop(void) +{ + NM_G_MUTEX_LOCKED(&nmtst_host_id_lock); + HostIdData *h; + + g_assert(nmtst_host_id_stack); + g_assert(nmtst_host_id_stack->len > 0); + + nm_log_dbg(LOGD_CORE, "nmtst: host-id pop"); + + h = &g_array_index(nmtst_host_id_stack, HostIdData, nmtst_host_id_stack->len - 1); + + g_free((char *) h->host_id); + g_array_set_size(nmtst_host_id_stack, nmtst_host_id_stack->len - 1u); + + if (!g_atomic_pointer_compare_and_exchange( + &host_id_static, + h, + nmtst_host_id_stack->len == 0u ? nmtst_host_id_static_0 + : nm_g_array_last(nmtst_host_id_stack, HostIdData))) + g_assert_not_reached(); +} + /*****************************************************************************/ static const UuidData * @@ -3423,15 +3499,14 @@ _is_reserved_ipv6_iid(const guint8 *iid) return FALSE; } -static gboolean -_set_stable_privacy(NMUtilsStableType stable_type, - struct in6_addr * addr, - const char * ifname, - const char * network_id, - guint32 dad_counter, - const guint8 * host_id, - gsize host_id_len, - GError ** error) +void +nm_utils_ipv6_addr_set_stable_privacy_with_host_id(NMUtilsStableType stable_type, + struct in6_addr * addr, + const char * ifname, + const char * network_id, + guint32 dad_counter, + const guint8 * host_id, + gsize host_id_len) { nm_auto_free_checksum GChecksum *sum = NULL; guint8 digest[NM_UTILS_CHECKSUM_LENGTH_SHA256]; @@ -3480,30 +3555,29 @@ _set_stable_privacy(NMUtilsStableType stable_type, } memcpy(addr->s6_addr + 8, &digest[0], 8); - return TRUE; } -gboolean -nm_utils_ipv6_addr_set_stable_privacy_impl(NMUtilsStableType stable_type, - struct in6_addr * addr, - const char * ifname, - const char * network_id, - guint32 dad_counter, - guint8 * host_id, - gsize host_id_len, - GError ** error) +void +nm_utils_ipv6_addr_set_stable_privacy(NMUtilsStableType stable_type, + struct in6_addr * addr, + const char * ifname, + const char * network_id, + guint32 dad_counter) { - return _set_stable_privacy(stable_type, - addr, - ifname, - network_id, - dad_counter, - host_id, - host_id_len, - error); + const guint8 *host_id; + gsize host_id_len; + + nm_utils_host_id_get(&host_id, &host_id_len); + + nm_utils_ipv6_addr_set_stable_privacy_with_host_id(stable_type, + addr, + ifname, + network_id, + dad_counter, + host_id, + host_id_len); } -#define RFC7217_IDGEN_RETRIES 3 /** * nm_utils_ipv6_addr_set_stable_privacy: * @@ -3513,19 +3587,16 @@ nm_utils_ipv6_addr_set_stable_privacy_impl(NMUtilsStableType stable_type, * Returns: %TRUE on success, %FALSE if the address could not be generated. */ gboolean -nm_utils_ipv6_addr_set_stable_privacy(NMUtilsStableType stable_type, - struct in6_addr * addr, - const char * ifname, - const char * network_id, - guint32 dad_counter, - GError ** error) +nm_utils_ipv6_addr_set_stable_privacy_may_fail(NMUtilsStableType stable_type, + struct in6_addr * addr, + const char * ifname, + const char * network_id, + guint32 dad_counter, + GError ** error) { - const guint8 *host_id; - gsize host_id_len; - g_return_val_if_fail(network_id, FALSE); - if (dad_counter >= RFC7217_IDGEN_RETRIES) { + if (dad_counter >= NM_STABLE_PRIVACY_RFC7217_IDGEN_RETRIES) { g_set_error_literal(error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, @@ -3533,16 +3604,8 @@ nm_utils_ipv6_addr_set_stable_privacy(NMUtilsStableType stable_type, return FALSE; } - nm_utils_host_id_get(&host_id, &host_id_len); - - return _set_stable_privacy(stable_type, - addr, - ifname, - network_id, - dad_counter, - host_id, - host_id_len, - error); + nm_utils_ipv6_addr_set_stable_privacy(stable_type, addr, ifname, network_id, dad_counter); + return TRUE; } /*****************************************************************************/ @@ -4069,8 +4132,8 @@ nm_utils_get_reverse_dns_domains_ip_4(guint32 addr, guint8 plen, GPtrArray *doma len = len0; str = s = g_malloc(len); for (i = octets; i > 0; i--) - nm_utils_strbuf_append(&s, &len, "%u.", p[i - 1] & 0xff); - nm_utils_strbuf_append_str(&s, &len, "in-addr.arpa"); + nm_strbuf_append(&s, &len, "%u.", p[i - 1] & 0xff); + nm_strbuf_append_str(&s, &len, "in-addr.arpa"); g_ptr_array_add(domains, str); @@ -4121,8 +4184,8 @@ nm_utils_get_reverse_dns_domains_ip_6(const struct in6_addr *ip, guint8 plen, GP str = s = g_malloc(len); for (j = nibbles - 1; j >= 0; j--) - nm_utils_strbuf_append(&s, &len, "%x.", (addr.s6_addr[j / 2] >> N_SHIFT(j)) & 0xf); - nm_utils_strbuf_append_str(&s, &len, "ip6.arpa"); + nm_strbuf_append(&s, &len, "%x.", (addr.s6_addr[j / 2] >> N_SHIFT(j)) & 0xf); + nm_strbuf_append_str(&s, &len, "ip6.arpa"); g_ptr_array_add(domains, str); |