mirror of
https://github.com/borgbackup/borg.git
synced 2026-07-16 13:33:03 -04:00
commit
68409aa10c
6 changed files with 91 additions and 6 deletions
|
|
@ -183,8 +183,16 @@ def get_limited_unpacker(kind):
|
|||
object_hook=StableDict,
|
||||
unicode_errors='surrogateescape',
|
||||
))
|
||||
elif kind == 'key':
|
||||
args.update(dict(use_list=True, # default value
|
||||
max_array_len=0, # not used
|
||||
max_map_len=10, # EncryptedKey dict
|
||||
max_str_len=4000, # inner key data
|
||||
object_hook=StableDict,
|
||||
unicode_errors='surrogateescape',
|
||||
))
|
||||
else:
|
||||
raise ValueError('kind must be "server", "client" or "manifest"')
|
||||
raise ValueError('kind must be "server", "client", "manifest" or "key"')
|
||||
return msgpack.Unpacker(**args)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -481,7 +481,9 @@ class KeyfileKeyBase(AESKeyBase):
|
|||
return False
|
||||
|
||||
def decrypt_key_file(self, data, passphrase):
|
||||
d = msgpack.unpackb(data)
|
||||
unpacker = get_limited_unpacker('key')
|
||||
unpacker.feed(data)
|
||||
d = unpacker.unpack()
|
||||
assert d[b'version'] == 1
|
||||
assert d[b'algorithm'] == b'sha256'
|
||||
key = passphrase.kdf(d[b'salt'], d[b'iterations'], 32)
|
||||
|
|
|
|||
|
|
@ -172,6 +172,7 @@ class KeyManager:
|
|||
(id_lines, id_repoid, id_complete_checksum) = data.split('/')
|
||||
except ValueError:
|
||||
print("the id line must contain exactly three '/', try again")
|
||||
continue
|
||||
if sha256_truncated(data.lower().encode('ascii'), 2) != checksum:
|
||||
print('line checksum did not match, try same line again')
|
||||
continue
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ has_lchflags = hasattr(os, 'lchflags')
|
|||
src_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
||||
|
||||
|
||||
def exec_cmd(*args, archiver=None, fork=False, exe=None, **kw):
|
||||
def exec_cmd(*args, archiver=None, fork=False, exe=None, input=b'', **kw):
|
||||
if fork:
|
||||
try:
|
||||
if exe is None:
|
||||
|
|
@ -54,7 +54,7 @@ def exec_cmd(*args, archiver=None, fork=False, exe=None, **kw):
|
|||
borg = (exe, )
|
||||
elif not isinstance(exe, tuple):
|
||||
raise ValueError('exe must be None, a tuple or a str')
|
||||
output = subprocess.check_output(borg + args, stderr=subprocess.STDOUT)
|
||||
output = subprocess.check_output(borg + args, stderr=subprocess.STDOUT, input=input)
|
||||
ret = 0
|
||||
except subprocess.CalledProcessError as e:
|
||||
output = e.output
|
||||
|
|
@ -63,7 +63,7 @@ def exec_cmd(*args, archiver=None, fork=False, exe=None, **kw):
|
|||
else:
|
||||
stdin, stdout, stderr = sys.stdin, sys.stdout, sys.stderr
|
||||
try:
|
||||
sys.stdin = StringIO()
|
||||
sys.stdin = StringIO(input.decode())
|
||||
sys.stdout = sys.stderr = output = StringIO()
|
||||
if archiver is None:
|
||||
archiver = Archiver()
|
||||
|
|
@ -1502,6 +1502,51 @@ id: 2 / e29442 3506da 4e1ea7 / 25f62a 5a3d41 - 02
|
|||
2: 737475 - 88
|
||||
"""
|
||||
|
||||
def test_key_import_paperkey(self):
|
||||
repo_id = 'e294423506da4e1ea76e8dcdf1a3919624ae3ae496fddf905610c351d3f09239'
|
||||
self.cmd('init', self.repository_location, '--encryption', 'keyfile')
|
||||
self._set_repository_id(self.repository_path, unhexlify(repo_id))
|
||||
|
||||
key_file = self.keys_path + '/' + os.listdir(self.keys_path)[0]
|
||||
with open(key_file, 'w') as fd:
|
||||
fd.write(KeyfileKey.FILE_ID + ' ' + repo_id + '\n')
|
||||
fd.write(b2a_base64(b'abcdefghijklmnopqrstu').decode())
|
||||
|
||||
typed_input = (
|
||||
b'2 / e29442 3506da 4e1ea7 / 25f62a 5a3d41 02\n' # Forgot to type "-"
|
||||
b'2 / e29442 3506da 4e1ea7 25f62a 5a3d41 - 02\n' # Forgot to type second "/"
|
||||
b'2 / e29442 3506da 4e1ea7 / 25f62a 5a3d42 - 02\n' # Typo (..42 not ..41)
|
||||
b'2 / e29442 3506da 4e1ea7 / 25f62a 5a3d41 - 02\n' # Correct! Congratulations
|
||||
b'616263 646566 676869 6a6b6c 6d6e6f 707172 - 6d\n'
|
||||
b'\n\n' # Abort [yN] => N
|
||||
b'737475 88\n' # missing "-"
|
||||
b'73747i - 88\n' # typo
|
||||
b'73747 - 88\n' # missing nibble
|
||||
b'73 74 75 - 89\n' # line checksum mismatch
|
||||
b'00a1 - 88\n' # line hash collision - overall hash mismatch, have to start over
|
||||
|
||||
b'2 / e29442 3506da 4e1ea7 / 25f62a 5a3d41 - 02\n'
|
||||
b'616263 646566 676869 6a6b6c 6d6e6f 707172 - 6d\n'
|
||||
b'73 74 75 - 88\n'
|
||||
)
|
||||
|
||||
# In case that this has to change, here is a quick way to find a colliding line hash:
|
||||
#
|
||||
# from hashlib import sha256
|
||||
# hash_fn = lambda x: sha256(b'\x00\x02' + x).hexdigest()[:2]
|
||||
# for i in range(1000):
|
||||
# if hash_fn(i.to_bytes(2, byteorder='big')) == '88': # 88 = line hash
|
||||
# print(i.to_bytes(2, 'big'))
|
||||
# break
|
||||
|
||||
self.cmd('key', 'import', '--paper', self.repository_location, input=typed_input)
|
||||
|
||||
# Test abort paths
|
||||
typed_input = b'\ny\n'
|
||||
self.cmd('key', 'import', '--paper', self.repository_location, input=typed_input)
|
||||
typed_input = b'2 / e29442 3506da 4e1ea7 / 25f62a 5a3d41 - 02\n\ny\n'
|
||||
self.cmd('key', 'import', '--paper', self.repository_location, input=typed_input)
|
||||
|
||||
|
||||
@unittest.skipUnless('binary' in BORG_EXES, 'no borg.exe available')
|
||||
class ArchiverTestCaseBinary(ArchiverTestCase):
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@ import os
|
|||
import tempfile
|
||||
import unittest
|
||||
|
||||
from ..xattr import is_enabled, getxattr, setxattr, listxattr, buffer
|
||||
import pytest
|
||||
|
||||
from ..xattr import is_enabled, getxattr, setxattr, listxattr, buffer, split_lstring
|
||||
from . import BaseTestCase
|
||||
|
||||
|
||||
|
|
@ -58,3 +60,13 @@ class XattrTestCase(BaseTestCase):
|
|||
got_value = getxattr(self.tmpfile.name, 'user.big')
|
||||
self.assert_equal(value, got_value)
|
||||
self.assert_equal(len(buffer), 128)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('lstring, splitted', (
|
||||
(b'', []),
|
||||
(b'\x00', [b'']),
|
||||
(b'\x01a', [b'a']),
|
||||
(b'\x01a\x02cd', [b'a', b'cd']),
|
||||
))
|
||||
def test_split_lstring(lstring, splitted):
|
||||
assert split_lstring(lstring) == splitted
|
||||
|
|
|
|||
|
|
@ -62,6 +62,9 @@ FreeBSD `FreeBSD ports`_ ``cd /usr/ports/archi
|
|||
Mageia `cauldron`_ ``urpmi borgbackup``
|
||||
NetBSD `pkgsrc`_ ``pkg_add py-borgbackup``
|
||||
NixOS `.nix file`_ N/A
|
||||
OpenBSD `OpenBSD ports`_ ``pkg_add borgbackup``
|
||||
OpenIndiana `OpenIndiana hipster repository`_ ``pkg install borg``
|
||||
openSUSE `openSUSE official repository`_ ``zypper in borgbackup``
|
||||
OS X `Brew cask`_ ``brew cask install borgbackup``
|
||||
Raspbian `Raspbian testing`_ ``apt install borgbackup``
|
||||
Ubuntu `Ubuntu packages`_, `Ubuntu PPA`_ ``apt install borgbackup``
|
||||
|
|
@ -255,6 +258,20 @@ Install the dependencies with development headers::
|
|||
sudo dnf install gcc gcc-c++
|
||||
sudo dnf install fuse-devel fuse pkgconfig # optional, for FUSE support
|
||||
|
||||
openSUSE Tumbleweed / Leap
|
||||
++++++++++++++++++++++++++
|
||||
|
||||
Install the dependencies automatically using zypper::
|
||||
|
||||
sudo zypper source-install --build-deps-only borgbackup
|
||||
|
||||
Alternatively, you can enumerate all build dependencies in the command line::
|
||||
|
||||
sudo zypper install python3 python3-devel \
|
||||
libacl-devel liblz4-devel openssl-devel \
|
||||
python3-Cython python3-Sphinx python3-msgpack-python \
|
||||
python3-pytest python3-setuptools python3-setuptools_scm \
|
||||
python3-sphinx_rtd_theme python3-llfuse gcc gcc-c++
|
||||
|
||||
Mac OS X
|
||||
++++++++
|
||||
|
|
|
|||
Loading…
Reference in a new issue