upgrade --archives-tam: make sure all archives are TAM authenticated

borg check (rebuild_manifest and rebuild_refcounts) drops archives without TAM,
so let's just always add the TAM.

for unencrypted repos (encryption=none) the TAM is insecure,
but without encryption and authentication, there is no expectation
of security anyway.
This commit is contained in:
Thomas Waldmann 2023-06-24 01:06:16 +02:00
parent c58228c2c7
commit 005662a8fe
No known key found for this signature in database
GPG Key ID: 243ACFA951F78E01
1 changed files with 48 additions and 5 deletions

View File

@ -72,10 +72,11 @@ try:
from .helpers import umount
from .helpers import msgpack, msgpack_fallback
from .helpers import uid2user, gid2group
from .helpers import safe_decode
from .nanorst import rst_to_terminal
from .patterns import ArgparsePatternAction, ArgparseExcludeFileAction, ArgparsePatternFileAction, parse_exclude_pattern
from .patterns import PatternMatcher
from .item import Item
from .item import Item, ArchiveItem
from .platform import get_flags, get_process_id, SyncFile
from .remote import RepositoryServer, RemoteRepository, cache_if_remote
from .repository import Repository, LIST_SCAN_LIMIT, TAG_PUT, TAG_DELETE, TAG_COMMIT
@ -1711,10 +1712,34 @@ class Archiver:
DASHES, logger=logging.getLogger('borg.output.stats'))
return self.exit_code
@with_repository(fake=('tam', 'disable_tam'), invert_fake=True, manifest=False, exclusive=True)
@with_repository(fake=('tam', 'disable_tam', 'archives_tam'), invert_fake=True, manifest=False, exclusive=True)
def do_upgrade(self, args, repository, manifest=None, key=None):
"""upgrade a repository from a previous version"""
if args.tam:
if args.archives_tam:
manifest, key = Manifest.load(repository, (Manifest.Operation.CHECK,), force_tam_not_required=args.force)
with Cache(repository, key, manifest) as cache:
stats = Statistics()
for info in manifest.archives.list(sort_by=['ts']):
archive_id = info.id
archive_formatted = format_archive(info)
cdata = repository.get(archive_id)
data = key.decrypt(archive_id, cdata)
archive, verified = key.unpack_and_verify_archive(data, force_tam_not_required=True)
if not verified: # we do not have an archive TAM yet -> add TAM now!
archive = ArchiveItem(internal_dict=archive)
archive.cmdline = [safe_decode(arg) for arg in archive.cmdline]
data = key.pack_and_authenticate_metadata(archive.as_dict(), context=b'archive')
new_archive_id = key.id_hash(data)
cache.add_chunk(new_archive_id, data, stats)
cache.chunk_decref(archive_id, stats)
manifest.archives[info.name] = (new_archive_id, info.ts)
print("Added archive TAM: %s -> [%s]" % (archive_formatted, bin_to_hex(new_archive_id)))
else:
print("Archive TAM present: %s" % archive_formatted)
manifest.write()
repository.commit(compact=False)
cache.commit()
elif args.tam:
manifest, key = Manifest.load(repository, (Manifest.Operation.CHECK,), force_tam_not_required=args.force)
if not hasattr(key, 'change_passphrase'):
@ -1722,10 +1747,9 @@ class Archiver:
return EXIT_ERROR
if not manifest.tam_verified or not manifest.config.get(b'tam_required', False):
# The standard archive listing doesn't include the archive ID like in borg 1.1.x
print('Manifest contents:')
for archive_info in manifest.archives.list(sort_by=['ts']):
print(format_archive(archive_info), '[%s]' % bin_to_hex(archive_info.id))
print(format_archive(archive_info))
manifest.config[b'tam_required'] = True
manifest.write()
repository.commit()
@ -4103,6 +4127,23 @@ class Archiver:
Borg 1.x.y upgrades
+++++++++++++++++++
Archive TAM authentication:
Use ``borg upgrade --archives-tam REPO`` to add archive TAMs to all
archives that are not TAM authenticated yet.
This is a convenient method to just trust all archives present - if
an archive does not have TAM authentication yet, a TAM will be added.
Archives created by old borg versions < 1.0.9 do not have TAMs.
Archives created by newer borg version should have TAMs already.
If you have a high risk environment, you should not just run this,
but first verify that the archives are authentic and not malicious
(== have good content, have a good timestamp).
Borg 1.2.5+ needs all archives to be TAM authenticated for safety reasons.
This upgrade needs to be done once per repository.
Manifest TAM authentication:
Use ``borg upgrade --tam REPO`` to require manifest authentication
introduced with Borg 1.0.9 to address security issues. This means
that modifying the repository after doing this with a version prior
@ -4183,6 +4224,8 @@ class Archiver:
help='Enable manifest authentication (in key and cache) (Borg 1.0.9 and later).')
subparser.add_argument('--disable-tam', dest='disable_tam', action='store_true',
help='Disable manifest authentication (in key and cache).')
subparser.add_argument('--archives-tam', dest='archives_tam', action='store_true',
help='add TAM authentication for all archives.')
subparser.add_argument('location', metavar='REPOSITORY', nargs='?', default='',
type=location_validator(archive=False),
help='path to the repository to be upgraded')