1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232
|
summary: Verify that snapd correctly removes expired users created with assertions.
details: |
Check snapd removes expired users created with assertions, and also is able to
reimports the user with a new expiration date.
systems: [ubuntu-2*]
environment:
# use snapd from the spread run so that we have testkeys trusted in the
# snapd run
NESTED_BUILD_SNAPD_FROM_CURRENT: true
# use secure boot and TPM to enable encryption
NESTED_ENABLE_TPM: true
NESTED_ENABLE_SECURE_BOOT: true
# don't use cloud-init it doesn't work with grade secured
NESTED_USE_CLOUD_INIT: false
# sign all the snaps we build for the image with fakestore
NESTED_SIGN_SNAPS_FAKESTORE: true
NESTED_CUSTOM_AUTO_IMPORT_ASSERTION: $TESTSLIB/assertions/developer1-{VERSION}-auto-import.assert
NESTED_CUSTOM_MODEL: $TESTSLIB/assertions/developer1-{VERSION}-secured.model
# for the fake store
NESTED_FAKESTORE_BLOB_DIR: $(pwd)/fake-store-blobdir
NESTED_UBUNTU_IMAGE_SNAPPY_FORCE_SAS_URL: http://localhost:11028
# unset this otherwise ubuntu-image complains about overriding the channel for
# a model with grade higher than dangerous when building the image
NESTED_CORE_CHANNEL: ""
prepare: |
if [ "$TRUST_TEST_KEYS" = "false" ]; then
echo "This test needs test keys to be trusted"
exit
fi
# set the expiration of the assert to 60 minutes, and replace the version
# with the version we are testing
VERSION="$(tests.nested show version)"
EXPIRATION_1HR=$(date --rfc-3339=seconds -d "$(date) + 60 minute" | sed 's/ /T/')
EXPIRATION_2HR=$(date --rfc-3339=seconds -d "$(date) + 120 minute" | sed 's/ /T/')
EXPIRATION_3HR=$(date --rfc-3339=seconds -d "$(date) + 180 minute" | sed 's/ /T/')
#shellcheck disable=SC2002,SC2016
cat ./user2.json | gojq --arg date "$EXPIRATION_1HR" '. + {until: $date}' > ./user2-final.json
sed -i "s/{VERSION}/$VERSION/g" ./user2-final.json
#shellcheck disable=SC2002,SC2016
cat ./user2-2.json | gojq --arg date "$EXPIRATION_2HR" '. + {until: $date}' > ./user2-2-final.json
sed -i "s/{VERSION}/$VERSION/g" ./user2-2-final.json
#shellcheck disable=SC2002,SC2016
cat ./user3.json | gojq --arg date "$EXPIRATION_3HR" '. + {until: $date}' > ./user3-final.json
sed -i "s/{VERSION}/$VERSION/g" ./user3-final.json
# sign the users using gendeveloper1
gendeveloper1 sign-model < ./user2-final.json > user2.assert
gendeveloper1 sign-model < ./user2-2-final.json > user2-2.assert
gendeveloper1 sign-model < ./user3-final.json > user3.assert
#shellcheck source=tests/lib/nested.sh
. "$TESTSLIB/nested.sh"
# Setup the fake-store for ubuntu-image to use when creating our core image.
# We immediately tear down the staging store, to make sure snapd is not pointed
# towards this once we invoke ubuntu-image.
# We also need to point NESTED_UBUNTU_IMAGE_SNAPPY_FORCE_SAS_URL towards the newly
# setup fake-store to actually have it use it.
"$TESTSTOOLS"/store-state setup-fake-store "$NESTED_FAKESTORE_BLOB_DIR"
"$TESTSTOOLS"/store-state teardown-staging-store
echo "Expose the needed assertions through the fakestore"
cp "$TESTSLIB"/assertions/developer1.account "$NESTED_FAKESTORE_BLOB_DIR/asserts"
cp "$TESTSLIB"/assertions/developer1.account-key "$NESTED_FAKESTORE_BLOB_DIR/asserts"
KEY_NAME=$(tests.nested download snakeoil-key)
SNAKEOIL_KEY="$PWD/$KEY_NAME.key"
SNAKEOIL_CERT="$PWD/$KEY_NAME.pem"
# Get the nested system version
VERSION="$(tests.nested show version)"
echo "Grab and prepare the gadget snap"
snap download --basename=pc --channel="$VERSION/edge" pc
unsquashfs -d pc-gadget pc.snap
echo "Sign the shim binary"
tests.nested secboot-sign gadget pc-gadget "$SNAKEOIL_KEY" "$SNAKEOIL_CERT"
echo "Add the prepare-device hook"
mkdir -p pc-gadget/meta/hooks
cp prepare-device pc-gadget/meta/hooks/prepare-device
# delay all refreshes for a week from now, as otherwise refreshes for our
# snaps (which are asserted by the testrootorg authority-id) may happen, which
# will break things because the signing keys won't match, etc. and
# specifically snap-bootstrap in the kernel snap from the store won't trust
# the seed keys to unlock the encrypted data partition in the initramfs
sed defaults.yaml -e "s/HOLD-TIME/$(date --date="next week" +%Y-%m-%dT%H:%M:%S%:z)/" >> \
pc-gadget/meta/gadget.yaml
snap pack pc-gadget/ "$(tests.nested get extra-snaps-path)"
#shellcheck disable=SC2148
systemd-run --collect --unit fakedevicesvc fakedevicesvc localhost:11029
tests.nested build-image core
tests.nested create-vm core
restore: |
if [ "$TRUST_TEST_KEYS" = "false" ]; then
echo "This test needs test keys to be trusted"
exit
fi
systemctl stop fakedevicesvc
"$TESTSTOOLS"/store-state teardown-fake-store "$NESTED_FAKESTORE_BLOB_DIR"
execute: |
if [ "$TRUST_TEST_KEYS" = "false" ]; then
echo "This test needs test keys to be trusted"
exit
fi
#shellcheck source=tests/lib/nested.sh
. "$TESTSLIB/nested.sh"
# wait until device is initialized and has a serial
remote.wait-for device-initialized
setup_ramdisk() {
local ASSERT="$1"
if ! remote.exec "test -e /dev/ram0"; then
remote.exec "sudo mknod -m 660 /dev/ram0 b 1 0"
remote.exec "sudo chown root:disk /dev/ram0"
fi
remote.exec "sudo mkfs.ext3 /dev/ram0"
remote.exec "sudo mount /dev/ram0 /mnt"
remote.push "$ASSERT"
remote.exec "sudo cp $ASSERT /mnt/auto-import.assert"
remote.exec "sync"
}
teardown_ramdisk() {
remote.exec "sudo umount /mnt"
}
# Setup a ramdisk with the revision 1 of user2
setup_ramdisk ./user2.assert
# The system is already managed, which means we need to delete user1 from the auth
# state to allow auto-importing a new user. The new user has an expiration and will
# be removed automatically, so we only need to do this hacking once.
remote.exec "sudo systemctl stop snapd.socket snapd.service"
remote.exec "sudo cat /var/lib/snapd/state.json" > state.json
#shellcheck disable=SC2002
cat ./state.json | gojq 'del(.data.auth.users)' > ./state-updated.json
remote.push ./state-updated.json
remote.exec "sudo mv ./state-updated.json /var/lib/snapd/state.json"
remote.exec "sudo rm -rf /var/lib/snapd/assertions/asserts-v0/system-user/developer1"
remote.exec "sudo systemctl start snapd.socket snapd.service"
echo "$(snap auto-import) imports assertions from the mounted ramdisk"
remote.exec "sudo snap auto-import"
# ensure we are looking at the correct user and revision
remote.exec "snap known system-user" | MATCH "format: 2"
remote.exec "snap known system-user" | MATCH "revision: 1"
remote.exec "snap known system-user" | MATCH "name: user2"
remote.exec "snap known system-user" | MATCH "user-presence: until-expiration"
# check the user exists in the list of users
remote.exec "getent passwd user2" | MATCH 'user2:'
# remove the ramdisk
teardown_ramdisk
# lets put the system time ahead by 1h
retry -n 3 --wait 5 remote.exec "sudo timedatectl set-ntp false"
remote.exec "sudo date -s 'next hour'"
# run ensure state to have the user removed
remote.exec "sudo snap debug ensure-state-soon"
# wait for user to get removed
retry -n 30 --wait 1 sh -c "getent passwd user2 | NOMATCH 'user2:'"
# next step is to verify we can reimport the user, but with a higher revision
# and a new expiration date.
setup_ramdisk ./user2-2.assert
echo "$(snap auto-import) imports assertions from the mounted ramdisk"
remote.exec "sudo snap auto-import"
# ensure we are looking at the correct user and revision
remote.exec "snap known system-user" | MATCH "format: 2"
remote.exec "snap known system-user" | MATCH "revision: 2"
remote.exec "snap known system-user" | MATCH "name: user2"
remote.exec "snap known system-user" | MATCH "user-presence: until-expiration"
# remove the ramdisk
teardown_ramdisk
# lets put the system time ahead by 1h
remote.exec "sudo date -s 'next hour'"
# run ensure state to have the user removed
remote.exec "sudo snap debug ensure-state-soon"
# wait for user to get removed
retry -n 30 --wait 1 sh -c "getent passwd user2 | NOMATCH 'user2:'"
# last, we want to see if we can import a new system-user assertion which
# has nothing to do with user2.
setup_ramdisk ./user3.assert
echo "$(snap auto-import) imports assertions from the mounted ramdisk"
remote.exec "sudo snap auto-import"
# ensure we are looking at the correct user, and we could import a new user
# that wasn't user2
remote.exec "snap known system-user" | MATCH "format: 2"
remote.exec "snap known system-user" | MATCH "name: user3"
remote.exec "snap known system-user" | MATCH "user-presence: until-expiration"
# check the user exists in the list of users
remote.exec "getent passwd user3" | MATCH 'user3:'
# remove the ramdisk
teardown_ramdisk
|