shared: split random and hash utils
"nm-utils/nm-shared-utils.h" shall contain utility function without other dependencies. It is intended to be used by other projects as-is. nm_utils_random_bytes() requires getrandom() and a HAVE_GETRANDOM configure check. That makes it more cumbersome to re-use "nm-shared-utils.h", in cases where you don't care about nm_utils_random_bytes(). Split nm_utils_random_bytes() out to a separate file. Same for hash utils, which depend on nm_utils_random_bytes(). Also, hash utils will eventually be extended to use siphash24.
This commit is contained in:
@@ -421,7 +421,9 @@ libnm_core_lib_h_priv = \
|
|||||||
shared/nm-utils/c-list-util.h \
|
shared/nm-utils/c-list-util.h \
|
||||||
shared/nm-utils/nm-dedup-multi.h \
|
shared/nm-utils/nm-dedup-multi.h \
|
||||||
shared/nm-utils/nm-enum-utils.h \
|
shared/nm-utils/nm-enum-utils.h \
|
||||||
|
shared/nm-utils/nm-hash-utils.h \
|
||||||
shared/nm-utils/nm-shared-utils.h \
|
shared/nm-utils/nm-shared-utils.h \
|
||||||
|
shared/nm-utils/nm-random-utils.h \
|
||||||
shared/nm-utils/nm-udev-utils.h \
|
shared/nm-utils/nm-udev-utils.h \
|
||||||
shared/nm-meta-setting.h \
|
shared/nm-meta-setting.h \
|
||||||
libnm-core/crypto.h \
|
libnm-core/crypto.h \
|
||||||
@@ -437,7 +439,9 @@ libnm_core_lib_c_real = \
|
|||||||
shared/nm-utils/c-list-util.c \
|
shared/nm-utils/c-list-util.c \
|
||||||
shared/nm-utils/nm-dedup-multi.c \
|
shared/nm-utils/nm-dedup-multi.c \
|
||||||
shared/nm-utils/nm-enum-utils.c \
|
shared/nm-utils/nm-enum-utils.c \
|
||||||
|
shared/nm-utils/nm-hash-utils.c \
|
||||||
shared/nm-utils/nm-shared-utils.c \
|
shared/nm-utils/nm-shared-utils.c \
|
||||||
|
shared/nm-utils/nm-random-utils.c \
|
||||||
shared/nm-utils/nm-udev-utils.c \
|
shared/nm-utils/nm-udev-utils.c \
|
||||||
shared/nm-meta-setting.c \
|
shared/nm-meta-setting.c \
|
||||||
libnm-core/crypto.c \
|
libnm-core/crypto.c \
|
||||||
|
@@ -38,6 +38,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "nm-utils/nm-enum-utils.h"
|
#include "nm-utils/nm-enum-utils.h"
|
||||||
|
#include "nm-utils/nm-hash-utils.h"
|
||||||
#include "nm-common-macros.h"
|
#include "nm-common-macros.h"
|
||||||
#include "nm-utils-private.h"
|
#include "nm-utils-private.h"
|
||||||
#include "nm-setting-private.h"
|
#include "nm-setting-private.h"
|
||||||
|
@@ -23,6 +23,8 @@
|
|||||||
|
|
||||||
#include "nm-dedup-multi.h"
|
#include "nm-dedup-multi.h"
|
||||||
|
|
||||||
|
#include "nm-hash-utils.h"
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
50
shared/nm-utils/nm-hash-utils.c
Normal file
50
shared/nm-utils/nm-hash-utils.c
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||||
|
/* NetworkManager -- Network link manager
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* (C) Copyright 2017 Red Hat, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nm-default.h"
|
||||||
|
|
||||||
|
#include "nm-hash-utils.h"
|
||||||
|
|
||||||
|
#include "nm-shared-utils.h"
|
||||||
|
#include "nm-random-utils.h"
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
guint
|
||||||
|
NM_HASH_INIT (guint seed)
|
||||||
|
{
|
||||||
|
static volatile guint global_seed = 0;
|
||||||
|
guint g, s;
|
||||||
|
|
||||||
|
/* we xor @seed with a random @global_seed. This is to make the hashing behavior
|
||||||
|
* less predictable and harder to exploit collisions. */
|
||||||
|
g = global_seed;
|
||||||
|
if (G_UNLIKELY (g == 0)) {
|
||||||
|
nm_utils_random_bytes (&s, sizeof (s));
|
||||||
|
if (s == 0)
|
||||||
|
s = 42;
|
||||||
|
g_atomic_int_compare_and_exchange ((int *) &global_seed, 0, s);
|
||||||
|
g = global_seed;
|
||||||
|
nm_assert (g);
|
||||||
|
}
|
||||||
|
|
||||||
|
return g ^ seed;
|
||||||
|
}
|
47
shared/nm-utils/nm-hash-utils.h
Normal file
47
shared/nm-utils/nm-hash-utils.h
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||||
|
/* NetworkManager -- Network link manager
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* (C) Copyright 2017 Red Hat, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __NM_HASH_UTILS_H__
|
||||||
|
#define __NM_HASH_UTILS_H__
|
||||||
|
|
||||||
|
guint NM_HASH_INIT (guint seed);
|
||||||
|
|
||||||
|
static inline guint
|
||||||
|
NM_HASH_COMBINE (guint h, guint val)
|
||||||
|
{
|
||||||
|
/* see g_str_hash() for reasons */
|
||||||
|
return (h << 5) + h + val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline guint
|
||||||
|
NM_HASH_COMBINE_UINT64 (guint h, guint64 val)
|
||||||
|
{
|
||||||
|
return NM_HASH_COMBINE (h, (((guint) val) & 0xFFFFFFFFu) + ((guint) (val >> 32)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline guint
|
||||||
|
NM_HASH_POINTER (gconstpointer ptr)
|
||||||
|
{
|
||||||
|
/* same as g_direct_hash(), but inline. */
|
||||||
|
return GPOINTER_TO_UINT (ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __NM_HASH_UTILS_H__ */
|
165
shared/nm-utils/nm-random-utils.c
Normal file
165
shared/nm-utils/nm-random-utils.c
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||||
|
/* NetworkManager -- Network link manager
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* (C) Copyright 2017 Red Hat, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nm-default.h"
|
||||||
|
|
||||||
|
#include "nm-random-utils.h"
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#if USE_SYS_RANDOM_H
|
||||||
|
#include <sys/random.h>
|
||||||
|
#else
|
||||||
|
#include <linux/random.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "nm-shared-utils.h"
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_utils_random_bytes:
|
||||||
|
* @p: the buffer to fill
|
||||||
|
* @n: the number of bytes to write to @p.
|
||||||
|
*
|
||||||
|
* Uses getrandom() or reads /dev/urandom to fill the buffer
|
||||||
|
* with random data. If all fails, as last fallback it uses
|
||||||
|
* GRand to fill the buffer with pseudo random numbers.
|
||||||
|
* The function always succeeds in writing some random numbers
|
||||||
|
* to the buffer. The return value of FALSE indicates that the
|
||||||
|
* obtained bytes are probably not of good randomness.
|
||||||
|
*
|
||||||
|
* Returns: whether the written bytes are good. If you
|
||||||
|
* don't require good randomness, you can ignore the return
|
||||||
|
* value.
|
||||||
|
*
|
||||||
|
* Note that if calling getrandom() fails because there is not enough
|
||||||
|
* entroy (at early boot), the function will read /dev/urandom.
|
||||||
|
* Which of course, still has low entropy, and cause kernel to log
|
||||||
|
* a warning.
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
nm_utils_random_bytes (void *p, size_t n)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
int r;
|
||||||
|
gboolean has_high_quality = TRUE;
|
||||||
|
gboolean urandom_success;
|
||||||
|
guint8 *buf = p;
|
||||||
|
gboolean avoid_urandom = FALSE;
|
||||||
|
|
||||||
|
g_return_val_if_fail (p, FALSE);
|
||||||
|
g_return_val_if_fail (n > 0, FALSE);
|
||||||
|
|
||||||
|
#if HAVE_GETRANDOM
|
||||||
|
{
|
||||||
|
static gboolean have_syscall = TRUE;
|
||||||
|
|
||||||
|
if (have_syscall) {
|
||||||
|
r = getrandom (buf, n, GRND_NONBLOCK);
|
||||||
|
if (r > 0) {
|
||||||
|
if ((size_t) r == n)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* no or partial read. There is not enough entropy.
|
||||||
|
* Fill the rest reading from urandom, and remember that
|
||||||
|
* some bits are not hight quality. */
|
||||||
|
nm_assert (r < n);
|
||||||
|
buf += r;
|
||||||
|
n -= r;
|
||||||
|
has_high_quality = FALSE;
|
||||||
|
|
||||||
|
/* At this point, we don't want to read /dev/urandom, because
|
||||||
|
* the entropy pool is low (early boot?), and asking for more
|
||||||
|
* entropy causes kernel messages to be logged.
|
||||||
|
*
|
||||||
|
* We use our fallback via GRand. Note that g_rand_new() also
|
||||||
|
* tries to seed itself with data from /dev/urandom, but since
|
||||||
|
* we reuse the instance, it shouldn't matter. */
|
||||||
|
avoid_urandom = TRUE;
|
||||||
|
} else {
|
||||||
|
if (errno == ENOSYS) {
|
||||||
|
/* no support for getrandom(). We don't know whether
|
||||||
|
* we urandom will give us good quality. Assume yes. */
|
||||||
|
have_syscall = FALSE;
|
||||||
|
} else {
|
||||||
|
/* unknown error. We'll read urandom below, but we don't have
|
||||||
|
* high-quality randomness. */
|
||||||
|
has_high_quality = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
urandom_success = FALSE;
|
||||||
|
if (!avoid_urandom) {
|
||||||
|
fd_open:
|
||||||
|
fd = open ("/dev/urandom", O_RDONLY | O_CLOEXEC | O_NOCTTY);
|
||||||
|
if (fd < 0) {
|
||||||
|
r = errno;
|
||||||
|
if (r == EINTR)
|
||||||
|
goto fd_open;
|
||||||
|
} else {
|
||||||
|
r = nm_utils_fd_read_loop_exact (fd, buf, n, TRUE);
|
||||||
|
close (fd);
|
||||||
|
if (r >= 0)
|
||||||
|
urandom_success = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!urandom_success) {
|
||||||
|
static _nm_thread_local GRand *rand = NULL;
|
||||||
|
gsize i;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
/* we failed to fill the bytes reading from urandom.
|
||||||
|
* Fill the bits using GRand pseudo random numbers.
|
||||||
|
*
|
||||||
|
* We don't have good quality.
|
||||||
|
*/
|
||||||
|
has_high_quality = FALSE;
|
||||||
|
|
||||||
|
if (G_UNLIKELY (!rand))
|
||||||
|
rand = g_rand_new ();
|
||||||
|
|
||||||
|
nm_assert (n > 0);
|
||||||
|
i = 0;
|
||||||
|
for (;;) {
|
||||||
|
const union {
|
||||||
|
guint32 v32;
|
||||||
|
guint8 v8[4];
|
||||||
|
} v = {
|
||||||
|
.v32 = g_rand_int (rand),
|
||||||
|
};
|
||||||
|
|
||||||
|
for (j = 0; j < 4; ) {
|
||||||
|
buf[i++] = v.v8[j++];
|
||||||
|
if (i >= n)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
done:
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
return has_high_quality;
|
||||||
|
}
|
27
shared/nm-utils/nm-random-utils.h
Normal file
27
shared/nm-utils/nm-random-utils.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||||
|
/* NetworkManager -- Network link manager
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* (C) Copyright 2017 Red Hat, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __NM_RANDOM_UTILS_H__
|
||||||
|
#define __NM_RANDOM_UTILS_H__
|
||||||
|
|
||||||
|
gboolean nm_utils_random_bytes (void *p, size_t n);
|
||||||
|
|
||||||
|
#endif /* __NM_RANDOM_UTILS_H__ */
|
@@ -28,12 +28,6 @@
|
|||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
#if USE_SYS_RANDOM_H
|
|
||||||
#include <sys/random.h>
|
|
||||||
#else
|
|
||||||
#include <linux/random.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
const void *const _NM_PTRARRAY_EMPTY[1] = { NULL };
|
const void *const _NM_PTRARRAY_EMPTY[1] = { NULL };
|
||||||
@@ -863,29 +857,6 @@ nm_g_object_class_find_property_from_gtype (GType gtype,
|
|||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
guint
|
|
||||||
NM_HASH_INIT (guint seed)
|
|
||||||
{
|
|
||||||
static volatile guint global_seed = 0;
|
|
||||||
guint g, s;
|
|
||||||
|
|
||||||
/* we xor @seed with a random @global_seed. This is to make the hashing behavior
|
|
||||||
* less predictable and harder to exploit collisions. */
|
|
||||||
g = global_seed;
|
|
||||||
if (G_UNLIKELY (g == 0)) {
|
|
||||||
nm_utils_random_bytes (&s, sizeof (s));
|
|
||||||
if (s == 0)
|
|
||||||
s = 42;
|
|
||||||
g_atomic_int_compare_and_exchange ((int *) &global_seed, 0, s);
|
|
||||||
g = global_seed;
|
|
||||||
nm_assert (g);
|
|
||||||
}
|
|
||||||
|
|
||||||
return g ^ seed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_str_append_escape (GString *s, char ch)
|
_str_append_escape (GString *s, char ch)
|
||||||
{
|
{
|
||||||
@@ -1118,134 +1089,3 @@ nm_utils_fd_read_loop_exact (int fd, void *buf, size_t nbytes, bool do_poll)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* nm_utils_random_bytes:
|
|
||||||
* @p: the buffer to fill
|
|
||||||
* @n: the number of bytes to write to @p.
|
|
||||||
*
|
|
||||||
* Uses getrandom() or reads /dev/urandom to fill the buffer
|
|
||||||
* with random data. If all fails, as last fallback it uses
|
|
||||||
* GRand to fill the buffer with pseudo random numbers.
|
|
||||||
* The function always succeeds in writing some random numbers
|
|
||||||
* to the buffer. The return value of FALSE indicates that the
|
|
||||||
* obtained bytes are probably not of good randomness.
|
|
||||||
*
|
|
||||||
* Returns: whether the written bytes are good. If you
|
|
||||||
* don't require good randomness, you can ignore the return
|
|
||||||
* value.
|
|
||||||
*
|
|
||||||
* Note that if calling getrandom() fails because there is not enough
|
|
||||||
* entroy (at early boot), the function will read /dev/urandom.
|
|
||||||
* Which of course, still has low entropy, and cause kernel to log
|
|
||||||
* a warning.
|
|
||||||
*/
|
|
||||||
gboolean
|
|
||||||
nm_utils_random_bytes (void *p, size_t n)
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
int r;
|
|
||||||
gboolean has_high_quality = TRUE;
|
|
||||||
gboolean urandom_success;
|
|
||||||
guint8 *buf = p;
|
|
||||||
gboolean avoid_urandom = FALSE;
|
|
||||||
|
|
||||||
g_return_val_if_fail (p, FALSE);
|
|
||||||
g_return_val_if_fail (n > 0, FALSE);
|
|
||||||
|
|
||||||
#if HAVE_GETRANDOM
|
|
||||||
{
|
|
||||||
static gboolean have_syscall = TRUE;
|
|
||||||
|
|
||||||
if (have_syscall) {
|
|
||||||
r = getrandom (buf, n, GRND_NONBLOCK);
|
|
||||||
if (r > 0) {
|
|
||||||
if ((size_t) r == n)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
/* no or partial read. There is not enough entropy.
|
|
||||||
* Fill the rest reading from urandom, and remember that
|
|
||||||
* some bits are not hight quality. */
|
|
||||||
nm_assert (r < n);
|
|
||||||
buf += r;
|
|
||||||
n -= r;
|
|
||||||
has_high_quality = FALSE;
|
|
||||||
|
|
||||||
/* At this point, we don't want to read /dev/urandom, because
|
|
||||||
* the entropy pool is low (early boot?), and asking for more
|
|
||||||
* entropy causes kernel messages to be logged.
|
|
||||||
*
|
|
||||||
* We use our fallback via GRand. Note that g_rand_new() also
|
|
||||||
* tries to seed itself with data from /dev/urandom, but since
|
|
||||||
* we reuse the instance, it shouldn't matter. */
|
|
||||||
avoid_urandom = TRUE;
|
|
||||||
} else {
|
|
||||||
if (errno == ENOSYS) {
|
|
||||||
/* no support for getrandom(). We don't know whether
|
|
||||||
* we urandom will give us good quality. Assume yes. */
|
|
||||||
have_syscall = FALSE;
|
|
||||||
} else {
|
|
||||||
/* unknown error. We'll read urandom below, but we don't have
|
|
||||||
* high-quality randomness. */
|
|
||||||
has_high_quality = FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
urandom_success = FALSE;
|
|
||||||
if (!avoid_urandom) {
|
|
||||||
fd_open:
|
|
||||||
fd = open ("/dev/urandom", O_RDONLY | O_CLOEXEC | O_NOCTTY);
|
|
||||||
if (fd < 0) {
|
|
||||||
r = errno;
|
|
||||||
if (r == EINTR)
|
|
||||||
goto fd_open;
|
|
||||||
} else {
|
|
||||||
r = nm_utils_fd_read_loop_exact (fd, buf, n, TRUE);
|
|
||||||
close (fd);
|
|
||||||
if (r >= 0)
|
|
||||||
urandom_success = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!urandom_success) {
|
|
||||||
static _nm_thread_local GRand *rand = NULL;
|
|
||||||
gsize i;
|
|
||||||
int j;
|
|
||||||
|
|
||||||
/* we failed to fill the bytes reading from urandom.
|
|
||||||
* Fill the bits using GRand pseudo random numbers.
|
|
||||||
*
|
|
||||||
* We don't have good quality.
|
|
||||||
*/
|
|
||||||
has_high_quality = FALSE;
|
|
||||||
|
|
||||||
if (G_UNLIKELY (!rand))
|
|
||||||
rand = g_rand_new ();
|
|
||||||
|
|
||||||
nm_assert (n > 0);
|
|
||||||
i = 0;
|
|
||||||
for (;;) {
|
|
||||||
const union {
|
|
||||||
guint32 v32;
|
|
||||||
guint8 v8[4];
|
|
||||||
} v = {
|
|
||||||
.v32 = g_rand_int (rand),
|
|
||||||
};
|
|
||||||
|
|
||||||
for (j = 0; j < 4; ) {
|
|
||||||
buf[i++] = v.v8[j++];
|
|
||||||
if (i >= n)
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
done:
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
return has_high_quality;
|
|
||||||
}
|
|
||||||
|
@@ -378,30 +378,6 @@ GParamSpec *nm_g_object_class_find_property_from_gtype (GType gtype,
|
|||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
guint NM_HASH_INIT (guint seed);
|
|
||||||
|
|
||||||
static inline guint
|
|
||||||
NM_HASH_COMBINE (guint h, guint val)
|
|
||||||
{
|
|
||||||
/* see g_str_hash() for reasons */
|
|
||||||
return (h << 5) + h + val;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline guint
|
|
||||||
NM_HASH_COMBINE_UINT64 (guint h, guint64 val)
|
|
||||||
{
|
|
||||||
return NM_HASH_COMBINE (h, (((guint) val) & 0xFFFFFFFFu) + ((guint) (val >> 32)));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline guint
|
|
||||||
NM_HASH_POINTER (gconstpointer ptr)
|
|
||||||
{
|
|
||||||
/* same as g_direct_hash(), but inline. */
|
|
||||||
return GPOINTER_TO_UINT (ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NM_UTILS_STR_UTF8_SAFE_FLAG_NONE = 0,
|
NM_UTILS_STR_UTF8_SAFE_FLAG_NONE = 0,
|
||||||
NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL = 0x0001,
|
NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL = 0x0001,
|
||||||
@@ -430,8 +406,4 @@ int nm_utils_fd_read_loop_exact (int fd, void *buf, size_t nbytes, bool do_poll)
|
|||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
gboolean nm_utils_random_bytes (void *p, size_t n);
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
#endif /* __NM_SHARED_UTILS_H__ */
|
#endif /* __NM_SHARED_UTILS_H__ */
|
||||||
|
@@ -32,6 +32,7 @@
|
|||||||
#include <linux/rtnetlink.h>
|
#include <linux/rtnetlink.h>
|
||||||
|
|
||||||
#include "nm-utils/nm-dedup-multi.h"
|
#include "nm-utils/nm-dedup-multi.h"
|
||||||
|
#include "nm-utils/nm-random-utils.h"
|
||||||
|
|
||||||
#include "NetworkManagerUtils.h"
|
#include "NetworkManagerUtils.h"
|
||||||
#include "nm-utils.h"
|
#include "nm-utils.h"
|
||||||
|
@@ -36,6 +36,7 @@
|
|||||||
#include <linux/if_infiniband.h>
|
#include <linux/if_infiniband.h>
|
||||||
#include <net/ethernet.h>
|
#include <net/ethernet.h>
|
||||||
|
|
||||||
|
#include "nm-utils/nm-random-utils.h"
|
||||||
#include "nm-utils.h"
|
#include "nm-utils.h"
|
||||||
#include "nm-core-internal.h"
|
#include "nm-core-internal.h"
|
||||||
#include "nm-setting-connection.h"
|
#include "nm-setting-connection.h"
|
||||||
|
@@ -25,6 +25,8 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#include "nm-utils/nm-hash-utils.h"
|
||||||
|
|
||||||
#include "nm-connection.h"
|
#include "nm-connection.h"
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
Reference in New Issue
Block a user