1#!/usr/bin/env bash
2# SPDX-License-Identifier: LGPL-2.1-or-later
3# shellcheck disable=SC2016
4set -eux
5
6systemd-analyze log-level debug
7
8# Verify that the creds are properly loaded and we can read them from the service's unpriv user
9systemd-run -p LoadCredential=passwd:/etc/passwd \
10            -p LoadCredential=shadow:/etc/shadow \
11            -p SetCredential=dog:wuff \
12            -p DynamicUser=1 \
13            --wait \
14            --pipe \
15            cat '${CREDENTIALS_DIRECTORY}/passwd' '${CREDENTIALS_DIRECTORY}/shadow' '${CREDENTIALS_DIRECTORY}/dog' >/tmp/ts54-concat
16( cat /etc/passwd /etc/shadow && echo -n wuff ) | cmp /tmp/ts54-concat
17rm /tmp/ts54-concat
18
19# Test that SetCredential= acts as fallback for LoadCredential=
20echo piff > /tmp/ts54-fallback
21[ "$(systemd-run -p LoadCredential=paff:/tmp/ts54-fallback -p SetCredential=paff:poff --pipe --wait systemd-creds cat paff)" = "piff" ]
22rm /tmp/ts54-fallback
23[ "$(systemd-run -p LoadCredential=paff:/tmp/ts54-fallback -p SetCredential=paff:poff --pipe --wait systemd-creds cat paff)" = "poff" ]
24
25if systemd-detect-virt -q -c ; then
26    expected_credential=mynspawncredential
27    expected_value=strangevalue
28elif [ -d /sys/firmware/qemu_fw_cfg/by_name ]; then
29    # Verify that passing creds through kernel cmdline works
30    [ "$(systemd-creds --system cat kernelcmdlinecred)" = "uff" ]
31
32    # If we aren't run in nspawn, we are run in qemu
33    systemd-detect-virt -q -v
34    expected_credential=myqemucredential
35    expected_value=othervalue
36else
37    echo "qemu_fw_cfg support missing in kernel. Sniff!"
38    expected_credential=""
39    expected_value=""
40fi
41
42if [ "$expected_credential" != "" ] ; then
43    # If this test is run in nspawn a credential should have been passed to us. See test/TEST-54-CREDS/test.sh
44    [ "$(systemd-creds --system cat "$expected_credential")" = "$expected_value" ]
45
46    # Test that propagation from system credential to service credential works
47    [ "$(systemd-run -p LoadCredential="$expected_credential" --pipe --wait systemd-creds cat "$expected_credential")" = "$expected_value" ]
48
49    # Check it also works, if we rename it while propagating it
50    [ "$(systemd-run -p LoadCredential=miau:"$expected_credential" --pipe --wait systemd-creds cat miau)" = "$expected_value" ]
51
52    # Combine it with a fallback (which should have no effect, given the cred should be passed down)
53    [ "$(systemd-run -p LoadCredential="$expected_credential" -p SetCredential="$expected_credential":zzz --pipe --wait systemd-creds cat "$expected_credential")" = "$expected_value" ]
54fi
55
56# Verify that the creds are immutable
57systemd-run -p LoadCredential=passwd:/etc/passwd \
58            -p DynamicUser=1 \
59            --wait \
60            touch '${CREDENTIALS_DIRECTORY}/passwd' \
61    && { echo 'unexpected success'; exit 1; }
62systemd-run -p LoadCredential=passwd:/etc/passwd \
63            -p DynamicUser=1 \
64            --wait \
65            rm '${CREDENTIALS_DIRECTORY}/passwd' \
66    && { echo 'unexpected success'; exit 1; }
67
68# Check directory-based loading
69mkdir -p /tmp/ts54-creds/sub
70echo -n a >/tmp/ts54-creds/foo
71echo -n b >/tmp/ts54-creds/bar
72echo -n c >/tmp/ts54-creds/baz
73echo -n d >/tmp/ts54-creds/sub/qux
74systemd-run -p LoadCredential=cred:/tmp/ts54-creds \
75            -p DynamicUser=1 \
76            --wait \
77            --pipe \
78            cat '${CREDENTIALS_DIRECTORY}/cred_foo' \
79                '${CREDENTIALS_DIRECTORY}/cred_bar' \
80                '${CREDENTIALS_DIRECTORY}/cred_baz' \
81                '${CREDENTIALS_DIRECTORY}/cred_sub_qux' >/tmp/ts54-concat
82( echo -n abcd ) | cmp /tmp/ts54-concat
83rm /tmp/ts54-concat
84rm -rf /tmp/ts54-creds
85
86# Now test encrypted credentials (only supported when built with OpenSSL though)
87if systemctl --version | grep -q -- +OPENSSL ; then
88    echo -n $RANDOM >/tmp/test-54-plaintext
89    systemd-creds encrypt --name=test-54 /tmp/test-54-plaintext /tmp/test-54-ciphertext
90    systemd-creds decrypt --name=test-54 /tmp/test-54-ciphertext | cmp /tmp/test-54-plaintext
91
92    systemd-run -p LoadCredentialEncrypted=test-54:/tmp/test-54-ciphertext \
93                --wait \
94                --pipe \
95                cat '${CREDENTIALS_DIRECTORY}/test-54' | cmp /tmp/test-54-plaintext
96
97    echo -n $RANDOM >/tmp/test-54-plaintext
98    systemd-creds encrypt --name=test-54 /tmp/test-54-plaintext /tmp/test-54-ciphertext
99    systemd-creds decrypt --name=test-54 /tmp/test-54-ciphertext | cmp /tmp/test-54-plaintext
100
101    systemd-run -p SetCredentialEncrypted=test-54:"$(cat /tmp/test-54-ciphertext)" \
102                --wait \
103                --pipe \
104                cat '${CREDENTIALS_DIRECTORY}/test-54' | cmp /tmp/test-54-plaintext
105
106    rm /tmp/test-54-plaintext /tmp/test-54-ciphertext
107fi
108
109systemd-analyze log-level info
110
111echo OK >/testok
112
113exit 0
114