From 65d410c7cac1cdb312fd44ac5b4e8bb49f8a5f6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 2 Oct 2018 14:25:24 +0200 Subject: [PATCH] sd-id128: add sd_id128_get_boot_app_specific() --- TODO | 4 --- man/rules/meson.build | 1 + man/sd_id128_get_machine.xml | 56 +++++++++++++++++++----------- src/libsystemd/libsystemd.sym | 2 ++ src/libsystemd/sd-id128/sd-id128.c | 38 +++++++++++++++----- src/systemd/sd-id128.h | 1 + 6 files changed, 70 insertions(+), 32 deletions(-) diff --git a/TODO b/TODO index f848b9741e..0079b35963 100644 --- a/TODO +++ b/TODO @@ -181,10 +181,6 @@ Features: * add bpf-based implementation of devices cgroup controller logic for compat with cgroupsv2 as supported by newest kernel -* introduce sd_id128_get_boot_app_specific() which is like - sd_id128_get_machine_app_specific(). After all on long-running systems both - IDs have similar properties. - * sd-bus: add vtable flag, that may be used to request client creds implicitly and asynchronously before dispatching the operation diff --git a/man/rules/meson.build b/man/rules/meson.build index 99915c5e9f..ddb1c6d521 100644 --- a/man/rules/meson.build +++ b/man/rules/meson.build @@ -438,6 +438,7 @@ manpages = [ ['sd_id128_get_machine', '3', ['sd_id128_get_boot', + 'sd_id128_get_boot_app_specific', 'sd_id128_get_invocation', 'sd_id128_get_machine_app_specific'], ''], diff --git a/man/sd_id128_get_machine.xml b/man/sd_id128_get_machine.xml index 9587aa7d66..8425addd18 100644 --- a/man/sd_id128_get_machine.xml +++ b/man/sd_id128_get_machine.xml @@ -22,6 +22,7 @@ sd_id128_get_machine sd_id128_get_machine_app_specific sd_id128_get_boot + sd_id128_get_boot_app_specific sd_id128_get_invocation Retrieve 128-bit IDs @@ -46,6 +47,12 @@ sd_id128_t *ret + + int sd_id128_get_boot_app_specific + sd_id128_t app_id + sd_id128_t *ret + + int sd_id128_get_invocation sd_id128_t *ret @@ -69,19 +76,25 @@ sd_id128_get_machine(), but retrieves a machine ID that is specific to the application that is identified by the indicated application ID. It is recommended to use this function instead of sd_id128_get_machine() when passing an ID to untrusted environments, in order to make sure - that the original machine ID may not be determined externally. The application-specific ID should be generated via - a tool like journalctl --new-id128, and may be compiled into the application. This function will - return the same application-specific ID for each combination of machine ID and application ID. Internally, this - function calculates HMAC-SHA256 of the application ID, keyed by the machine ID. + that the original machine ID may not be determined externally. This way, the ID used by the application remains + stable on a given machine, but cannot be easily correlated with IDs used in other applications on the same + machine. The application-specific ID should be generated via a tool like journalctl --new-id128, + and may be compiled into the application. This function will return the same application-specific ID for each + combination of machine ID and application ID. Internally, this function calculates HMAC-SHA256 of the application + ID, keyed by the machine ID. - sd_id128_get_boot() returns the boot ID - of the executing kernel. This reads and parses the - /proc/sys/kernel/random/boot_id file exposed - by the kernel. It is randomly generated early at boot and is - unique for every running kernel instance. See - random4 - for more information. This function also internally caches the - returned ID to make this call a cheap operation. + sd_id128_get_boot() returns the boot ID of the executing kernel. This reads and parses + the /proc/sys/kernel/random/boot_id file exposed by the kernel. It is randomly generated early + at boot and is unique for every running kernel instance. See random4 for more + information. This function also internally caches the returned ID to make this call a cheap operation. It is + recommended to use this ID as-is only in trusted environments. In untrusted environments it is recommended to + derive an application specific ID using sd_id128_get_machine_app_specific(), see below. + + sd_id128_get_boot_app_specific() is analogous to + sd_id128_get_machine_app_specific() but returns an ID that changes between boots. Some + machines may be used for a long time without rebooting, hence the boot ID may remain constant for a long time, and + has properties similar to the machine ID during that time. sd_id128_get_invocation() returns the invocation ID of the currently executed service. In its current implementation, this reads and parses the $INVOCATION_ID environment @@ -89,10 +102,11 @@ systemd.exec5 for details. The ID is cached internally. In future a different mechanism to determine the invocation ID may be added. - Note that sd_id128_get_machine_app_specific(), sd_id128_get_boot() - and sd_id128_get_invocation() always return UUID v4 compatible IDs. - sd_id128_get_machine() will also return a UUID v4-compatible ID on new installations but might - not on older. It is possible to convert the machine ID into a UUID v4-compatible one. For more information, see + Note that sd_id128_get_machine_app_specific(), sd_id128_get_boot(), + sd_id128_get_boot_app_specific(), and sd_id128_get_invocation() always + return UUID v4 compatible IDs. sd_id128_get_machine() will also return a UUID v4-compatible + ID on new installations but might not on older. It is possible to convert the machine ID into a UUID v4-compatible + one. For more information, see machine-id5. For more information about the sd_id128_t @@ -104,10 +118,12 @@ Return Value Those calls return 0 on success (in which case ret is filled in), - or a negative errno-style error code. In particular, sd_id128_get_machine() - and sd_id128_get_machine_app_specific() return -ENOENT - if /etc/machine-id is missing, and -ENOMEDIUM if is - empty or all zeros. + or a negative errno-style error code. In particular, + sd_id128_get_machine(), + sd_id128_get_machine_app_specific(), and + sd_id128_get_boot_app_specific() return -ENOENT if + /etc/machine-id is missing, and -ENOMEDIUM if is empty + or all zeros. diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym index d06e95638e..480ef39c7a 100644 --- a/src/libsystemd/libsystemd.sym +++ b/src/libsystemd/libsystemd.sym @@ -648,4 +648,6 @@ global: sd_hwdb_enumerate; sd_hwdb_unrefp; + + sd_id128_get_boot_app_specific; } LIBSYSTEMD_239; diff --git a/src/libsystemd/sd-id128/sd-id128.c b/src/libsystemd/sd-id128/sd-id128.c index 9d93732d7e..b7cca832d8 100644 --- a/src/libsystemd/sd-id128/sd-id128.c +++ b/src/libsystemd/sd-id128/sd-id128.c @@ -284,19 +284,15 @@ _public_ int sd_id128_randomize(sd_id128_t *ret) { return 0; } -_public_ int sd_id128_get_machine_app_specific(sd_id128_t app_id, sd_id128_t *ret) { +static int get_app_specific(sd_id128_t base, sd_id128_t app_id, sd_id128_t *ret) { _cleanup_(khash_unrefp) khash *h = NULL; - sd_id128_t m, result; + sd_id128_t result; const void *p; int r; - assert_return(ret, -EINVAL); + assert(ret); - r = sd_id128_get_machine(&m); - if (r < 0) - return r; - - r = khash_new_with_key(&h, "hmac(sha256)", &m, sizeof(m)); + r = khash_new_with_key(&h, "hmac(sha256)", &base, sizeof(base)); if (r < 0) return r; @@ -314,3 +310,29 @@ _public_ int sd_id128_get_machine_app_specific(sd_id128_t app_id, sd_id128_t *re *ret = make_v4_uuid(result); return 0; } + +_public_ int sd_id128_get_machine_app_specific(sd_id128_t app_id, sd_id128_t *ret) { + sd_id128_t id; + int r; + + assert_return(ret, -EINVAL); + + r = sd_id128_get_machine(&id); + if (r < 0) + return r; + + return get_app_specific(id, app_id, ret); +} + +_public_ int sd_id128_get_boot_app_specific(sd_id128_t app_id, sd_id128_t *ret) { + sd_id128_t id; + int r; + + assert_return(ret, -EINVAL); + + r = sd_id128_get_boot(&id); + if (r < 0) + return r; + + return get_app_specific(id, app_id, ret); +} diff --git a/src/systemd/sd-id128.h b/src/systemd/sd-id128.h index 143a0ffb5e..78cf9462b0 100644 --- a/src/systemd/sd-id128.h +++ b/src/systemd/sd-id128.h @@ -42,6 +42,7 @@ int sd_id128_randomize(sd_id128_t *ret); int sd_id128_get_machine(sd_id128_t *ret); int sd_id128_get_machine_app_specific(sd_id128_t app_id, sd_id128_t *ret); +int sd_id128_get_boot_app_specific(sd_id128_t app_id, sd_id128_t *ret); int sd_id128_get_boot(sd_id128_t *ret); int sd_id128_get_invocation(sd_id128_t *ret);