diff options
author | Lars Wirzenius <liw@liw.fi> | 2014-01-12 14:56:43 +0000 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2014-01-12 14:56:43 +0000 |
commit | c3b8d11d5395a4ab8eb55680638ee3962179476a (patch) | |
tree | a9d46a02a603c46cfdf94cf5ff835a605993fcc5 /yarns | |
parent | f9e7a6522af273346d77debce154dedd5e14c5a8 (diff) | |
download | obnam-c3b8d11d5395a4ab8eb55680638ee3962179476a.tar.gz |
More encryption tests
Diffstat (limited to 'yarns')
-rw-r--r-- | yarns/0060-encryption.yarn | 51 | ||||
-rw-r--r-- | yarns/9000-implements.yarn | 53 | ||||
-rw-r--r-- | yarns/obnam.sh | 52 |
3 files changed, 146 insertions, 10 deletions
diff --git a/yarns/0060-encryption.yarn b/yarns/0060-encryption.yarn index 6903de8f..8ba2e704 100644 --- a/yarns/0060-encryption.yarn +++ b/yarns/0060-encryption.yarn @@ -60,9 +60,54 @@ second one, and verifying that we can, or can't, access the backup with the second key, depending on whether it has or hasn't been added to the client. -# obnam [options] client-keys -# obnam [options] add-key [CLIENT-NAME]... -# obnam [options] remove-key [CLIENT-NAME]... +First of all, we make a simple encrypted backup as the first client. + + SCENARIO adding and removing encryption keys to clients + GIVEN user U1 uses encryption key "Test Key One" from test-data/keyring-1 + AND directory L1 with interesting filesystem objects + WHEN user U1 backs up directory L1 to repository R + THEN user U1 uses key "Test Key One" in repository R + +Then we add the key of the second client to the repository. This is +necessary, because by now the client list is already encrypted using +only the first client's key, meaning the second client has no access +to the client list, and thus can't add itself. + + WHEN user U1 imports public key "Test Key Two" from test-data/keyring-2 + AND user U1 adds key "Test Key Two" to repository R + +Then we make a backup as the second client. + + GIVEN user U2 uses encryption key "Test Key Two" from test-data/keyring-2 + AND directory L2 with interesting filesystem objects + WHEN user U2 backs up directory L2 to repository R + THEN user U2 uses key "Test Key Two" in repository R + +Let's make sure both clients can still restore their own data. + + GIVEN a manifest of directory L1 in M1 + WHEN user U1 restores their latest generation in repository R into X1 + THEN L1, restored to X1, matches manifest M1 + + GIVEN a manifest of directory L2 in M2 + WHEN user U2 restores their latest generation in repository R into X2 + THEN L2, restored to X2, matches manifest M2 + +An unrelated client, which happens to use the same name as the first +client, should not be able to access the data. + + GIVEN a user U3 calling themselves U1 + WHEN user U3 attempts to restore their latest generation in repository R into X3 + THEN the attempt failed with exit code 1 + AND the error message matches "need more than 1 value to unpack" + +Likewise, even if a client has access to their own data, they should +not have access to another client's data. + + GIVEN a user U2 calling themselves U1 + WHEN user U2 attempts to restore their latest generation in repository R into X4 + THEN the attempt failed with exit code 1 + AND the error message matches "secret key not available" Key queries ----------- diff --git a/yarns/9000-implements.yarn b/yarns/9000-implements.yarn index 144b7245..50a07453 100644 --- a/yarns/9000-implements.yarn +++ b/yarns/9000-implements.yarn @@ -99,7 +99,13 @@ use. We store that. cp -a "$SRCDIR/$MATCH_3/." "$DATADIR/$MATCH_1.gnupg/." add_to_env "$MATCH_1" GNUPGHOME "$DATADIR/$MATCH_1.gnupg" fi - add_to_config "$DATADIR/$MATCH_1.conf" encrypt-with "$MATCH_2" + add_to_config "$MATCH_1" encrypt-with "$MATCH_2" + +Encryption scenarions, at least, also need users that pretend to be +someone else. + + IMPLEMENTS GIVEN a user (\S+) calling themselves (\S+) + add_to_config "$MATCH_1" client-name "$MATCH_2" Backing up ---------- @@ -130,7 +136,8 @@ Restoring data We need a way to restore data from a test backup repository. IMPLEMENTS WHEN user (\S+) restores their latest generation in repository (\S+) into (\S+) - run_obnam "$MATCH_1" restore -r "$DATADIR/$MATCH_2" --to "$DATADIR/$MATCH_3" + run_obnam "$MATCH_1" restore -r "$DATADIR/$MATCH_2" \ + --to "$DATADIR/$MATCH_3" Restore a specific generation. The generation number is an ordinal in the list of generations, not the "generation id" Obnam assigns, as @@ -146,6 +153,13 @@ that is unpredictable. run_obnam "$client" restore -r "$repo" \ --to "$to" --generation "$id" +We may also need to attempt a restore in a situation when we expect it +to fail. + + IMPLEMENTS WHEN user (\S+) attempts to restore their latest generation in repository (\S+) into (\S+) + attempt run_obnam "$MATCH_1" restore -r "$DATADIR/$MATCH_2" \ + --to "$DATADIR/$MATCH_3" + Removing (forgetting) generations --------------------------------- @@ -207,6 +221,41 @@ unpredictable. id2=$(run_obnam "$MATCH_1" -r "$DATADIR/$MATCH_4" genids | awk -v "n=$MATCH_3" 'NR == n') run_obnam "$MATCH_1" diff -r "$DATADIR/$MATCH_4" "$id1" "$id2" > "$DATADIR/$MATCH_5" +Encryption key management +------------------------- + +List clients and the encryption keys they use. + + IMPLEMENTS THEN user (\S+) uses key "(.+)" in repository (\S+) + run_obnam "$MATCH_1" -r "$DATADIR/$MATCH_3" client-keys | + grep -x "$MATCH_1 $MATCH_2" + +Import a key into one user's keyring from another keyring. + + IMPLEMENTS WHEN user (\S+) imports public key "(.+)" from (\S+) + GNUPGHOME="$SRCDIR/$MATCH_3" gpg --export --armor "$MATCH_2" | + GNUPGHOME="$DATADIR/$MATCH_1.gnupg" gpg --import + +Add a public key to a repository. + + IMPLEMENTS WHEN user (\S+) adds key "(.+)" to repository (\S+) + run_obnam "$MATCH_1" -r "$DATADIR/$MATCH_3" add-key --keyid "$MATCH_2" + +Checks on results of an attempted operation +------------------------------------------- + +The `attempt` shell function in `obnam.sh` runs a command, then +captures its stdout, stderr, and exit code. The scenarios can then +test the results in various ways as separate steps. + + IMPLEMENTS THEN the attempt failed with exit code (\d+) + attempt_exit_was "$MATCH_1" + +We can also match the stderr against a regular expression. + + IMPLEMENTS THEN the error message matches "(.+)" + attempt_matches stderr "$MATCH_1" + Checks on files --------------- diff --git a/yarns/obnam.sh b/yarns/obnam.sh index 7abdae23..727ecd76 100644 --- a/yarns/obnam.sh +++ b/yarns/obnam.sh @@ -26,14 +26,21 @@ run_obnam() { local name="$1" shift + + # Create the config file, if it doesn't already exist. + local conf="$DATADIR/$name.conf" + if [ ! -e "$conf" ] + then + add_to_config "$name" client-name "$name" + fi + ( if [ -e "$DATADIR/$name.env" ] then . "$DATADIR/$name.env" fi - "$SRCDIR/obnam" --no-default-config --config "$DATADIR/$name.conf" \ - --quiet --client-name="$name" \ - --log-level debug --log "$DATADIR/obnam.log" "$@" + "$SRCDIR/obnam" --no-default-config --config "$conf" \ + --quiet --log-level debug --log "$DATADIR/obnam.log" "$@" ) } @@ -49,22 +56,57 @@ add_to_env() } -# Add a setting to an Obnam configuration file. +# Add a setting to the configuration file for a given client. add_to_config() { - local filename="$1" + local client="$1" + local filename="$DATADIR/$client.conf" local key="$2" local value="$3" if [ ! -e "$filename" ] then printf '[config]\n' > "$filename" + printf 'client-name = %s\n' "$client" >> "$filename" fi printf '%s = %s\n' "$key" "$value" >> "$filename" } +# Attempt to run a command, which may fail. Capture its stdout, +# stderr, and exit code. + +attempt() +{ + if "$@" \ + > "$DATADIR/attempt.stdout" \ + 2> "$DATADIR/attempt.stderr" + then + exit=0 + else + exit=$? + fi + echo "$exit" > "$DATADIR/attempt.exit" +} + + +# Match captured output from attempt against a regular expression. + +attempt_matches() +{ + grep "$2" "$DATADIR/attempt.$1" +} + + +# Check exit code of latest attempt. + +attempt_exit_was() +{ + grep -Fx "$1" "$DATADIR/attempt.exit" +} + + # Create a manifest with summain of a directory. manifest() |