mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Try to respect custom GNUPGHOME env var
This commit is contained in:
parent
596924e510
commit
4294a82322
3 changed files with 81 additions and 7 deletions
1
changelog/66313.changed.md
Normal file
1
changelog/66313.changed.md
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Made gpg modules respect user's GNUPGHOME if set in shell environment
|
|
@ -11,6 +11,13 @@ Sign, encrypt, sign plus encrypt and verify text and files.
|
||||||
Be aware that the alternate ``gnupg`` and ``pretty-bad-protocol``
|
Be aware that the alternate ``gnupg`` and ``pretty-bad-protocol``
|
||||||
libraries are not supported.
|
libraries are not supported.
|
||||||
|
|
||||||
|
.. versionchanged:: 3008.0
|
||||||
|
|
||||||
|
When ``gnupghome`` is not set explicitly, this module now tries to
|
||||||
|
respect a custom ``GNUPGHOME`` environmental variable.
|
||||||
|
If a ``user`` is not passed, the current process' environment is queried,
|
||||||
|
otherwise the user's configured shell environment is taken as a reference
|
||||||
|
in the same way the ``cmd`` modules operate.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import functools
|
import functools
|
||||||
|
@ -23,6 +30,7 @@ import salt.utils.data
|
||||||
import salt.utils.files
|
import salt.utils.files
|
||||||
import salt.utils.immutabletypes as immutabletypes
|
import salt.utils.immutabletypes as immutabletypes
|
||||||
import salt.utils.path
|
import salt.utils.path
|
||||||
|
import salt.utils.platform
|
||||||
import salt.utils.stringutils
|
import salt.utils.stringutils
|
||||||
import salt.utils.versions
|
import salt.utils.versions
|
||||||
from salt.exceptions import SaltInvocationError
|
from salt.exceptions import SaltInvocationError
|
||||||
|
@ -153,11 +161,25 @@ def _get_user_gnupghome(user):
|
||||||
Return default GnuPG home directory path for a user
|
Return default GnuPG home directory path for a user
|
||||||
"""
|
"""
|
||||||
if user == "salt":
|
if user == "salt":
|
||||||
gnupghome = os.path.join(__salt__["config.get"]("config_dir"), "gpgkeys")
|
return os.path.join(__salt__["config.get"]("config_dir"), "gpgkeys")
|
||||||
else:
|
|
||||||
gnupghome = os.path.join(_get_user_info(user)["home"], ".gnupg")
|
|
||||||
|
|
||||||
return gnupghome
|
# Try to respect GNUPGHOME environment variable.
|
||||||
|
if user is None:
|
||||||
|
gnupghome_env = __salt__["environ.get"]("GNUPGHOME")
|
||||||
|
else:
|
||||||
|
cmd = 'echo -n "$GNUPGHOME"'
|
||||||
|
if salt.utils.platform.is_windows():
|
||||||
|
cmd = "echo %GNUPGHOME%"
|
||||||
|
gnupghome_env = __salt__["cmd.run_stdout"](
|
||||||
|
cmd, python_shell=True, runas=user
|
||||||
|
).strip()
|
||||||
|
if gnupghome_env.startswith("~"):
|
||||||
|
# This does not resolve `~` since that potentially complicates things a lot.
|
||||||
|
# It should have been resolved by the shell anyways.
|
||||||
|
log.warning("Found GNUPGHOME beginning with tilde, ignoring")
|
||||||
|
gnupghome_env = ""
|
||||||
|
|
||||||
|
return gnupghome_env or os.path.join(_get_user_info(user)["home"], ".gnupg")
|
||||||
|
|
||||||
|
|
||||||
def _restore_ownership(func):
|
def _restore_ownership(func):
|
||||||
|
|
|
@ -10,6 +10,7 @@ import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import time
|
import time
|
||||||
import types
|
import types
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import psutil
|
import psutil
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -204,7 +205,14 @@ def gpghome(tmp_path):
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def configure_loader_modules(gpghome):
|
def configure_loader_modules(gpghome):
|
||||||
return {gpg: {}}
|
return {
|
||||||
|
gpg: {
|
||||||
|
"__salt__": {
|
||||||
|
"environ.get": lambda *x: "",
|
||||||
|
"cmd.run_stdout": lambda *x, **y: "",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_list_keys():
|
def test_list_keys():
|
||||||
|
@ -1101,7 +1109,9 @@ def _import_result_mock(request):
|
||||||
indirect=True,
|
indirect=True,
|
||||||
)
|
)
|
||||||
def test_gpg_receive_keys_no_user_id(_import_result_mock):
|
def test_gpg_receive_keys_no_user_id(_import_result_mock):
|
||||||
with patch("salt.modules.gpg._create_gpg") as create:
|
with patch("salt.modules.gpg._create_gpg") as create, patch(
|
||||||
|
"salt.modules.gpg._create_gnupghome"
|
||||||
|
):
|
||||||
with patch.dict(
|
with patch.dict(
|
||||||
gpg.__salt__, {"user.info": MagicMock(), "config.option": Mock()}
|
gpg.__salt__, {"user.info": MagicMock(), "config.option": Mock()}
|
||||||
):
|
):
|
||||||
|
@ -1123,7 +1133,9 @@ def test_gpg_receive_keys_no_user_id(_import_result_mock):
|
||||||
indirect=True,
|
indirect=True,
|
||||||
)
|
)
|
||||||
def test_gpg_receive_keys_keyserver_unavailable(_import_result_mock):
|
def test_gpg_receive_keys_keyserver_unavailable(_import_result_mock):
|
||||||
with patch("salt.modules.gpg._create_gpg") as create:
|
with patch("salt.modules.gpg._create_gpg") as create, patch(
|
||||||
|
"salt.modules.gpg._create_gnupghome"
|
||||||
|
):
|
||||||
with patch.dict(
|
with patch.dict(
|
||||||
gpg.__salt__, {"user.info": MagicMock(), "config.option": Mock()}
|
gpg.__salt__, {"user.info": MagicMock(), "config.option": Mock()}
|
||||||
):
|
):
|
||||||
|
@ -1131,3 +1143,42 @@ def test_gpg_receive_keys_keyserver_unavailable(_import_result_mock):
|
||||||
res = gpg.receive_keys(keys="abc", user="abc")
|
res = gpg.receive_keys(keys="abc", user="abc")
|
||||||
assert res["res"] is False
|
assert res["res"] is False
|
||||||
assert any("No keyserver available" in x for x in res["message"])
|
assert any("No keyserver available" in x for x in res["message"])
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"user,envvar",
|
||||||
|
(
|
||||||
|
("testuser", ""),
|
||||||
|
("testuser", "/home/testuser/local/share/gnupg"),
|
||||||
|
(None, ""),
|
||||||
|
(None, "/home/testuser/local/share/gnupg"),
|
||||||
|
("salt", ""),
|
||||||
|
("salt", "/this/should/not/matter"),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
def test_get_user_gnupghome_respects_shell_env_setup(user, envvar):
|
||||||
|
config_dir = "/etc/salt" # minion_opts["config_dir"] is not set, only conf_dir (?)
|
||||||
|
user = user or "testuser"
|
||||||
|
if user == "salt":
|
||||||
|
homedir = "/opt/saltstack/salt"
|
||||||
|
expected = str(Path(config_dir) / "gpgkeys")
|
||||||
|
else:
|
||||||
|
homedir = f"/home/{user}"
|
||||||
|
expected = envvar or str(Path(homedir) / ".gnupg")
|
||||||
|
userinfo = {
|
||||||
|
"home": homedir,
|
||||||
|
"uid": 1000,
|
||||||
|
"gid": 1000,
|
||||||
|
"shell": "/bin/bash",
|
||||||
|
}
|
||||||
|
with patch.dict(
|
||||||
|
gpg.__salt__,
|
||||||
|
{
|
||||||
|
"user.info": lambda *x: userinfo,
|
||||||
|
"environ.get": lambda *x: envvar,
|
||||||
|
"cmd.run_stdout": lambda *x, **y: envvar,
|
||||||
|
"config.get": lambda *x: config_dir,
|
||||||
|
},
|
||||||
|
):
|
||||||
|
res = gpg._get_user_gnupghome(user)
|
||||||
|
assert res == expected
|
||||||
|
|
Loading…
Add table
Reference in a new issue