From 4979bdd82f85fd8701552f7e9b7abba08bd02359 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 25 Apr 2016 18:14:25 +0200 Subject: core: add nm_utils_get_secret_key() util --- src/nm-core-utils.c | 104 +++++++++++++++++++++++++++++----------------------- src/nm-core-utils.h | 2 + 2 files changed, 61 insertions(+), 45 deletions(-) diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c index 188e4737af..24d862aff8 100644 --- a/src/nm-core-utils.c +++ b/src/nm-core-utils.c @@ -2588,6 +2588,59 @@ nm_utils_is_specific_hostname (const char *name) /******************************************************************/ +char * +nm_utils_get_secret_key (gsize *out_key_len, GError **error) +{ + char *secret_key = NULL; + gsize key_len; + + /* Let's try to load a saved secret key first. */ + if (g_file_get_contents (NMSTATEDIR "/secret_key", &secret_key, &key_len, NULL)) { + if (key_len < 16) { + g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, + "Key is too short to be usable"); + key_len = 0; + } + } else { + int urandom = open ("/dev/urandom", O_RDONLY); + mode_t key_mask; + + if (urandom == -1) { + g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, + "Can't open /dev/urandom: %s", strerror (errno)); + key_len = 0; + goto out; + } + + /* RFC7217 mandates the key SHOULD be at least 128 bits. + * Let's use twice as much. */ + key_len = 32; + secret_key = g_malloc (key_len + 1); + + key_mask = umask (0077); + if (read (urandom, secret_key, key_len) == key_len) { + secret_key[key_len] = '\0'; + if (!g_file_set_contents (NMSTATEDIR "/secret_key", secret_key, key_len, error)) { + g_prefix_error (error, "Can't write " NMSTATEDIR "/secret_key: "); + key_len = 0; + } + } else { + g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, + "Could not obtain a secret"); + key_len = 0; + } + umask (key_mask); + close (urandom); + } + +out: + NM_SET_OUT (out_key_len, key_len); + if (key_len) + return secret_key; + g_free (secret_key); + return NULL; +} + /* Returns the "u" (universal/local) bit value for a Modified EUI-64 */ static gboolean get_gre_eui64_u_bit (guint32 addr) @@ -2773,9 +2826,8 @@ nm_utils_ipv6_addr_set_stable_privacy (struct in6_addr *addr, guint dad_counter, GError **error) { - gchar *secret_key = NULL; + gs_free gchar *secret_key = NULL; gsize key_len = 0; - gboolean success = FALSE; if (dad_counter >= RFC7217_IDGEN_RETRIES) { g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, @@ -2783,50 +2835,12 @@ nm_utils_ipv6_addr_set_stable_privacy (struct in6_addr *addr, return FALSE; } - /* Let's try to load a saved secret key first. */ - if (g_file_get_contents (NMSTATEDIR "/secret_key", &secret_key, &key_len, NULL)) { - if (key_len < 16) { - g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, - "Key is too short to be usable"); - key_len = 0; - } - } else { - int urandom = open ("/dev/urandom", O_RDONLY); - mode_t key_mask; - - if (urandom == -1) { - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, - "Can't open /dev/urandom: %s", strerror (errno)); - return FALSE; - } - - /* RFC7217 mandates the key SHOULD be at least 128 bits. - * Let's use twice as much. */ - key_len = 32; - secret_key = g_malloc (key_len); - - key_mask = umask (0077); - if (read (urandom, secret_key, key_len) == key_len) { - if (!g_file_set_contents (NMSTATEDIR "/secret_key", secret_key, key_len, error)) { - g_prefix_error (error, "Can't write " NMSTATEDIR "/secret_key: "); - key_len = 0; - } - } else { - g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, - "Could not obtain a secret"); - key_len = 0; - } - umask (key_mask); - close (urandom); - } - - if (key_len) { - success = _set_stable_privacy (addr, ifname, uuid, dad_counter, - secret_key, key_len, error); - } + secret_key = nm_utils_get_secret_key (&key_len, error); + if (!secret_key) + return FALSE; - g_free (secret_key); - return success; + return _set_stable_privacy (addr, ifname, uuid, dad_counter, + secret_key, key_len, error); } /** diff --git a/src/nm-core-utils.h b/src/nm-core-utils.h index 486942a22a..82d9424ec5 100644 --- a/src/nm-core-utils.h +++ b/src/nm-core-utils.h @@ -307,6 +307,8 @@ const char *nm_utils_ip4_property_path (const char *ifname, const char *property gboolean nm_utils_is_specific_hostname (const char *name); +char *nm_utils_get_secret_key (gsize *out_key_len, GError **error); + /* IPv6 Interface Identifer helpers */ /** -- cgit v1.2.1