diff --git a/src/libnm-core-impl/nm-utils.c b/src/libnm-core-impl/nm-utils.c index 5bb43c8d00..4c4d98d25b 100644 --- a/src/libnm-core-impl/nm-utils.c +++ b/src/libnm-core-impl/nm-utils.c @@ -3055,151 +3055,6 @@ nm_utils_uuid_generate(void) return nm_uuid_generate_random_str_malloc(); } -/** - * nm_utils_uuid_generate_from_string_bin: - * @uuid: the UUID to update inplace. This function cannot - * fail to succeed. - * @s: a string to use as the seed for the UUID - * @slen: if negative, treat @s as zero terminated C string. - * Otherwise, assume the length as given (and allow @s to be - * non-null terminated or contain '\0'). - * @uuid_type: a type identifier which UUID format to generate. - * @type_args: additional arguments, depending on the uuid_type - * - * For a given @s, this function will always return the same UUID. - * - * Returns: the input @uuid. This function cannot fail. - **/ -NMUuid * -nm_utils_uuid_generate_from_string_bin(NMUuid * uuid, - const char *s, - gssize slen, - int uuid_type, - gpointer type_args) -{ - g_return_val_if_fail(uuid, FALSE); - g_return_val_if_fail(slen == 0 || s, FALSE); - - if (slen < 0) - slen = s ? strlen(s) : 0; - - switch (uuid_type) { - case NM_UTILS_UUID_TYPE_LEGACY: - g_return_val_if_fail(!type_args, NULL); - nm_crypto_md5_hash(NULL, 0, (guint8 *) s, slen, (guint8 *) uuid, sizeof(*uuid)); - break; - case NM_UTILS_UUID_TYPE_VERSION3: - case NM_UTILS_UUID_TYPE_VERSION5: - { - NMUuid ns_uuid = {}; - - if (type_args) { - /* type_args can be a name space UUID. Interpret it as (char *) */ - if (!nm_uuid_parse(type_args, &ns_uuid)) - g_return_val_if_reached(NULL); - } - - if (uuid_type == NM_UTILS_UUID_TYPE_VERSION3) { - nm_crypto_md5_hash((guint8 *) s, - slen, - (guint8 *) &ns_uuid, - sizeof(ns_uuid), - (guint8 *) uuid, - sizeof(*uuid)); - } else { - nm_auto_free_checksum GChecksum *sum = NULL; - union { - guint8 sha1[NM_UTILS_CHECKSUM_LENGTH_SHA1]; - NMUuid uuid; - } digest; - - sum = g_checksum_new(G_CHECKSUM_SHA1); - g_checksum_update(sum, (guchar *) &ns_uuid, sizeof(ns_uuid)); - g_checksum_update(sum, (guchar *) s, slen); - nm_utils_checksum_get_digest(sum, digest.sha1); - - G_STATIC_ASSERT_EXPR(sizeof(digest.sha1) > sizeof(digest.uuid)); - *uuid = digest.uuid; - } - - uuid->uuid[6] = (uuid->uuid[6] & 0x0F) | (uuid_type << 4); - uuid->uuid[8] = (uuid->uuid[8] & 0x3F) | 0x80; - break; - } - default: - g_return_val_if_reached(NULL); - } - - return uuid; -} - -/** - * nm_utils_uuid_generate_from_string: - * @s: a string to use as the seed for the UUID - * @slen: if negative, treat @s as zero terminated C string. - * Otherwise, assume the length as given (and allow @s to be - * non-null terminated or contain '\0'). - * @uuid_type: a type identifier which UUID format to generate. - * @type_args: additional arguments, depending on the uuid_type - * - * For a given @s, this function will always return the same UUID. - * - * Returns: a newly allocated UUID suitable for use as the #NMSettingConnection - * object's #NMSettingConnection:id: property - **/ -char * -nm_utils_uuid_generate_from_string(const char *s, gssize slen, int uuid_type, gpointer type_args) -{ - NMUuid uuid; - - nm_utils_uuid_generate_from_string_bin(&uuid, s, slen, uuid_type, type_args); - return nm_uuid_unparse(&uuid, g_new(char, 37)); -} - -/** - * _nm_utils_uuid_generate_from_strings: - * @string1: a variadic list of strings. Must be NULL terminated. - * - * Returns a variant3 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_utils_uuid_generate_from_strings(const char *string1, ...) -{ - if (!string1) - return nm_utils_uuid_generate_from_string(NULL, - 0, - NM_UTILS_UUID_TYPE_VERSION3, - NM_UTILS_UUID_NS); - - { - nm_auto_str_buf NMStrBuf str = NM_STR_BUF_INIT(NM_UTILS_GET_NEXT_REALLOC_SIZE_104, 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_utils_uuid_generate_from_string(nm_str_buf_get_str_unsafe(&str), - str.len, - NM_UTILS_UUID_TYPE_VERSION3, - NM_UTILS_UUID_NS); - } -} - /*****************************************************************************/ static gboolean diff --git a/src/libnm-core-intern/nm-core-internal.h b/src/libnm-core-intern/nm-core-internal.h index f4edcedefb..03c2cbb5b4 100644 --- a/src/libnm-core-intern/nm-core-internal.h +++ b/src/libnm-core-intern/nm-core-internal.h @@ -352,24 +352,6 @@ gboolean _nm_utils_check_module_file(const char * name, /*****************************************************************************/ -#define NM_UTILS_UUID_TYPE_LEGACY 0 -#define NM_UTILS_UUID_TYPE_VERSION3 3 -#define NM_UTILS_UUID_TYPE_VERSION5 5 - -NMUuid *nm_utils_uuid_generate_from_string_bin(NMUuid * uuid, - const char *s, - gssize slen, - int uuid_type, - gpointer type_args); - -char * -nm_utils_uuid_generate_from_string(const char *s, gssize slen, int uuid_type, gpointer type_args); - -/* arbitrarily chosen namespace UUID for _nm_utils_uuid_generate_from_strings() */ -#define NM_UTILS_UUID_NS "b425e9fb-7598-44b4-9e3b-5a2e3aaa4905" - -char *_nm_utils_uuid_generate_from_strings(const char *string1, ...) G_GNUC_NULL_TERMINATED; - void _nm_dbus_errors_init(void); extern gboolean _nm_utils_is_manager_process; diff --git a/src/libnm-glib-aux/nm-uuid.c b/src/libnm-glib-aux/nm-uuid.c index d4ccca52a6..564daeb720 100644 --- a/src/libnm-glib-aux/nm-uuid.c +++ b/src/libnm-glib-aux/nm-uuid.c @@ -5,6 +5,7 @@ #include "nm-uuid.h" #include "libnm-glib-aux/nm-random-utils.h" +#include "libnm-glib-aux/nm-str-buf.h" /*****************************************************************************/ @@ -153,3 +154,150 @@ nm_uuid_generate_random_str(char buf[static 37]) nm_uuid_generate_random(&uuid); return nm_uuid_unparse(&uuid, buf); } + +/*****************************************************************************/ + +/** + * nm_utils_uuid_generate_from_string_bin: + * @uuid: the UUID to update inplace. This function cannot + * fail to succeed. + * @s: a string to use as the seed for the UUID + * @slen: if negative, treat @s as zero terminated C string. + * Otherwise, assume the length as given (and allow @s to be + * non-null terminated or contain '\0'). + * @uuid_type: a type identifier which UUID format to generate. + * @type_args: additional arguments, depending on the uuid_type + * + * For a given @s, this function will always return the same UUID. + * + * Returns: the input @uuid. This function cannot fail. + **/ +NMUuid * +nm_utils_uuid_generate_from_string_bin(NMUuid * uuid, + const char *s, + gssize slen, + int uuid_type, + gpointer type_args) +{ + g_return_val_if_fail(uuid, FALSE); + g_return_val_if_fail(slen == 0 || s, FALSE); + + if (slen < 0) + slen = s ? strlen(s) : 0; + + switch (uuid_type) { + case NM_UTILS_UUID_TYPE_LEGACY: + g_return_val_if_fail(!type_args, NULL); + nm_crypto_md5_hash(NULL, 0, (guint8 *) s, slen, (guint8 *) uuid, sizeof(*uuid)); + break; + case NM_UTILS_UUID_TYPE_VERSION3: + case NM_UTILS_UUID_TYPE_VERSION5: + { + NMUuid ns_uuid = {}; + + if (type_args) { + /* type_args can be a name space UUID. Interpret it as (char *) */ + if (!nm_uuid_parse(type_args, &ns_uuid)) + g_return_val_if_reached(NULL); + } + + if (uuid_type == NM_UTILS_UUID_TYPE_VERSION3) { + nm_crypto_md5_hash((guint8 *) s, + slen, + (guint8 *) &ns_uuid, + sizeof(ns_uuid), + (guint8 *) uuid, + sizeof(*uuid)); + } else { + nm_auto_free_checksum GChecksum *sum = NULL; + union { + guint8 sha1[NM_UTILS_CHECKSUM_LENGTH_SHA1]; + NMUuid uuid; + } digest; + + sum = g_checksum_new(G_CHECKSUM_SHA1); + g_checksum_update(sum, (guchar *) &ns_uuid, sizeof(ns_uuid)); + g_checksum_update(sum, (guchar *) s, slen); + nm_utils_checksum_get_digest(sum, digest.sha1); + + G_STATIC_ASSERT_EXPR(sizeof(digest.sha1) > sizeof(digest.uuid)); + *uuid = digest.uuid; + } + + uuid->uuid[6] = (uuid->uuid[6] & 0x0F) | (uuid_type << 4); + uuid->uuid[8] = (uuid->uuid[8] & 0x3F) | 0x80; + break; + } + default: + g_return_val_if_reached(NULL); + } + + return uuid; +} + +/** + * nm_utils_uuid_generate_from_string: + * @s: a string to use as the seed for the UUID + * @slen: if negative, treat @s as zero terminated C string. + * Otherwise, assume the length as given (and allow @s to be + * non-null terminated or contain '\0'). + * @uuid_type: a type identifier which UUID format to generate. + * @type_args: additional arguments, depending on the uuid_type + * + * For a given @s, this function will always return the same UUID. + * + * Returns: a newly allocated UUID suitable for use as the #NMSettingConnection + * object's #NMSettingConnection:id: property + **/ +char * +nm_utils_uuid_generate_from_string(const char *s, gssize slen, int uuid_type, gpointer type_args) +{ + NMUuid uuid; + + nm_utils_uuid_generate_from_string_bin(&uuid, s, slen, uuid_type, type_args); + return nm_uuid_unparse(&uuid, g_new(char, 37)); +} + +/** + * _nm_utils_uuid_generate_from_strings: + * @string1: a variadic list of strings. Must be NULL terminated. + * + * Returns a variant3 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_utils_uuid_generate_from_strings(const char *string1, ...) +{ + if (!string1) + return nm_utils_uuid_generate_from_string(NULL, + 0, + NM_UTILS_UUID_TYPE_VERSION3, + NM_UTILS_UUID_NS); + + { + nm_auto_str_buf NMStrBuf str = NM_STR_BUF_INIT(NM_UTILS_GET_NEXT_REALLOC_SIZE_104, 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_utils_uuid_generate_from_string(nm_str_buf_get_str_unsafe(&str), + str.len, + NM_UTILS_UUID_TYPE_VERSION3, + NM_UTILS_UUID_NS); + } +} diff --git a/src/libnm-glib-aux/nm-uuid.h b/src/libnm-glib-aux/nm-uuid.h index a4be9536c3..2535d0d228 100644 --- a/src/libnm-glib-aux/nm-uuid.h +++ b/src/libnm-glib-aux/nm-uuid.h @@ -47,4 +47,24 @@ char *nm_uuid_generate_random_str(char buf[static 37]); /*****************************************************************************/ +#define NM_UTILS_UUID_TYPE_LEGACY 0 +#define NM_UTILS_UUID_TYPE_VERSION3 3 +#define NM_UTILS_UUID_TYPE_VERSION5 5 + +NMUuid *nm_utils_uuid_generate_from_string_bin(NMUuid * uuid, + const char *s, + gssize slen, + int uuid_type, + gpointer type_args); + +char * +nm_utils_uuid_generate_from_string(const char *s, gssize slen, int uuid_type, gpointer type_args); + +/* arbitrarily chosen namespace UUID for _nm_utils_uuid_generate_from_strings() */ +#define NM_UTILS_UUID_NS "b425e9fb-7598-44b4-9e3b-5a2e3aaa4905" + +char *_nm_utils_uuid_generate_from_strings(const char *string1, ...) G_GNUC_NULL_TERMINATED; + +/*****************************************************************************/ + #endif /* __NM_UUID_H__ */