Merge pull request #28988 from keszybz/sd128-arbitrary-values

Add sd-id128 and systemd-id128 functionality to do "app specific" with any "base"
This commit is contained in:
Luca Boccassi 2023-09-03 14:05:32 +01:00 committed by GitHub
commit 626a9eba09
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 242 additions and 109 deletions

2
TODO
View file

@ -310,6 +310,8 @@ Features:
aforementioned journald subscription varlink service, to enable
activation-by-message id and similar.
* .service with invalid Sockets= starts successfully.
* landlock: lock down RuntimeDirectory= via landlock, so that services lose
ability to write anywehere else below /run/. Similar for
StateDirectory=. Benefit would be clear delegation via unit files: services

View file

@ -672,7 +672,8 @@ manpages = [
''],
['sd_id128_get_machine',
'3',
['sd_id128_get_boot',
['sd_id128_get_app_specific',
'sd_id128_get_boot',
'sd_id128_get_boot_app_specific',
'sd_id128_get_invocation',
'sd_id128_get_machine_app_specific'],

View file

@ -17,6 +17,7 @@
<refnamediv>
<refname>sd_id128_get_machine</refname>
<refname>sd_id128_get_app_specific</refname>
<refname>sd_id128_get_machine_app_specific</refname>
<refname>sd_id128_get_boot</refname>
<refname>sd_id128_get_boot_app_specific</refname>
@ -33,6 +34,13 @@
<paramdef>sd_id128_t *<parameter>ret</parameter></paramdef>
</funcprototype>
<funcprototype>
<funcdef>int <function>sd_id128_get_app_specific</function></funcdef>
<paramdef>sd_id128_t <parameter>base</parameter></paramdef>
<paramdef>sd_id128_t <parameter>app_id</parameter></paramdef>
<paramdef>sd_id128_t *<parameter>ret</parameter></paramdef>
</funcprototype>
<funcprototype>
<funcdef>int <function>sd_id128_get_machine_app_specific</function></funcdef>
<paramdef>sd_id128_t <parameter>app_id</parameter></paramdef>
@ -69,16 +77,25 @@
ID from this machine ID, in an irreversible (cryptographically secure) way. To make this easy
<function>sd_id128_get_machine_app_specific()</function> is provided, see below.</para>
<para><function>sd_id128_get_app_specific()</function> returns a machine ID that is a combination of the
<parameter>base</parameter> and <parameter>app_id</parameter> parameters. Internally, this function
calculates HMAC-SHA256 of the <parameter>app_id</parameter> parameter keyed by the
<parameter>base</parameter> parameter, and truncates this result to fit in
<structname>sd_id128_t</structname> and turns it into a valid Variant 1 Version 4 UUID, in accordance
with <ulink url="https://tools.ietf.org/html/rfc4122">RFC 4122</ulink>. Neither of the two input
parameters can be calculated from the output parameter <parameter>ret</parameter>.</para>
<para><function>sd_id128_get_machine_app_specific()</function> is similar to
<function>sd_id128_get_machine()</function>, 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
<function>sd_id128_get_machine()</function> 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 <command>systemd-id128 new</command>,
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.</para>
<function>sd_id128_get_machine()</function>, 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 <function>sd_id128_get_machine()</function> 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
<command>systemd-id128 new</command>, 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 calls <function>sd_id128_get_app_specific()</function> with the result from
<function>sd_id128_get_machine()</function> and the <parameter>app_id</parameter> parameter.</para>
<para><function>sd_id128_get_boot()</function> returns the boot ID of the executing kernel. This reads and parses
the <filename>/proc/sys/kernel/random/boot_id</filename> file exposed by the kernel. It is randomly generated early
@ -89,9 +106,9 @@
derive an application specific ID using <function>sd_id128_get_boot_app_specific()</function>, see below.</para>
<para><function>sd_id128_get_boot_app_specific()</function> is analogous to
<function>sd_id128_get_machine_app_specific()</function> 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.</para>
<function>sd_id128_get_machine_app_specific()</function>, 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.</para>
<para><function>sd_id128_get_invocation()</function> returns the invocation ID of the currently executed
service. In its current implementation, this tries to read and parse the following:
@ -181,7 +198,10 @@
<term><constant>-ENXIO</constant></term>
<listitem><para>Returned by <function>sd_id128_get_invocation()</function> if no invocation ID is
set.</para>
set. Also returned by <function>sd_id128_get_app_specific()</function>,
<function>sd_id128_get_machine_app_specific()</function>, and
<function>sd_id128_get_boot_app_specific()</function> when the <parameter>app_id</parameter>
parameter is all zeros.</para>
<xi:include href="version-info.xml" xpointer="v242"/></listitem>
</varlistentry>

View file

@ -44,6 +44,13 @@
<arg choice="opt" rep="repeat">OPTIONS</arg>
<arg choice="plain">invocation-id</arg>
</cmdsynopsis>
<cmdsynopsis>
<command>systemd-id128</command>
<arg choice="opt" rep="repeat">OPTIONS</arg>
<arg choice="plain">show</arg>
<arg choice="opt" rep="repeat">NAME|UUID</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
@ -63,12 +70,6 @@
<para>With <command>boot-id</command>, the identifier of the current boot will be
printed.</para>
<para>Both <command>machine-id</command> and <command>boot-id</command> may be combined
with the <option>--app-specific=<replaceable>app-id</replaceable></option> switch to
generate application-specific IDs. See
<citerefentry><refentrytitle>sd_id128_get_machine</refentrytitle><manvolnum>3</manvolnum></citerefentry>
for the discussion when this is useful.</para>
<para>With <command>invocation-id</command>, the identifier of the current service invocation
will be printed. This is available in systemd services. See
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
@ -76,9 +77,17 @@
<para>With <command>show</command>, well-known IDs are printed (for now, only GPT partition type UUIDs),
along with brief identifier strings. When no arguments are specified, all known IDs are shown. When
arguments are specified, they must be the identifiers or ID values of one or more known IDs, which are
then printed. Combine with <option>--uuid</option> to list the IDs in UUID style, i.e. the way GPT
partition type UUIDs are usually shown.</para>
arguments are specified, they may be the identifiers or ID values of one or more known IDs, which are
then printed with their name, or arbitrary IDs, which are then printed with a placeholder name. Combine
with <option>--uuid</option> to list the IDs in UUID style, i.e. the way GPT partition type UUIDs are
usually shown.</para>
<para><command>machine-id</command>, <command>boot-id</command>, and <command>show</command> may be
combined with the <option>--app-specific=<replaceable>app-id</replaceable></option> switch to generate
application-specific IDs. See
<citerefentry><refentrytitle>sd_id128_get_machine</refentrytitle><manvolnum>3</manvolnum></citerefentry>
for the discussion when this is useful. Support for <command>show --app-specific=</command> was added in
version 255.</para>
</refsect1>
<refsect1>
@ -96,14 +105,28 @@
<xi:include href="version-info.xml" xpointer="v240"/></listitem>
</varlistentry>
<varlistentry>
<term><option>-P</option></term>
<term><option>--value</option></term>
<listitem><para>Only print the value. May be combined with
<option>-u</option>/<option>--uuid</option>.</para>
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
</varlistentry>
<varlistentry>
<term><option>-a <replaceable>app-id</replaceable></option></term>
<term><option>--app-specific=<replaceable>app-id</replaceable></option></term>
<listitem><para>With this option, an identifier that is the result of hashing the
application identifier <replaceable>app-id</replaceable> and the machine identifier will be
printed. The <replaceable>app-id</replaceable> argument must be a valid sd-id128 string
identifying the application.</para>
<listitem><para>With this option, identifiers will be printed that are the result of hashing the
application identifier <replaceable>app-id</replaceable> and another ID. The
<replaceable>app-id</replaceable> argument must be a valid sd-id128 string identifying the
application. When used with <command>machine-id</command>, the other ID will be the machine ID as
described in
<citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>, when
used with <command>boot-id</command>, the other ID will be the boot ID, and when used with
<command>show</command>, the other ID or IDs should be specified via the positional arguments.</para>
<xi:include href="version-info.xml" xpointer="v240"/>
</listitem>
@ -129,7 +152,49 @@
<refsect1>
<title>Exit status</title>
<para>On success, 0 is returned, a non-zero failure code otherwise.</para>
<para>On success 0 is returned, and a non-zero failure code otherwise.</para>
</refsect1>
<refsect1>
<title>Examples</title>
<example>
<title>Show a well-known UUID</title>
<programlisting>
$ systemd-id128 show -P user-home
773f91ef66d449b5bd83d683bf40ad16
$ systemd-id128 show -Pu user-home
773f91ef-66d4-49b5-bd83-d683bf40ad16
$ systemd-id128 show 773f91ef-66d4-49b5-bd83-d683bf40ad16
NAME ID
user-home 773f91ef66d449b5bd83d683bf40ad16
</programlisting>
</example>
<example>
<title>Generate an application-specific UUID</title>
<programlisting>
$ systemd-id128 machine-id -u
3a9d668b-4db7-4939-8a4a-5e78a03bffb7
$ systemd-id128 new -u
1fb8f24b-02df-458d-9659-cc8ace68e28a
$ systemd-id128 --app=1fb8f24b-02df-458d-9659-cc8ace68e28a
47b82cb1-5339-43da-b2a6-1c350aef1bd1
$ systemd-id128 -Pu show 3a9d668b-4db7-4939-8a4a-5e78a03bffb7 --app=1fb8f24b-02df-458d-9659-cc8ace68e28a
47b82cb1-5339-43da-b2a6-1c350aef1bd1
</programlisting>
<para>On a given machine with the ID 3a9d668b-4db7-4939-8a4a-5e78a03bffb7, for the application
1fb8f24b-02df-458d-9659-cc8ace68e28a, we generate an application-specific machine ID. If we want to
later recreate the same calculation on a different machine, we need to specify both IDs explicitly.
</para>
</example>
</refsect1>
<refsect1>

View file

@ -242,20 +242,6 @@ static int console_setup(void) {
return 0;
}
static int set_machine_id(const char *m) {
sd_id128_t t;
assert(m);
if (sd_id128_from_string(m, &t) < 0)
return -EINVAL;
if (sd_id128_is_null(t))
return -EINVAL;
arg_machine_id = t;
return 0;
}
static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
int r;
@ -392,7 +378,7 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
if (proc_cmdline_value_missing(key, value))
return 0;
r = set_machine_id(value);
r = id128_from_string_nonzero(value, &arg_machine_id);
if (r < 0)
log_warning_errno(r, "MachineID '%s' is not valid, ignoring: %m", value);
@ -1045,7 +1031,7 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_MACHINE_ID:
r = set_machine_id(optarg);
r = id128_from_string_nonzero(optarg, &arg_machine_id);
if (r < 0)
return log_error_errno(r, "MachineID '%s' is not valid: %m", optarg);
break;

View file

@ -16,6 +16,7 @@
static Id128PrettyPrintMode arg_mode = ID128_PRINT_ID128;
static sd_id128_t arg_app = {};
static bool arg_value = false;
static int verb_new(int argc, char **argv, void *userdata) {
return id128_print_new(arg_mode);
@ -67,8 +68,16 @@ static int verb_invocation_id(int argc, char **argv, void *userdata) {
}
static int show_one(Table **table, const char *name, sd_id128_t uuid, bool first) {
sd_id128_t u;
int r;
assert(table);
if (sd_id128_is_null(arg_app))
u = uuid;
else
assert_se(sd_id128_get_app_specific(uuid, arg_app, &u) == 0);
if (arg_mode == ID128_PRINT_PRETTY) {
_cleanup_free_ char *id = NULL;
@ -78,26 +87,28 @@ static int show_one(Table **table, const char *name, sd_id128_t uuid, bool first
ascii_strupper(id);
r = id128_pretty_print_sample(id, uuid);
r = id128_pretty_print_sample(id, u);
if (r < 0)
return r;
if (!first)
puts("");
return 0;
} else {
if (!*table) {
*table = table_new("name", "id");
if (!*table)
return log_oom();
table_set_width(*table, 0);
}
return table_add_many(*table,
TABLE_STRING, name,
arg_mode == ID128_PRINT_ID128 ? TABLE_ID128 : TABLE_UUID,
uuid);
}
if (arg_value)
return id128_pretty_print(u, arg_mode);
if (!*table) {
*table = table_new("name", "id");
if (!*table)
return log_oom();
table_set_width(*table, 0);
}
return table_add_many(*table,
TABLE_STRING, name,
arg_mode == ID128_PRINT_ID128 ? TABLE_ID128 : TABLE_UUID,
u);
}
static int verb_show(int argc, char **argv, void *userdata) {
@ -162,7 +173,7 @@ static int help(void) {
" 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"
" show [NAME] Print one or more well-known GPT partition type IDs\n"
" show [NAME|UUID] Print one or more UUIDs\n"
" help Show this help\n"
"\nOptions:\n"
" -h --help Show this help\n"
@ -191,6 +202,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, ARG_VERSION },
{ "pretty", no_argument, NULL, 'p' },
{ "value", no_argument, NULL, 'P' },
{ "app-specific", required_argument, NULL, 'a' },
{ "uuid", no_argument, NULL, 'u' },
{},
@ -201,7 +213,7 @@ static int parse_argv(int argc, char *argv[]) {
assert(argc >= 0);
assert(argv);
while ((c = getopt_long(argc, argv, "hpa:u", options, NULL)) >= 0)
while ((c = getopt_long(argc, argv, "hpa:uP", options, NULL)) >= 0)
switch (c) {
case 'h':
@ -212,10 +224,19 @@ static int parse_argv(int argc, char *argv[]) {
case 'p':
arg_mode = ID128_PRINT_PRETTY;
arg_value = false;
break;
case 'P':
arg_value = true;
if (arg_mode == ID128_PRINT_PRETTY)
arg_mode = ID128_PRINT_ID128;
break;
case 'a':
r = sd_id128_from_string(optarg, &arg_app);
r = id128_from_string_nonzero(optarg, &arg_app);
if (r == -ENXIO)
return log_error_errno(r, "Application ID cannot be all zeros.");
if (r < 0)
return log_error_errno(r, "Failed to parse \"%s\" as application-ID: %m", optarg);
break;

View file

@ -828,3 +828,8 @@ global:
sd_journal_step_one;
sd_session_get_leader;
} LIBSYSTEMD_253;
LIBSYSTEMD_255 {
global:
sd_id128_get_app_specific;
} LIBSYSTEMD_254;

View file

@ -13,6 +13,23 @@
#include "string-util.h"
#include "sync-util.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;
}
bool id128_is_valid(const char *s) {
size_t l;

View file

@ -21,6 +21,8 @@ typedef enum Id128Flag {
ID128_REFUSE_NULL = 1 << 3, /* Refuse all zero ID with -ENOMEDIUM. */
} Id128Flag;
int id128_from_string_nonzero(const char *s, sd_id128_t *ret);
int id128_read_fd(int fd, Id128Flag f, sd_id128_t *ret);
int id128_read_at(int dir_fd, const char *path, Id128Flag f, sd_id128_t *ret);
static inline int id128_read(const char *path, Id128Flag f, sd_id128_t *ret) {

View file

@ -338,18 +338,20 @@ _public_ int sd_id128_randomize(sd_id128_t *ret) {
return 0;
}
static int get_app_specific(sd_id128_t base, sd_id128_t app_id, sd_id128_t *ret) {
uint8_t hmac[SHA256_DIGEST_SIZE];
sd_id128_t result;
_public_ int sd_id128_get_app_specific(sd_id128_t base, sd_id128_t app_id, sd_id128_t *ret) {
assert_cc(sizeof(sd_id128_t) < SHA256_DIGEST_SIZE); /* Check that we don't need to pad with zeros. */
union {
uint8_t hmac[SHA256_DIGEST_SIZE];
sd_id128_t result;
} buf;
assert(ret);
assert_return(ret, -EINVAL);
assert_return(!sd_id128_is_null(app_id), -ENXIO);
hmac_sha256(&base, sizeof(base), &app_id, sizeof(app_id), hmac);
hmac_sha256(&base, sizeof(base), &app_id, sizeof(app_id), buf.hmac);
/* Take only the first half. */
memcpy(&result, hmac, MIN(sizeof(hmac), sizeof(result)));
*ret = id128_make_v4_uuid(result);
*ret = id128_make_v4_uuid(buf.result);
return 0;
}
@ -363,7 +365,7 @@ _public_ int sd_id128_get_machine_app_specific(sd_id128_t app_id, sd_id128_t *re
if (r < 0)
return r;
return get_app_specific(id, app_id, ret);
return sd_id128_get_app_specific(id, app_id, ret);
}
_public_ int sd_id128_get_boot_app_specific(sd_id128_t app_id, sd_id128_t *ret) {
@ -376,5 +378,5 @@ _public_ int sd_id128_get_boot_app_specific(sd_id128_t app_id, sd_id128_t *ret)
if (r < 0)
return r;
return get_app_specific(id, app_id, ret);
return sd_id128_get_app_specific(id, app_id, ret);
}

View file

@ -370,16 +370,11 @@ int config_parse_address_generation_type(
}
if (comma) {
r = sd_id128_from_string(comma + 1, &secret_key);
r = id128_from_string_nonzero(comma + 1, &secret_key);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse secret key in %s=, ignoring assignment: %s",
lvalue, rvalue);
return 0;
}
if (sd_id128_is_null(secret_key)) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Secret key in %s= cannot be null, ignoring assignment: %s",
r == -ENXIO ? "Secret key in %s= cannot be null, ignoring assignment: %s"
: "Failed to parse secret key in %s=, ignoring assignment: %s",
lvalue, rvalue);
return 0;
}

View file

@ -976,13 +976,12 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_UUID:
r = sd_id128_from_string(optarg, &arg_uuid);
if (r < 0)
return log_error_errno(r, "Invalid UUID: %s", optarg);
if (sd_id128_is_null(arg_uuid))
r = id128_from_string_nonzero(optarg, &arg_uuid);
if (r == -ENXIO)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Machine UUID may not be all zeroes.");
if (r < 0)
return log_error_errno(r, "Invalid UUID: %s", optarg);
arg_settings_mask |= SETTING_MACHINE_ID;
break;

View file

@ -2438,11 +2438,8 @@ static int context_load_partition_table(Context *context) {
if (r < 0)
return log_error_errno(r, "Failed to get current GPT disk label UUID: %m");
r = sd_id128_from_string(disk_uuid_string, &disk_uuid);
if (r < 0)
return log_error_errno(r, "Failed to parse current GPT disk label UUID: %m");
if (sd_id128_is_null(disk_uuid)) {
r = id128_from_string_nonzero(disk_uuid_string, &disk_uuid);
if (r == -ENXIO) {
r = derive_uuid(context->seed, "disk-uuid", &disk_uuid);
if (r < 0)
return log_error_errno(r, "Failed to acquire disk GPT uuid: %m");
@ -2450,7 +2447,8 @@ static int context_load_partition_table(Context *context) {
r = fdisk_set_disklabel_id(c);
if (r < 0)
return log_error_errno(r, "Failed to set GPT disk label: %m");
}
} else if (r < 0)
return log_error_errno(r, "Failed to parse current GPT disk label UUID: %m");
r = fdisk_get_partitions(c, &t);
if (r < 0)

View file

@ -19,6 +19,7 @@
#include "fileio.h"
#include "fs-util.h"
#include "hostname-util.h"
#include "id128-util.h"
#include "in-addr-util.h"
#include "log.h"
#include "macro.h"
@ -944,25 +945,19 @@ int config_parse_id128(
void *data,
void *userdata) {
sd_id128_t t, *result = data;
sd_id128_t *result = data;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
r = sd_id128_from_string(rvalue, &t);
if (r < 0) {
r = id128_from_string_nonzero(rvalue, result);
if (r == -ENXIO)
log_syntax(unit, LOG_WARNING, filename, line, r, "128-bit ID/UUID is all 0, ignoring: %s", rvalue);
else if (r < 0)
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse 128-bit ID/UUID, ignoring: %s", rvalue);
return 0;
}
if (sd_id128_is_null(t)) {
log_syntax(unit, LOG_WARNING, filename, line, 0, "128-bit ID/UUID is all 0, ignoring: %s", rvalue);
return 0;
}
*result = t;
return 0;
}

View file

@ -11,12 +11,10 @@
#include "terminal-util.h"
int id128_pretty_print_sample(const char *name, sd_id128_t id) {
_cleanup_free_ char *man_link = NULL, *mod_link = NULL;
const char *on, *off;
unsigned i;
_cleanup_free_ char *man_link = NULL, *mod_link = NULL;
on = ansi_highlight();
off = ansi_normal();
const char *on = ansi_highlight(),
*off = ansi_normal();
if (terminal_urlify("man:systemd-id128(1)", "systemd-id128(1)", &man_link) < 0)
return log_oom();
@ -34,8 +32,8 @@ int id128_pretty_print_sample(const char *name, sd_id128_t id) {
on, SD_ID128_FORMAT_VAL(id), off,
man_link,
on, name);
for (i = 0; i < 16; i++)
printf("%02x%s", id.bytes[i], i != 15 ? "," : "");
for (size_t i = 0; i < 16; i++)
printf("%02x%s", id.bytes[i], i < 15 ? "," : "");
printf(")%s\n\n", off);
printf("As Python constant:\n"

View file

@ -50,6 +50,7 @@ int sd_id128_get_machine(sd_id128_t *ret);
int sd_id128_get_boot(sd_id128_t *ret);
int sd_id128_get_invocation(sd_id128_t *ret);
int sd_id128_get_app_specific(sd_id128_t base, sd_id128_t app_id, 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);

View file

@ -20,6 +20,7 @@
#define ID128_WALDI SD_ID128_MAKE(01, 02, 03, 04, 05, 06, 07, 08, 09, 0a, 0b, 0c, 0d, 0e, 0f, 10)
#define STR_WALDI "0102030405060708090a0b0c0d0e0f10"
#define UUID_WALDI "01020304-0506-0708-090a-0b0c0d0e0f10"
#define STR_NULL "00000000000000000000000000000000"
TEST(id128) {
sd_id128_t id, id2;
@ -75,6 +76,13 @@ TEST(id128) {
assert_se(sd_id128_from_string("01020304-0506-0708-090a0b0c0d0e0f10", &id) < 0);
assert_se(sd_id128_from_string("010203040506-0708-090a-0b0c0d0e0f10", &id) < 0);
assert_se(id128_from_string_nonzero(STR_WALDI, &id) == 0);
assert_se(id128_from_string_nonzero(STR_NULL, &id) == -ENXIO);
assert_se(id128_from_string_nonzero("01020304-0506-0708-090a-0b0c0d0e0f101", &id) < 0);
assert_se(id128_from_string_nonzero("01020304-0506-0708-090a-0b0c0d0e0f10-", &id) < 0);
assert_se(id128_from_string_nonzero("01020304-0506-0708-090a0b0c0d0e0f10", &id) < 0);
assert_se(id128_from_string_nonzero("010203040506-0708-090a-0b0c0d0e0f10", &id) < 0);
assert_se(id128_is_valid(STR_WALDI));
assert_se(id128_is_valid(UUID_WALDI));
assert_se(!id128_is_valid(""));
@ -172,6 +180,11 @@ TEST(id128) {
assert_se(lseek(fd, 0, SEEK_SET) == 0);
assert_se(id128_read_fd(fd, ID128_FORMAT_ANY, NULL) == -EUCLEAN);
/* build/systemd-id128 -a f03daaeb1c334b43a732172944bf772e show 51df0b4bc3b04c9780e299b98ca373b8 */
assert_se(sd_id128_get_app_specific(SD_ID128_MAKE(51,df,0b,4b,c3,b0,4c,97,80,e2,99,b9,8c,a3,73,b8),
SD_ID128_MAKE(f0,3d,aa,eb,1c,33,4b,43,a7,32,17,29,44,bf,77,2e), &id) >= 0);
assert_se(sd_id128_equal(id, SD_ID128_MAKE(1d,ee,59,54,e7,5c,4d,6f,b9,6c,c6,c0,4c,a1,8a,86)));
if (sd_booted() > 0 && sd_id128_get_machine(NULL) >= 0) {
assert_se(sd_id128_get_machine_app_specific(SD_ID128_MAKE(f0,3d,aa,eb,1c,33,4b,43,a7,32,17,29,44,bf,77,2e), &id) >= 0);
assert_se(sd_id128_get_machine_app_specific(SD_ID128_MAKE(f0,3d,aa,eb,1c,33,4b,43,a7,32,17,29,44,bf,77,2e), &id2) >= 0);
@ -179,6 +192,10 @@ TEST(id128) {
assert_se(sd_id128_get_machine_app_specific(SD_ID128_MAKE(51,df,0b,4b,c3,b0,4c,97,80,e2,99,b9,8c,a3,73,b8), &id2) >= 0);
assert_se(!sd_id128_equal(id, id2));
}
/* Check return values */
assert_se(sd_id128_get_app_specific(SD_ID128_ALLF, SD_ID128_NULL, &id) == -ENXIO);
assert_se(sd_id128_get_app_specific(SD_ID128_NULL, SD_ID128_ALLF, &id) == 0);
}
TEST(sd_id128_get_invocation) {

View file

@ -9,9 +9,18 @@ set -o pipefail
systemd-id128 --help
systemd-id128 help
systemd-id128 show
systemd-id128 show --pretty | tail -n10
systemd-id128 show --pretty | tail
systemd-id128 show --value | tail
systemd-id128 show 4f68bce3e8cd4db196e7fbcaf984b709 # root-x86-64
systemd-id128 show --pretty 4f68bce3e8cd4db196e7fbcaf984b709
systemd-id128 show root-x86-64
systemd-id128 show --pretty root-x86-64
[[ "$(systemd-id128 show 4f68bce3e8cd4db196e7fbcaf984b709)" = "$(systemd-id128 show root-x86-64)" ]]
[[ "$(systemd-id128 show 4f68bce3-e8cd-4db1-96e7-fbcaf984b709)" = "$(systemd-id128 show root-x86-64)" ]]
systemd-id128 show root-x86-64 --app-specific=4f68bce3e8cd4db196e7fbcaf984b709
systemd-id128 show --pretty root-x86-64 --app-specific=4f68bce3e8cd4db196e7fbcaf984b709
[[ "$(systemd-id128 show root-x86-64 --app-specific=4f68bce3e8cd4db196e7fbcaf984b709 -P)" = "8ee5535e7cb14c249e1d28b8dfbb939c" ]]
[[ "$(systemd-id128 new | wc -c)" -eq 33 ]]
systemd-id128 new -p