all: merge branch 'th/uuid-generate-from-strings'

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1403
This commit is contained in:
Thomas Haller 2022-10-03 18:03:20 +02:00
commit 2ecfec708f
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
7 changed files with 220 additions and 55 deletions

View file

@ -1725,11 +1725,12 @@ new_default_connection(NMDevice *self)
/* Create a stable UUID. The UUID is also the Network_ID for stable-privacy addr-gen-mode,
* thus when it changes we will also generate different IPv6 addresses. */
uuid = nm_uuid_generate_from_strings("default-wired",
uuid = nm_uuid_generate_from_strings(NM_UUID_TYPE_VERSION3,
&nm_uuid_ns_1,
"default-wired",
nm_utils_machine_id_str(),
defname,
perm_hw_addr ?: iface,
NULL);
perm_hw_addr ?: iface);
g_object_set(setting,
NM_SETTING_CONNECTION_ID,

View file

@ -2296,7 +2296,8 @@ test_read_missing_id_uuid(void)
gs_free char *expected_uuid = NULL;
const char *FILENAME = TEST_KEYFILES_DIR "/Test_Missing_ID_UUID";
expected_uuid = nm_uuid_generate_from_strings("keyfile", FILENAME, NULL);
expected_uuid =
nm_uuid_generate_from_strings(NM_UUID_TYPE_VERSION3, &nm_uuid_ns_1, "keyfile", FILENAME);
connection = keyfile_read_connection_from_file(FILENAME);

View file

@ -3800,7 +3800,10 @@ nm_keyfile_read_ensure_uuid(NMConnection *connection, const char *fallback_uuid_
if (nm_setting_connection_get_uuid(s_con))
return FALSE;
hashed_uuid = nm_uuid_generate_from_strings("keyfile", fallback_uuid_seed, NULL);
hashed_uuid = nm_uuid_generate_from_strings(NM_UUID_TYPE_VERSION3,
&nm_uuid_ns_1,
"keyfile",
fallback_uuid_seed);
g_object_set(s_con, NM_SETTING_CONNECTION_UUID, hashed_uuid, NULL);
return TRUE;
}

View file

@ -7946,12 +7946,18 @@ test_nm_utils_uuid_generate_from_string(void)
/*****************************************************************************/
static void
__test_uuid(const char *expected_uuid, const char *str, gssize slen, char *uuid_test)
_check_uuid(NMUuidType uuid_type,
const NMUuid *type_arg,
const char *expected_uuid,
const char *str,
gssize slen,
char *uuid_test)
{
g_assert(uuid_test);
g_assert(nm_uuid_is_normalized(uuid_test));
g_assert(str);
if (strcmp(uuid_test, expected_uuid)) {
if (!nm_streq(uuid_test, expected_uuid)) {
g_error("UUID test failed (1): text=%s, len=%lld, expected=%s, uuid_test=%s",
str,
(long long) slen,
@ -7960,7 +7966,7 @@ __test_uuid(const char *expected_uuid, const char *str, gssize slen, char *uuid_
}
g_free(uuid_test);
uuid_test = nm_uuid_generate_from_string_str(str, slen, NM_UUID_TYPE_VERSION3, &nm_uuid_ns_1);
uuid_test = nm_uuid_generate_from_string_str(str, slen, uuid_type, type_arg);
g_assert(uuid_test);
g_assert(nm_utils_is_uuid(uuid_test));
@ -7975,8 +7981,22 @@ __test_uuid(const char *expected_uuid, const char *str, gssize slen, char *uuid_
g_free(uuid_test);
}
#define _test_uuid(expected_uuid, str, strlen, ...) \
__test_uuid(expected_uuid, str, strlen, nm_uuid_generate_from_strings(__VA_ARGS__, NULL))
#define check_uuid(uuid_type, type_arg, expected_uuid, str, ...) \
({ \
const NMUuidType _uuid_type = (uuid_type); \
const NMUuid *_type_arg = type_arg; \
const char *_expected_uuid = (expected_uuid); \
const char *_str = (str); \
const gsize _strlen = NM_STRLEN(str); \
\
_check_uuid( \
_uuid_type, \
_type_arg, \
_expected_uuid, \
_str, \
_strlen, \
nm_uuid_generate_from_strings_strv(_uuid_type, _type_arg, NM_MAKE_STRV(__VA_ARGS__))); \
})
static void
test_nm_utils_uuid_generate_from_strings(void)
@ -7998,20 +8018,141 @@ test_nm_utils_uuid_generate_from_strings(void)
g_assert_cmpstr(NM_UUID_NS_1, ==, nm_uuid_unparse(&nm_uuid_ns_1, buf));
g_assert_cmpstr(NM_UUID_NS_ZERO, ==, nm_uuid_unparse(&nm_uuid_ns_zero, buf));
_test_uuid("b07c334a-399b-32de-8d50-58e4e08f98e3", "", 0, NULL);
_test_uuid("b8a426cb-bcb5-30a3-bd8f-6786fea72df9", "\0", 1, "");
_test_uuid("12a4a982-7aae-39e1-951e-41aeb1250959", "a\0", 2, "a");
_test_uuid("69e22c7e-f89f-3a43-b239-1cb52ed8db69", "aa\0", 3, "aa");
_test_uuid("59829fd3-5ad5-3d90-a7b0-4911747e4088", "\0\0", 2, "", "");
_test_uuid("01ad0e06-6c50-3384-8d86-ddab81421425", "a\0\0", 3, "a", "");
_test_uuid("e1ed8647-9ed3-3ec8-8c6d-e8204524d71d", "aa\0\0", 4, "aa", "");
_test_uuid("fb1c7cd6-275c-3489-9382-83b900da8af0", "\0a\0", 3, "", "a");
_test_uuid("5d79494e-c4ba-31a6-80a2-d6016ccd7e17", "a\0a\0", 4, "a", "a");
_test_uuid("fd698d86-1b60-3ebe-855f-7aada9950a8d", "aa\0a\0", 5, "aa", "a");
_test_uuid("8c573b48-0f01-30ba-bb94-c5f59f4fe517", "\0aa\0", 4, "", "aa");
_test_uuid("2bdd3d46-eb83-3c53-a41b-a724d04b5544", "a\0aa\0", 5, "a", "aa");
_test_uuid("13d4b780-07c1-3ba7-b449-81c4844ef039", "aa\0aa\0", 6, "aa", "aa");
_test_uuid("dd265bf7-c05a-3037-9939-b9629858a477", "a\0b\0", 4, "a", "b");
_check_uuid(NM_UUID_TYPE_VERSION3,
&nm_uuid_ns_1,
"457229f4-fe49-32f5-8b09-c531d81f44d9",
"x",
1,
nm_uuid_generate_from_strings_strv(NM_UUID_TYPE_VERSION3, &nm_uuid_ns_1, NULL));
check_uuid(NM_UUID_TYPE_VERSION3,
&nm_uuid_ns_1,
"b07c334a-399b-32de-8d50-58e4e08f98e3",
"",
NULL);
check_uuid(NM_UUID_TYPE_VERSION3,
&nm_uuid_ns_1,
"b8a426cb-bcb5-30a3-bd8f-6786fea72df9",
"\0",
"");
check_uuid(NM_UUID_TYPE_VERSION3,
&nm_uuid_ns_1,
"12a4a982-7aae-39e1-951e-41aeb1250959",
"a\0",
"a");
check_uuid(NM_UUID_TYPE_VERSION3,
&nm_uuid_ns_1,
"69e22c7e-f89f-3a43-b239-1cb52ed8db69",
"aa\0",
"aa");
check_uuid(NM_UUID_TYPE_VERSION3,
&nm_uuid_ns_1,
"59829fd3-5ad5-3d90-a7b0-4911747e4088",
"\0\0",
"",
"");
check_uuid(NM_UUID_TYPE_VERSION3,
&nm_uuid_ns_1,
"01ad0e06-6c50-3384-8d86-ddab81421425",
"a\0\0",
"a",
"");
check_uuid(NM_UUID_TYPE_VERSION3,
&nm_uuid_ns_1,
"e1ed8647-9ed3-3ec8-8c6d-e8204524d71d",
"aa\0\0",
"aa",
"");
check_uuid(NM_UUID_TYPE_VERSION3,
&nm_uuid_ns_1,
"fb1c7cd6-275c-3489-9382-83b900da8af0",
"\0a\0",
"",
"a");
check_uuid(NM_UUID_TYPE_VERSION3,
&nm_uuid_ns_1,
"5d79494e-c4ba-31a6-80a2-d6016ccd7e17",
"a\0a\0",
"a",
"a");
check_uuid(NM_UUID_TYPE_VERSION3,
&nm_uuid_ns_1,
"fd698d86-1b60-3ebe-855f-7aada9950a8d",
"aa\0a\0",
"aa",
"a");
check_uuid(NM_UUID_TYPE_VERSION3,
&nm_uuid_ns_1,
"8c573b48-0f01-30ba-bb94-c5f59f4fe517",
"\0aa\0",
"",
"aa");
check_uuid(NM_UUID_TYPE_VERSION3,
&nm_uuid_ns_1,
"2bdd3d46-eb83-3c53-a41b-a724d04b5544",
"a\0aa\0",
"a",
"aa");
check_uuid(NM_UUID_TYPE_VERSION3,
&nm_uuid_ns_1,
"13d4b780-07c1-3ba7-b449-81c4844ef039",
"aa\0aa\0",
"aa",
"aa");
check_uuid(NM_UUID_TYPE_VERSION3,
&nm_uuid_ns_1,
"dd265bf7-c05a-3037-9939-b9629858a477",
"a\0b\0",
"a",
"b");
check_uuid(NM_UUID_TYPE_VERSION5,
_uuid(NM_UUID_NS_URL),
"dd247a64-df22-5d30-8087-0bd709f6941a",
"a\0b\0",
"a",
"b");
check_uuid(NM_UUID_TYPE_VERSION5,
_uuid(NM_UUID_NS_URL),
"cbb93d73-085d-5072-94cd-a394b8149993",
"\0b\0",
"",
"b");
check_uuid(NM_UUID_TYPE_VERSION3,
_uuid(NM_UUID_NS_URL),
"916dcdd8-5042-3b9b-9763-4312a31e5735",
"aa\0a\0",
"aa",
"a");
check_uuid(NM_UUID_TYPE_VERSION3,
NULL,
"1700bb72-7116-3d1f-8cd2-6d074a40a3a9",
"aa\0a\0",
"aa",
"a");
check_uuid(NM_UUID_TYPE_VERSION3,
&nm_uuid_ns_zero,
"1700bb72-7116-3d1f-8cd2-6d074a40a3a9",
"aa\0a\0",
"aa",
"a");
check_uuid(NM_UUID_TYPE_VERSION5,
NULL,
"03c5de66-28ad-5a2e-8ed3-e256f3218900",
"aa\0a\0",
"aa",
"a");
check_uuid(NM_UUID_TYPE_VERSION5,
&nm_uuid_ns_zero,
"03c5de66-28ad-5a2e-8ed3-e256f3218900",
"aa\0a\0",
"aa",
"a");
check_uuid(NM_UUID_TYPE_LEGACY,
NULL,
"c38f63cf-1e50-ad7f-ae26-50f85cc5da47",
"aa\0a\0",
"aa",
"a");
}
static void

View file

@ -12,7 +12,8 @@
const NMUuid nm_uuid_ns_zero =
NM_UUID_INIT(00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00);
/* arbitrarily chosen namespace UUID for nm_uuid_generate_from_strings() */
/* arbitrarily chosen namespace UUID for some uses of nm_uuid_generate_from_strings().
* Try not to re-use this namespace, instead, generate a unique one. */
const NMUuid nm_uuid_ns_1 =
NM_UUID_INIT(b4, 25, e9, fb, 75, 98, 44, b4, 9e, 3b, 5a, 2e, 3a, aa, 49, 05);
@ -406,42 +407,51 @@ nm_uuid_generate_from_string_str(const char *s,
}
/**
* nm_uuid_generate_from_strings:
* @string1: a variadic list of strings. Must be NULL terminated.
* nm_uuid_generate_from_strings_strv:
* @uuid_type: the UUID type to use. Prefer version 5 unless you have
* good reasons.
* @type_args: the namespace UUID.
* @strv: (allow-none): the strv list to hash. Can be NULL, in which
* case the result is different from an empty array.
*
* Returns a variant3 UUID based on the concatenated C strings.
* Returns a @uuid_type UUID based on the concatenated C strings.
* It does not simply concatenate them, but also includes the
* terminating '\0' character. For example "a", "b", gives
* "a\0b\0".
*
* This has the advantage, that the following invocations
* all give different UUIDs: (NULL), (""), ("",""), ("","a"), ("a",""),
* ("aa"), ("aa", ""), ("", "aa"), ...
*/
char *
nm_uuid_generate_from_strings(const char *string1, ...)
nm_uuid_generate_from_strings_strv(NMUuidType uuid_type,
const NMUuid *type_args,
const char *const *strv)
{
if (!string1)
return nm_uuid_generate_from_string_str(NULL, 0, NM_UUID_TYPE_VERSION3, &nm_uuid_ns_1);
nm_auto_str_buf NMStrBuf str = NM_STR_BUF_INIT_A(NM_UTILS_GET_NEXT_REALLOC_SIZE_232, TRUE);
gsize slen;
const char *s;
{
nm_auto_str_buf NMStrBuf str = NM_STR_BUF_INIT_A(NM_UTILS_GET_NEXT_REALLOC_SIZE_232, FALSE);
va_list args;
const char *s;
nm_str_buf_append_len(&str, string1, strlen(string1) + 1u);
va_start(args, string1);
s = va_arg(args, const char *);
while (s) {
nm_str_buf_append_len(&str, s, strlen(s) + 1u);
s = va_arg(args, const char *);
}
va_end(args);
return nm_uuid_generate_from_string_str(nm_str_buf_get_str_unsafe(&str),
str.len,
NM_UUID_TYPE_VERSION3,
&nm_uuid_ns_1);
if (!strv) {
/* NULL is treated differently from an empty strv. We achieve that
* by using a non-empty, non-NUL terminated string (which cannot happen
* in the other cases). */
slen = 1;
s = "x";
} else if (!strv[0]) {
slen = 0;
s = "";
} else if (!strv[1]) {
slen = strlen(strv[0]) + 1u;
s = strv[0];
} else {
/* We concatenate the NUL termiated string, including the NUL
* character. This way, ("a","a"), ("aa"), ("aa","") all hash
* differently. */
for (; strv[0]; strv++)
nm_str_buf_append_len(&str, strv[0], strlen(strv[0]) + 1u);
slen = str.len;
s = nm_str_buf_get_str_unsafe(&str);
}
return nm_uuid_generate_from_string_str(s, slen, uuid_type, type_args);
}

View file

@ -9,6 +9,9 @@ typedef struct _NMUuid {
#define NM_UUID_INIT_ZERO() ((NMUuid){.uuid = {0}})
/* Beware, the 16 macro arguments are two hex-digits, not plain numbers. The macro
* will automatically add the "0x". In particular, "09" is not an octal number, it's
* 0x09. This oddity is so that the arguments look very much like the UUID in string form. */
#define NM_UUID_INIT(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) \
((NMUuid){ \
.uuid = {(0x##a0), \
@ -120,7 +123,12 @@ char *nm_uuid_generate_from_string_str(const char *s,
NMUuidType uuid_type,
const NMUuid *type_args);
char *nm_uuid_generate_from_strings(const char *string1, ...) G_GNUC_NULL_TERMINATED;
char *nm_uuid_generate_from_strings_strv(NMUuidType uuid_type,
const NMUuid *type_args,
const char *const *strv);
#define nm_uuid_generate_from_strings(uuid_type, type_args, ...) \
nm_uuid_generate_from_strings_strv((uuid_type), (type_args), NM_MAKE_STRV(__VA_ARGS__))
/*****************************************************************************/

View file

@ -307,13 +307,14 @@ connection_setting_add(GHashTable *nic,
s_index ? " " : "",
s_index ? s_index : "");
uuid = nm_uuid_generate_from_strings("ibft",
uuid = nm_uuid_generate_from_strings(NM_UUID_TYPE_VERSION3,
&nm_uuid_ns_1,
"ibft",
s_hwaddr,
s_vlanid ? "V" : "v",
s_vlanid ? s_vlanid : "",
s_ipaddr ? "A" : "DHCP",
s_ipaddr ? s_ipaddr : "",
NULL);
s_ipaddr ? s_ipaddr : "");
s_con = (NMSetting *) nm_connection_get_setting_connection(connection);
if (!s_con) {