Преглед изворни кода

always implicitly require archive TAMs

they must be there since the upgrade to borg 1.2.6 (or other
borg versions that also have a fix for CVE-2023-36811).
Thomas Waldmann пре 1 година
родитељ
комит
2d78fa89a5
5 измењених фајлова са 13 додато и 34 уклоњено
  1. 4 5
      src/borg/archive.py
  2. 1 1
      src/borg/cache.py
  3. 7 23
      src/borg/crypto/key.py
  4. 0 3
      src/borg/testsuite/archiver/checks.py
  5. 1 2
      src/borg/testsuite/key.py

+ 4 - 5
src/borg/archive.py

@@ -493,7 +493,7 @@ class Archive:
         self.name = name  # overwritten later with name from archive metadata
         self.name_in_manifest = name  # can differ from .name later (if borg check fixed duplicate archive names)
         self.comment = None
-        self.tam_verified = False
+        self.tam_verified = True
         self.numeric_ids = numeric_ids
         self.noatime = noatime
         self.noctime = noctime
@@ -533,8 +533,7 @@ class Archive:
     def _load_meta(self, id):
         cdata = self.repository.get(id)
         _, data = self.repo_objs.parse(id, cdata)
-        # we do not require TAM for archives, otherwise we can not even borg list a repo with old archives.
-        archive, self.tam_verified, _ = self.key.unpack_and_verify_archive(data, force_tam_not_required=True)
+        archive, _ = self.key.unpack_and_verify_archive(data)
         metadata = ArchiveItem(internal_dict=archive)
         if metadata.version not in (1, 2):  # legacy: still need to read v1 archives
             raise Exception("Unknown archive metadata version")
@@ -1998,7 +1997,7 @@ class ArchiveChecker:
                 # **after** doing the low-level checks and having a strong indication that we
                 # are likely looking at an archive item here, also check the TAM authentication:
                 try:
-                    archive, verified, _ = self.key.unpack_and_verify_archive(data, force_tam_not_required=False)
+                    archive, _ = self.key.unpack_and_verify_archive(data)
                 except IntegrityError as integrity_error:
                     # TAM issues - do not accept this archive!
                     # either somebody is trying to attack us with a fake archive data or
@@ -2269,7 +2268,7 @@ class ArchiveChecker:
                     del self.manifest.archives[info.name]
                     continue
                 try:
-                    archive, verified, salt = self.key.unpack_and_verify_archive(data, force_tam_not_required=False)
+                    archive, salt = self.key.unpack_and_verify_archive(data)
                 except IntegrityError as integrity_error:
                     # looks like there is a TAM issue with this archive, this might be an attack!
                     # when upgrading to borg 1.2.5, users are expected to TAM-authenticate all archives they

+ 1 - 1
src/borg/cache.py

@@ -755,7 +755,7 @@ class LocalCache(CacheStatsMixin):
             nonlocal processed_item_metadata_chunks
             csize, data = decrypted_repository.get(archive_id)
             chunk_idx.add(archive_id, 1, len(data))
-            archive, verified, _ = self.key.unpack_and_verify_archive(data, force_tam_not_required=True)
+            archive, _ = self.key.unpack_and_verify_archive(data)
             archive = ArchiveItem(internal_dict=archive)
             if archive.version not in (1, 2):  # legacy
                 raise Exception("Unknown archive metadata version")

+ 7 - 23
src/borg/crypto/key.py

@@ -15,7 +15,7 @@ import argon2.low_level
 from ..constants import *  # NOQA
 from ..helpers import StableDict
 from ..helpers import Error, IntegrityError
-from ..helpers import get_keys_dir, get_security_dir
+from ..helpers import get_keys_dir
 from ..helpers import get_limited_unpacker
 from ..helpers import bin_to_hex
 from ..helpers.passphrase import Passphrase, PasswordRetriesExceeded, PassphraseWrong
@@ -276,37 +276,21 @@ class KeyBase:
         logger.debug("TAM-verified manifest")
         return unpacked
 
-    def unpack_and_verify_archive(self, data, force_tam_not_required=False):
-        """Unpack msgpacked *data* and return (object, did_verify)."""
-        tam_required = self.tam_required
-        if force_tam_not_required and tam_required:
-            # for a long time, borg only checked manifest for "tam_required" and
-            # people might have archives without TAM, so don't be too annoyingly loud here:
-            logger.debug("Archive authentication DISABLED.")
-            tam_required = False
+    def unpack_and_verify_archive(self, data):
+        """Unpack msgpacked *data* and return (object, salt)."""
         data = bytearray(data)
         unpacker = get_limited_unpacker("archive")
         unpacker.feed(data)
         unpacked = unpacker.unpack()
         if "tam" not in unpacked:
-            if tam_required:
-                archive_name = unpacked.get("name", "<unknown>")
-                raise ArchiveTAMRequiredError(archive_name)
-            else:
-                logger.debug("Archive TAM not found and not required")
-                return unpacked, False, None
+            archive_name = unpacked.get("name", "<unknown>")
+            raise ArchiveTAMRequiredError(archive_name)
         tam = unpacked.pop("tam", None)
         if not isinstance(tam, dict):
             raise ArchiveTAMInvalid()
         tam_type = tam.get("type", "<none>")
         if tam_type != "HKDF_HMAC_SHA512":
-            if tam_required:
-                raise TAMUnsupportedSuiteError(repr(tam_type))
-            else:
-                logger.debug(
-                    "Ignoring archive TAM made with unsupported suite, since TAM is not required: %r", tam_type
-                )
-                return unpacked, False, None
+            raise TAMUnsupportedSuiteError(repr(tam_type))
         tam_hmac = tam.get("hmac")
         tam_salt = tam.get("salt")
         if not isinstance(tam_salt, (bytes, str)) or not isinstance(tam_hmac, (bytes, str)):
@@ -320,7 +304,7 @@ class KeyBase:
         if not hmac.compare_digest(calculated_hmac, tam_hmac):
             raise ArchiveTAMInvalid()
         logger.debug("TAM-verified archive")
-        return unpacked, True, tam_salt
+        return unpacked, tam_salt
 
 
 class PlaintextKey(KeyBase):

+ 0 - 3
src/borg/testsuite/archiver/checks.py

@@ -425,9 +425,6 @@ def test_check_rebuild_refcounts(archiver):
     repository = Repository(archiver.repository_path, exclusive=True)
     with repository:
         write_archive_without_tam(repository, "archive_no_tam")
-    output = cmd(archiver, "rlist", "--format='{name} tam:{tam}{NL}'")
-    assert "archive_tam tam:verified" in output  # good
-    assert "archive_no_tam tam:none" in output  # could be borg < 1.0.9 archive or fake
     cmd(archiver, "check", "--repair")
     output = cmd(archiver, "rlist", "--format='{name} tam:{tam}{NL}'")
     assert "archive_tam tam:verified" in output  # TAM-verified archive still there

+ 1 - 2
src/borg/testsuite/key.py

@@ -352,8 +352,7 @@ class TestTAM:
         unpacked = msgpack.unpackb(blob)
         assert unpacked["tam"]["type"] == "HKDF_HMAC_SHA512"
 
-        unpacked, verified, _ = key.unpack_and_verify_archive(blob)
-        assert verified
+        unpacked, _ = key.unpack_and_verify_archive(blob)
         assert unpacked["foo"] == "bar"
         assert "tam" not in unpacked