Skip to content

Tests: Smart card authentication tests for SSSD's CKF_PROTECTED_AUTH… - #8744

Merged
sumit-bose merged 1 commit into
SSSD:masterfrom
krishnavema:pinpad-tests
Jul 6, 2026
Merged

Tests: Smart card authentication tests for SSSD's CKF_PROTECTED_AUTH…#8744
sumit-bose merged 1 commit into
SSSD:masterfrom
krishnavema:pinpad-tests

Conversation

@krishnavema

@krishnavema krishnavema commented May 28, 2026

Copy link
Copy Markdown
Contributor

Smart card authentication tests for SSSD's CKF_PROTECTED_AUTHENTICATION_PATH (hardware pinpad) support, verifying that p11_child detects the flag, passes NULL PIN to C_Login, and PAM prompts for external keypad
entry instead of keyboard PIN input.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a comprehensive suite of system tests for SSSD smart card pinpad authentication, covering scenarios such as successful login via su, correct external keypad prompting, local user authentication, and keyboard-less PIN entry. The review feedback correctly identifies a security vulnerability where sensitive private key files are written to /tmp with default permissions and are not cleaned up after execution. It is recommended to restrict these files to 0600 permissions and ensure they are deleted in a finally block to prevent credential leakage.

Comment on lines +134 to +161
client.fs.write(pem_cert, cert_content)
client.fs.write(pem_key, key_content)

x509_args: CLIBuilderArgs = {
"in": (client.host.cli.option.VALUE, pem_cert),
"outform": (client.host.cli.option.VALUE, "DER"),
"out": (client.host.cli.option.VALUE, der_cert),
}
client.host.conn.run(client.host.cli.command("openssl x509", x509_args))

rsa_args: CLIBuilderArgs = {
"in": (client.host.cli.option.VALUE, pem_key),
"outform": (client.host.cli.option.VALUE, "DER"),
"out": (client.host.cli.option.VALUE, der_key),
}
client.host.conn.run(client.host.cli.command("openssl rsa", rsa_args))

for obj_path, obj_type in [(der_key, "privkey"), (der_cert, "cert")]:
args: CLIBuilderArgs = {
"module": (client.host.cli.option.VALUE, OPENSC_MODULE),
"login": (client.host.cli.option.SWITCH, True),
"pin": (client.host.cli.option.VALUE, pin),
"write-object": (client.host.cli.option.VALUE, obj_path),
"type": (client.host.cli.option.VALUE, obj_type),
"id": (client.host.cli.option.VALUE, cert_id),
"label": (client.host.cli.option.VALUE, username),
}
client.host.conn.run(client.host.cli.command("pkcs11-tool", args))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

The private key files are written to /tmp with default permissions, which can make them readable by other local users on the system. Additionally, these temporary files are never cleaned up from the filesystem after the test completes, leading to sensitive credential leakage.

To resolve this, restrict the permissions of the private key files to 0600 immediately after creation, and ensure all temporary files are cleaned up in a finally block.

    try:
        client.fs.write(pem_cert, cert_content)
        client.fs.write(pem_key, key_content)
        client.host.conn.run(f"chmod 600 {pem_key}", raise_on_error=False)

        x509_args: CLIBuilderArgs = {
            "in": (client.host.cli.option.VALUE, pem_cert),
            "outform": (client.host.cli.option.VALUE, "DER"),
            "out": (client.host.cli.option.VALUE, der_cert),
        }
        client.host.conn.run(client.host.cli.command("openssl x509", x509_args))

        rsa_args: CLIBuilderArgs = {
            "in": (client.host.cli.option.VALUE, pem_key),
            "outform": (client.host.cli.option.VALUE, "DER"),
            "out": (client.host.cli.option.VALUE, der_key),
        }
        client.host.conn.run(client.host.cli.command("openssl rsa", rsa_args))
        client.host.conn.run(f"chmod 600 {der_key}", raise_on_error=False)

        for obj_path, obj_type in [(der_key, "privkey"), (der_cert, "cert")]:
            args: CLIBuilderArgs = {
                "module": (client.host.cli.option.VALUE, OPENSC_MODULE),
                "login": (client.host.cli.option.SWITCH, True),
                "pin": (client.host.cli.option.VALUE, pin),
                "write-object": (client.host.cli.option.VALUE, obj_path),
                "type": (client.host.cli.option.VALUE, obj_type),
                "id": (client.host.cli.option.VALUE, cert_id),
                "label": (client.host.cli.option.VALUE, username),
            }
            client.host.conn.run(client.host.cli.command("pkcs11-tool", args))
    finally:
        client.host.conn.run(f"rm -f {pem_cert} {pem_key} {der_cert} {der_key}", raise_on_error=False)

Comment on lines +456 to +529
try:
req_args: CLIBuilderArgs = {
"x509": (client.host.cli.option.SWITCH, True),
"nodes": (client.host.cli.option.SWITCH, True),
"sha256": (client.host.cli.option.SWITCH, True),
"days": (client.host.cli.option.VALUE, "365"),
"newkey": (client.host.cli.option.VALUE, "rsa:2048"),
"keyout": (client.host.cli.option.VALUE, key_pem),
"out": (client.host.cli.option.VALUE, cert_pem),
"subj": (client.host.cli.option.VALUE, "/CN=Pinpad Test Cert"),
}
client.host.conn.run(client.host.cli.command("openssl req", req_args))

x509_args: CLIBuilderArgs = {
"in": (client.host.cli.option.VALUE, cert_pem),
"outform": (client.host.cli.option.VALUE, "DER"),
"out": (client.host.cli.option.VALUE, cert_der),
}
client.host.conn.run(client.host.cli.command("openssl x509", x509_args))

rsa_args: CLIBuilderArgs = {
"in": (client.host.cli.option.VALUE, key_pem),
"outform": (client.host.cli.option.VALUE, "DER"),
"out": (client.host.cli.option.VALUE, key_der),
}
client.host.conn.run(client.host.cli.command("openssl rsa", rsa_args))

for obj_path, obj_type in [(key_der, "privkey"), (cert_der, "cert")]:
args: CLIBuilderArgs = {
"module": (client.host.cli.option.VALUE, OPENSC_MODULE),
"login": (client.host.cli.option.SWITCH, True),
"pin": (client.host.cli.option.VALUE, TOKEN_PIN),
"write-object": (client.host.cli.option.VALUE, obj_path),
"type": (client.host.cli.option.VALUE, obj_type),
"id": (client.host.cli.option.VALUE, cert_id),
"label": (client.host.cli.option.VALUE, username),
}
client.host.conn.run(client.host.cli.command("pkcs11-tool", args))

ensure_pcscd_accessible(client)

client.host.fs.rm("/etc/sssd/pki/sssd_auth_ca_db.pem")
cert_data = client.host.fs.read(cert_pem)
client.host.fs.append("/etc/sssd/pki/sssd_auth_ca_db.pem", cert_data)

client.authselect.select("sssd", ["with-smartcard"])
client.sssd.common.local()
client.sssd.dom("local")["local_auth_policy"] = "only"
client.sssd.section(f"certmap/local/{username}")["matchrule"] = (
"<SUBJECT>.*CN=Pinpad Test Cert.*"
)
client.sssd.pam["pam_cert_auth"] = "True"
client.sssd.pam["p11_child_timeout"] = "60"
client.sssd.start(debug_level="0xFFF0", check_config=False)

result = client.host.conn.run(
f"su - {username} -c 'su - {username} -c whoami'",
raise_on_error=False,
)

output = result.stdout + result.stderr
assert "Use external keypad" in output, (
f"Expected 'Use external keypad' prompt but got: "
f"stdout={result.stdout!r}, stderr={result.stderr!r}"
)
assert result.rc == 0, (
f"Authentication failed with rc={result.rc}, "
f"stdout={result.stdout!r}, stderr={result.stderr!r}"
)
assert username in result.stdout, (
f"'{username}' not found in whoami output: {result.stdout}"
)
finally:
cleanup_hw_card(client, cert_id=cert_id)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The generated self-signed private key files are written to /tmp with default permissions and are never cleaned up from the filesystem after the test completes, leading to sensitive credential leakage.

To resolve this, restrict the permissions of the private key files to 0600 immediately after creation, and ensure all temporary files are cleaned up in the finally block.

    try:
        req_args: CLIBuilderArgs = {
            "x509": (client.host.cli.option.SWITCH, True),
            "nodes": (client.host.cli.option.SWITCH, True),
            "sha256": (client.host.cli.option.SWITCH, True),
            "days": (client.host.cli.option.VALUE, "365"),
            "newkey": (client.host.cli.option.VALUE, "rsa:2048"),
            "keyout": (client.host.cli.option.VALUE, key_pem),
            "out": (client.host.cli.option.VALUE, cert_pem),
            "subj": (client.host.cli.option.VALUE, "/CN=Pinpad Test Cert"),
        }
        client.host.conn.run(client.host.cli.command("openssl req", req_args))
        client.host.conn.run(f"chmod 600 {key_pem}", raise_on_error=False)

        x509_args: CLIBuilderArgs = {
            "in": (client.host.cli.option.VALUE, cert_pem),
            "outform": (client.host.cli.option.VALUE, "DER"),
            "out": (client.host.cli.option.VALUE, cert_der),
        }
        client.host.conn.run(client.host.cli.command("openssl x509", x509_args))

        rsa_args: CLIBuilderArgs = {
            "in": (client.host.cli.option.VALUE, key_pem),
            "outform": (client.host.cli.option.VALUE, "DER"),
            "out": (client.host.cli.option.VALUE, key_der),
        }
        client.host.conn.run(client.host.cli.command("openssl rsa", rsa_args))
        client.host.conn.run(f"chmod 600 {key_der}", raise_on_error=False)

        for obj_path, obj_type in [(key_der, "privkey"), (cert_der, "cert")]:
            args: CLIBuilderArgs = {
                "module": (client.host.cli.option.VALUE, OPENSC_MODULE),
                "login": (client.host.cli.option.SWITCH, True),
                "pin": (client.host.cli.option.VALUE, TOKEN_PIN),
                "write-object": (client.host.cli.option.VALUE, obj_path),
                "type": (client.host.cli.option.VALUE, obj_type),
                "id": (client.host.cli.option.VALUE, cert_id),
                "label": (client.host.cli.option.VALUE, username),
            }
            client.host.conn.run(client.host.cli.command("pkcs11-tool", args))

        ensure_pcscd_accessible(client)

        client.host.fs.rm("/etc/sssd/pki/sssd_auth_ca_db.pem")
        cert_data = client.host.fs.read(cert_pem)
        client.host.fs.append("/etc/sssd/pki/sssd_auth_ca_db.pem", cert_data)

        client.authselect.select("sssd", ["with-smartcard"])
        client.sssd.common.local()
        client.sssd.dom("local")["local_auth_policy"] = "only"
        client.sssd.section(f"certmap/local/{username}")["matchrule"] = (
            "<SUBJECT>.*CN=Pinpad Test Cert.*"
        )
        client.sssd.pam["pam_cert_auth"] = "True"
        client.sssd.pam["p11_child_timeout"] = "60"
        client.sssd.start(debug_level="0xFFF0", check_config=False)

        result = client.host.conn.run(
            f"su - {username} -c 'su - {username} -c whoami'",
            raise_on_error=False,
        )

        output = result.stdout + result.stderr
        assert "Use external keypad" in output, (
            f"Expected 'Use external keypad' prompt but got: "
            f"stdout={result.stdout!r}, stderr={result.stderr!r}"
        )
        assert result.rc == 0, (
            f"Authentication failed with rc={result.rc}, "
            f

@krishnavema
krishnavema force-pushed the pinpad-tests branch 2 times, most recently from 3d8ac0b to d0a8fd2 Compare June 1, 2026 03:55
@krishnavema
krishnavema requested a review from sumit-bose June 1, 2026 08:16
@krishnavema
krishnavema marked this pull request as ready for review June 1, 2026 08:16
@krishnavema
krishnavema marked this pull request as draft June 2, 2026 14:22
@krishnavema
krishnavema marked this pull request as ready for review June 4, 2026 13:19
@krishnavema

krishnavema commented Jun 5, 2026

Copy link
Copy Markdown
Contributor Author

Removed the cleanup_hw_card and enroll_to_hw_card methods that were corrupting the smart card on every run, and consolidated five redundant tests into a single local-user test that covers all SSSD pinpad
code paths — CKF_PROTECTED_AUTHENTICATION_PATH detection, PAM prompt format, and p11_child login — without ever writing to or cleaning the physical card

Test result:
tests/test_smartcard_pinpad.py::test_smartcard_pinpad__su_as_local_user (client) PASSED [100%]

Comment thread src/tests/system/tests/test_smartcard_pinpad.py Outdated
Comment thread src/tests/system/tests/test_smartcard_pinpad.py Outdated
@krishnavema
krishnavema requested a review from sumit-bose June 10, 2026 08:30
@alexey-tikhonov
alexey-tikhonov requested a review from spoore1 June 11, 2026 12:54
@alexey-tikhonov alexey-tikhonov added the no-backport This should go to target branch only. label Jun 11, 2026
Comment thread src/tests/system/tests/test_smartcard_pinpad.py Outdated
Comment thread src/tests/system/tests/test_smartcard_pinpad.py Outdated
Comment thread src/tests/system/tests/test_smartcard_pinpad.py Outdated
Comment thread src/tests/system/tests/test_smartcard_pinpad.py

@spoore1 spoore1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good. I have a few questions/suggestions in-line.

Comment thread src/tests/system/tests/test_smartcard_pinpad.py Outdated
Comment thread src/tests/system/tests/test_smartcard_pinpad.py Outdated
Comment thread src/tests/system/tests/test_smartcard_pinpad.py Outdated
Comment thread src/tests/system/tests/test_smartcard_pinpad.py

@sssd-bot sssd-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review done using Claude Code / claude-opus-4-6

Functional Issues

  1. su command may hang or time out without stdin input (test_smartcard_pinpad.py:207-210): The su command is invoked without an input= parameter, relying on the physical pinpad for PIN entry. In a CI environment where no human is pressing buttons on a hardware keypad, this command will block indefinitely waiting for PIN entry, eventually timing out. If these tests are intended for manual-only execution on a machine with a physical pinpad reader, this should be clearly documented with a marker or skip condition beyond detect_pinpad_reader(). If CI execution is intended, the test needs a mechanism to simulate pinpad entry or a timeout with a clear skip/failure message.

  2. detect_pinpad_reader uses result after the loop without guaranteed assignment (test_smartcard_pinpad.py:90-95): After the for attempt in range(2) loop, the code accesses result.stdout at line 91. If attempt == 0 succeeds (the break at line 78), result is correctly set. But the variable result is only assigned inside the loop body (line 73-76). If Python somehow skips the loop (e.g., range(2) were changed to range(0)), result would be unbound. While currently safe with range(2), the logic is fragile -- consider assigning result = None before the loop or restructuring to make the data flow clearer.

  3. chmod 666 on all USB devices is overly broad and not reverted (test_smartcard_pinpad.py:44): The _reset_usb_devices function sets world-read-write permissions on every USB device node (/dev/bus/usb/*/*). This is a security concern as flagged by reviewer spoore1 -- it grants any user on the system access to all USB devices (keyboards, storage, etc.), and the permissions are never restored. Even in a test environment, this could cause unexpected interactions. At minimum, save and restore the original permissions, or target only the specific smart card reader device.

  4. Package installation in test code (test_smartcard_pinpad.py:60): detect_pinpad_reader installs ccid via dnf install -y ccid at runtime. This was flagged by reviewer spoore1 -- tests should not install packages. Package dependencies should be declared in the CI container configuration (sssd-ci-containers packages role). If ccid is missing, the test should skip rather than attempt installation.

  5. No input= for su means authentication will fail for the outer su (test_smartcard_pinpad.py:207-209): The nested su - username -c 'su - username -c whoami' command requires authentication twice. The outer su needs the user's password/PIN, and the inner su also needs it. With a real pinpad reader, the user physically enters the PIN. But with no input= parameter, if su falls back to expecting stdin input for any reason (e.g., pinpad not detected by PAM), the command will hang. There should be a timeout on this conn.run call.

Nits & Non-functional Issues

  1. Hardcoded PAM log path instead of using framework accessor (test_smartcard_pinpad.py:230): The test reads the PAM log via client.fs.read("/var/log/sssd/sssd_pam.log"). Other tests in the codebase use the framework-provided client.sssd.logs.pam accessor (see test_passkey.py:521, test_ipa.py:384). Using the accessor is more robust against path changes.

  2. Missing @pytest.mark.builtwith marker (test_smartcard_pinpad.py:172-173): The existing test_smartcard.py tests that use KnownTopology.Client include @pytest.mark.builtwith(client="virtualsmartcard") (or a similar marker). This test lacks any builtwith marker. While pinpad tests may need a different marker (since they require real hardware rather than virtual smart cards), the absence should be intentional and documented. A custom marker or topology requirement would help the CI system skip these tests when no pinpad hardware is available.

  3. sed commands via raw conn.run instead of framework utilities (test_smartcard_pinpad.py:110-115): Reviewer spoore1 suggested using host.fs.sed() if available. The raw sed -i commands are functional but bypass the test framework's abstraction layer. Using framework utilities is preferred for consistency and better error handling.

  4. Temporary files in /tmp not cleaned up (test_smartcard_pinpad.py:127-128): The enroll_card() function writes a private key to /tmp/pinpad_test.key and a certificate to /tmp/pinpad_test.crt but never removes them. While the existing setup_local_card() in the framework has a similar pattern, explicitly cleaning up sensitive files (especially the private key) after use is good practice.

  5. Inconsistent use of client.host.fs vs client.fs (test_smartcard_pinpad.py:167-169 vs 230,237): In enroll_card(), the code uses client.host.fs.rm(), client.host.fs.read(), and client.host.fs.append(). In the test function, it uses client.fs.read(). While both may resolve to the same underlying filesystem, the inconsistency is confusing. The existing framework code in setup_local_card() uses client.host.fs.*, which suggests that should be the pattern in helper functions, while test functions commonly use client.fs.*.

  6. USB_RESET_SCRIPT bare except (test_smartcard_pinpad.py:32): The inline Python script uses a bare except: pass which silently swallows all exceptions including KeyboardInterrupt and SystemExit. While this is intentional (best-effort reset), using except Exception: pass would be more correct Python style.

  7. Single test case provides limited coverage (test_smartcard_pinpad.py:174): The file contains only one test (test_smartcard_pinpad__su_as_local_user). Consider adding negative test cases, such as: pinpad disabled (should fall back to keyboard PIN), wrong certificate on card, or testing with local_auth_policy set to values other than "only".

  8. client.sssd.dom("local")["local_auth_policy"] = "only" repeats setup already in common.local() (test_smartcard_pinpad.py:200-201): client.sssd.common.local() already configures the local domain with proxy provider. Then line 201 sets local_auth_policy. The existing setup_local_card() in the framework does the same pattern, so this is consistent but worth noting that the test largely reimplements setup_local_card() logic inline.

Review of Existing Review Comments

  • sumit-bose on token label (line 16): Addressed -- the token label was changed from "MyEID" to "SSSD Test Token" as suggested.

  • sumit-bose on token URI matching (line 42): Addressed -- detect_pinpad_reader now checks token_uri = f"token={TOKEN_LABEL.replace(' ', '%20')}" against the output (line 90-95), which is a more specific match than just checking for "token" in stdout.

  • sumit-bose on dropping ensure_pcscd_accessible (line 49): Addressed -- the function was removed and its checks are now done within detect_pinpad_reader() running as the sssd user via runuser -u sssd.

  • sumit-bose on make up-smartcard-pinpad (line 69): The comment asked about CI container support. The PR author acknowledged the oversight. This remains unresolved -- there is no corresponding sssd-ci-containers PR to provide the test infrastructure. The test will silently skip in CI via detect_pinpad_reader(), but the missing container support means the test is effectively untestable in CI.

  • sumit-bose on re-adding enable_pinpad method and cert enrollment (lines 64, 91): Partially addressed -- enroll_card() and enable_opensc_pinpad() functions are present in the current version. However, sumit-bose's suggestion to "assume that everything has to be setup before the test is run" has not been adopted -- the test still performs card enrollment and OpenSC configuration inline.

  • spoore1 on USB device permission changes (line 44): Not addressed -- chmod 666 /dev/bus/usb/*/* is still present without saving/restoring original permissions.

  • spoore1 on package installation (line 60): Not addressed -- dnf install -y ccid is still performed inline in the test code.

  • spoore1 on using host.fs.sed() (line 115): Not addressed -- raw sed commands via conn.run() are still used.

  • spoore1 on using client.auth.su.smartcard_with_output() (lines 207-210): Not directly applicable -- the existing smartcard_with_output() utility passes a PIN via input=, which defeats the purpose of testing pinpad authentication where no stdin PIN input should occur. However, the test could benefit from a new framework utility method for pinpad authentication to avoid raw conn.run calls.

  • gemini-code-assist on temp file permissions and cleanup (lines 134-161, 456-529): Not addressed -- private key files are still written to /tmp without restricted permissions and without cleanup.

  • spoore1's CHANGES_REQUESTED status: Multiple suggestions remain unaddressed.

@krishnavema
krishnavema force-pushed the pinpad-tests branch 2 times, most recently from 9cd42a5 to a5a6650 Compare June 18, 2026 17:55
@sumit-bose

Copy link
Copy Markdown
Contributor

Hi,

thank you for the updates, the test is working for me. May I ask how you make the Smartcard reader available in the SSSD-CI client container? It looks like you make the USB bus available. I just forward the PCSCD socket /run/pcscd/pcscd.comm but the test works the same for me although there are various error around thr USB reset and starting PCSCD.

I tend to ACK the patch. I'm just wondering, after seeing the Smartcard related variable declaration at the beginning of the file if e.g. TOKEN_LABEL, TOKEN_PIN and CERT_ID could be set via mhc.yaml as well with the values you are using as defaults? This would add some additional flexibility with respect to the used Smartcard. @krishnavema . @spoore1 what do you think about this? Imo this does not have to be part of this patch since the test has to run manually anyways.

bye,
Sumit

@krishnavema

Copy link
Copy Markdown
Contributor Author

Hi,

thank you for the updates, the test is working for me. May I ask how you make the Smartcard reader available in the SSSD-CI client container? It looks like you make the USB bus available. I just forward the PCSCD socket /run/pcscd/pcscd.comm but the test works the same for me although there are various error around thr USB reset and starting PCSCD.

I tend to ACK the patch. I'm just wondering, after seeing the Smartcard related variable declaration at the beginning of the file if e.g. TOKEN_LABEL, TOKEN_PIN and CERT_ID could be set via mhc.yaml as well with the values you are using as defaults? This would add some additional flexibility with respect to the used Smartcard. @krishnavema . @spoore1 what do you think about this? Imo this does not have to be part of this patch since the test has to run manually anyways.

bye, Sumit

I tried by mounting the USB bus directly into the container (/dev/bus/usb:/dev/bus/usb:rw) with cgroup device rules (c 189:* rmw) in yml, and run pcscd inside the container to communicate with the reader.

@spoore1 spoore1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like my comment/suggestion about using the auth.su.smartcard_with_output() was incorrect. sssd-bot report points out that it passes the PIN via keyboard not necessarily testing the keypad entry. I believe you should put back the original host.conn.run() that didn't pass the PIN. That is unless you are adding updates to sssd-test-framework as well. Besides that. LGTM.

Comment thread src/tests/system/tests/test_smartcard_pinpad.py Outdated
@spoore1

spoore1 commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Hi,
thank you for the updates, the test is working for me. May I ask how you make the Smartcard reader available in the SSSD-CI client container? It looks like you make the USB bus available. I just forward the PCSCD socket /run/pcscd/pcscd.comm but the test works the same for me although there are various error around thr USB reset and starting PCSCD.
I tend to ACK the patch. I'm just wondering, after seeing the Smartcard related variable declaration at the beginning of the file if e.g. TOKEN_LABEL, TOKEN_PIN and CERT_ID could be set via mhc.yaml as well with the values you are using as defaults? This would add some additional flexibility with respect to the used Smartcard. @krishnavema . @spoore1 what do you think about this? Imo this does not have to be part of this patch since the test has to run manually anyways.
bye, Sumit

I tried by mounting the USB bus directly into the container (/dev/bus/usb:/dev/bus/usb:rw) with cgroup device rules (c 189:* rmw) in yml, and run pcscd inside the container to communicate with the reader.

@sumit-bose @krishnavema
I like the idea of having the variables defined in the mhc.yaml file and reading them from there. It would allow different people to test easier. I do think we should consider updating this in a future PR.

@spoore1
spoore1 self-requested a review June 29, 2026 11:55

@spoore1 spoore1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have a device to test with but, it LGTM.

@sumit-bose

Copy link
Copy Markdown
Contributor

Hi,
thank you for the updates, the test is working for me. May I ask how you make the Smartcard reader available in the SSSD-CI client container? It looks like you make the USB bus available. I just forward the PCSCD socket /run/pcscd/pcscd.comm but the test works the same for me although there are various error around thr USB reset and starting PCSCD.
I tend to ACK the patch. I'm just wondering, after seeing the Smartcard related variable declaration at the beginning of the file if e.g. TOKEN_LABEL, TOKEN_PIN and CERT_ID could be set via mhc.yaml as well with the values you are using as defaults? This would add some additional flexibility with respect to the used Smartcard. @krishnavema . @spoore1 what do you think about this? Imo this does not have to be part of this patch since the test has to run manually anyways.
bye, Sumit

I tried by mounting the USB bus directly into the container (/dev/bus/usb:/dev/bus/usb:rw) with cgroup device rules (c 189:* rmw) in yml, and run pcscd inside the container to communicate with the reader.

@sumit-bose @krishnavema I like the idea of having the variables defined in the mhc.yaml file and reading them from there. It would allow different people to test easier. I do think we should consider updating this in a future PR.

Hi,

yes, I think this can be done in a later PR by using the current values as defaults.

bye,
Sumit

@sumit-bose

Copy link
Copy Markdown
Contributor

Hi,
thank you for the updates, the test is working for me. May I ask how you make the Smartcard reader available in the SSSD-CI client container? It looks like you make the USB bus available. I just forward the PCSCD socket /run/pcscd/pcscd.comm but the test works the same for me although there are various error around thr USB reset and starting PCSCD.
I tend to ACK the patch. I'm just wondering, after seeing the Smartcard related variable declaration at the beginning of the file if e.g. TOKEN_LABEL, TOKEN_PIN and CERT_ID could be set via mhc.yaml as well with the values you are using as defaults? This would add some additional flexibility with respect to the used Smartcard. @krishnavema . @spoore1 what do you think about this? Imo this does not have to be part of this patch since the test has to run manually anyways.
bye, Sumit

I tried by mounting the USB bus directly into the container (/dev/bus/usb:/dev/bus/usb:rw) with cgroup device rules (c 189:* rmw) in yml, and run pcscd inside the container to communicate with the reader.

Hi,

ok, I tested with the variant as well and it is working as expected.

bye,
Sumit

@sumit-bose sumit-bose left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi,

thank you for the test and all the updates, ACK.

bye,
Sumit

@sumit-bose

Copy link
Copy Markdown
Contributor

Hi,

I think the CI failures are all known issues, setting 'Accepted'.

bye,
Sumit

…ENTICATION_PATH (hardware pinpad) support

Reviewed-by: Scott Poore <spoore@redhat.com>
Reviewed-by: Sumit Bose <sbose@redhat.com>
@sssd-bot

Copy link
Copy Markdown
Contributor

The pull request was accepted by @sumit-bose with the following PR CI status:


🟢 CodeQL (success)
🟢 osh-diff-scan:fedora-rawhide-x86_64:upstream (success)
🟢 rpm-build:centos-stream-10-x86_64:upstream (success)
🟢 rpm-build:fedora-43-x86_64:upstream (success)
🟢 rpm-build:fedora-44-x86_64:upstream (success)
🟢 rpm-build:fedora-rawhide-x86_64:upstream (success)
🟢 testing-farm:fedora-43-x86_64:upstream (success)
🟢 testing-farm:fedora-44-x86_64:centos-stream-10 (success)
🔴 testing-farm:fedora-44-x86_64:upstream (failure)
🔴 testing-farm:fedora-rawhide-x86_64:upstream (failure)
🟢 Analyze (target) / cppcheck (success)
🟢 ci / intgcheck (centos-10) (success)
🟢 ci / intgcheck (fedora-43) (success)
🟢 ci / intgcheck (fedora-44) (success)
🔴 ci / intgcheck (fedora-45) (failure)
🟢 ci / prepare (success)
🔴 ci / system (centos-10) (failure)
🟢 ci / system (fedora-43) (success)
🔴 ci / system (fedora-44) (failure)
🔴 ci / system (fedora-45) (failure)
➖ Coverity scan / coverity (skipped)
🟢 Static code analysis / codeql (success)
🟢 Static code analysis / pre-commit (success)
🟢 Static code analysis / python-system-tests (success)


There are unsuccessful or unfinished checks. Make sure that the failures are not related to this pull request before merging.

@sumit-bose
sumit-bose merged commit 11817a6 into SSSD:master Jul 6, 2026
17 of 18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Accepted no-backport This should go to target branch only.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants