summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2016-04-25 18:14:25 +0200
committerThomas Haller <thaller@redhat.com>2016-04-25 21:03:03 +0200
commit4979bdd82f85fd8701552f7e9b7abba08bd02359 (patch)
tree8d534ab4aa19250064153fd9aaeede1d134d6643
parentbad9becf99670f4c6a1e9491a7d8d47a080d9a85 (diff)
downloadNetworkManager-4979bdd82f85fd8701552f7e9b7abba08bd02359.tar.gz
core: add nm_utils_get_secret_key() util
-rw-r--r--src/nm-core-utils.c104
-rw-r--r--src/nm-core-utils.h2
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 */
/**