-
Notifications
You must be signed in to change notification settings - Fork 279
Smartcard multi token tests #8519
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
krishnavema
wants to merge
2
commits into
SSSD:master
Choose a base branch
from
krishnavema:smartcard-multi-token-tests
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+161
−1
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,8 +8,78 @@ | |
|
|
||
| import pytest | ||
| from sssd_test_framework.roles.client import Client | ||
| from sssd_test_framework.roles.ipa import IPA | ||
| from sssd_test_framework.topology import KnownTopology | ||
|
|
||
| TOKEN1_LABEL = "SC_Token_1" | ||
| TOKEN2_LABEL = "SC_Token_2" | ||
| TOKEN_PIN = "123456" | ||
|
Comment on lines
+14
to
+16
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To improve readability and maintainability of the polling loop in TOKEN1_LABEL = "SC_Token_1"
TOKEN2_LABEL = "SC_Token_2"
TOKEN_PIN = "123456"
# Constants for the user resolvability polling loop
USER_RESOLVABLE_ATTEMPTS = 15
USER_RESOLVABLE_INTERVAL_S = 2
USER_RESOLVABLE_CACHE_EXPIRY_ATTEMPT = 3 |
||
|
|
||
|
|
||
| def enroll_to_token( | ||
| client: Client, | ||
| ipa: IPA, | ||
| username: str, | ||
| *, | ||
| token_label: str, | ||
| cert_id: str = "01", | ||
| pin: str = TOKEN_PIN, | ||
| ) -> None: | ||
| """ | ||
| Request an IPA-signed certificate for *username* and store it on *token_label*. | ||
|
|
||
| :param client: Client role object. | ||
| :type client: Client | ||
| :param ipa: IPA role object whose CA issues the certificate. | ||
| :type ipa: IPA | ||
| :param username: IPA principal to issue the certificate for. | ||
| :type username: str | ||
| :param token_label: SoftHSM token label to write the objects to. | ||
| :type token_label: str | ||
| :param cert_id: PKCS#11 object ID, defaults to "01". | ||
| :type cert_id: str, optional | ||
| :param pin: User PIN for the token, defaults to TOKEN_PIN. | ||
| :type pin: str, optional | ||
| """ | ||
| cert, key, _ = ipa.ca.request(username) | ||
| cert_content = ipa.fs.read(cert) | ||
| key_content = ipa.fs.read(key) | ||
|
|
||
| cert_path = f"/opt/test_ca/{username}_{token_label}.crt" | ||
| key_path = f"/opt/test_ca/{username}_{token_label}.key" | ||
|
|
||
| client.fs.write(cert_path, cert_content) | ||
| client.fs.write(key_path, key_content) | ||
|
|
||
| client.smartcard.add_key(key_path, key_id=cert_id, pin=pin, token_label=token_label, label=username) | ||
| client.smartcard.add_cert(cert_path, cert_id=cert_id, pin=pin, token_label=token_label, label=username) | ||
|
|
||
|
|
||
| def setup_two_tokens( | ||
| client: Client, | ||
| ipa: IPA, | ||
| *, | ||
| token1_username: str, | ||
| token2_username: str, | ||
| ) -> None: | ||
| """ | ||
| Create two SoftHSM tokens, each holding an IPA-signed certificate. | ||
|
|
||
| :param client: Client role object. | ||
| :type client: Client | ||
| :param ipa: IPA role object. | ||
| :type ipa: IPA | ||
| :param token1_username: IPA user whose cert goes onto token 1. | ||
| :type token1_username: str | ||
| :param token2_username: IPA user whose cert goes onto token 2. | ||
| :type token2_username: str | ||
| """ | ||
| client.smartcard.initialize_card(label=TOKEN1_LABEL, user_pin=TOKEN_PIN) | ||
| enroll_to_token(client, ipa, token1_username, token_label=TOKEN1_LABEL) | ||
|
|
||
| client.smartcard.initialize_card(label=TOKEN2_LABEL, user_pin=TOKEN_PIN, reset=False) | ||
| enroll_to_token(client, ipa, token2_username, token_label=TOKEN2_LABEL) | ||
|
|
||
|
|
||
| @pytest.mark.importance("critical") | ||
| @pytest.mark.topology(KnownTopology.Client) | ||
|
|
@@ -30,3 +100,93 @@ def test_smartcard__su_as_local_user(client: Client): | |
| result = client.host.conn.run("su - localuser1 -c 'su - localuser1 -c whoami'", input="123456") | ||
| assert "PIN" in result.stderr, "String 'PIN' was not found in stderr!" | ||
| assert "localuser1" in result.stdout, "'localuser1' not found in 'whoami' output!" | ||
|
|
||
|
|
||
| @pytest.mark.importance("critical") | ||
| @pytest.mark.topology(KnownTopology.IPA) | ||
| @pytest.mark.builtwith(client="virtualsmartcard") | ||
| def test_smartcard__two_tokens_match_on_first(client: Client, ipa: IPA): | ||
| """ | ||
| :title: Two smart cards – valid certificate on the first token | ||
| :setup: | ||
| 1. Create IPA user and a decoy IPA user | ||
| 2. Initialize two SoftHSM tokens (simulating two smart cards) | ||
| 3. Place the target user's IPA certificate on token 1 | ||
| 4. Place the decoy user's IPA certificate on token 2 | ||
| 5. Configure SSSD for smart card authentication and start services | ||
| :steps: | ||
| 1. Authenticate as the target IPA user via nested ``su`` with the | ||
| smart card PIN | ||
| :expectedresults: | ||
| 1. SSSD's ``p11_child`` finds valid certificates on both tokens, | ||
| SSSD maps the token-1 certificate to the target user, prompts | ||
| for PIN, and authentication succeeds | ||
| :customerscenario: True | ||
| """ | ||
| username = "scuser_t1" | ||
| decoy = "scdecoy_t1" | ||
| ipa.user(username).add() | ||
| ipa.user(decoy).add() | ||
|
|
||
| setup_two_tokens(client, ipa, token1_username=username, token2_username=decoy) | ||
| client.sssd.common.smartcard_with_softhsm(client.smartcard) | ||
| assert client.auth.su.smartcard_with_su(username, TOKEN_PIN) | ||
|
|
||
|
|
||
| @pytest.mark.importance("critical") | ||
| @pytest.mark.topology(KnownTopology.IPA) | ||
| @pytest.mark.builtwith(client="virtualsmartcard") | ||
| def test_smartcard__two_tokens_match_on_second(client: Client, ipa: IPA): | ||
| """ | ||
| :title: Two smart cards – valid certificate only on the second token | ||
| :setup: | ||
| 1. Create IPA user and a decoy IPA user | ||
| 2. Initialize two SoftHSM tokens (simulating two smart cards) | ||
| 3. Place the decoy user's IPA certificate on token 1 | ||
| 4. Place the target user's IPA certificate on token 2 | ||
| 5. Configure SSSD for smart card authentication and start services | ||
| :steps: | ||
| 1. Authenticate as the target IPA user via nested ``su`` with the | ||
| smart card PIN | ||
| :expectedresults: | ||
| 1. SSSD's ``p11_child`` does **not** stop at token 1 (whose cert | ||
| maps to the decoy user); it continues to token 2, finds the | ||
| certificate that maps to the target user, prompts for PIN, and | ||
| authentication succeeds | ||
| :customerscenario: True | ||
| """ | ||
| username = "scuser_t2" | ||
| decoy = "scdecoy_t2" | ||
| ipa.user(username).add() | ||
| ipa.user(decoy).add() | ||
|
|
||
| setup_two_tokens(client, ipa, token1_username=decoy, token2_username=username) | ||
| client.sssd.common.smartcard_with_softhsm(client.smartcard) | ||
| assert client.auth.su.smartcard_with_su(username, TOKEN_PIN) | ||
|
|
||
|
|
||
| @pytest.mark.importance("critical") | ||
| @pytest.mark.topology(KnownTopology.IPA) | ||
| @pytest.mark.builtwith(client="virtualsmartcard") | ||
| def test_smartcard__two_tokens_match_on_both(client: Client, ipa: IPA): | ||
| """ | ||
| :title: Two smart cards – valid certificate on both tokens | ||
| :setup: | ||
| 1. Create IPA user | ||
| 2. Initialize two SoftHSM tokens (simulating two smart cards) | ||
| 3. Place a valid IPA certificate for the same user on both tokens | ||
| 4. Configure SSSD for smart card authentication and start services | ||
| :steps: | ||
| 1. Authenticate as the IPA user via nested ``su`` with the PIN of | ||
| the first token | ||
| :expectedresults: | ||
| 1. SSSD's ``p11_child`` finds valid certificates on both tokens and | ||
| authentication succeeds regardless of which token is tried first | ||
| :customerscenario: True | ||
| """ | ||
| username = "scuser_both" | ||
| ipa.user(username).add() | ||
|
|
||
| setup_two_tokens(client, ipa, token1_username=username, token2_username=username) | ||
| client.sssd.common.smartcard_with_softhsm(client.smartcard) | ||
| assert client.auth.su.smartcard_with_su(username, TOKEN_PIN, num_certs=2) | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change introduces a dependency on a personal fork (
krishnavema/sssd-test-framework). While this might be acceptable for development, it poses a security and maintenance risk for the main branch. The changes from this fork should be merged into the upstreamSSSD/sssd-test-frameworkrepository, and the dependency should point to an official release or commit from the upstream repository before this pull request is merged.