diff options
author | Lars Wirzenius <liw@liw.fi> | 2011-04-17 10:28:51 +0100 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2011-04-17 10:28:51 +0100 |
commit | 41f04afddf5692f11708f5687ca2a49612c6e75b (patch) | |
tree | c93169fe9847b37bf15c36ac138d87f448880b77 | |
parent | 50e18b6a18609247eae1b34c77fddcbcf260e42a (diff) | |
parent | 2428b02c2076b776e8ae65752fe2dc9fad85e6ee (diff) | |
download | obnam-41f04afddf5692f11708f5687ca2a49612c6e75b.tar.gz |
Merge changes to put encrypted backup tests into blackboxtest.
That's where they belong, after all.
-rwxr-xr-x | blackboxtest | 81 | ||||
-rw-r--r-- | obnamlib/encryption.py | 4 | ||||
-rw-r--r-- | obnamlib/plugins/encryption_plugin.py | 14 | ||||
-rwxr-xr-x | test-encrypted-repo | 42 |
4 files changed, 84 insertions, 57 deletions
diff --git a/blackboxtest b/blackboxtest index b90f4ede..7c36eb72 100755 --- a/blackboxtest +++ b/blackboxtest @@ -49,6 +49,10 @@ class ObnamTestCase(unittest.TestCase): backup operations, and for verifyting results. ''' + + # These are the keys in test-gpghome. + gpgkey = '3B1802F81B321347' + gpgkey2 = 'DF3D13AA11E69900' def setUp(self): self.client_name = 'client_name' @@ -56,6 +60,8 @@ class ObnamTestCase(unittest.TestCase): self.data = self.mkdir('data') self.repo = self.mkdir('repo') self.restored = self.mkdir('restored') + self.gpghome = os.path.join(self.tempdir, 'gpghome') + shutil.copytree('test-gpghome', self.gpghome) self.setUpHook() def setUpHook(self): @@ -84,9 +90,12 @@ class ObnamTestCase(unittest.TestCase): ''' logging.debug('executing %s' % argv) - + + env = dict(os.environ) + env['GNUPGHOME'] = self.gpghome + p = subprocess.Popen(argv, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) + stderr=subprocess.PIPE, env=env) stdout, stderr = p.communicate() if stderr_ignore: lines = [line for line in stderr.splitlines() @@ -103,6 +112,8 @@ class ObnamTestCase(unittest.TestCase): '--quiet', '--log', 'blackboxtest-obnam.log', '--log-level', 'debug', + '--encrypt-with', self.gpgkey, + '--weak-random', '--client-name', self.client_name] + args, stderr_ignore=stderr_ignore) @@ -321,6 +332,12 @@ class ObnamTestCase(unittest.TestCase): self.report_contents(self.data, origs) self.report_contents(self.restored, restoreds) raise Exception('spurious %s in restored data' % name) + + def remove_encryption_metadata(self, parent, subdir): + for x in ['key', 'userkeys']: + pathname = os.path.join(parent, subdir, x) + if os.path.exists(pathname): + os.remove(pathname) class RestoreTests(ObnamTestCase): @@ -381,15 +398,6 @@ class BackupTests(ObnamTestCase): self.restore() self.assert_restored_correctly() - def test_reuses_chunk(self): - n = 100 - for i in range(n): - self.create_file(self.data, 'target%d' % i, 'content1') - self.backup() - - s = self.open_repository() - self.assertEqual(len(s.list_chunks()), 1) - def test_does_not_include_roots_from_old_gens_unless_specified_again(self): foo = self.create_dir(self.data, 'foo') self.backup(roots=[foo]) @@ -463,6 +471,7 @@ class ForgetTests(ObnamTestCase): self.create_file(self.data, 'big', self.random_string(1024**2)) self.backup() self.forget(genids=self.generations()) + self.remove_encryption_metadata(self.repo, 'chunks') self.assertEqual(self.disk_usage(os.path.join(self.repo, 'chunks')), 0) @@ -475,10 +484,60 @@ class ForgetTests(ObnamTestCase): genids = self.generations() forgettable = genids[:-1] self.forget(genids=forgettable) + self.remove_encryption_metadata(self.repo, 'chunks') chunks = os.path.join(self.repo, 'chunks') self.assertEqual(self.disk_usage(chunks), 0) +class EncryptionTests(ObnamTestCase): + + def setUpHook(self): + self.create_file(self.data, 'foo', 'foo') + self.backup() + + def client_keys(self): + output = self.obnam(['client-keys', '--repository', self.repo]) + return [tuple(line.split()) for line in output.splitlines()] + + def list_keys(self): + output = self.obnam(['list-keys', '--repository', self.repo]) + keys = dict() + latest_key = None + for line in output.splitlines(): + if line.startswith('key:'): + latest_key = line.split()[1] + else: + keys[latest_key] = keys.get(latest_key, []) + [line.strip()] + for key in keys: + keys[key].sort() + return keys + + def test_has_client_key_after_backup(self): + self.assertEqual(self.client_keys(), + [(self.client_name, self.gpgkey)]) + + def test_removes_client(self): + self.obnam(['remove-client', '--repository', self.repo, + self.client_name]) + self.assertEqual(self.client_keys(), []) + + def test_only_client_key_listed_initially(self): + self.assertEqual(self.list_keys().keys(), [self.gpgkey]) + + def test_adds_key(self): + self.obnam(['add-key', '--keyid', self.gpgkey2, + '--repository', self.repo]) + self.assertEqual(sorted(self.list_keys().keys()), + sorted([self.gpgkey, self.gpgkey2])) + + def test_removes_key(self): + self.obnam(['add-key', '--keyid', self.gpgkey2, + '--repository', self.repo]) + self.obnam(['remove-key', '--keyid', self.gpgkey2, + '--repository', self.repo]) + self.assertEqual(self.list_keys().keys(), [self.gpgkey]) + + if __name__ == '__main__': logging.basicConfig(filename='blackboxtest.log', level=logging.DEBUG, diff --git a/obnamlib/encryption.py b/obnamlib/encryption.py index 8c064f61..feaec35b 100644 --- a/obnamlib/encryption.py +++ b/obnamlib/encryption.py @@ -28,9 +28,7 @@ def generate_symmetric_key(numbits, filename='/dev/random'): key = f.read(bytes) f.close() - # Passphrase should not contain newlines. Hex encode? - - return key + return key.encode('hex') def _gpg_pipe(args, data, passphrase): diff --git a/obnamlib/plugins/encryption_plugin.py b/obnamlib/plugins/encryption_plugin.py index 1e9396bb..f96ab12e 100644 --- a/obnamlib/plugins/encryption_plugin.py +++ b/obnamlib/plugins/encryption_plugin.py @@ -31,6 +31,9 @@ class EncryptionPlugin(obnamlib.ObnamPlugin): self.app.config.new_string(['keyid'], 'PGP key id to add to/remove from ' 'the backup repository') + self.app.config.new_boolean(['weak-random'], + 'use /dev/urandom instead of /dev/random ' + 'to generate symmetric keys') hooks = [ ('repository-toplevel-init', self.toplevel_init), @@ -59,6 +62,13 @@ class EncryptionPlugin(obnamlib.ObnamPlugin): if self._pubkey is None: self._pubkey = obnamlib.get_public_key(self.keyid) return self._pubkey + + @property + def devrandom(self): + if self.app.config['weak-random']: + return '/dev/urandom' + else: + return '/dev/random' def toplevel_init(self, repo, toplevel): '''Initialize a new toplevel for encryption.''' @@ -69,7 +79,9 @@ class EncryptionPlugin(obnamlib.ObnamPlugin): pubkeys = obnamlib.Keyring() pubkeys.add(self.pubkey) - symmetric_key = obnamlib.generate_symmetric_key(self.symmetric_key_bits) + symmetric_key = obnamlib.generate_symmetric_key( + self.symmetric_key_bits, + filename=self.devrandom) encrypted = obnamlib.encrypt_with_keyring(symmetric_key, pubkeys) repo.fs.fs.write_file(os.path.join(toplevel, 'key'), encrypted) diff --git a/test-encrypted-repo b/test-encrypted-repo deleted file mode 100755 index 4dc1ad82..00000000 --- a/test-encrypted-repo +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/sh - -set -e - -cmd="./obnam --repository=temp.repo --log=temp.log --log-level=debug" -cmd="$cmd --client-name=yeehaa --encrypt-with=3B1802F81B321347" - -key2="DF3D13AA11E69900" - -rm -rf temp.gpghome temp.data temp.repo temp.restored temp.log - -cp -a test-gpghome temp.gpghome -export GNUPGHOME=temp.gpghome - -cp -a debian temp.data -summain -r temp.data > temp.data.manifest - -$cmd backup temp.data -$cmd generations -$cmd restore --generation latest --to temp.restored -summain -r temp.restored/$(pwd)/temp.data > temp.restored.manifest -diff -u temp.data.manifest temp.restored.manifest - -$cmd add-key --keyid $key2 yeehaa - -echo "client keys:" -$cmd client-keys - -echo "list-keys:" -$cmd list-keys - -echo "list-toplevels:" -$cmd list-toplevels - -echo "remove key" -$cmd remove-key --keyid $key2 yeehaa -$cmd list-keys - -echo "remove client" -$cmd remove-client yeehaa -$cmd client-keys - |