diff --git a/docs/faq.rst b/docs/faq.rst index 83d5bfd59..943ae6e70 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -410,13 +410,6 @@ How important is the $HOME/.config/borg directory? The Borg config directory has content that you should take care of: -``security`` subdirectory - Each directory here represents one Borg repository by its ID and contains the last known status. - If a repository's status is different from this information at the beginning of BorgBackup - operation, Borg outputs warning messages and asks for confirmation, so make sure you do not lose - or manipulate these files. However, apart from those warnings, a loss of these files can be - recovered. - ``keys`` subdirectory All your borg keyfile keys are stored in this directory. Please note that borg repokey keys are stored inside the repository. You MUST make sure to have an @@ -426,6 +419,22 @@ The Borg config directory has content that you should take care of: Make sure that only you have access to the Borg config directory. +.. _home_data_borg: + +How important is the $HOME/.local/share/borg directory? +------------------------------------------------------- + +The Borg data directory has content that you should take care of: + +``security`` subdirectory + Each directory here represents one Borg repository by its ID and contains the last known status. + If a repository's status is different from this information at the beginning of BorgBackup + operation, Borg outputs warning messages and asks for confirmation, so make sure you do not lose + or manipulate these files. However, apart from those warnings, a loss of these files can be + recovered. + +Make sure that only you have access to the Borg data directory. + .. _cache_security: Do I need to take security precautions regarding the cache? diff --git a/docs/usage/general/environment.rst.inc b/docs/usage/general/environment.rst.inc index ddeb225c8..8fbd8210d 100644 --- a/docs/usage/general/environment.rst.inc +++ b/docs/usage/general/environment.rst.inc @@ -145,10 +145,14 @@ Directories and files: `XDG env var`_ ``XDG_CONFIG_HOME`` is set, then ``$XDG_CONFIG_HOME/borg`` is being used instead. This directory contains all borg configuration directories, see the FAQ for a security advisory about the data in this directory: :ref:`home_config_borg` + BORG_DATA_DIR + Defaults to ``$BORG_BASE_DIR/.local/share/borg``. If ``BORG_BASE_DIR`` is not explicitly set while + `XDG env var`_ ``XDG_DATA_HOME`` is set, then ``$XDG_DATA_HOME/borg`` is being used instead. + This directory contains all borg data directories, see the FAQ + for a security advisory about the data in this directory: :ref:`home_data_borg` BORG_SECURITY_DIR - Defaults to ``$BORG_CONFIG_DIR/security``. - This directory contains information borg uses to track its usage of NONCES ("numbers used - once" - usually in encryption context) and other security relevant data. + Defaults to ``$BORG_DATA_DIR/security``. + This directory contains security relevant data. BORG_KEYS_DIR Defaults to ``$BORG_CONFIG_DIR/keys``. This directory contains keys for encrypted repositories. diff --git a/src/borg/cache.py b/src/borg/cache.py index 7dbde9ce9..d37db1814 100644 --- a/src/borg/cache.py +++ b/src/borg/cache.py @@ -62,7 +62,7 @@ class SecurityManager: def __init__(self, repository): self.repository = repository - self.dir = get_security_dir(repository.id_str) + self.dir = get_security_dir(repository.id_str, legacy=(repository.version == 1)) self.cache_dir = cache_dir(repository) self.key_type_file = os.path.join(self.dir, "key-type") self.location_file = os.path.join(self.dir, "location") @@ -71,7 +71,7 @@ def __init__(self, repository): @staticmethod def destroy(repository, path=None): """destroy the security dir for ``repository`` or at ``path``""" - path = path or get_security_dir(repository.id_str) + path = path or get_security_dir(repository.id_str, legacy=(repository.version == 1)) if os.path.exists(path): shutil.rmtree(path) diff --git a/src/borg/crypto/key.py b/src/borg/crypto/key.py index c9caf7819..76d225ec1 100644 --- a/src/borg/crypto/key.py +++ b/src/borg/crypto/key.py @@ -114,7 +114,7 @@ def key_factory(repository, manifest_chunk, *, ro_cls=RepoObj): def tam_required_file(repository): - security_dir = get_security_dir(bin_to_hex(repository.id)) + security_dir = get_security_dir(bin_to_hex(repository.id), legacy=(repository.version == 1)) return os.path.join(security_dir, "tam_required") diff --git a/src/borg/helpers/fs.py b/src/borg/helpers/fs.py index af7297095..80e62c403 100644 --- a/src/borg/helpers/fs.py +++ b/src/borg/helpers/fs.py @@ -85,14 +85,27 @@ def get_security_dir(repository_id=None, *, legacy=False): """Determine where to store local security information.""" security_dir = os.environ.get("BORG_SECURITY_DIR") if security_dir is None: + get_dir = get_config_dir if legacy else get_data_dir # note: do not just give this as default to the environment.get(), see issue #5979. - security_dir = os.path.join(get_config_dir(legacy=legacy), "security") + security_dir = os.path.join(get_dir(legacy=legacy), "security") if repository_id: security_dir = os.path.join(security_dir, repository_id) ensure_dir(security_dir) return security_dir +def get_data_dir(*, legacy=False): + """Determine where to store borg changing data on the client""" + assert legacy is False, "there is no legacy variant of the borg data dir" + data_dir = os.environ.get( + "BORG_DATA_DIR", join_base_dir(".local", "share", "borg", legacy=legacy) or platformdirs.user_data_dir("borg") + ) + + # Create path if it doesn't exist yet + ensure_dir(data_dir) + return data_dir + + def get_cache_dir(*, legacy=False): """Determine where to repository keys and cache""" diff --git a/src/borg/testsuite/helpers.py b/src/borg/testsuite/helpers.py index bfb4f5c32..eba51b311 100644 --- a/src/borg/testsuite/helpers.py +++ b/src/borg/testsuite/helpers.py @@ -740,11 +740,13 @@ def test_get_security_dir(monkeypatch): monkeypatch.setenv("BORG_SECURITY_DIR", "/var/tmp") assert get_security_dir() == "/var/tmp" else: - monkeypatch.delenv("XDG_CONFIG_HOME", raising=False) + monkeypatch.delenv("XDG_DATA_HOME", raising=False) monkeypatch.delenv("BORG_SECURITY_DIR", raising=False) - assert get_security_dir() == os.path.join(home_dir, ".config", "borg", "security") - assert get_security_dir(repository_id="1234") == os.path.join(home_dir, ".config", "borg", "security", "1234") - monkeypatch.setenv("XDG_CONFIG_HOME", "/var/tmp/.config") + assert get_security_dir() == os.path.join(home_dir, ".local", "share", "borg", "security") + assert get_security_dir(repository_id="1234") == os.path.join( + home_dir, ".local", "share", "borg", "security", "1234" + ) + monkeypatch.setenv("XDG_DATA_HOME", "/var/tmp/.config") assert get_security_dir() == os.path.join("/var/tmp/.config", "borg", "security") monkeypatch.setenv("BORG_SECURITY_DIR", "/var/tmp") assert get_security_dir() == "/var/tmp" diff --git a/src/borg/testsuite/key.py b/src/borg/testsuite/key.py index f0245af34..3d3292fc1 100644 --- a/src/borg/testsuite/key.py +++ b/src/borg/testsuite/key.py @@ -115,6 +115,7 @@ def canonical_path(self): _location = _Location() id = bytes(32) id_str = bin_to_hex(id) + version = 2 def save_key(self, data): self.key_data = data