diff options
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.c | 67 |
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 */ |