Repository: borgbackup/borg

Issue:
BORG_SECURITY_DIR should be in XDG_HOME_DATA, not XDG_HOME_CONFIG
<!--
Thank you for reporting an issue.

*IMPORTANT* -  *before* creating a new issue please look around:
 - Borgbackup documentation: http://borgbackup.readthedocs.io/en/stable/index.html
 - FAQ: https://borgbackup.readthedocs.io/en/stable/faq.html
 and
 - open issues in Github tracker: https://github.com/borgbackup/borg/issues
  
If you cannot find a similar problem, then create a new issue.

Please fill in as much of the template as possible.
-->

## Have you checked borgbackup docs, FAQ, and open Github issues?

Yes

## Is this a BUG / ISSUE report or a QUESTION?

ISSUE

## System information. For client/server mode post info for both machines.

#### Your borg version (borg -V).

borg 1.1.16

#### Operating system (distribution) and version.

Linux 5.11.13-arch1-1

## Describe the problem you're observing.

Currently, BORG_SECURITY_DIR defaults to BORG_CONFIG_DIR/security. However, this is data that often changes, and not related to borg configuration made by the user. It should be moved to XDG_DATA_HOME so that versionning and backup of $XDG_CONFIG_HOME isn't cluttered by those changes ?


Discussion:
codecov-commenter: ## [Codecov](https://app.codecov.io/gh/borgbackup/borg/pull/7583?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=borgbackup) Report
> Merging [#7583](https://app.codecov.io/gh/borgbackup/borg/pull/7583?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=borgbackup) (1d45d9f) into [master](https://app.codecov.io/gh/borgbackup/borg/commit/f5c9f23467913500e664f95afe329511a5e59e40?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=borgbackup) (f5c9f23) will **decrease** coverage by `0.01%`.
> The diff coverage is `100.00%`.

:exclamation: Your organization is not using the GitHub App Integration. As a result you may experience degraded service beginning May 15th. Please [install the Github App Integration](https://github.com/apps/codecov) for your organization. [Read more](https://about.codecov.io/blog/codecov-is-updating-its-github-integration/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=borgbackup).

```diff
@@            Coverage Diff             @@
##           master    #7583      +/-   ##
==========================================
- Coverage   83.76%   83.75%   -0.01%     
==========================================
  Files          66       66              
  Lines       11779    11785       +6     
  Branches     2150     2150              
==========================================
+ Hits         9867     9871       +4     
- Misses       1338     1340       +2     
  Partials      574      574              
```


| [Impacted Files](https://app.codecov.io/gh/borgbackup/borg/pull/7583?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=borgbackup) | Coverage Δ | |
|---|---|---|
| [src/borg/helpers/fs.py](https://app.codecov.io/gh/borgbackup/borg/pull/7583?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=borgbackup#diff-c3JjL2JvcmcvaGVscGVycy9mcy5weQ==) | `84.16% <100.00%> (+0.40%)` | :arrow_up: |

... and [1 file with indirect coverage changes](https://app.codecov.io/gh/borgbackup/borg/pull/7583/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=borgbackup)



Patch:
diff --git a/docs/faq.rst b/docs/faq.rst
index 83d5bfd5..943ae6e7 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 ddeb225c..8fbd8210 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 7dbde9ce..d37db181 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 c9caf781..76d225ec 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 af729709..80e62c40 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"""
 


Test patch:
diff --git a/src/borg/testsuite/helpers.py b/src/borg/testsuite/helpers.py
index bfb4f5c3..eba51b31 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 f0245af3..3d3292fc 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