From ff7dad484c512b873b86849068a6c0527c575a2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 21 Aug 2018 15:38:04 +0200 Subject: [PATCH 1/5] journalctl: move generate_new_id128() to shared --- src/journal/journalctl.c | 32 ++------------------------------ src/shared/id128-print.c | 37 +++++++++++++++++++++++++++++++++++++ src/shared/id128-print.h | 5 +++++ src/shared/meson.build | 2 ++ 4 files changed, 46 insertions(+), 30 deletions(-) create mode 100644 src/shared/id128-print.c create mode 100644 src/shared/id128-print.h diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index a9e4af1dd8..3ff4d29664 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -38,6 +38,7 @@ #include "fsprg.h" #include "glob-util.h" #include "hostname-util.h" +#include "id128-print.h" #include "io-util.h" #include "journal-def.h" #include "journal-internal.h" @@ -1007,35 +1008,6 @@ static int parse_argv(int argc, char *argv[]) { return 1; } -static int generate_new_id128(void) { - sd_id128_t id; - int r; - unsigned i; - - r = sd_id128_randomize(&id); - if (r < 0) - return log_error_errno(r, "Failed to generate ID: %m"); - - printf("As string:\n" - SD_ID128_FORMAT_STR "\n\n" - "As UUID:\n" - "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n\n" - "As man:sd-id128(3) macro:\n" - "#define MESSAGE_XYZ SD_ID128_MAKE(", - SD_ID128_FORMAT_VAL(id), - SD_ID128_FORMAT_VAL(id)); - for (i = 0; i < 16; i++) - printf("%02x%s", id.bytes[i], i != 15 ? "," : ""); - fputs(")\n\n", stdout); - - printf("As Python constant:\n" - ">>> import uuid\n" - ">>> MESSAGE_XYZ = uuid.UUID('" SD_ID128_FORMAT_STR "')\n", - SD_ID128_FORMAT_VAL(id)); - - return 0; -} - static int add_matches(sd_journal *j, char **args) { char **i; bool have_term = false; @@ -2092,7 +2064,7 @@ int main(int argc, char *argv[]) { switch (arg_action) { case ACTION_NEW_ID128: - r = generate_new_id128(); + r = id128_generate_new(); goto finish; case ACTION_SETUP_KEYS: diff --git a/src/shared/id128-print.c b/src/shared/id128-print.c new file mode 100644 index 0000000000..212080fbcc --- /dev/null +++ b/src/shared/id128-print.c @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include + +#include "sd-id128.h" + +#include "id128-print.h" +#include "log.h" + +int id128_generate_new(void) { + sd_id128_t id; + int r; + unsigned i; + + r = sd_id128_randomize(&id); + if (r < 0) + return log_error_errno(r, "Failed to generate ID: %m"); + + printf("As string:\n" + SD_ID128_FORMAT_STR "\n\n" + "As UUID:\n" + "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n\n" + "As man:sd-id128(3) macro:\n" + "#define MESSAGE_XYZ SD_ID128_MAKE(", + SD_ID128_FORMAT_VAL(id), + SD_ID128_FORMAT_VAL(id)); + for (i = 0; i < 16; i++) + printf("%02x%s", id.bytes[i], i != 15 ? "," : ""); + fputs(")\n\n", stdout); + + printf("As Python constant:\n" + ">>> import uuid\n" + ">>> MESSAGE_XYZ = uuid.UUID('" SD_ID128_FORMAT_STR "')\n", + SD_ID128_FORMAT_VAL(id)); + + return 0; +} diff --git a/src/shared/id128-print.h b/src/shared/id128-print.h new file mode 100644 index 0000000000..6b5b331bbf --- /dev/null +++ b/src/shared/id128-print.h @@ -0,0 +1,5 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#pragma once + +int id128_generate_new(void); diff --git a/src/shared/meson.build b/src/shared/meson.build index 17370f4048..498b73c750 100644 --- a/src/shared/meson.build +++ b/src/shared/meson.build @@ -44,6 +44,8 @@ shared_sources = files(''' generator.c generator.h gpt.h + id128-print.c + id128-print.h ima-util.c ima-util.h import-util.c 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 2/5] 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); From 0d1d512f7f42071595f0c950f911f3557fda09ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 21 Aug 2018 16:08:48 +0200 Subject: [PATCH 3/5] systemd-id128: a new tool to print machine/boot/invocation/app-specific ids The raison d'etre for this program is printing machine-app-specific IDs. We provide a library function for that, but not a convenient API. We can hardly ask people to quickly hack their own C programs or call libsystemd through CFFI in python or another scripting language if they just want to print an ID. Verb 'new' was already available as 'journalctl --new-id128', but this makes it more discoverable. v2: - rename binary to systemd-id128 - make --app-specific= into a switch that applies to boot-id and machine-id --- man/sd_id128_get_machine.xml | 3 +- meson.build | 8 ++ src/id128/id128.c | 167 +++++++++++++++++++++++++++++++++++ src/journal/journalctl.c | 2 +- src/shared/id128-print.c | 23 +++-- src/shared/id128-print.h | 7 +- 6 files changed, 201 insertions(+), 9 deletions(-) create mode 100644 src/id128/id128.c diff --git a/man/sd_id128_get_machine.xml b/man/sd_id128_get_machine.xml index 8425addd18..f797a8af4e 100644 --- a/man/sd_id128_get_machine.xml +++ b/man/sd_id128_get_machine.xml @@ -78,7 +78,7 @@ 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. 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, + machine. The application-specific ID should be generated via a tool like systemd-id128 new, 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. @@ -145,6 +145,7 @@ systemd1, + systemd-id1281, sd-id1283, machine-id5, systemd.exec5, diff --git a/meson.build b/meson.build index 1c4febfa4b..49da6825e0 100644 --- a/meson.build +++ b/meson.build @@ -2323,6 +2323,14 @@ executable('systemd-cgroups-agent', install : true, install_dir : rootlibexecdir) +exe = executable('systemd-id128', + 'src/id128/id128.c', + include_directories : includes, + link_with : [libshared], + install_rpath : rootlibexecdir, + install : true) +public_programs += exe + exe = executable('systemd-path', 'src/path/path.c', include_directories : includes, diff --git a/src/id128/id128.c b/src/id128/id128.c new file mode 100644 index 0000000000..a6391313be --- /dev/null +++ b/src/id128/id128.c @@ -0,0 +1,167 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include +#include + +#include "alloc-util.h" +#include "id128-print.h" +#include "terminal-util.h" +#include "util.h" +#include "verbs.h" + +static bool arg_pretty = false; +static sd_id128_t arg_app = {}; + +static int verb_new(int argc, char **argv, void *userdata) { + return id128_print_new(arg_pretty); +} + +static int verb_machine_id(int argc, char **argv, void *userdata) { + sd_id128_t id; + int r; + + if (sd_id128_is_null(arg_app)) + r = sd_id128_get_machine(&id); + else + r = sd_id128_get_machine_app_specific(arg_app, &id); + if (r < 0) + return log_error_errno(r, "Failed to get %smachine-ID: %m", + sd_id128_is_null(arg_app) ? "" : "app-specific "); + + return id128_pretty_print(id, arg_pretty); +} + +static int verb_boot_id(int argc, char **argv, void *userdata) { + sd_id128_t id; + int r; + + if (sd_id128_is_null(arg_app)) + r = sd_id128_get_boot(&id); + else + r = sd_id128_get_boot_app_specific(arg_app, &id); + if (r < 0) + return log_error_errno(r, "Failed to get %sboot-ID: %m", + sd_id128_is_null(arg_app) ? "" : "app-specific "); + + return id128_pretty_print(id, arg_pretty); +} + +static int verb_invocation_id(int argc, char **argv, void *userdata) { + sd_id128_t id; + int r; + + if (!sd_id128_is_null(arg_app)) + return log_error_errno(EINVAL, "Verb \"invocation-id\" cannot be combined with --app-specific=."); + + r = sd_id128_get_invocation(&id); + if (r < 0) + return log_error_errno(r, "Failed to get invocation-ID: %m"); + + return id128_pretty_print(id, arg_pretty); +} + +static int help(void) { + _cleanup_free_ char *link = NULL; + int r; + + r = terminal_urlify_man("systemd-id128", "1", &link); + if (r < 0) + return log_oom(); + + printf("%s [OPTIONS...] {COMMAND} ...\n\n" + "Generate and print id128 strings.\n\n" + " -h --help Show this help\n\n" + " -p --pretty Generate samples of program code\n\n" + " -a --app-specific=ID Generate app-specific IDs\n\n" + "Commands:\n" + " new Generate a new id128 string\n" + " machine-id Print the ID of current machine\n" + " boot-id Print the ID of current boot\n" + " invocation-id Print the ID of current invocation\n" + " help Show this help\n" + "\nSee the %s for details.\n" + , program_invocation_short_name + , link + ); + + return 0; +} + +static int verb_help(int argc, char **argv, void *userdata) { + return help(); +} + +static int parse_argv(int argc, char *argv[]) { + enum { + ARG_VERSION = 0x100, + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { "app-specific", required_argument, NULL, 'a' }, + {}, + }; + + int c, r; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "hpa:", options, NULL)) >= 0) + switch (c) { + + case 'h': + return help(); + + case ARG_VERSION: + return version(); + + case 'p': + arg_pretty = true; + break; + + case 'a': + r = sd_id128_from_string(optarg, &arg_app); + if (r < 0) + return log_error_errno(r, "Failed to parse \"%s\" as application-ID: %m", optarg); + break; + + case '?': + return -EINVAL; + + default: + assert_not_reached("Unhandled option"); + } + + return 1; +} + +static int id128_main(int argc, char *argv[]) { + static const Verb verbs[] = { + { "new", VERB_ANY, 1, 0, verb_new }, + { "machine-id", VERB_ANY, 1, 0, verb_machine_id }, + { "boot-id", VERB_ANY, 1, 0, verb_boot_id }, + { "invocation-id", VERB_ANY, 1, 0, verb_invocation_id }, + { "help", VERB_ANY, VERB_ANY, 0, verb_help }, + {} + }; + + return dispatch_verb(argc, argv, verbs, NULL); +} + +int main(int argc, char *argv[]) { + int r; + + log_parse_environment(); + log_open(); + + r = parse_argv(argc, argv); + if (r <= 0) + goto finish; + + r = id128_main(argc, argv); + + finish: + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 3ff4d29664..b42f676bae 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -2064,7 +2064,7 @@ int main(int argc, char *argv[]) { switch (arg_action) { case ACTION_NEW_ID128: - r = id128_generate_new(); + r = id128_print_new(true); goto finish; case ACTION_SETUP_KEYS: diff --git a/src/shared/id128-print.c b/src/shared/id128-print.c index 212080fbcc..5b5dac605a 100644 --- a/src/shared/id128-print.c +++ b/src/shared/id128-print.c @@ -7,14 +7,14 @@ #include "id128-print.h" #include "log.h" -int id128_generate_new(void) { - sd_id128_t id; - int r; +int id128_pretty_print(sd_id128_t id, bool pretty) { unsigned i; - r = sd_id128_randomize(&id); - if (r < 0) - return log_error_errno(r, "Failed to generate ID: %m"); + if (!pretty) { + printf(SD_ID128_FORMAT_STR "\n", + SD_ID128_FORMAT_VAL(id)); + return 0; + } printf("As string:\n" SD_ID128_FORMAT_STR "\n\n" @@ -35,3 +35,14 @@ int id128_generate_new(void) { return 0; } + +int id128_print_new(bool pretty) { + sd_id128_t id; + int r; + + r = sd_id128_randomize(&id); + if (r < 0) + return log_error_errno(r, "Failed to generate ID: %m"); + + return id128_pretty_print(id, pretty); +} diff --git a/src/shared/id128-print.h b/src/shared/id128-print.h index 6b5b331bbf..5d50de0fc8 100644 --- a/src/shared/id128-print.h +++ b/src/shared/id128-print.h @@ -2,4 +2,9 @@ #pragma once -int id128_generate_new(void); +#include + +#include "sd-id128.h" + +int id128_pretty_print(sd_id128_t id, bool pretty); +int id128_print_new(bool pretty); From adda90b03e0af45445b0afa65b90f9c1c55bae05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 21 Aug 2018 16:25:21 +0200 Subject: [PATCH 4/5] man: add man page for systemd-id128 --- man/rules/meson.build | 1 + man/sd_id128_get_machine.xml | 15 ++++- man/systemd-id128.xml | 122 +++++++++++++++++++++++++++++++++++ 3 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 man/systemd-id128.xml diff --git a/man/rules/meson.build b/man/rules/meson.build index ddb1c6d521..303b584654 100644 --- a/man/rules/meson.build +++ b/man/rules/meson.build @@ -659,6 +659,7 @@ manpages = [ 'ENABLE_HIBERNATE'], ['systemd-hostnamed.service', '8', ['systemd-hostnamed'], 'ENABLE_HOSTNAMED'], ['systemd-hwdb', '8', [], 'ENABLE_HWDB'], + ['systemd-id128', '1', [], ''], ['systemd-importd.service', '8', ['systemd-importd'], 'ENABLE_IMPORTD'], ['systemd-inhibit', '1', [], ''], ['systemd-initctl.service', diff --git a/man/sd_id128_get_machine.xml b/man/sd_id128_get_machine.xml index f797a8af4e..0884838324 100644 --- a/man/sd_id128_get_machine.xml +++ b/man/sd_id128_get_machine.xml @@ -134,7 +134,20 @@ Application-specific machine ID - Here's a simple example for an application specific machine ID: + First, generate the application ID: + $ systemd-id128 -p new +As string: +c273277323db454ea63bb96e79b53e97 + +As UUID: +c2732773-23db-454e-a63b-b96e79b53e97 + +As man:sd-id128(3) macro: +#define MESSAGE_XYZ SD_ID128_MAKE(c2,73,27,73,23,db,45,4e,a6,3b,b9,6e,79,b5,3e,97) +... + + + Then use the new identifier in an example application: diff --git a/man/systemd-id128.xml b/man/systemd-id128.xml new file mode 100644 index 0000000000..8a76cccd86 --- /dev/null +++ b/man/systemd-id128.xml @@ -0,0 +1,122 @@ + + + + + + + + systemd-id128 + systemd + + + + systemd-id128 + 1 + + + + systemd-id128 + Generate and print sd-128 identifiers + + + + + systemd-id128 + OPTIONS + new + + + + systemd-id128 + OPTIONS + machine-id + + + + systemd-id128 + OPTIONS + boot-id + + + + systemd-id128 + OPTIONS + invocation-id + + + + + Description + + id128 may be used to conveniently print + sd-id1283 + UUIDs. What identifier is printed depends on the specific verb. + + With new, a new random identifier will be generated. + + With machine-id, the identifier of the current machine will be + printed. See + machine-id5. + + + With boot-id, the identifier of the current boot will be + printed. + + Both machine-id and boot-id may be combined + with the switch to + generate application-specific IDs. See + sd_id128_get_machine3 + for the discussion when this is useful. + + With invocation-id, the identifier of the current service invocation + will be printed. This is available in systemd services. See + systemd.exec5. + + + + + Options + + The following options are understood: + + + + + + + Generate output as programming language snippets. + + + + + + + With this option, an identifier that is the result of hashing the + application identifier app-id and the machine identifier will be + printed. The app-id argument must be a valid sd-id128 string + identifying the application. + + + + + + + + + + Exit status + + On success, 0 is returned, a non-zero failure code otherwise. + + + + See Also + + systemd1, + sd-id1283, + sd_id128_get_machine3 + + + + From 87d57be06f85859f3862e53d4389b520ad7eabc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 2 Oct 2018 15:02:04 +0200 Subject: [PATCH 5/5] Prettify printing of uuids I know this a bit over the top, but I'm following reviewers' requests. --- src/shared/id128-print.c | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/src/shared/id128-print.c b/src/shared/id128-print.c index 5b5dac605a..eea3ee5ca8 100644 --- a/src/shared/id128-print.c +++ b/src/shared/id128-print.c @@ -4,11 +4,15 @@ #include "sd-id128.h" +#include "alloc-util.h" #include "id128-print.h" #include "log.h" +#include "terminal-util.h" int id128_pretty_print(sd_id128_t id, bool pretty) { unsigned i; + _cleanup_free_ char *man_link = NULL, *mod_link = NULL; + const char *on, *off; if (!pretty) { printf(SD_ID128_FORMAT_STR "\n", @@ -16,22 +20,34 @@ int id128_pretty_print(sd_id128_t id, bool pretty) { return 0; } + on = ansi_highlight(); + off = ansi_normal(); + + if (terminal_urlify("man:systemd-id128(1)", "systemd-id128(1)", &man_link) < 0) + return log_oom(); + + if (terminal_urlify("https://docs.python.org/3/library/uuid.html", "uuid", &mod_link) < 0) + return log_oom(); + printf("As string:\n" - SD_ID128_FORMAT_STR "\n\n" + "%s" SD_ID128_FORMAT_STR "%s\n\n" "As UUID:\n" - "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n\n" - "As man:sd-id128(3) macro:\n" - "#define MESSAGE_XYZ SD_ID128_MAKE(", - SD_ID128_FORMAT_VAL(id), - SD_ID128_FORMAT_VAL(id)); + "%s%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x%s\n\n" + "As %s macro:\n" + "%s#define MESSAGE_XYZ SD_ID128_MAKE(", + on, SD_ID128_FORMAT_VAL(id), off, + on, SD_ID128_FORMAT_VAL(id), off, + man_link, + on); for (i = 0; i < 16; i++) printf("%02x%s", id.bytes[i], i != 15 ? "," : ""); - fputs(")\n\n", stdout); + printf(")%s\n\n", off); printf("As Python constant:\n" - ">>> import uuid\n" - ">>> MESSAGE_XYZ = uuid.UUID('" SD_ID128_FORMAT_STR "')\n", - SD_ID128_FORMAT_VAL(id)); + ">>> import %s\n" + ">>> %sMESSAGE_XYZ = uuid.UUID('" SD_ID128_FORMAT_STR "')%s\n", + mod_link, + on, SD_ID128_FORMAT_VAL(id), off); return 0; }