summaryrefslogtreecommitdiff
path: root/yarns
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2014-01-12 14:56:43 +0000
committerLars Wirzenius <liw@liw.fi>2014-01-12 14:56:43 +0000
commitc3b8d11d5395a4ab8eb55680638ee3962179476a (patch)
treea9d46a02a603c46cfdf94cf5ff835a605993fcc5 /yarns
parentf9e7a6522af273346d77debce154dedd5e14c5a8 (diff)
downloadobnam-c3b8d11d5395a4ab8eb55680638ee3962179476a.tar.gz
More encryption tests
Diffstat (limited to 'yarns')
-rw-r--r--yarns/0060-encryption.yarn51
-rw-r--r--yarns/9000-implements.yarn53
-rw-r--r--yarns/obnam.sh52
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()