summaryrefslogtreecommitdiff
path: root/src/libnm-systemd-core/src/libsystemd/sd-id128/id128-util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libnm-systemd-core/src/libsystemd/sd-id128/id128-util.c')
-rw-r--r--src/libnm-systemd-core/src/libsystemd/sd-id128/id128-util.c67
1 files changed, 59 insertions, 8 deletions
diff --git a/src/libnm-systemd-core/src/libsystemd/sd-id128/id128-util.c b/src/libnm-systemd-core/src/libsystemd/sd-id128/id128-util.c
index c20f7325ad..1fc011c7f3 100644
--- a/src/libnm-systemd-core/src/libsystemd/sd-id128/id128-util.c
+++ b/src/libnm-systemd-core/src/libsystemd/sd-id128/id128-util.c
@@ -11,9 +11,29 @@
#include "hexdecoct.h"
#include "id128-util.h"
#include "io-util.h"
+#include "sha256.h"
#include "stdio-util.h"
#include "string-util.h"
+#include "strv.h"
#include "sync-util.h"
+#include "virt.h"
+
+int id128_from_string_nonzero(const char *s, sd_id128_t *ret) {
+ sd_id128_t t;
+ int r;
+
+ assert(ret);
+
+ r = sd_id128_from_string(ASSERT_PTR(s), &t);
+ if (r < 0)
+ return r;
+
+ if (sd_id128_is_null(t))
+ return -ENXIO;
+
+ *ret = t;
+ return 0;
+}
#if 0 /* NM_IGNORED */
bool id128_is_valid(const char *s) {
@@ -24,7 +44,7 @@ bool id128_is_valid(const char *s) {
l = strlen(s);
if (l == SD_ID128_STRING_MAX - 1)
- /* Plain formatted 128bit hex string */
+ /* Plain formatted 128-bit hex string */
return in_charset(s, HEXDIGITS);
if (l == SD_ID128_UUID_STRING_MAX - 1) {
@@ -53,7 +73,7 @@ int id128_read_fd(int fd, Id128Flag f, sd_id128_t *ret) {
assert(fd >= 0);
- /* Reads an 128bit ID from a file, which may either be in plain format (32 hex digits), or in UUID format, both
+ /* Reads an 128-bit ID from a file, which may either be in plain format (32 hex digits), or in UUID format, both
* optionally followed by a newline and nothing else. ID files should really be newline terminated, but if they
* aren't that's OK too, following the rule of "Be conservative in what you send, be liberal in what you
* accept".
@@ -151,7 +171,7 @@ int id128_write_fd(int fd, Id128Flag f, sd_id128_t id) {
}
buffer[sz - 1] = '\n';
- r = loop_write(fd, buffer, sz, false);
+ r = loop_write(fd, buffer, sz);
if (r < 0)
return r;
@@ -178,11 +198,11 @@ int id128_write_at(int dir_fd, const char *path, Id128Flag f, sd_id128_t id) {
}
void id128_hash_func(const sd_id128_t *p, struct siphash *state) {
- siphash24_compress(p, sizeof(sd_id128_t), state);
+ siphash24_compress_typesafe(*p, state);
}
int id128_compare_func(const sd_id128_t *a, const sd_id128_t *b) {
- return memcmp(a, b, 16);
+ return memcmp(a, b, sizeof(sd_id128_t));
}
sd_id128_t id128_make_v4_uuid(sd_id128_t id) {
@@ -210,9 +230,22 @@ int id128_get_product(sd_id128_t *ret) {
/* Reads the systems product UUID from DMI or devicetree (where it is located on POWER). This is
* particularly relevant in VM environments, where VM managers typically place a VM uuid there. */
- r = id128_read("/sys/class/dmi/id/product_uuid", ID128_FORMAT_UUID, &uuid);
- if (r == -ENOENT)
- r = id128_read("/proc/device-tree/vm,uuid", ID128_FORMAT_UUID, &uuid);
+ r = detect_container();
+ if (r < 0)
+ return r;
+ if (r > 0) /* Refuse returning this in containers, as this is not a property of our system then, but
+ * of the host */
+ return -ENOENT;
+
+ FOREACH_STRING(i,
+ "/sys/class/dmi/id/product_uuid", /* KVM */
+ "/proc/device-tree/vm,uuid", /* Device tree */
+ "/sys/hypervisor/uuid") { /* Xen */
+
+ r = id128_read(i, ID128_FORMAT_UUID, &uuid);
+ if (r != -ENOENT)
+ break;
+ }
if (r < 0)
return r;
@@ -222,4 +255,22 @@ int id128_get_product(sd_id128_t *ret) {
*ret = uuid;
return 0;
}
+
+sd_id128_t id128_digest(const void *data, size_t size) {
+ assert(data || size == 0);
+
+ /* Hashes a UUID from some arbitrary data */
+
+ if (size == SIZE_MAX)
+ size = strlen(data);
+
+ uint8_t h[SHA256_DIGEST_SIZE];
+ sd_id128_t id;
+
+ /* Take the first half of the SHA256 result */
+ assert_cc(sizeof(h) >= sizeof(id.bytes));
+ memcpy(id.bytes, sha256_direct(data, size, h), sizeof(id.bytes));
+
+ return id128_make_v4_uuid(id);
+}
#endif /* NM_IGNORED */