-
Notifications
You must be signed in to change notification settings - Fork 20
Test: changes for krb_misc #240
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -163,21 +163,38 @@ def __init__(self, role: KDC, name: str) -> None: | |
| self.name: str = name | ||
| """Principal name.""" | ||
|
|
||
| def add(self, *, password: str | None = "Secret123") -> KDCPrincipal: | ||
| def add( | ||
| self, | ||
| *, | ||
| password: str | None = "Secret123", | ||
| requires_preauth: bool = False, | ||
| extra_options: str | None = None, | ||
| ) -> KDCPrincipal: | ||
| """ | ||
| Add a new Kerberos principal. | ||
|
|
||
| Random password is generated if ``password`` is ``None``. | ||
|
|
||
| :param password: Principal's password, defaults to 'Secret123' | ||
| :type password: str | None | ||
| :param requires_preauth: Add +requires_preauth flag (for clock skew tests), defaults to False | ||
| :type requires_preauth: bool, optional | ||
| :param extra_options: Extra addprinc options (e.g. '+nokey'), defaults to None | ||
| :type extra_options: str | None, optional | ||
| :return: Self. | ||
| :rtype: KDCPrincipal | ||
| """ | ||
| opts: list[str] = [] | ||
| if requires_preauth: | ||
| opts.append("+requires_preauth") | ||
| if extra_options: | ||
| opts.append(extra_options) | ||
| opts_str = " " + " ".join(opts) if opts else "" | ||
|
Contributor
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. Nitpick, I find this strange, for the leading space? I think it's more readable, add a space in the command on line 195,
Contributor
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. +1 |
||
|
|
||
| if password is not None: | ||
| self.role.kadmin(f'addprinc -pw "{password}" "{self.name}"') | ||
| self.role.kadmin(f'addprinc -pw "{password}"{opts_str} "{self.name}"') | ||
| else: | ||
| self.role.kadmin(f'addprinc -randkey "{self.name}"') | ||
| self.role.kadmin(f'addprinc -randkey{opts_str} "{self.name}"') | ||
|
|
||
| return self | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1597,3 +1597,55 @@ def password(self, user: str, password: str, new_password: str, retyped: str | N | |
| raise ExpectScriptError(result.rc) | ||
|
|
||
| return result.rc == 0 | ||
|
|
||
|
Contributor
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. Why is it important that this is done via SSH? |
||
| def password_via_ssh( | ||
| self, | ||
| user: str, | ||
| password: str, | ||
| new_password: str, | ||
| retyped: str | None = None, | ||
| *, | ||
| host: str = "localhost", | ||
| raise_on_error: bool = True, | ||
| ) -> bool: | ||
| """ | ||
| Change password via SSH session (port of sssd-qe expect script). | ||
|
|
||
| SSHs as user, runs passwd interactively, and changes password. | ||
| Used when testing krb5_child "Initial authentication for change password". | ||
|
|
||
| :param user: Username. | ||
| :param password: Current password. | ||
| :param new_password: New password. | ||
| :param retyped: Retyped new password (defaults to new_password). | ||
| :param host: SSH target host, defaults to "localhost". | ||
| :param raise_on_error: Raise ExpectScriptError on failure. | ||
| :return: True if password change succeeded. | ||
| """ | ||
| if retyped is None: | ||
| retyped = new_password | ||
|
|
||
| result = self.host.conn.expect( | ||
| rf""" | ||
| set timeout {DEFAULT_AUTHENTICATION_TIMEOUT} | ||
| spawn ssh -o StrictHostKeyChecking=no -l {user} {host} | ||
| expect -nocase "*password:" | ||
| send "{password}\r" | ||
| send "passwd\r" | ||
| expect -nocase "*Current Password:" | ||
| send "{password}\r" | ||
| expect -nocase "New password:" | ||
| send "{new_password}\r" | ||
| expect -nocase "Retype new password:" | ||
| send "{retyped}\r" | ||
| expect -re "passwd: .+ updated successfully" | ||
| send "exit\r" | ||
| expect eof | ||
|
Comment on lines
+1630
to
+1643
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. Using a fixed set timeout {DEFAULT_AUTHENTICATION_TIMEOUT}
set prompt "\n.*\[#\$>\] $"
spawn ssh -o StrictHostKeyChecking=no -l {user} {host}
expect -nocase "*password:"
send "{password}\r"
expect -re $prompt
send "passwd\r"
expect -nocase "*Current Password:"
send "{password}\r"
expect -nocase "New password:"
send "{new_password}\r"
expect -nocase "Retype new password:"
send "{retyped}\r"
expect -re "passwd: .+ updated successfully"
send "exit\r"
expect eof |
||
| """, | ||
| raise_on_error=raise_on_error, | ||
| ) | ||
|
|
||
| if raise_on_error and result.rc > 200: | ||
| raise ExpectScriptError(result.rc) | ||
|
|
||
| return result.rc == 0 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,95 @@ | ||
| """Kerberos and keytab utilities.""" | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| from pytest_mh import MultihostHost, MultihostUtility | ||
| from pytest_mh.conn import ProcessResult | ||
|
|
||
| __all__ = [ | ||
| "Krb5KeytabUtils", | ||
| ] | ||
|
|
||
|
|
||
| class Krb5KeytabUtils(MultihostUtility[MultihostHost]): | ||
| """ | ||
| Keytab manipulation via ktutil (expect-based). | ||
|
|
||
| Port of expect scripts from sssd-qe client/krb_provider/krb_misc_bugzilla. | ||
| """ | ||
|
|
||
| def ktutil_create_mixed_keytab( | ||
| self, | ||
| wrong_principal: str, | ||
| valid_keytab: str, | ||
| output_keytab: str, | ||
| password: str = "Secret123", | ||
| *, | ||
| raise_on_error: bool = True, | ||
| ) -> ProcessResult: | ||
| """ | ||
| Create keytab with wrong principal first, then entries from valid keytab. | ||
|
|
||
| BZ 805281: Uses ktutil to add a password-based entry (wrong realm) first, | ||
| then merge with an existing keytab. Tests that SSSD selects the correct | ||
| principal when multiple realms exist in one keytab. | ||
|
|
||
| :param wrong_principal: Principal to add first (e.g. nfs/host@TEST.EXAMPLE.COM) | ||
| :param valid_keytab: Path to keytab with correct principal | ||
| :param output_keytab: Path for the combined keytab output | ||
| :param password: Password for addent -password, defaults to "Secret123" | ||
| :param raise_on_error: Raise on failure, defaults to True | ||
| :return: Process result from expect | ||
| """ | ||
| return self.host.conn.expect( | ||
| f""" | ||
| spawn ktutil | ||
| expect "ktutil: " | ||
| send "addent -password -p {wrong_principal} -k 3 -e rc4-hmac\\r" | ||
| expect "Password: *" | ||
| send "{password}\\r" | ||
| send "rkt {valid_keytab}\\r" | ||
| send "wkt {output_keytab}\\r" | ||
| expect eof | ||
| """, | ||
| raise_on_error=raise_on_error, | ||
| ) | ||
|
|
||
| def ktutil_create_keytab( | ||
| self, | ||
| principal: str, | ||
| output_keytab: str, | ||
| password: str = "Secret123", | ||
| enctype: str = "aes256-cts-hmac-sha1-96", | ||
| kvno: int = 1, | ||
| *, | ||
| raise_on_error: bool = True, | ||
| ) -> ProcessResult: | ||
| """ | ||
| Create keytab with single password-based entry (BZ 1198478). | ||
|
|
||
| Uses ktutil to add a principal with password and write to keytab file. | ||
| Useful for dummy keytabs (principal in keytab but not on KDC). | ||
|
|
||
| :param principal: Principal name (e.g. bla@EXAMPLE.COM) | ||
| :param output_keytab: Path for the keytab output | ||
| :param password: Password for addent -password, defaults to "Secret123" | ||
| :param enctype: Encryption type (default: aes256-cts-hmac-sha1-96) | ||
| :param kvno: Key version number, defaults to 1 | ||
| :param raise_on_error: Raise on failure, defaults to True | ||
| :return: Process result from expect | ||
| """ | ||
| return self.host.conn.expect( | ||
| f""" | ||
| spawn ktutil | ||
| expect "ktutil: " | ||
| send "addent -password -p {principal} -k {kvno} -e {enctype}\\r" | ||
| expect "Password: *" | ||
| send "{password}\\r" | ||
| expect "ktutil: " | ||
| send "wkt {output_keytab}\\r" | ||
| expect "ktutil: " | ||
| send "q\\r" | ||
| expect eof | ||
| """, | ||
| raise_on_error=raise_on_error, | ||
| ) |
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.
nitpick, we use
argseverywhere else. I would just use the same variable name.