mirror of https://github.com/borgbackup/borg.git
give clean error msg for invalid nonce file, see #7967
That rather long traceback was not pretty. Of course users should usually have valid nonce files, but multiple users managed to corrupt the file contents somehow. Also: - add Error / ErrorWithTraceback exception classes to RPC layer. - add hex_to_bin helper - also call hex_to_bin for the local nonce file (security dir)
This commit is contained in:
parent
5b77bfef06
commit
d9132a34d4
|
@ -1,9 +1,9 @@
|
|||
import os
|
||||
import sys
|
||||
from binascii import unhexlify
|
||||
|
||||
from ..helpers import Error
|
||||
from ..helpers import get_security_dir
|
||||
from ..helpers import bin_to_hex
|
||||
from ..helpers import bin_to_hex, hex_to_bin
|
||||
from ..platform import SaveFile
|
||||
from ..remote import InvalidRPCMethod
|
||||
|
||||
|
@ -23,9 +23,15 @@ class NonceManager:
|
|||
def get_local_free_nonce(self):
|
||||
try:
|
||||
with open(self.nonce_file) as fd:
|
||||
return bytes_to_long(unhexlify(fd.read()))
|
||||
nonce_hex = fd.read().strip()
|
||||
except FileNotFoundError:
|
||||
return None
|
||||
else:
|
||||
try:
|
||||
nonce_bytes = hex_to_bin(nonce_hex, length=8)
|
||||
except ValueError as e:
|
||||
raise Error(f"Local security dir has an invalid nonce file: {e}") from None
|
||||
return bytes_to_long(nonce_bytes)
|
||||
|
||||
def commit_local_nonce_reservation(self, next_unreserved, start_nonce):
|
||||
if self.get_local_free_nonce() != start_nonce:
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import argparse
|
||||
import binascii
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
|
@ -8,7 +9,6 @@ import shlex
|
|||
import socket
|
||||
import stat
|
||||
import uuid
|
||||
from binascii import hexlify
|
||||
from collections import Counter, OrderedDict
|
||||
from datetime import datetime, timezone
|
||||
from functools import partial
|
||||
|
@ -27,7 +27,18 @@ from ..platformflags import is_win32
|
|||
|
||||
|
||||
def bin_to_hex(binary):
|
||||
return hexlify(binary).decode('ascii')
|
||||
return binascii.hexlify(binary).decode('ascii')
|
||||
|
||||
|
||||
def hex_to_bin(hex, length=None):
|
||||
try:
|
||||
binary = binascii.unhexlify(hex)
|
||||
binary_len = len(binary)
|
||||
if length is not None and binary_len != length:
|
||||
raise ValueError(f"Expected {length} bytes ({2 * length} hex digits), got {binary_len} bytes.")
|
||||
except binascii.Error as e:
|
||||
raise ValueError(str(e)) from None
|
||||
return binary
|
||||
|
||||
|
||||
def safe_decode(s, coding='utf-8', errors='surrogateescape'):
|
||||
|
|
|
@ -18,7 +18,7 @@ from subprocess import Popen, PIPE
|
|||
from . import __version__
|
||||
from .compress import Compressor
|
||||
from .constants import * # NOQA
|
||||
from .helpers import Error, IntegrityError
|
||||
from .helpers import Error, ErrorWithTraceback, IntegrityError
|
||||
from .helpers import bin_to_hex
|
||||
from .helpers import get_base_dir
|
||||
from .helpers import get_limited_unpacker
|
||||
|
@ -747,7 +747,11 @@ This problem will go away as soon as the server has been upgraded to 1.0.7+.
|
|||
old_server = b'exception_args' not in unpacked
|
||||
args = unpacked.get(b'exception_args')
|
||||
|
||||
if error == 'DoesNotExist':
|
||||
if error == 'Error':
|
||||
raise Error(args[0].decode())
|
||||
elif error == 'ErrorWithTraceback':
|
||||
raise ErrorWithTraceback(args[0].decode())
|
||||
elif error == 'DoesNotExist':
|
||||
raise Repository.DoesNotExist(self.location.processed)
|
||||
elif error == 'AlreadyExists':
|
||||
raise Repository.AlreadyExists(self.location.processed)
|
||||
|
|
|
@ -16,7 +16,7 @@ from .hashindex import NSIndex
|
|||
from .helpers import Error, ErrorWithTraceback, IntegrityError, format_file_size, parse_file_size
|
||||
from .helpers import Location
|
||||
from .helpers import ProgressIndicatorPercent
|
||||
from .helpers import bin_to_hex
|
||||
from .helpers import bin_to_hex, hex_to_bin
|
||||
from .helpers import secure_erase, safe_unlink
|
||||
from .helpers import Manifest
|
||||
from .helpers import msgpack
|
||||
|
@ -363,9 +363,15 @@ class Repository:
|
|||
nonce_path = os.path.join(self.path, 'nonce')
|
||||
try:
|
||||
with open(nonce_path) as fd:
|
||||
return int.from_bytes(unhexlify(fd.read()), byteorder='big')
|
||||
nonce_hex = fd.read().strip()
|
||||
except FileNotFoundError:
|
||||
return None
|
||||
else:
|
||||
try:
|
||||
nonce_bytes = hex_to_bin(nonce_hex, length=8)
|
||||
except ValueError as e:
|
||||
raise Error(f"Repository has an invalid nonce file: {e}") from None
|
||||
return int.from_bytes(nonce_bytes, byteorder='big')
|
||||
|
||||
def commit_nonce_reservation(self, next_unreserved, start_nonce):
|
||||
if self.do_lock and not self.lock.got_exclusive_lock():
|
||||
|
|
Loading…
Reference in New Issue