From e67425347a09b07f23d95f5dd8f565e5cf8d9774 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 28 Nov 2014 14:26:24 +0100 Subject: libnm/test: add test for nm_utils_uuid_generate_from_string() --- libnm-core/nm-utils.c | 2 ++ libnm-core/tests/test-general.c | 43 ++++++++++++++++++++++++++++++++++++++++ libnm-util/nm-utils.c | 2 ++ libnm-util/tests/test-general.c | 44 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 91 insertions(+) diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 7f6cf49a1f..d27a0251b4 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -1964,6 +1964,8 @@ nm_utils_uuid_generate_from_string (const char *s) uuid_t *uuid; char *buf = NULL; + g_return_val_if_fail (s && *s, NULL); + uuid = g_malloc0 (sizeof (*uuid)); crypto_md5_hash (NULL, 0, s, strlen (s), (char *) uuid, sizeof (*uuid)); diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index 76d6d0ff80..827585bf37 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -3802,6 +3802,48 @@ test_hexstr2bin (void) } } +/******************************************************************************/ + +static void +_test_uuid (const char *expected_uuid, const char *str) +{ + gs_free char *uuid_test = NULL; + + g_assert (str); + + uuid_test = nm_utils_uuid_generate_from_string (str); + + g_assert (uuid_test); + g_assert (nm_utils_is_uuid (uuid_test)); + + if (strcmp (uuid_test, expected_uuid)) { + g_error ("UUID test failed: text=%s, uuid=%s, expected=%s", + str, uuid_test, expected_uuid); + } +} + +static void +test_nm_utils_uuid_generate_from_string (void) +{ + gs_free char *uuid_test = NULL; + + _test_uuid ("0cc175b9-c0f1-b6a8-31c3-99e269772661", "a"); + _test_uuid ("098f6bcd-4621-d373-cade-4e832627b4f6", "test"); + _test_uuid ("59c0547b-7fe2-1c15-2cce-e328e8bf6742", "/etc/NetworkManager/system-connections/em1"); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*char *nm_utils_uuid_generate_from_string(const char *): *s && *s*"); + uuid_test = nm_utils_uuid_generate_from_string (""); + g_assert (uuid_test == NULL); + g_test_assert_expected_messages (); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*char *nm_utils_uuid_generate_from_string(const char *): *s && *s*"); + uuid_test = nm_utils_uuid_generate_from_string (NULL); + g_assert (uuid_test == NULL); + g_test_assert_expected_messages (); +} + +/******************************************************************************/ + NMTST_DEFINE (); int main (int argc, char **argv) @@ -3896,6 +3938,7 @@ int main (int argc, char **argv) g_test_add_func ("/core/general/test_setting_ip6_gateway", test_setting_ip6_gateway); g_test_add_func ("/core/general/hexstr2bin", test_hexstr2bin); + g_test_add_func ("/core/general/test_nm_utils_uuid_generate_from_string", test_nm_utils_uuid_generate_from_string); return g_test_run (); } diff --git a/libnm-util/nm-utils.c b/libnm-util/nm-utils.c index 9735394275..2cbac34d3a 100644 --- a/libnm-util/nm-utils.c +++ b/libnm-util/nm-utils.c @@ -1490,6 +1490,8 @@ nm_utils_uuid_generate_from_string (const char *s) uuid_t *uuid; char *buf = NULL; + g_return_val_if_fail (s && *s, NULL); + if (!nm_utils_init (&error)) { g_warning ("error initializing crypto: (%d) %s", error ? error->code : 0, diff --git a/libnm-util/tests/test-general.c b/libnm-util/tests/test-general.c index c0cdb70a12..1d1f84eb43 100644 --- a/libnm-util/tests/test-general.c +++ b/libnm-util/tests/test-general.c @@ -2490,6 +2490,48 @@ test_libnm_linking (void) g_free (err); } +/******************************************************************************/ + +static void +_test_uuid (const char *expected_uuid, const char *str) +{ + gs_free char *uuid_test = NULL; + + g_assert (str); + + uuid_test = nm_utils_uuid_generate_from_string (str); + + g_assert (uuid_test); + g_assert (nm_utils_is_uuid (uuid_test)); + + if (strcmp (uuid_test, expected_uuid)) { + g_error ("UUID test failed: text=%s, uuid=%s, expected=%s", + str, uuid_test, expected_uuid); + } +} + +static void +test_nm_utils_uuid_generate_from_string (void) +{ + gs_free char *uuid_test = NULL; + + _test_uuid ("0cc175b9-c0f1-b6a8-31c3-99e269772661", "a"); + _test_uuid ("098f6bcd-4621-d373-cade-4e832627b4f6", "test"); + _test_uuid ("59c0547b-7fe2-1c15-2cce-e328e8bf6742", "/etc/NetworkManager/system-connections/em1"); + + g_test_expect_message ("libnm-util", G_LOG_LEVEL_CRITICAL, "*char *nm_utils_uuid_generate_from_string(const char *): *s && *s*"); + uuid_test = nm_utils_uuid_generate_from_string (""); + g_assert (uuid_test == NULL); + g_test_assert_expected_messages (); + + g_test_expect_message ("libnm-util", G_LOG_LEVEL_CRITICAL, "*char *nm_utils_uuid_generate_from_string(const char *): *s && *s*"); + uuid_test = nm_utils_uuid_generate_from_string (NULL); + g_assert (uuid_test == NULL); + g_test_assert_expected_messages (); +} + +/******************************************************************************/ + NMTST_DEFINE (); int main (int argc, char **argv) @@ -2567,6 +2609,8 @@ int main (int argc, char **argv) test_libnm_linking (); + test_nm_utils_uuid_generate_from_string (); + base = g_path_get_basename (argv[0]); fprintf (stdout, "%s: SUCCESS\n", base); g_free (base); -- cgit v1.2.1 From 50d1de13cbabb9e0de0b674deb9d068880c7d0d8 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 27 Nov 2014 19:29:27 +0100 Subject: libnm: don't heap allocate uuid temporary variable --- libnm-core/nm-utils.c | 8 +++----- libnm-util/nm-utils.c | 11 ++++------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index d27a0251b4..409d4dcc1e 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -1961,18 +1961,16 @@ nm_utils_uuid_generate (void) char * nm_utils_uuid_generate_from_string (const char *s) { - uuid_t *uuid; + uuid_t uuid; char *buf = NULL; g_return_val_if_fail (s && *s, NULL); - uuid = g_malloc0 (sizeof (*uuid)); - crypto_md5_hash (NULL, 0, s, strlen (s), (char *) uuid, sizeof (*uuid)); + crypto_md5_hash (NULL, 0, s, strlen (s), (char *) uuid, sizeof (uuid)); buf = g_malloc0 (37); - uuid_unparse_lower (*uuid, &buf[0]); + uuid_unparse_lower (uuid, &buf[0]); - g_free (uuid); return buf; } diff --git a/libnm-util/nm-utils.c b/libnm-util/nm-utils.c index 2cbac34d3a..cde29976ce 100644 --- a/libnm-util/nm-utils.c +++ b/libnm-util/nm-utils.c @@ -1487,7 +1487,7 @@ char * nm_utils_uuid_generate_from_string (const char *s) { GError *error = NULL; - uuid_t *uuid; + uuid_t uuid; char *buf = NULL; g_return_val_if_fail (s && *s, NULL); @@ -1501,21 +1501,18 @@ nm_utils_uuid_generate_from_string (const char *s) return NULL; } - uuid = g_malloc0 (sizeof (*uuid)); - if (!crypto_md5_hash (NULL, 0, s, strlen (s), (char *) uuid, sizeof (*uuid), &error)) { + if (!crypto_md5_hash (NULL, 0, s, strlen (s), (char *) uuid, sizeof (uuid), &error)) { g_warning ("error generating UUID: (%d) %s", error ? error->code : 0, error ? error->message : "unknown"); if (error) g_error_free (error); - goto out; + return NULL; } buf = g_malloc0 (37); - uuid_unparse_lower (*uuid, &buf[0]); + uuid_unparse_lower (uuid, &buf[0]); -out: - g_free (uuid); return buf; } -- cgit v1.2.1 From 21eb6b5d0de9656c9b6189d4d4733204b33742d8 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 27 Nov 2014 14:31:49 +0100 Subject: libnm: accept additional length argument in nm_utils_uuid_generate_from_string() This makes the function also useful for non C-strings, non UTF-8-strings, and generic blobs. --- libnm-core/nm-utils.c | 11 +++++++++-- libnm-core/nm-utils.h | 2 +- libnm-core/tests/test-general.c | 6 +++--- src/settings/plugins/ibft/reader.c | 2 +- src/settings/plugins/ifcfg-rh/reader.c | 4 ++-- src/settings/plugins/ifnet/connection_parser.c | 2 +- src/settings/plugins/ifupdown/parser.c | 2 +- src/settings/plugins/keyfile/reader.c | 2 +- 8 files changed, 19 insertions(+), 12 deletions(-) diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 409d4dcc1e..e2f29512a1 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -1952,6 +1952,9 @@ nm_utils_uuid_generate (void) /** * 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'). * * For a given @s, this function will always return the same UUID. * @@ -1959,14 +1962,18 @@ nm_utils_uuid_generate (void) * object's #NMSettingConnection:id: property **/ char * -nm_utils_uuid_generate_from_string (const char *s) +nm_utils_uuid_generate_from_string (const char *s, gssize slen) { uuid_t uuid; char *buf = NULL; g_return_val_if_fail (s && *s, NULL); + g_return_val_if_fail (slen < 0 || slen > 0, FALSE); - crypto_md5_hash (NULL, 0, s, strlen (s), (char *) uuid, sizeof (uuid)); + if (slen < 0) + slen = strlen (s); + + crypto_md5_hash (NULL, 0, s, slen, (char *) uuid, sizeof (uuid)); buf = g_malloc0 (37); uuid_unparse_lower (uuid, &buf[0]); diff --git a/libnm-core/nm-utils.h b/libnm-core/nm-utils.h index 85f5afd06a..9fb366a81b 100644 --- a/libnm-core/nm-utils.h +++ b/libnm-core/nm-utils.h @@ -121,7 +121,7 @@ GPtrArray *nm_utils_ip_routes_from_variant (GVariant *value, int family); char *nm_utils_uuid_generate (void); -char *nm_utils_uuid_generate_from_string (const char *s); +char *nm_utils_uuid_generate_from_string (const char *s, gssize slen); gboolean nm_utils_file_is_certificate (const char *filename); gboolean nm_utils_file_is_private_key (const char *filename, gboolean *out_encrypted); diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index 827585bf37..2fd68b0600 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -3811,7 +3811,7 @@ _test_uuid (const char *expected_uuid, const char *str) g_assert (str); - uuid_test = nm_utils_uuid_generate_from_string (str); + uuid_test = nm_utils_uuid_generate_from_string (str, -1); g_assert (uuid_test); g_assert (nm_utils_is_uuid (uuid_test)); @@ -3832,12 +3832,12 @@ test_nm_utils_uuid_generate_from_string (void) _test_uuid ("59c0547b-7fe2-1c15-2cce-e328e8bf6742", "/etc/NetworkManager/system-connections/em1"); g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*char *nm_utils_uuid_generate_from_string(const char *): *s && *s*"); - uuid_test = nm_utils_uuid_generate_from_string (""); + uuid_test = nm_utils_uuid_generate_from_string ("", -1); g_assert (uuid_test == NULL); g_test_assert_expected_messages (); g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*char *nm_utils_uuid_generate_from_string(const char *): *s && *s*"); - uuid_test = nm_utils_uuid_generate_from_string (NULL); + uuid_test = nm_utils_uuid_generate_from_string (NULL, -1); g_assert (uuid_test == NULL); g_test_assert_expected_messages (); } diff --git a/src/settings/plugins/ibft/reader.c b/src/settings/plugins/ibft/reader.c index 9bb1f471a8..61c4e1cfe7 100644 --- a/src/settings/plugins/ibft/reader.c +++ b/src/settings/plugins/ibft/reader.c @@ -408,7 +408,7 @@ connection_setting_add (const GPtrArray *block, s_vlanid ? s_vlanid : "0", s_hwaddr, s_ip4addr ? s_ip4addr : "DHCP"); - uuid = nm_utils_uuid_generate_from_string (uuid_data); + uuid = nm_utils_uuid_generate_from_string (uuid_data, -1); g_free (uuid_data); s_con = nm_setting_connection_new (); diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c index 8a35b9472a..52dee9d5e5 100644 --- a/src/settings/plugins/ifcfg-rh/reader.c +++ b/src/settings/plugins/ifcfg-rh/reader.c @@ -148,7 +148,7 @@ make_connection_setting (const char *file, uuid = svGetValue (ifcfg, "UUID", FALSE); if (!uuid || !strlen (uuid)) { g_free (uuid); - uuid = nm_utils_uuid_generate_from_string (ifcfg->fileName); + uuid = nm_utils_uuid_generate_from_string (ifcfg->fileName, -1); } g_object_set (s_con, @@ -4588,7 +4588,7 @@ uuid_from_file (const char *filename) uuid = svGetValue (ifcfg, "UUID", FALSE); if (!uuid || !strlen (uuid)) { g_free (uuid); - uuid = nm_utils_uuid_generate_from_string (ifcfg->fileName); + uuid = nm_utils_uuid_generate_from_string (ifcfg->fileName, -1); } svCloseFile (ifcfg); diff --git a/src/settings/plugins/ifnet/connection_parser.c b/src/settings/plugins/ifnet/connection_parser.c index 651cd8ea71..ba76579a12 100644 --- a/src/settings/plugins/ifnet/connection_parser.c +++ b/src/settings/plugins/ifnet/connection_parser.c @@ -1629,7 +1629,7 @@ ifnet_update_connection_from_config_block (const char *conn_name, id = connection_id_from_ifnet_name (conn_name); uuid = g_strdup (ifnet_get_data (conn_name, "uuid")); if (!uuid) - uuid = nm_utils_uuid_generate_from_string (id); + uuid = nm_utils_uuid_generate_from_string (id, -1); g_object_set (setting, NM_SETTING_CONNECTION_TYPE, type, diff --git a/src/settings/plugins/ifupdown/parser.c b/src/settings/plugins/ifupdown/parser.c index c6421d92e9..9af11976c8 100644 --- a/src/settings/plugins/ifupdown/parser.c +++ b/src/settings/plugins/ifupdown/parser.c @@ -686,7 +686,7 @@ ifupdown_update_connection_from_if_block (NMConnection *connection, idstr = g_strconcat ("Ifupdown (", block->name, ")", NULL); uuid_base = idstr; - uuid = nm_utils_uuid_generate_from_string (uuid_base); + uuid = nm_utils_uuid_generate_from_string (uuid_base, -1); g_object_set (s_con, NM_SETTING_CONNECTION_TYPE, type, NM_SETTING_CONNECTION_INTERFACE_NAME, block->name, diff --git a/src/settings/plugins/keyfile/reader.c b/src/settings/plugins/keyfile/reader.c index 242ba570b3..94982cef39 100644 --- a/src/settings/plugins/keyfile/reader.c +++ b/src/settings/plugins/keyfile/reader.c @@ -1316,7 +1316,7 @@ nm_keyfile_plugin_connection_from_file (const char *filename, GError **error) if (!nm_setting_connection_get_uuid (s_con)) { char *hashed_uuid; - hashed_uuid = nm_utils_uuid_generate_from_string (filename); + hashed_uuid = nm_utils_uuid_generate_from_string (filename, -1); g_object_set (s_con, NM_SETTING_CONNECTION_UUID, hashed_uuid, NULL); g_free (hashed_uuid); } -- cgit v1.2.1 From 1e313e000dceda2bd7a753c407cc3078a37ce402 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 27 Nov 2014 18:40:18 +0100 Subject: libnm: add a type argument to nm_utils_uuid_generate_from_string() There are different types (variants) of UUIDs defined. Especially variants 3 and 5 are name based variants (rfc4122). The way we create our UUIDs in nm_utils_uuid_generate_from_string() however does not create them according to RFC and does not set the flags to indicate the variant. Modify the signature of nm_utils_uuid_generate_from_string() to accept a "uuid_type" argument, so that we later can add other algorithms without breaking API. --- libnm-core/nm-utils.c | 8 +++++++- libnm-core/nm-utils.h | 4 +++- libnm-core/tests/test-general.c | 25 ++++++++++++++----------- src/settings/plugins/ibft/reader.c | 2 +- src/settings/plugins/ifcfg-rh/reader.c | 4 ++-- src/settings/plugins/ifnet/connection_parser.c | 2 +- src/settings/plugins/ifupdown/parser.c | 2 +- src/settings/plugins/keyfile/reader.c | 2 +- 8 files changed, 30 insertions(+), 19 deletions(-) diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index e2f29512a1..a5acc24cd5 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -1955,6 +1955,8 @@ nm_utils_uuid_generate (void) * @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. * @@ -1962,7 +1964,7 @@ nm_utils_uuid_generate (void) * object's #NMSettingConnection:id: property **/ char * -nm_utils_uuid_generate_from_string (const char *s, gssize slen) +nm_utils_uuid_generate_from_string (const char *s, gssize slen, int uuid_type, gpointer type_args) { uuid_t uuid; char *buf = NULL; @@ -1970,6 +1972,10 @@ nm_utils_uuid_generate_from_string (const char *s, gssize slen) g_return_val_if_fail (s && *s, NULL); g_return_val_if_fail (slen < 0 || slen > 0, FALSE); + /* for now, only support legacy type */ + g_return_val_if_fail (uuid_type == NM_UTILS_UUID_TYPE_LEGACY, NULL); + g_return_val_if_fail (!type_args, NULL); + if (slen < 0) slen = strlen (s); diff --git a/libnm-core/nm-utils.h b/libnm-core/nm-utils.h index 9fb366a81b..9aecaa94e1 100644 --- a/libnm-core/nm-utils.h +++ b/libnm-core/nm-utils.h @@ -120,8 +120,10 @@ GVariant *nm_utils_ip_routes_to_variant (GPtrArray *routes); GPtrArray *nm_utils_ip_routes_from_variant (GVariant *value, int family); +#define NM_UTILS_UUID_TYPE_LEGACY 0 + char *nm_utils_uuid_generate (void); -char *nm_utils_uuid_generate_from_string (const char *s, gssize slen); +char *nm_utils_uuid_generate_from_string (const char *s, gssize slen, int uuid_type, gpointer type_args); gboolean nm_utils_file_is_certificate (const char *filename); gboolean nm_utils_file_is_private_key (const char *filename, gboolean *out_encrypted); diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index 2fd68b0600..c18b7a066e 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -3805,21 +3805,24 @@ test_hexstr2bin (void) /******************************************************************************/ static void -_test_uuid (const char *expected_uuid, const char *str) +_test_uuid (int uuid_type, const char *expected_uuid, const char *str, gssize slen, gpointer type_args) { gs_free char *uuid_test = NULL; g_assert (str); - uuid_test = nm_utils_uuid_generate_from_string (str, -1); + uuid_test = nm_utils_uuid_generate_from_string (str, slen, uuid_type, type_args); g_assert (uuid_test); g_assert (nm_utils_is_uuid (uuid_test)); if (strcmp (uuid_test, expected_uuid)) { - g_error ("UUID test failed: text=%s, uuid=%s, expected=%s", - str, uuid_test, expected_uuid); + g_error ("UUID test failed: type=%d; text=%s, len=%lld, uuid=%s, expected=%s", uuid_type, + str, (long long) slen, uuid_test, expected_uuid); } + + if (slen < 0) + _test_uuid (uuid_type, expected_uuid, str, strlen (str), type_args); } static void @@ -3827,17 +3830,17 @@ test_nm_utils_uuid_generate_from_string (void) { gs_free char *uuid_test = NULL; - _test_uuid ("0cc175b9-c0f1-b6a8-31c3-99e269772661", "a"); - _test_uuid ("098f6bcd-4621-d373-cade-4e832627b4f6", "test"); - _test_uuid ("59c0547b-7fe2-1c15-2cce-e328e8bf6742", "/etc/NetworkManager/system-connections/em1"); + _test_uuid (NM_UTILS_UUID_TYPE_LEGACY, "0cc175b9-c0f1-b6a8-31c3-99e269772661", "a", -1, NULL); + _test_uuid (NM_UTILS_UUID_TYPE_LEGACY, "098f6bcd-4621-d373-cade-4e832627b4f6", "test", -1, NULL); + _test_uuid (NM_UTILS_UUID_TYPE_LEGACY, "59c0547b-7fe2-1c15-2cce-e328e8bf6742", "/etc/NetworkManager/system-connections/em1", -1, NULL); - g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*char *nm_utils_uuid_generate_from_string(const char *): *s && *s*"); - uuid_test = nm_utils_uuid_generate_from_string ("", -1); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*char *nm_utils_uuid_generate_from_string(const char *, gssize, int, gpointer): *s && *s*"); + uuid_test = nm_utils_uuid_generate_from_string ("", 0, NM_UTILS_UUID_TYPE_LEGACY, NULL); g_assert (uuid_test == NULL); g_test_assert_expected_messages (); - g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*char *nm_utils_uuid_generate_from_string(const char *): *s && *s*"); - uuid_test = nm_utils_uuid_generate_from_string (NULL, -1); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*char *nm_utils_uuid_generate_from_string(const char *, gssize, int, gpointer): *s && *s*"); + uuid_test = nm_utils_uuid_generate_from_string (NULL, 0, NM_UTILS_UUID_TYPE_LEGACY, NULL); g_assert (uuid_test == NULL); g_test_assert_expected_messages (); } diff --git a/src/settings/plugins/ibft/reader.c b/src/settings/plugins/ibft/reader.c index 61c4e1cfe7..ebac9607ac 100644 --- a/src/settings/plugins/ibft/reader.c +++ b/src/settings/plugins/ibft/reader.c @@ -408,7 +408,7 @@ connection_setting_add (const GPtrArray *block, s_vlanid ? s_vlanid : "0", s_hwaddr, s_ip4addr ? s_ip4addr : "DHCP"); - uuid = nm_utils_uuid_generate_from_string (uuid_data, -1); + uuid = nm_utils_uuid_generate_from_string (uuid_data, -1, NM_UTILS_UUID_TYPE_LEGACY, NULL); g_free (uuid_data); s_con = nm_setting_connection_new (); diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c index 52dee9d5e5..145a0a3915 100644 --- a/src/settings/plugins/ifcfg-rh/reader.c +++ b/src/settings/plugins/ifcfg-rh/reader.c @@ -148,7 +148,7 @@ make_connection_setting (const char *file, uuid = svGetValue (ifcfg, "UUID", FALSE); if (!uuid || !strlen (uuid)) { g_free (uuid); - uuid = nm_utils_uuid_generate_from_string (ifcfg->fileName, -1); + uuid = nm_utils_uuid_generate_from_string (ifcfg->fileName, -1, NM_UTILS_UUID_TYPE_LEGACY, NULL); } g_object_set (s_con, @@ -4588,7 +4588,7 @@ uuid_from_file (const char *filename) uuid = svGetValue (ifcfg, "UUID", FALSE); if (!uuid || !strlen (uuid)) { g_free (uuid); - uuid = nm_utils_uuid_generate_from_string (ifcfg->fileName, -1); + uuid = nm_utils_uuid_generate_from_string (ifcfg->fileName, -1, NM_UTILS_UUID_TYPE_LEGACY, NULL); } svCloseFile (ifcfg); diff --git a/src/settings/plugins/ifnet/connection_parser.c b/src/settings/plugins/ifnet/connection_parser.c index ba76579a12..41baf31507 100644 --- a/src/settings/plugins/ifnet/connection_parser.c +++ b/src/settings/plugins/ifnet/connection_parser.c @@ -1629,7 +1629,7 @@ ifnet_update_connection_from_config_block (const char *conn_name, id = connection_id_from_ifnet_name (conn_name); uuid = g_strdup (ifnet_get_data (conn_name, "uuid")); if (!uuid) - uuid = nm_utils_uuid_generate_from_string (id, -1); + uuid = nm_utils_uuid_generate_from_string (id, -1, NM_UTILS_UUID_TYPE_LEGACY, NULL); g_object_set (setting, NM_SETTING_CONNECTION_TYPE, type, diff --git a/src/settings/plugins/ifupdown/parser.c b/src/settings/plugins/ifupdown/parser.c index 9af11976c8..15081a4c59 100644 --- a/src/settings/plugins/ifupdown/parser.c +++ b/src/settings/plugins/ifupdown/parser.c @@ -686,7 +686,7 @@ ifupdown_update_connection_from_if_block (NMConnection *connection, idstr = g_strconcat ("Ifupdown (", block->name, ")", NULL); uuid_base = idstr; - uuid = nm_utils_uuid_generate_from_string (uuid_base, -1); + uuid = nm_utils_uuid_generate_from_string (uuid_base, -1, NM_UTILS_UUID_TYPE_LEGACY, NULL); g_object_set (s_con, NM_SETTING_CONNECTION_TYPE, type, NM_SETTING_CONNECTION_INTERFACE_NAME, block->name, diff --git a/src/settings/plugins/keyfile/reader.c b/src/settings/plugins/keyfile/reader.c index 94982cef39..9dc0a7b4aa 100644 --- a/src/settings/plugins/keyfile/reader.c +++ b/src/settings/plugins/keyfile/reader.c @@ -1316,7 +1316,7 @@ nm_keyfile_plugin_connection_from_file (const char *filename, GError **error) if (!nm_setting_connection_get_uuid (s_con)) { char *hashed_uuid; - hashed_uuid = nm_utils_uuid_generate_from_string (filename, -1); + hashed_uuid = nm_utils_uuid_generate_from_string (filename, -1, NM_UTILS_UUID_TYPE_LEGACY, NULL); g_object_set (s_con, NM_SETTING_CONNECTION_UUID, hashed_uuid, NULL); g_free (hashed_uuid); } -- cgit v1.2.1 From e7661c9b525e5a4cd3bafe605b4fc464a4d5f620 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 28 Nov 2014 12:11:49 +0100 Subject: libnm: implement variant3 UUIDs according to rfc4122 Compare the results: perl -e 'use UUID::Tiny ":std"; print(uuid_to_string(create_uuid(UUID_V3, UUID_NS_DNS, "test"))."\n");' python -c 'from uuid import *; print(uuid3(UUID("6ba7b810-9dad-11d1-80b4-00c04fd430c8"), "test"))' --- libnm-core/nm-utils.c | 36 ++++++++++++++++++++++++++++++------ libnm-core/nm-utils.h | 1 + libnm-core/tests/test-general.c | 24 ++++++++++++++++++++---- 3 files changed, 51 insertions(+), 10 deletions(-) diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index a5acc24cd5..bfb68636f0 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -1969,17 +1969,41 @@ nm_utils_uuid_generate_from_string (const char *s, gssize slen, int uuid_type, g uuid_t uuid; char *buf = NULL; - g_return_val_if_fail (s && *s, NULL); - g_return_val_if_fail (slen < 0 || slen > 0, FALSE); + g_return_val_if_fail (slen == 0 || s, FALSE); - /* for now, only support legacy type */ - g_return_val_if_fail (uuid_type == NM_UTILS_UUID_TYPE_LEGACY, NULL); - g_return_val_if_fail (!type_args, NULL); + g_return_val_if_fail (uuid_type == NM_UTILS_UUID_TYPE_LEGACY || uuid_type == NM_UTILS_UUID_TYPE_VARIANT3, NULL); + g_return_val_if_fail (!type_args || uuid_type == NM_UTILS_UUID_TYPE_VARIANT3, NULL); if (slen < 0) slen = strlen (s); + else if (slen == 0) + s = ""; - crypto_md5_hash (NULL, 0, s, slen, (char *) uuid, sizeof (uuid)); + switch (uuid_type) { + case NM_UTILS_UUID_TYPE_LEGACY: + g_return_val_if_fail (slen > 0, NULL); + crypto_md5_hash (NULL, 0, s, slen, (char *) uuid, sizeof (uuid)); + break; + case NM_UTILS_UUID_TYPE_VARIANT3: { + uuid_t ns_uuid = { 0 }; + GString *str; + + if (type_args) { + /* type_args can be a name space UUID. Interpret it as (char *) */ + if (uuid_parse ((char *) type_args, ns_uuid) != 0) + g_return_val_if_reached (NULL); + } + str = g_string_sized_new (sizeof (ns_uuid) + slen + 1); + g_string_append_len (str, (const char *) ns_uuid, sizeof (ns_uuid)); + g_string_append_len (str, s, slen); + crypto_md5_hash (NULL, 0, str->str, str->len, (char *) uuid, sizeof (uuid)); + uuid[6] = (uuid[6] & 0x0F) | 0x30; + uuid[8] = (uuid[8] & 0x3F) | 0x80; + break; + } + default: + g_return_val_if_reached (NULL); + } buf = g_malloc0 (37); uuid_unparse_lower (uuid, &buf[0]); diff --git a/libnm-core/nm-utils.h b/libnm-core/nm-utils.h index 9aecaa94e1..fe67bc3384 100644 --- a/libnm-core/nm-utils.h +++ b/libnm-core/nm-utils.h @@ -121,6 +121,7 @@ GPtrArray *nm_utils_ip_routes_from_variant (GVariant *value, int family); #define NM_UTILS_UUID_TYPE_LEGACY 0 +#define NM_UTILS_UUID_TYPE_VARIANT3 1 char *nm_utils_uuid_generate (void); char *nm_utils_uuid_generate_from_string (const char *s, gssize slen, int uuid_type, gpointer type_args); diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index c18b7a066e..72b7765e09 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -3804,13 +3804,14 @@ test_hexstr2bin (void) /******************************************************************************/ +#define UUID_NIL "00000000-0000-0000-0000-000000000000" +#define UUID_NS_DNS "6ba7b810-9dad-11d1-80b4-00c04fd430c8" + static void _test_uuid (int uuid_type, const char *expected_uuid, const char *str, gssize slen, gpointer type_args) { gs_free char *uuid_test = NULL; - g_assert (str); - uuid_test = nm_utils_uuid_generate_from_string (str, slen, uuid_type, type_args); g_assert (uuid_test); @@ -3823,6 +3824,9 @@ _test_uuid (int uuid_type, const char *expected_uuid, const char *str, gssize sl if (slen < 0) _test_uuid (uuid_type, expected_uuid, str, strlen (str), type_args); + + if (uuid_type == NM_UTILS_UUID_TYPE_VARIANT3 && !type_args) + _test_uuid (uuid_type, expected_uuid, str, slen, UUID_NIL); } static void @@ -3834,15 +3838,27 @@ test_nm_utils_uuid_generate_from_string (void) _test_uuid (NM_UTILS_UUID_TYPE_LEGACY, "098f6bcd-4621-d373-cade-4e832627b4f6", "test", -1, NULL); _test_uuid (NM_UTILS_UUID_TYPE_LEGACY, "59c0547b-7fe2-1c15-2cce-e328e8bf6742", "/etc/NetworkManager/system-connections/em1", -1, NULL); - g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*char *nm_utils_uuid_generate_from_string(const char *, gssize, int, gpointer): *s && *s*"); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*char *nm_utils_uuid_generate_from_string(const char *, gssize, int, gpointer): *slen > 0*"); uuid_test = nm_utils_uuid_generate_from_string ("", 0, NM_UTILS_UUID_TYPE_LEGACY, NULL); g_assert (uuid_test == NULL); g_test_assert_expected_messages (); - g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*char *nm_utils_uuid_generate_from_string(const char *, gssize, int, gpointer): *s && *s*"); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*char *nm_utils_uuid_generate_from_string(const char *, gssize, int, gpointer): *slen > 0*"); uuid_test = nm_utils_uuid_generate_from_string (NULL, 0, NM_UTILS_UUID_TYPE_LEGACY, NULL); g_assert (uuid_test == NULL); g_test_assert_expected_messages (); + + _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "4ae71336-e44b-39bf-b9d2-752e234818a5", NULL, 0, NULL); + _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "4ae71336-e44b-39bf-b9d2-752e234818a5", "", -1, NULL); + _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "0531103a-d8fc-3dd4-b972-d98e4750994e", "a", -1, NULL); + _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "96e17d7a-ac89-38cf-95e1-bf5098da34e1", "test", -1, NULL); + _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "8156568e-4ae6-3f34-a93e-18e2c6cbbf78", "a\0b", 3, NULL); + + _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "c87ee674-4ddc-3efe-a74e-dfe25da5d7b3", NULL, 0, UUID_NS_DNS); + _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "c87ee674-4ddc-3efe-a74e-dfe25da5d7b3", "", -1, UUID_NS_DNS); + _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "4c104dd0-4821-30d5-9ce3-0e7a1f8b7c0d", "a", -1, UUID_NS_DNS); + _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "45a113ac-c7f2-30b0-90a5-a399ab912716", "test", -1, UUID_NS_DNS); + _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "002a0ada-f547-375a-bab5-896a11d1927e", "a\0b", 3, UUID_NS_DNS); } /******************************************************************************/ -- cgit v1.2.1 From 9a08d8602c8775e3fd6e203b89900ba579bcce9b Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 27 Nov 2014 14:09:03 +0100 Subject: core: add nm_utils_uuid_generate_from_strings() Add function to create variant3 UUIDs based on a set of concatenated strings. --- src/NetworkManagerUtils.c | 42 ++++++++++++++++++++++++++++++++++++++++ src/NetworkManagerUtils.h | 4 ++++ src/tests/test-general.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+) diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index 0dcd643bf3..6ca2d9920d 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -1739,6 +1739,48 @@ nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 max return v; } +/** + * 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\0". + * + * This has the advantage, that the following invocations + * all give different UUIDs: (""), ("",""), ("","a"), ("a",""), + * ("aa"), ("aa", ""), ("", "aa"), ... + */ +char * +nm_utils_uuid_generate_from_strings (const char *string1, ...) +{ + GString *str; + va_list args; + const char *s; + char *uuid; + + if (!string1) + return nm_utils_uuid_generate_from_string (NULL, 0, NM_UTILS_UUID_TYPE_VARIANT3, NM_UTILS_UUID_NS); + + str = g_string_sized_new (120); /* effectively allocates power of 2 (128)*/ + + g_string_append_len (str, string1, strlen (string1) + 1); + + va_start (args, string1); + s = va_arg (args, const char *); + while (s) { + g_string_append_len (str, s, strlen (s) + 1); + s = va_arg (args, const char *); + } + + uuid = nm_utils_uuid_generate_from_string (str->str, str->len, NM_UTILS_UUID_TYPE_VARIANT3, NM_UTILS_UUID_NS); + + g_string_free (str, TRUE); + return uuid; +} + +/**************************************************************************/ static gint64 monotonic_timestamp_offset_sec; diff --git a/src/NetworkManagerUtils.h b/src/NetworkManagerUtils.h index f2ff4bdbe7..a0dab49267 100644 --- a/src/NetworkManagerUtils.h +++ b/src/NetworkManagerUtils.h @@ -160,6 +160,10 @@ void nm_utils_log_connection_diff (NMConnection *connection, NMConnection *diff_ gint64 nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 max, gint64 fallback); +#define NM_UTILS_UUID_NS "b425e9fb-7598-44b4-9e3b-5a2e3aaa4905" + +char *nm_utils_uuid_generate_from_strings (const char *string1, ...) G_GNUC_NULL_TERMINATED; + #define NM_UTILS_NS_PER_SECOND ((gint64) 1000000000) gint64 nm_utils_get_monotonic_timestamp_ns (void); gint64 nm_utils_get_monotonic_timestamp_us (void); diff --git a/src/tests/test-general.c b/src/tests/test-general.c index c67db87cf1..3f8ab65b65 100644 --- a/src/tests/test-general.c +++ b/src/tests/test-general.c @@ -729,6 +729,53 @@ test_connection_sort_autoconnect_priority (void) /*******************************************/ +static void +__test_uuid (const char *expected_uuid, const char *str, gssize slen, char *uuid_test) +{ + g_assert (uuid_test); + g_assert (nm_utils_is_uuid (uuid_test)); + + if (strcmp (uuid_test, expected_uuid)) { + g_error ("UUID test failed (1): text=%s, len=%lld, expected=%s, uuid_test=%s", + str, (long long) slen, expected_uuid, uuid_test); + } + g_free (uuid_test); + + uuid_test = nm_utils_uuid_generate_from_string (str, slen, NM_UTILS_UUID_TYPE_VARIANT3, NM_UTILS_UUID_NS); + + g_assert (uuid_test); + g_assert (nm_utils_is_uuid (uuid_test)); + + if (strcmp (uuid_test, expected_uuid)) { + g_error ("UUID test failed (2): text=%s; len=%lld, expected=%s, uuid2=%s", + str, (long long) slen, expected_uuid, uuid_test); + } + g_free (uuid_test); +} + +#define _test_uuid(expected_uuid, str, strlen, ...) __test_uuid (expected_uuid, str, strlen, nm_utils_uuid_generate_from_strings(__VA_ARGS__, NULL)) + +static void +test_nm_utils_uuid_generate_from_strings (void) +{ + _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"); +} + +/*******************************************/ + NMTST_DEFINE (); int @@ -751,6 +798,8 @@ main (int argc, char **argv) g_test_add_func ("/general/connection-sort/autoconnect-priority", test_connection_sort_autoconnect_priority); + g_test_add_func ("/general/nm_utils_uuid_generate_from_strings", test_nm_utils_uuid_generate_from_strings); + return g_test_run (); } -- cgit v1.2.1 From b15994679882805f29403d9635bc0913f37e683d Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 28 Nov 2014 12:53:04 +0100 Subject: settings: change algorithm for UUID generation based on strings In several cases, connection uuids are generated based on some strings. Change the algorithm, to prefix the hashed identifier differently for each setting type. This makes collisions very unlikely. Also, change the algorithm, to create proper Variant3 UUIDs. This is a behavioral change, but it only affects code places that were added since nm-0-9-10 and were not yet part of a stable release. --- src/settings/plugins/ibft/reader.c | 15 ++++++++------- src/settings/plugins/keyfile/reader.c | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/settings/plugins/ibft/reader.c b/src/settings/plugins/ibft/reader.c index ebac9607ac..066a79f25e 100644 --- a/src/settings/plugins/ibft/reader.c +++ b/src/settings/plugins/ibft/reader.c @@ -384,7 +384,7 @@ connection_setting_add (const GPtrArray *block, GError **error) { NMSetting *s_con; - char *id, *uuid, *uuid_data; + char *id, *uuid; const char *s_hwaddr = NULL, *s_ip4addr = NULL, *s_vlanid; if (!parse_ibft_config (block, error, @@ -404,12 +404,13 @@ connection_setting_add (const GPtrArray *block, prefix ? prefix : "", iface); - uuid_data = g_strdup_printf ("%s%s%s", - s_vlanid ? s_vlanid : "0", - s_hwaddr, - s_ip4addr ? s_ip4addr : "DHCP"); - uuid = nm_utils_uuid_generate_from_string (uuid_data, -1, NM_UTILS_UUID_TYPE_LEGACY, NULL); - g_free (uuid_data); + uuid = nm_utils_uuid_generate_from_strings ("ibft", + s_hwaddr, + s_vlanid ? "V" : "v", + s_vlanid ? s_vlanid : "", + s_ip4addr ? "A" : "DHCP", + s_ip4addr ? s_ip4addr : "", + NULL); s_con = nm_setting_connection_new (); g_object_set (s_con, diff --git a/src/settings/plugins/keyfile/reader.c b/src/settings/plugins/keyfile/reader.c index 9dc0a7b4aa..1d2ecdad9b 100644 --- a/src/settings/plugins/keyfile/reader.c +++ b/src/settings/plugins/keyfile/reader.c @@ -1316,7 +1316,7 @@ nm_keyfile_plugin_connection_from_file (const char *filename, GError **error) if (!nm_setting_connection_get_uuid (s_con)) { char *hashed_uuid; - hashed_uuid = nm_utils_uuid_generate_from_string (filename, -1, NM_UTILS_UUID_TYPE_LEGACY, NULL); + hashed_uuid = nm_utils_uuid_generate_from_strings ("keyfile", filename, NULL); g_object_set (s_con, NM_SETTING_CONNECTION_UUID, hashed_uuid, NULL); g_free (hashed_uuid); } -- cgit v1.2.1 From b88715e05bc16c40ae68958c58aa86c2ad029a82 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 1 Dec 2014 13:03:23 +0100 Subject: libnm: normalize missing connection UUID Extend nm_connection_normalize() to add a connection UUID in case it is unset. --- libnm-core/nm-connection.c | 19 +++++++++++++++++++ libnm-core/nm-setting-connection.c | 18 ++++++++++-------- libnm-core/tests/test-general.c | 20 ++++++++++++++++++++ 3 files changed, 49 insertions(+), 8 deletions(-) diff --git a/libnm-core/nm-connection.c b/libnm-core/nm-connection.c index a432baa48b..907713bd08 100644 --- a/libnm-core/nm-connection.c +++ b/libnm-core/nm-connection.c @@ -526,6 +526,24 @@ _nm_connection_find_base_type_setting (NMConnection *connection) return setting; } +static gboolean +_normalize_connection_uuid (NMConnection *self) +{ + NMSettingConnection *s_con = nm_connection_get_setting_connection (self); + char *uuid; + + g_assert (s_con); + + if (nm_setting_connection_get_uuid (s_con)) + return FALSE; + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, NM_SETTING_CONNECTION_UUID, uuid, NULL); + g_free (uuid); + + return TRUE; +} + static gboolean _normalize_connection_type (NMConnection *self) { @@ -913,6 +931,7 @@ nm_connection_normalize (NMConnection *connection, * We only do this, after verifying that the connection contains no un-normalizable * errors, because in that case we rather fail without touching the settings. */ + was_modified |= _normalize_connection_uuid (connection); was_modified |= _normalize_connection_type (connection); was_modified |= _normalize_connection_slave_type (connection); was_modified |= _normalize_ip_config (connection, parameters); diff --git a/libnm-core/nm-setting-connection.c b/libnm-core/nm-setting-connection.c index 61293d88ab..01f5d423c1 100644 --- a/libnm-core/nm-setting-connection.c +++ b/libnm-core/nm-setting-connection.c @@ -777,14 +777,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) return FALSE; } - if (!priv->uuid) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_MISSING_PROPERTY, - _("property is missing")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_UUID); - return FALSE; - } else if (!nm_utils_is_uuid (priv->uuid)) { + if (priv->uuid && !nm_utils_is_uuid (priv->uuid)) { g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, @@ -908,6 +901,15 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) /* *** errors above here should be always fatal, below NORMALIZABLE_ERROR *** */ + if (!priv->uuid) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_UUID); + return NM_SETTING_VERIFY_NORMALIZABLE_ERROR; + } + if (normerr_base_type) { g_set_error (error, NM_CONNECTION_ERROR, diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index 72b7765e09..990a5e0eea 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -3029,6 +3029,25 @@ test_setting_old_uuid (void) g_assert (success == TRUE); } +/******************************************************************************/ + +static void +test_connection_normalize_uuid (void) +{ + gs_unref_object NMConnection *con = NULL; + + con = nmtst_create_minimal_connection ("test1", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + + nmtst_assert_connection_verifies_and_normalizable (con); + + g_object_set (nm_connection_get_setting_connection (con), + NM_SETTING_CONNECTION_UUID, NULL, + NULL); + nmtst_assert_connection_verifies_after_normalization (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY); +} + +/******************************************************************************/ + /* * Test normalization of interface-name */ @@ -3910,6 +3929,7 @@ int main (int argc, char **argv) g_test_add_func ("/core/general/test_connection_replace_settings_bad", test_connection_replace_settings_bad); g_test_add_func ("/core/general/test_connection_new_from_dbus", test_connection_new_from_dbus); g_test_add_func ("/core/general/test_connection_normalize_virtual_iface_name", test_connection_normalize_virtual_iface_name); + g_test_add_func ("/core/general/test_connection_normalize_uuid", test_connection_normalize_uuid); g_test_add_func ("/core/general/test_connection_normalize_type", test_connection_normalize_type); g_test_add_func ("/core/general/test_connection_normalize_slave_type_1", test_connection_normalize_slave_type_1); g_test_add_func ("/core/general/test_connection_normalize_slave_type_2", test_connection_normalize_slave_type_2); -- cgit v1.2.1 From 74bdaf1ad899a8dcb8e8d4a29eed2fceee2cc502 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 3 Dec 2014 17:29:54 +0100 Subject: libnm: hide nm_utils_uuid_generate_from_string() from public API --- libnm-core/nm-core-internal.h | 5 +++++ libnm-core/nm-utils.h | 4 ---- libnm/libnm.ver | 1 - 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h index c0bbd71eac..5af90267a5 100644 --- a/libnm-core/nm-core-internal.h +++ b/libnm-core/nm-core-internal.h @@ -117,6 +117,11 @@ char ** _nm_utils_strsplit_set (const char *str, const char *delimiters, int max_tokens); +#define NM_UTILS_UUID_TYPE_LEGACY 0 +#define NM_UTILS_UUID_TYPE_VARIANT3 1 + +char *nm_utils_uuid_generate_from_string (const char *s, gssize slen, int uuid_type, gpointer type_args); + void _nm_dbus_errors_init (void); extern gboolean _nm_utils_is_manager_process; diff --git a/libnm-core/nm-utils.h b/libnm-core/nm-utils.h index fe67bc3384..a9ecd5ec90 100644 --- a/libnm-core/nm-utils.h +++ b/libnm-core/nm-utils.h @@ -120,11 +120,7 @@ GVariant *nm_utils_ip_routes_to_variant (GPtrArray *routes); GPtrArray *nm_utils_ip_routes_from_variant (GVariant *value, int family); -#define NM_UTILS_UUID_TYPE_LEGACY 0 -#define NM_UTILS_UUID_TYPE_VARIANT3 1 - char *nm_utils_uuid_generate (void); -char *nm_utils_uuid_generate_from_string (const char *s, gssize slen, int uuid_type, gpointer type_args); gboolean nm_utils_file_is_certificate (const char *filename); gboolean nm_utils_file_is_private_key (const char *filename, gboolean *out_encrypted); diff --git a/libnm/libnm.ver b/libnm/libnm.ver index 58d886029d..d89e478d00 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -793,7 +793,6 @@ global: nm_utils_security_valid; nm_utils_ssid_to_utf8; nm_utils_uuid_generate; - nm_utils_uuid_generate_from_string; nm_utils_wep_key_valid; nm_utils_wifi_channel_to_freq; nm_utils_wifi_find_next_channel; -- cgit v1.2.1 From 924fd189b85c0e5f95a596d42e635e9245f958fd Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 4 Dec 2014 16:49:47 +0100 Subject: libnm: allow empty strings for nm_utils_uuid_generate_from_string() Since commit ef3de46c432743e2449612369d13eee66b22cb89 crypto_md5_hash() allows empty password. Also support empty strings for nm_utils_uuid_generate_from_string(). --- libnm-core/nm-utils.c | 1 - libnm-core/tests/test-general.c | 27 +++++++++++---------------- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index bfb68636f0..e4b3519c70 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -1981,7 +1981,6 @@ nm_utils_uuid_generate_from_string (const char *s, gssize slen, int uuid_type, g switch (uuid_type) { case NM_UTILS_UUID_TYPE_LEGACY: - g_return_val_if_fail (slen > 0, NULL); crypto_md5_hash (NULL, 0, s, slen, (char *) uuid, sizeof (uuid)); break; case NM_UTILS_UUID_TYPE_VARIANT3: { diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index 990a5e0eea..91d421190c 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -3841,39 +3841,34 @@ _test_uuid (int uuid_type, const char *expected_uuid, const char *str, gssize sl str, (long long) slen, uuid_test, expected_uuid); } - if (slen < 0) + if (slen < 0) { + /* also test that passing slen==-1 yields the same result as passing strlen(str). */ _test_uuid (uuid_type, expected_uuid, str, strlen (str), type_args); + } else if (str && slen == 0) { + /* also test if we accept NULL for slen==0 */ + _test_uuid (uuid_type, expected_uuid, NULL, 0, type_args); + } - if (uuid_type == NM_UTILS_UUID_TYPE_VARIANT3 && !type_args) + if (uuid_type == NM_UTILS_UUID_TYPE_VARIANT3 && !type_args) { + /* For NM_UTILS_UUID_TYPE_VARIANT3, a missing @type_args is equal to UUID_NIL */ _test_uuid (uuid_type, expected_uuid, str, slen, UUID_NIL); + } } static void test_nm_utils_uuid_generate_from_string (void) { - gs_free char *uuid_test = NULL; - + _test_uuid (NM_UTILS_UUID_TYPE_LEGACY, "d41d8cd9-8f00-b204-e980-0998ecf8427e", "", -1, NULL); _test_uuid (NM_UTILS_UUID_TYPE_LEGACY, "0cc175b9-c0f1-b6a8-31c3-99e269772661", "a", -1, NULL); _test_uuid (NM_UTILS_UUID_TYPE_LEGACY, "098f6bcd-4621-d373-cade-4e832627b4f6", "test", -1, NULL); + _test_uuid (NM_UTILS_UUID_TYPE_LEGACY, "70350f60-27bc-e371-3f6b-76473084309b", "a\0b", 3, NULL); _test_uuid (NM_UTILS_UUID_TYPE_LEGACY, "59c0547b-7fe2-1c15-2cce-e328e8bf6742", "/etc/NetworkManager/system-connections/em1", -1, NULL); - g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*char *nm_utils_uuid_generate_from_string(const char *, gssize, int, gpointer): *slen > 0*"); - uuid_test = nm_utils_uuid_generate_from_string ("", 0, NM_UTILS_UUID_TYPE_LEGACY, NULL); - g_assert (uuid_test == NULL); - g_test_assert_expected_messages (); - - g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*char *nm_utils_uuid_generate_from_string(const char *, gssize, int, gpointer): *slen > 0*"); - uuid_test = nm_utils_uuid_generate_from_string (NULL, 0, NM_UTILS_UUID_TYPE_LEGACY, NULL); - g_assert (uuid_test == NULL); - g_test_assert_expected_messages (); - - _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "4ae71336-e44b-39bf-b9d2-752e234818a5", NULL, 0, NULL); _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "4ae71336-e44b-39bf-b9d2-752e234818a5", "", -1, NULL); _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "0531103a-d8fc-3dd4-b972-d98e4750994e", "a", -1, NULL); _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "96e17d7a-ac89-38cf-95e1-bf5098da34e1", "test", -1, NULL); _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "8156568e-4ae6-3f34-a93e-18e2c6cbbf78", "a\0b", 3, NULL); - _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "c87ee674-4ddc-3efe-a74e-dfe25da5d7b3", NULL, 0, UUID_NS_DNS); _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "c87ee674-4ddc-3efe-a74e-dfe25da5d7b3", "", -1, UUID_NS_DNS); _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "4c104dd0-4821-30d5-9ce3-0e7a1f8b7c0d", "a", -1, UUID_NS_DNS); _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "45a113ac-c7f2-30b0-90a5-a399ab912716", "test", -1, UUID_NS_DNS); -- cgit v1.2.1