-
Notifications
You must be signed in to change notification settings - Fork 98
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #218 from ebiggers/cli-tests
Add tests for command-line interface Add tests that directly test the fscrypt command-line tool. See cli-tests/README.md for information about the test framework. The following test scripts are included: * t_change_passphrase * t_encrypt_custom * t_encrypt_login * t_encrypt_raw_key * t_encrypt * t_lock * t_not_enabled * t_not_supported * t_passphrase_hashing * t_setup * t_status * t_unlock * t_v1_policy_fs_keyring * t_v1_policy Unfortunately, we can't actually make Travis CI run these tests yet because they need kernel v5.4 or later, and Travis CI doesn't support an Ubuntu version that has that yet. But for now, they can be run manually using make cli-test.
- Loading branch information
Showing
41 changed files
with
2,157 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ bin/staticcheck | |
bin/gocovmerge | ||
bin/misspell | ||
bin/config | ||
cli-tests/*.out.actual | ||
*coverage.out | ||
.vscode | ||
tags |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
# fscrypt command-line interface tests | ||
|
||
## Usage | ||
|
||
To run the command-line interface (CLI) tests for `fscrypt`, ensure | ||
that your kernel is v5.4 or later and has `CONFIG_FS_ENCRYPTION=y`. | ||
Also ensure that you have the following packages installed: | ||
|
||
* e2fsprogs | ||
* expect | ||
* keyutils | ||
|
||
Then, run: | ||
|
||
```shell | ||
make cli-test | ||
``` | ||
|
||
You'll need to enter your `sudo` password, as the tests require root. | ||
|
||
If you only want to run specific tests, run a command like: | ||
|
||
```shell | ||
make && sudo cli-tests/run.sh t_encrypt t_unlock | ||
``` | ||
|
||
## Updating the expected output | ||
|
||
When the output of `fscrypt` has intentionally changed, the test | ||
`.out` files need to be updated. This can be done automatically by | ||
the following command, but be sure to review the changes: | ||
|
||
```shell | ||
make cli-test-update | ||
``` | ||
|
||
## Writing CLI tests | ||
|
||
The fscrypt CLI tests are `bash` scripts named like `t_*.sh`. | ||
|
||
The test scripts must be executable and begin by sourcing `common.sh`. | ||
They all run in bash "extra-strict mode" (`-e -u -o pipefail`). They | ||
run as root and have access to the following environment: | ||
|
||
* `$DEV`, `$DEV_ROOT`: ext4 filesystem images with encryption enabled | ||
|
||
* `$MNT`, `$MNT_ROOT`: the mountpoints of the above filesystems. | ||
Initially all filesystems are mounted and are setup for fscrypt. | ||
Login protectors will be stored on `$MNT_ROOT`. | ||
|
||
* `$TMPDIR`: a temporary directory that the test may use | ||
|
||
* `$FSCRYPT_CONF`: location of the fscrypt.conf file. Initially this | ||
file exists and specifies to use v2 policies with the default | ||
settings, except password hashing is configured to be extra fast. | ||
|
||
* `$TEST_USER`: a non-root user that the test may use. Their password | ||
is `TEST_USER_PASS`. | ||
|
||
Any output (stdout and stderr) the test prints is compared to the | ||
corresponding `.out` file. If a difference is detected then the test | ||
is considered to have failed. The output is first sent through some | ||
standard filters; see `run.sh`. | ||
|
||
The test is also failed if it exits with nonzero status. | ||
|
||
See `common.sh` for utility functions the tests may use. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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" | ||
} |
Oops, something went wrong.