mirror of
https://github.com/borgbackup/borg.git
synced 2024-12-26 01:37:20 +00:00
added retry counter for passwords, fixes #703
This commit is contained in:
parent
bc93dfab5a
commit
3dc2fc03f0
1 changed files with 15 additions and 3 deletions
18
borg/key.py
18
borg/key.py
|
@ -18,6 +18,10 @@
|
||||||
PREFIX = b'\0' * 8
|
PREFIX = b'\0' * 8
|
||||||
|
|
||||||
|
|
||||||
|
class PasswordRetriesExceeded(Error):
|
||||||
|
"""exceeded the maximum password retries"""
|
||||||
|
|
||||||
|
|
||||||
class UnsupportedPayloadError(Error):
|
class UnsupportedPayloadError(Error):
|
||||||
"""Unsupported payload type {}. A newer version is required to access this repository."""
|
"""Unsupported payload type {}. A newer version is required to access this repository."""
|
||||||
|
|
||||||
|
@ -185,7 +189,7 @@ def new(cls, allow_empty=False):
|
||||||
passphrase = cls.env_passphrase()
|
passphrase = cls.env_passphrase()
|
||||||
if passphrase is not None:
|
if passphrase is not None:
|
||||||
return passphrase
|
return passphrase
|
||||||
while True:
|
for retry in range(1, 11):
|
||||||
passphrase = cls.getpass('Enter new passphrase: ')
|
passphrase = cls.getpass('Enter new passphrase: ')
|
||||||
if allow_empty or passphrase:
|
if allow_empty or passphrase:
|
||||||
passphrase2 = cls.getpass('Enter same passphrase again: ')
|
passphrase2 = cls.getpass('Enter same passphrase again: ')
|
||||||
|
@ -196,6 +200,8 @@ def new(cls, allow_empty=False):
|
||||||
print('Passphrases do not match', file=sys.stderr)
|
print('Passphrases do not match', file=sys.stderr)
|
||||||
else:
|
else:
|
||||||
print('Passphrase must not be blank', file=sys.stderr)
|
print('Passphrase must not be blank', file=sys.stderr)
|
||||||
|
else:
|
||||||
|
raise PasswordRetriesExceeded
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<Passphrase "***hidden***">'
|
return '<Passphrase "***hidden***">'
|
||||||
|
@ -231,7 +237,7 @@ def detect(cls, repository, manifest_data):
|
||||||
passphrase = Passphrase.env_passphrase()
|
passphrase = Passphrase.env_passphrase()
|
||||||
if passphrase is None:
|
if passphrase is None:
|
||||||
passphrase = Passphrase.getpass(prompt)
|
passphrase = Passphrase.getpass(prompt)
|
||||||
while True:
|
for retry in range(1, 3):
|
||||||
key.init(repository, passphrase)
|
key.init(repository, passphrase)
|
||||||
try:
|
try:
|
||||||
key.decrypt(None, manifest_data)
|
key.decrypt(None, manifest_data)
|
||||||
|
@ -240,6 +246,8 @@ def detect(cls, repository, manifest_data):
|
||||||
return key
|
return key
|
||||||
except IntegrityError:
|
except IntegrityError:
|
||||||
passphrase = Passphrase.getpass(prompt)
|
passphrase = Passphrase.getpass(prompt)
|
||||||
|
else:
|
||||||
|
raise PasswordRetriesExceeded
|
||||||
|
|
||||||
def change_passphrase(self):
|
def change_passphrase(self):
|
||||||
class ImmutablePassphraseError(Error):
|
class ImmutablePassphraseError(Error):
|
||||||
|
@ -259,8 +267,12 @@ def detect(cls, repository, manifest_data):
|
||||||
target = key.find_key()
|
target = key.find_key()
|
||||||
prompt = 'Enter passphrase for key %s: ' % target
|
prompt = 'Enter passphrase for key %s: ' % target
|
||||||
passphrase = Passphrase.env_passphrase(default='')
|
passphrase = Passphrase.env_passphrase(default='')
|
||||||
while not key.load(target, passphrase):
|
for retry in range(1, 4):
|
||||||
|
if key.load(target, passphrase):
|
||||||
|
break
|
||||||
passphrase = Passphrase.getpass(prompt)
|
passphrase = Passphrase.getpass(prompt)
|
||||||
|
else:
|
||||||
|
raise PasswordRetriesExceeded
|
||||||
num_blocks = num_aes_blocks(len(manifest_data) - 41)
|
num_blocks = num_aes_blocks(len(manifest_data) - 41)
|
||||||
key.init_ciphers(PREFIX + long_to_bytes(key.extract_nonce(manifest_data) + num_blocks))
|
key.init_ciphers(PREFIX + long_to_bytes(key.extract_nonce(manifest_data) + num_blocks))
|
||||||
return key
|
return key
|
||||||
|
|
Loading…
Reference in a new issue