diff options
Diffstat (limited to 'cli-tests/common.sh')
| -rw-r--r-- | cli-tests/common.sh | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/cli-tests/common.sh b/cli-tests/common.sh new file mode 100644 index 0000000..fcebfd6 --- /dev/null +++ b/cli-tests/common.sh @@ -0,0 +1,154 @@ +#!/bin/bash +# +# common.sh - helper functions for fscrypt command-line interface tests +# +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# + +# Use extra-strict mode. +set -e -u -o pipefail + +# Don't allow running the test scripts directly. They need to be run via +# run.sh, to set up everything correctly. +if [ -z "${MNT:-}" ] || [ -z "${MNT_ROOT:-}" ]; then + echo 1>&2 "ERROR: This script can only be run via run.sh, not on its own." + exit 1 +fi + +# Prints an error message, then fails the test by exiting with failure status. +_fail() +{ + [ $# -ne 1 ] && _fail "wrong argument count to ${FUNCNAME[0]}" + echo 1>&2 "ERROR: $1" + exit 1 +} + +# Runs a shell command and expects that it fails. +_expect_failure() +{ + [ $# -ne 1 ] && _fail "wrong argument count to ${FUNCNAME[0]}" + if eval "$1"; then + _fail "command unexpectedly succeeded: \"$1\"" + fi +} + +# Prints a message to mark the beginning of the next part of the test. +_print_header() +{ + [ $# -ne 1 ] && _fail "wrong argument count to ${FUNCNAME[0]}" + echo + echo "# $1" +} + +# Deletes all files on the test filesystems, including all policies and +# protectors. Leaves the fscrypt metadata directories themselves. +_reset_filesystems() +{ + local mnt + + [ $# -ne 0 ] && _fail "wrong argument count to ${FUNCNAME[0]}" + + for mnt in "$MNT" "$MNT_ROOT"; do + rm -rf "${mnt:?}"/* "${mnt:?}"/.fscrypt/{policies,protectors}/* + done +} + +# Prints the number of filesystems that have encryption support enabled. +_get_enabled_fs_count() +{ + local count + + [ $# -ne 0 ] && _fail "wrong argument count to ${FUNCNAME[0]}" + + count=$(fscrypt status | awk '/filesystems supporting encryption/ { print $4 }') + if [ -z "$count" ]; then + _fail "encryption support status line not found" + fi + echo "$count" +} + +# Prints the number of filesystems that have fscrypt metadata. +_get_setup_fs_count() +{ + local count + + [ $# -ne 0 ] && _fail "wrong argument count to ${FUNCNAME[0]}" + + count=$(fscrypt status | awk '/filesystems with fscrypt metadata/ { print $5 }') + if [ -z "$count" ]; then + _fail "fscrypt metadata status line not found" + fi + echo "$count" +} + +# Removes all fscrypt metadata from the given filesystem. +_rm_metadata() +{ + [ $# -ne 1 ] && _fail "wrong argument count to ${FUNCNAME[0]}" + + rm -r "${1:?}/.fscrypt" +} + +# Runs a shell command, ignoring its output (stdout and stderr) if it succeeds. +# If the command fails, prints its output and fails the test. +_run_noisy_command() +{ + [ $# -ne 1 ] && _fail "wrong argument count to ${FUNCNAME[0]}" + + if ! eval "$1" &> "$TMPDIR/out"; then + _fail "Command failed: '$1'. Output was: $(cat "$TMPDIR/out")" + fi +} + +# Runs the given shell command as the test user. +_user_do() +{ + [ $# -ne 1 ] && _fail "wrong argument count to ${FUNCNAME[0]}" + + su "$TEST_USER" --command="$1" +} + +# Runs the given shell command as the test user and expects it to fail. +_user_do_and_expect_failure() +{ + [ $# -ne 1 ] && _fail "wrong argument count to ${FUNCNAME[0]}" + + _expect_failure "_user_do '$1'" +} + +# Gives the test a new session keyring which contains the test user's keyring +# but not root's keyring. Also clears the test user's keyring. This must be +# called at the beginning of the test script as it may re-execute the script. +_setup_session_keyring() +{ + [ $# -ne 0 ] && _fail "wrong argument count to ${FUNCNAME[0]}" + + # This *should* just use 'keyctl new_session', but that doesn't work if + # the session keyring is owned by a user other than root. So instead we + # have to use 'keyctl session' and re-execute the script. + if [ -z "${FSCRYPT_SESSION_KEYRING_SET:-}" ]; then + export FSCRYPT_SESSION_KEYRING_SET=1 + set +e + keyctl session - "$0" |& grep -v '^Joined session keyring' + exit "${PIPESTATUS[0]}" + fi + + # Link the test user's keyring into the new session keyring. + keyctl setperm @s 0x3f000000 # all possessor permissions + _user_do "keyctl link @u @s" + + # Clear the test user's keyring. + _user_do "keyctl clear @u" +} |