mirror of
https://github.com/saltstack/salt.git
synced 2025-04-10 14:51:40 +00:00
Create GNUPGHOME if it does not exist
This commit is contained in:
parent
75e1569db1
commit
596924e510
3 changed files with 81 additions and 46 deletions
1
changelog/66312.fixed.md
Normal file
1
changelog/66312.fixed.md
Normal file
|
@ -0,0 +1 @@
|
|||
Made gpg modules create GNUPGHOME if it does not exist
|
|
@ -173,32 +173,35 @@ def _restore_ownership(func):
|
|||
userinfo = _get_user_info(user)
|
||||
run_user = _get_user_info()
|
||||
|
||||
if not os.path.exists(gnupghome):
|
||||
_create_gnupghome(user, gnupghome)
|
||||
|
||||
if userinfo["uid"] != run_user["uid"]:
|
||||
group = None
|
||||
if os.path.exists(gnupghome):
|
||||
# Given user is different from one who runs Salt process,
|
||||
# need to fix ownership permissions for GnuPG home dir
|
||||
group = __salt__["file.gid_to_group"](run_user["gid"])
|
||||
for path in [gnupghome] + __salt__["file.find"](gnupghome):
|
||||
__salt__["file.chown"](path, run_user["name"], group)
|
||||
# Given user is different from one who runs Salt process,
|
||||
# need to fix ownership permissions for GnuPG home dir
|
||||
for path in [gnupghome] + __salt__["file.find"](gnupghome):
|
||||
__salt__["file.chown"](
|
||||
path, user=run_user["uid"], group=run_user["gid"]
|
||||
)
|
||||
if keyring and os.path.exists(keyring):
|
||||
if group is None:
|
||||
group = __salt__["file.gid_to_group"](run_user["gid"])
|
||||
__salt__["file.chown"](keyring, run_user["name"], group)
|
||||
__salt__["file.chown"](
|
||||
keyring, user=run_user["uid"], group=run_user["gid"]
|
||||
)
|
||||
|
||||
# Filter special kwargs
|
||||
for key in list(kwargs):
|
||||
if key.startswith("__"):
|
||||
del kwargs[key]
|
||||
filtered_kwargs = {k: v for k, v in kwargs.items() if not k.startswith("__")}
|
||||
|
||||
ret = func(*args, **kwargs)
|
||||
ret = func(*args, **filtered_kwargs)
|
||||
|
||||
if userinfo["uid"] != run_user["uid"]:
|
||||
group = __salt__["file.gid_to_group"](userinfo["gid"])
|
||||
for path in [gnupghome] + __salt__["file.find"](gnupghome):
|
||||
__salt__["file.chown"](path, user, group)
|
||||
__salt__["file.chown"](
|
||||
path, user=userinfo["uid"], group=userinfo["gid"]
|
||||
)
|
||||
if keyring and os.path.exists(keyring):
|
||||
__salt__["file.chown"](keyring, user, group)
|
||||
__salt__["file.chown"](
|
||||
keyring, user=userinfo["uid"], group=userinfo["gid"]
|
||||
)
|
||||
return ret
|
||||
|
||||
return func_wrapper
|
||||
|
@ -216,11 +219,24 @@ def _create_gpg(user=None, gnupghome=None, keyring=None):
|
|||
"Please pass keyring as a string. Multiple keyrings are not allowed"
|
||||
)
|
||||
|
||||
gpg = gnupg.GPG(gnupghome=gnupghome, keyring=keyring)
|
||||
try:
|
||||
gpg = gnupg.GPG(gnupghome=gnupghome, keyring=keyring)
|
||||
except ValueError as err:
|
||||
if not str(err).startswith("gnupghome should be a directory"):
|
||||
raise
|
||||
_create_gnupghome(user, gnupghome)
|
||||
gpg = gnupg.GPG(gnupghome=gnupghome, keyring=keyring)
|
||||
|
||||
return gpg
|
||||
|
||||
|
||||
def _create_gnupghome(user, gnupghome):
|
||||
user_info = _get_user_info(user)
|
||||
__salt__["file.mkdir"](
|
||||
gnupghome, user=user_info["uid"], group=user_info["gid"], mode="0700"
|
||||
)
|
||||
|
||||
|
||||
def _list_keys(secret=False, user=None, gnupghome=None, keyring=None):
|
||||
"""
|
||||
Helper function for listing keys
|
||||
|
|
|
@ -12,6 +12,37 @@ pytestmark = [
|
|||
]
|
||||
|
||||
|
||||
def _kill_gpg_agent(root):
|
||||
gpg_connect_agent = shutil.which("gpg-connect-agent")
|
||||
if gpg_connect_agent:
|
||||
gnupghome = root / ".gnupg"
|
||||
if not gnupghome.is_dir():
|
||||
gnupghome = root
|
||||
try:
|
||||
subprocess.run(
|
||||
[gpg_connect_agent, "killagent", "/bye"],
|
||||
env={"GNUPGHOME": str(gnupghome)},
|
||||
shell=False,
|
||||
check=True,
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL,
|
||||
)
|
||||
except subprocess.CalledProcessError:
|
||||
# This is likely CentOS 7 or Amazon Linux 2
|
||||
pass
|
||||
|
||||
# If the above errored or was not enough, as a last resort, let's check
|
||||
# the running processes.
|
||||
for proc in psutil.process_iter():
|
||||
try:
|
||||
if "gpg-agent" in proc.name():
|
||||
for arg in proc.cmdline():
|
||||
if str(root) in arg:
|
||||
proc.terminate()
|
||||
except Exception: # pylint: disable=broad-except
|
||||
pass
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def gpghome(tmp_path):
|
||||
root = tmp_path / "gpghome"
|
||||
|
@ -20,34 +51,7 @@ def gpghome(tmp_path):
|
|||
yield root
|
||||
finally:
|
||||
# Make sure we don't leave any gpg-agents running behind
|
||||
gpg_connect_agent = shutil.which("gpg-connect-agent")
|
||||
if gpg_connect_agent:
|
||||
gnupghome = root / ".gnupg"
|
||||
if not gnupghome.is_dir():
|
||||
gnupghome = root
|
||||
try:
|
||||
subprocess.run(
|
||||
[gpg_connect_agent, "killagent", "/bye"],
|
||||
env={"GNUPGHOME": str(gnupghome)},
|
||||
shell=False,
|
||||
check=True,
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL,
|
||||
)
|
||||
except subprocess.CalledProcessError:
|
||||
# This is likely CentOS 7 or Amazon Linux 2
|
||||
pass
|
||||
|
||||
# If the above errored or was not enough, as a last resort, let's check
|
||||
# the running processes.
|
||||
for proc in psutil.process_iter():
|
||||
try:
|
||||
if "gpg-agent" in proc.name():
|
||||
for arg in proc.cmdline():
|
||||
if str(root) in arg:
|
||||
proc.terminate()
|
||||
except Exception: # pylint: disable=broad-except
|
||||
pass
|
||||
_kill_gpg_agent(root)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
@ -931,3 +935,17 @@ def test_read_key_multiple(
|
|||
else:
|
||||
assert len(res) == 1
|
||||
assert any(key["fingerprint"] == key_a_fp for key in res)
|
||||
|
||||
|
||||
def test_missing_gnupghome(gpg, tmp_path):
|
||||
"""
|
||||
Ensure the directory passed as `gnupghome` is created before
|
||||
python-gnupg is invoked. Issue #66312.
|
||||
"""
|
||||
gnupghome = tmp_path / "gnupghome"
|
||||
try:
|
||||
res = gpg.list_keys(gnupghome=tmp_path / "gnupghome")
|
||||
assert res == []
|
||||
finally:
|
||||
# Make sure we don't leave any gpg-agents running behind
|
||||
_kill_gpg_agent(gnupghome)
|
||||
|
|
Loading…
Add table
Reference in a new issue