From ee46e4d9820f1ab631fb1dda780a2ac43f02ce1c Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Tue, 18 Apr 2023 12:10:36 +0200 Subject: [PATCH 1/3] test: cover missed stuff from securebits-util.h --- src/test/test-secure-bits.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/test/test-secure-bits.c b/src/test/test-secure-bits.c index d44bef6a09..27e6a20e09 100644 --- a/src/test/test-secure-bits.c +++ b/src/test/test-secure-bits.c @@ -28,6 +28,7 @@ TEST(secure_bits_basic) { r = secure_bits_from_string(*bit); assert_se(r > 0); + assert_se(secure_bits_is_valid(r)); assert_se(secure_bits_to_string_alloc(r, &s) >= 0); printf("%s = 0x%x = %s\n", *bit, (unsigned)r, s); assert_se(streq(*bit, s)); @@ -38,6 +39,7 @@ TEST(secure_bits_basic) { assert_se(joined); r = secure_bits_from_string(joined); assert_se(r > 0); + assert_se(secure_bits_is_valid(r)); assert_se(secure_bits_to_string_alloc(r, &str) >= 0); printf("%s = 0x%x = %s\n", joined, (unsigned)r, str); assert_se(streq(joined, str)); @@ -54,6 +56,16 @@ TEST(secure_bits_basic) { /* Empty secure bits */ assert_se(secure_bits_to_string_alloc(0, &str) >= 0); assert_se(isempty(str)); + + str = mfree(str); + + /* Bits to string with check */ + assert_se(secure_bits_to_string_alloc_with_check(INT_MAX, &str) == -EINVAL); + assert_se(str == NULL); + assert_se(secure_bits_to_string_alloc_with_check( + (1 << SECURE_KEEP_CAPS) | (1 << SECURE_KEEP_CAPS_LOCKED), + &str) >= 0); + assert_se(streq(str, "keep-caps keep-caps-locked")); } TEST(secure_bits_mix) { @@ -75,6 +87,7 @@ TEST(secure_bits_mix) { r = secure_bits_from_string(s->input); assert_se(r > 0); + assert_se(secure_bits_is_valid(r)); assert_se(secure_bits_to_string_alloc(r, &str) >= 0); printf("%s = 0x%x = %s\n", s->input, (unsigned)r, str); assert_se(streq(s->expected, str)); From c74e13a5c334d6bb4eefc5cac1fa26cb9c5a4dd1 Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Tue, 25 Apr 2023 12:58:15 +0200 Subject: [PATCH 2/3] creds: make --pretty behave in a slightly more expected manner --- man/systemd-creds.xml | 3 ++- src/creds/creds.c | 15 ++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/man/systemd-creds.xml b/man/systemd-creds.xml index b16ee09cee..fbe62262af 100644 --- a/man/systemd-creds.xml +++ b/man/systemd-creds.xml @@ -228,7 +228,8 @@ When specified with encrypt controls whether to show the encrypted credential as SetCredentialEncrypted= setting that may be pasted directly into a - unit file. + unit file. Has effect only when used together with and - + as the output file. diff --git a/src/creds/creds.c b/src/creds/creds.c index ef32efe1e2..670e719d21 100644 --- a/src/creds/creds.c +++ b/src/creds/creds.c @@ -506,20 +506,21 @@ static int verb_encrypt(int argc, char **argv, void *userdata) { if (base64_size < 0) return base64_size; - if (arg_pretty) { + /* Pretty print makes sense only if we're printing stuff to stdout + * and if a cred name is provided via --name= (since we can't use + * the output file name as the cred name here) */ + if (arg_pretty && !output_path && name) { _cleanup_free_ char *escaped = NULL, *indented = NULL, *j = NULL; - if (name) { - escaped = cescape(name); - if (!escaped) - return log_oom(); - } + escaped = cescape(name); + if (!escaped) + return log_oom(); indented = strreplace(base64_buf, "\n", " \\\n "); if (!indented) return log_oom(); - j = strjoin("SetCredentialEncrypted=", name, ": \\\n ", indented, "\n"); + j = strjoin("SetCredentialEncrypted=", escaped, ": \\\n ", indented, "\n"); if (!j) return log_oom(); From ad2875af9eb59e6957f6001ca53599ca4f32c5ac Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Tue, 25 Apr 2023 18:32:07 +0200 Subject: [PATCH 3/3] test: add a couple of sanity tests for systemd-creds --- test/units/testsuite-54.sh | 146 +++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) diff --git a/test/units/testsuite-54.sh b/test/units/testsuite-54.sh index cc732989a2..d243d93d81 100755 --- a/test/units/testsuite-54.sh +++ b/test/units/testsuite-54.sh @@ -5,6 +5,152 @@ set -eux systemd-analyze log-level debug +run_with_cred_compare() { + local cred="${1:?}" + local exp="${2?}" + shift 2 + + diff <(systemd-run -p SetCredential="$cred" --wait --pipe -- systemd-creds "$@") <(echo -ne "$exp") +} + +# Sanity checks +# +# Create a dummy "full" disk (similar to /dev/full) to check out-of-space +# scenarios +mkdir /tmp/full +mount -t tmpfs -o size=1,nr_inodes=1 tmpfs /tmp/full + +# verb: setup +# Run this first, otherwise any encrypted credentials wouldn't be decryptable +# as we regnerate the host key +rm -fv /var/lib/systemd/credential.secret +systemd-creds setup +test -e /var/lib/systemd/credential.secret +rm -fv /var/lib/systemd/credential.secret + +# Prepare a couple of dummy credentials for the cat/list verbs +CRED_DIR="$(mktemp -d)" +ENC_CRED_DIR="$(mktemp -d)" +echo foo >"$CRED_DIR/secure-or-weak" +echo foo >"$CRED_DIR/insecure" +echo foo | systemd-creds --name="encrypted" encrypt - - | base64 -d >"$ENC_CRED_DIR/encrypted" +echo foo | systemd-creds encrypt - - | base64 -d >"$ENC_CRED_DIR/encrypted-unnamed" +chmod -R 0400 "$CRED_DIR" "$ENC_CRED_DIR" +chmod -R 0444 "$CRED_DIR/insecure" +mkdir /tmp/empty/ + +systemd-creds --system +systemd-creds --no-pager --help +systemd-creds --version +systemd-creds has-tpm2 || : +systemd-creds has-tpm2 -q || : + +# verb: list +systemd-creds list --system +ENCRYPTED_CREDENTIALS_DIRECTORY="$ENC_CRED_DIR" CREDENTIALS_DIRECTORY="$CRED_DIR" systemd-creds list --no-legend +ENCRYPTED_CREDENTIALS_DIRECTORY="$ENC_CRED_DIR" CREDENTIALS_DIRECTORY="$CRED_DIR" systemd-creds list --json=pretty | jq +ENCRYPTED_CREDENTIALS_DIRECTORY="$ENC_CRED_DIR" CREDENTIALS_DIRECTORY="$CRED_DIR" systemd-creds list --json=short | jq +ENCRYPTED_CREDENTIALS_DIRECTORY="$ENC_CRED_DIR" CREDENTIALS_DIRECTORY="$CRED_DIR" systemd-creds list --json=off +ENCRYPTED_CREDENTIALS_DIRECTORY="/tmp/empty/" CREDENTIALS_DIRECTORY="/tmp/empty/" systemd-creds list + +# verb: cat +for cred in secure-or-weak insecure encrypted encrypted-unnamed; do + ENCRYPTED_CREDENTIALS_DIRECTORY="$ENC_CRED_DIR" CREDENTIALS_DIRECTORY="$CRED_DIR" systemd-creds cat "$cred" +done +run_with_cred_compare "mycred:" "" cat mycred +run_with_cred_compare "mycred:\n" "\n" cat mycred +run_with_cred_compare "mycred:foo" "foo" cat mycred +run_with_cred_compare "mycred:foo" "foofoofoo" cat mycred mycred mycred +# Note: --newline= does nothing when stdout is not a tty, which is the case here +run_with_cred_compare "mycred:foo" "foo" --newline=yes cat mycred +run_with_cred_compare "mycred:foo" "foo" --newline=no cat mycred +run_with_cred_compare "mycred:foo" "foo" --newline=auto cat mycred +run_with_cred_compare "mycred:foo" "foo" --transcode=no cat mycred +run_with_cred_compare "mycred:foo" "foo" --transcode=0 cat mycred +run_with_cred_compare "mycred:foo" "foo" --transcode=false cat mycred +run_with_cred_compare "mycred:foo" "Zm9v" --transcode=base64 cat mycred +run_with_cred_compare "mycred:Zm9v" "foo" --transcode=unbase64 cat mycred +run_with_cred_compare "mycred:Zm9v" "foofoofoo" --transcode=unbase64 cat mycred mycred mycred +run_with_cred_compare "mycred:Zm9vCg==" "foo\n" --transcode=unbase64 cat mycred +run_with_cred_compare "mycred:hello world" "68656c6c6f20776f726c64" --transcode=hex cat mycred +run_with_cred_compare "mycred:68656c6c6f20776f726c64" "hello world" --transcode=unhex cat mycred +run_with_cred_compare "mycred:68656c6c6f20776f726c64" "hello worldhello world" --transcode=unhex cat mycred mycred +run_with_cred_compare "mycred:68656c6c6f0a776f726c64" "hello\nworld" --transcode=unhex cat mycred +run_with_cred_compare 'mycred:{ "foo" : "bar", "baz" : [ 3, 4 ] }' '{"foo":"bar","baz":[3,4]}\n' --json=short cat mycred +systemd-run -p SetCredential='mycred:{ "foo" : "bar", "baz" : [ 3, 4 ] }' --wait --pipe -- systemd-creds --json=pretty cat mycred | jq + +# verb: encrypt/decrypt +echo "According to all known laws of aviation..." >/tmp/cred.orig +systemd-creds --with-key=host encrypt /tmp/cred.orig /tmp/cred.enc +systemd-creds decrypt /tmp/cred.enc /tmp/cred.dec +diff /tmp/cred.orig /tmp/cred.dec +rm -f /tmp/cred.{enc,dec} +# --pretty +cred_name="fo'''o''bar" +cred_option="$(systemd-creds --pretty --name="$cred_name" encrypt /tmp/cred.orig -)" +mkdir -p /run/systemd/system +cat >/run/systemd/system/test-54-pretty-cred.service <