Run HSM validation as pkiuser to verify token permissions

Run all commands as pkiuser when validating that the HSM token
is available, that the token library path is correct and that
the password can read keys. This will avoid issues where the
initial validation is ok but the pkiuser is not granted read
access to some part of the token. This is very possible
when using softhsm2.

Fixes: https://pagure.io/freeipa/issue/9626

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
This commit is contained in:
Rob Crittenden authored and Florence Blanc-Renaud committed 2024-07-31 18:33:29 +02:00
1 parent 4d075fdd2a
commit 202de166c6
2 files changed
+74 -3

No files matched your search

+17 -3
View File
@@ -18,6 +18,7 @@ import six
from ipalib.constants import IPA_CA_CN
from ipalib.install import certstore
from ipalib.install.service import enroll_only, master_install_only, replica_install_only
from ipaplatform.constants import constants
from ipaserver.install import sysupgrade
from ipapython.install import typing
from ipapython.install.core import group, knob, extend_knob
@@ -208,8 +209,15 @@ def hsm_validator(token_name, token_library, token_password):
raise ValueError(
"Token library path '%s' does not exist" % token_library
)
pkiuser = constants.PKI_USER
pkigroup = constants.PKI_GROUP
if 'libsofthsm' in token_library:
import grp
group = grp.getgrnam(constants.ODS_GROUP)
if str(constants.PKI_USER) in group.gr_mem:
pkigroup = constants.ODS_GROUP
with certdb.NSSDatabase() as tempnssdb:
tempnssdb.create_db()
tempnssdb.create_db(user=str(pkiuser), group=str(pkigroup))
# Try adding the token library to the temporary database in
# case it isn't already available. Ignore all errors.
command = [
@@ -223,6 +231,7 @@ def hsm_validator(token_name, token_library, token_password):
# It may fail if p11-kit has already registered the library, that's
# ok.
ipautil.run(command, stdin='\n', cwd=tempnssdb.secdir,
runas=pkiuser, suplementary_groups=[pkigroup],
raiseonerr=False)
command = [
@@ -232,7 +241,8 @@ def hsm_validator(token_name, token_library, token_password):
'-force'
]
lines = ipautil.run(
command, cwd=tempnssdb.secdir, capture_output=True).output
command, cwd=tempnssdb.secdir, capture_output=True,
runas=pkiuser, suplementary_groups=[pkigroup]).output
found = False
token_line = f'token: {token_name}'
for line in lines.split('\n'):
@@ -241,9 +251,11 @@ def hsm_validator(token_name, token_library, token_password):
break
if not found:
raise ValueError(
"Token named '%s' was not found" % token_name
"Token named '%s' was not found. Check permissions"
% token_name
)
pwdfile = ipautil.write_tmp_file(token_password)
os.fchown(pwdfile.fileno(), pkiuser.uid, pkigroup.gid)
args = [
paths.CERTUTIL,
"-d", '{}:{}'.format(tempnssdb.dbtype, tempnssdb.secdir),
@@ -252,6 +264,8 @@ def hsm_validator(token_name, token_library, token_password):
"-f", pwdfile.name,
]
result = ipautil.run(args, cwd=tempnssdb.secdir,
runas=pkiuser,
suplementary_groups=[pkigroup],
capture_error=True, raiseonerr=False)
if result.returncode != 0 and len(result.error_output):
if 'SEC_ERROR_BAD_PASSWORD' in result.error_output:
+57
View File
@@ -833,6 +833,13 @@ class TestHSMNegative(IntegrationTest):
cls.token_name, cls.token_password = get_hsm_token(cls.master)
@classmethod
def uninstall(cls, mh):
cls.master.run_command(
['softhsm2-util', '--delete-token', '--token', cls.token_name],
raiseonerr=False
)
def test_hsm_negative_wrong_token_details(self):
check_version(self.master)
# wrong token name
@@ -868,6 +875,51 @@ class TestHSMNegative(IntegrationTest):
)
assert result.returncode != 0
def test_hsm_negative_bad_token_dir_permissions(self):
"""Create an unreadable softhsm2 token and install should fail.
This is most often seen on replicas where the pkiuser is not
a member of the ods group.
"""
check_version(self.master)
token_name = 'bad_perms'
token_passwd = 'Secret123'
self.master.run_command(
['softhsm2-util', '--delete-token', '--token', token_name],
raiseonerr=False
)
self.master.run_command(
['usermod', 'pkiuser', '-a', '-G', 'ods']
)
self.master.run_command(
['softhsm2-util', '--init-token',
'--free', '--pin', token_passwd, '--so-pin', token_passwd,
'--label', token_name]
)
self.master.run_command(
['usermod', 'pkiuser', '-r', '-G', 'ods']
)
result = tasks.install_master(
self.master, raiseonerr=False,
extra_args=(
'--token-name', token_name,
'--token-library-path', hsm_lib_path,
'--token-password', token_passwd
)
)
self.master.run_command(
['usermod', 'pkiuser', '-a', '-G', 'ods']
)
self.master.run_command(
['softhsm2-util', '--delete-token', '--token', token_name],
raiseonerr=False
)
assert result.returncode != 0
assert (
f"Token named '{token_name}' was not found"
in result.stderr_text
)
def test_hsm_negative_special_char_token_name(self):
check_version(self.master)
token_name = 'hsm:token'
@@ -912,6 +964,11 @@ class TestHSMNegative(IntegrationTest):
'--token-password-file', self.token_password_file
)
)
self.master.run_command(
['softhsm2-util', '--delete-token', '--token', self.token_name],
raiseonerr=False
)
# assert 'error message non existing token lib' in result.stderr_text
assert result.returncode != 0