sssd_test_framework.utils.authentication

Testing authentications and authorization mechanisms.

Module Attributes

DEFAULT_AUTHENTICATION_TIMEOUT

Default timeout for authentication failure.

Classes

AuthenticationUtils(*args, **kwargs)

Methods for testing various authentication and authorization mechanisms.

KerberosAuthenticationUtils(*args, **kwargs)

Methods for testing Kerberos authentication and KCM.

PasskeyAuthenticationUseCases(value)

Authentication methods for passkey authentication.

PasswdUtils(*args, **kwargs)

Change authentication tokens with passwd tool.

SSHAuthenticationUtils(*args, **kwargs)

Methods for testing authentication and authorization via ssh.

SSHPasswdUtils(*args, **kwargs)

Change password via SSH session using passwd command.

SUAuthenticationUtils(*args, **kwargs)

Methods for testing authentication and authorization via su.

SudoAuthenticationUtils(*args, **kwargs)

Methods for testing authentication and authorization via sudo.

class sssd_test_framework.utils.authentication.AuthenticationUtils(*args, **kwargs)

Bases: MultihostUtility[MultihostHost]

Methods for testing various authentication and authorization mechanisms.

It executes commands on remote host in order to test authentication and authorization via su, ssh, sudo and kerberos.

Note

Since the authentication via su and ssh command can be mostly done via the same mechanisms (like password or two-factor authentication), it implements the same API. Therefore you can test su and ssh in the same test case through parametrization.

Example
@pytest.mark.topology(KnownTopologyGroup.AnyProvider)
@pytest.mark.parametrize('method', ['su', 'ssh'])
def test_example(client: Client, provider: GenericProvider, method: str):
    ldap.user('tuser').add(password='Secret123')

    client.sssd.start()
    assert client.auth.parametrize(method).password('tuser', 'Secret123')
Parameters:
  • host (MultihostHost) – Remote host.

  • fs (LinuxFileSystem) – File system utils.

su: SUAuthenticationUtils

Test authentication and authorization via su.

Example usage
@pytest.mark.topology(KnownTopology.LDAP)
def test_example(client: Client, ldap: LDAP):
    ldap.user('tuser').add(password='Secret123')

    client.sssd.start()
    assert client.auth.su.password('tuser', 'Secret123')
sudo: SudoAuthenticationUtils

Test authentication and authorization via sudo.

Example usage
@pytest.mark.topology(KnownTopology.LDAP)
def test_example(client: Client, ldap: LDAP):
    u = ldap.user('tuser').add(password='Secret123')
    ldap.sudorule('allow_ls').add(user=u, host='ALL', command='/bin/ls')

    client.sssd.common.sudo()
    client.sssd.start()

    assert client.auth.sudo.list('tuser', 'Secret123', expected=['(root) /bin/ls'])
    assert client.auth.sudo.run('tuser', 'Secret123', command='/bin/ls /root')
ssh: SSHAuthenticationUtils

Test authentication and authorization via ssh.

Example usage
@pytest.mark.topology(KnownTopology.LDAP)
def test_example(client: Client, ldap: LDAP):
    ldap.user('tuser').add(password='Secret123')

    client.sssd.start()
    assert client.auth.ssh.password('tuser', 'Secret123')
passwd: PasswdUtils

Change authentication tokens with passwd tool

Example usage
@pytest.mark.topology(KnownTopology.LDAP)
def test_example(client: Client, ldap: LDAP):
    ldap.user('tuser').add(password='Secret123')
    # Change the ACI record so that users can change their password
    ldap.aci.add(
        '(targetattr="userpassword")(version 3.0; acl "pwp test"; allow (all) userdn="ldap:///self";)'
    )

    client.sssd.start()
    assert client.auth.passwd.password('tuser', 'Secret123', 'New_password123')
idp: IdpAuthenticationUtils

Authenticate to External Identity Providers

parametrize(method: str) SUAuthenticationUtils | SSHAuthenticationUtils

Return authentication tool based on the method. The method can be either su or ssh.

Parameters:

method (str) – su or ssh

Raises:

ValueError – If invalid method is specified.

Returns:

Authentication tool.

Return type:

HostSU | HostSSH

kerberos(ssh: Connection | None = None) KerberosAuthenticationUtils

Test authentication and authorization via Kerberos.

Example usage
@pytest.mark.topology(KnownTopology.LDAP)
def test_example(client: Client, ldap: LDAP, kdc: KDC):
    ldap.user('tuser').add()
    kdc.principal('tuser').add()

    client.sssd.common.krb5_auth(kdc)
    client.sssd.start()

    with client.ssh('tuser', 'Secret123') as ssh:
        with client.auth.kerberos(ssh) as krb:
            assert krb.has_tgt(kdc.realm)
Parameters:

ssh (Connection) – SSH connection for the target user.

Returns:

Kerberos authentication object.

Return type:

KerberosAuthenticationUtils

class sssd_test_framework.utils.authentication.KerberosAuthenticationUtils(*args, **kwargs)

Bases: MultihostUtility[MultihostHost]

Methods for testing Kerberos authentication and KCM.

Parameters:
  • host (MultihostHost) – Multihost host.

  • ssh (Connection | None, optional) – SSH client for the target user, defaults to None

conn: Connection

SSH client for the target user.

kinit(principal: str, *, password: str, realm: str | None = None, args: list[str] | None = None) ProcessResult

Run kinit command.

Principal can be without the realm part. The realm can be given in separate parameter realm, in such case the principal name is constructed as $principal@$realm. If the principal does not contain realm specification and realm parameter is not set then the default realm is used.

Parameters:
  • principal (str) – Kerberos principal.

  • password (str) – Principal’s password.

  • realm (str | None, optional) – Kerberos realm that is appended to the principal ($principal@$realm), defaults to None

  • args (list[str] | None, optional) – Additional parameters to klist, defaults to None

Returns:

Command result.

Return type:

ProcessResult

kvno(principal: str, *, realm: str | None = None, args: list[str] | None = None) ProcessResult

Run kvno command.

Principal can be without the realm part. The realm can be given in separate parameter realm, in such case the principal name is constructed as $principal@$realm. If the principal does not contain realm specification and realm parameter is not set then the default realm is used.

Parameters:
  • principal (str) – Kerberos principal.

  • realm (str | None, optional) – Kerberos realm that is appended to the principal ($principal@$realm), defaults to None

  • args (list[str] | None, optional) – Additional parameters to klist, defaults to None

Returns:

Command result.

Return type:

ProcessResult

klist(*, args: list[str] | None = None) ProcessResult

Run klist command.

Parameters:

args (list[str] | None, optional) – Additional parameters to klist, defaults to None

Returns:

Command result.

Return type:

ProcessResult

kswitch(principal: str, realm: str) ProcessResult

Run kswitch -p principal@realm command.

Parameters:
  • principal (str) – Kerberos principal.

  • realm (str) – Kerberos realm that is appended to the principal ($principal@$realm)

Returns:

Command result.

Return type:

ProcessResult

kdestroy(*, all: bool = False, ccache: str | None = None, principal: str | None = None, realm: str | None = None) ProcessResult

Run kdestroy command.

Principal can be without the realm part. The realm can be given in separate parameter realm, in such case the principal name is constructed as $principal@$realm. If the principal does not contain realm specification and realm parameter is not set then the default realm is used.

Parameters:
  • all (bool, optional) – Destroy all ccaches (kdestroy -A), defaults to False

  • ccache (str | None, optional) – Destroy specific ccache (kdestroy -c $cache), defaults to None

  • principal (str | None, optional) – Destroy ccache for given principal (kdestroy -p $princ), defaults to None

  • realm (str | None, optional) – Kerberos realm that is appended to the principal ($principal@$realm), defaults to None

Returns:

Command result.

Return type:

ProcessResult

has_tgt(principal: str | None, realm: str) bool

Check that the user has obtained Kerberos Ticket Granting Ticket for given principle. If principal is None then primary principal is checked.

Parameters:
  • principal (str | None) – Expected principal for which the TGT was obtained (without the realm part).

  • realm (str) – Expected realm for which the TGT was obtained.

Returns:

True if TGT is available, False otherwise.

Return type:

bool

user_has_tgt(username: str, realm: str) bool

Check that the specified user has obtained Kerberos Ticket Granting Ticket for itself. This is for use cases where SSH cannot be used to check for the ticket like with users that authenticate through Identity Providers via other means than SSH such as GDM logins.

Parameters:
  • username (str) – User to check for TGT default principal.

  • realm (str) – Expected realm for which the TGT was obtained.

Returns:

True if TGT is available, False otherwise.

Return type:

bool

has_primary_cache(principal: str, realm: str) bool

Check that the ccache for given principal is the primary one.

Parameters:
  • principal (str) – Kerberos principal.

  • realm (str) – Kerberos realm that is appended to the principal ($principal@$realm)

Returns:

True if the ccache for given principal is the primary one.

Return type:

bool

has_tickets(principal: str, realm: str, expected: list[str]) bool

Check that the ccache contains all tickets from expected and nothing more.

Parameters:
  • principal (str) – Kerberos principal.

  • realm (str) – Kerberos realm that is appended to the principal ($principal@$realm)

  • expected (list[str]) – List of tickets that must be present in the ccache.

Returns:

True if the ccache contains exactly expected tickets.

Return type:

bool

cache_count() int

Return number of existing credential caches (or number of principals) for active user (klist -l).

Returns:

Number of existing ccaches.

Return type:

int

list_principals(env: dict[str, Any] | None = None) dict[str, list[str]]

List all principals that have existing credential cache.

Parameters:

env (dict[str, Any] | None, optional) – Additional environment variables passed to klist -A command, defaults to None

Returns:

Dictionary with principal as the key and list of available tickets as value.

Return type:

dict[str, list[str]]

list_ccaches() dict[str, str]

List all available ccaches.

Returns:

Dictionary with principal as the key and ccache name as value.

Return type:

dict[str, str]

list_tgt_times(realm: str) tuple[datetime, datetime]

Return start and expiration time of primary ccache TGT.

Parameters:

realm (str) – Expected realm for which the TGT was obtained.

Returns:

(start time, expiration time) of the TGT

Return type:

tuple[int, int]

ktutil_create_mixed_keytab(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.

Parameters:
  • wrong_principal – Principal to add first (e.g. nfs/host@TEST.EXAMPLE.COM)

  • valid_keytab – Path to keytab with correct principal

  • output_keytab – Path for the combined keytab output

  • password – Password for addent -password, defaults to “Secret123”

  • raise_on_error – Raise on failure, defaults to True

Returns:

Process result from expect

ktutil_create_keytab(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).

Parameters:
  • principal – Principal name (e.g. bla@EXAMPLE.COM)

  • output_keytab – Path for the keytab output

  • password – Password for addent -password, defaults to “Secret123”

  • enctype – Encryption type (default: aes256-cts-hmac-sha1-96)

  • kvno – Key version number, defaults to 1

  • raise_on_error – Raise on failure, defaults to True

Returns:

Process result from expect

class sssd_test_framework.utils.authentication.SSHAuthenticationUtils(*args, **kwargs)

Bases: MultihostUtility[MultihostHost]

Methods for testing authentication and authorization via ssh.

Parameters:

host (MultihostHost) – Multihost host.

opts

SSH CLI options.

passwd: SSHPasswdUtils

Change password via SSH session using passwd command.

password_with_output(username: str, password: str, hostname: str = 'localhost') tuple[int, int, str, str]

SSH to the remote host and authenticate the user with password and captures standard output and error.

Parameters:
  • username (str) – Username.

  • password (str) – User password.

  • hostname (str) – The hostname to connect to.

Returns:

Tuple containing [except return code, command exit code, stdout, stderr].

Return type:

Tuple[int, int, str, str]

password(username: str, password: str, hostname: str = 'localhost') bool

SSH to the remote host and authenticate the user with password.

Parameters:
  • username (str) – Username.

  • password (str) – User password.

  • hostname (str) – The hostname to connect to.

Returns:

True if authentication was successful, False otherwise.

Return type:

bool

password_expired_with_output(username: str, password: str, new_password: str, hostname: str = 'localhost') tuple[int, int, str, str]

SSH to the remote host and authenticate the user with password, expect that the password is expired and change it to the new password and captures standard output and error.

Parameters:
  • username (str) – Username.

  • password (str) – Old, expired user password.

  • new_password (str) – New user password.

  • hostname (str) – The hostname to connect to.

Returns:

Tuple containing [except return code, command exit code, stdout, stderr].

Return type:

Tuple[int, int, str, str]

password_expired(username: str, password: str, new_password: str, hostname: str = 'localhost') bool

SSH to the remote host and authenticate the user with password, expect that the password is expired and change it to the new password.

Parameters:
  • username (str) – Username.

  • password (str) – Old, expired user password.

  • new_password (str) – New user password.

  • hostname (str) – The hostname to connect to.

Returns:

True if authentication and password change was successful, False otherwise.

Return type:

bool

class sssd_test_framework.utils.authentication.SUAuthenticationUtils(*args, **kwargs)

Bases: MultihostUtility[MultihostHost]

Methods for testing authentication and authorization via su.

Parameters:
  • host (MultihostHost) – Multihost host.

  • fs (LinuxFileSystem.) – Linux File system.

fs: LinuxFileSystem
password_with_output(username: str, password: str) tuple[int, int, str, str]

Call su - $username and authenticate the user with password and captures standard output and error.

Parameters:
  • username (str) – Username.

  • password (str) – User password.

Returns:

Tuple containing [return code, command code, stdout, stderr].

Return type:

Tuple[int, int, str, str]

password(username: str, password: str) bool

SSH to the remote host and authenticate the user with password.

Parameters:
  • username (str) – Username.

  • password (str) – User password.

Returns:

True if authentication was successful, False otherwise.

Return type:

bool

password_expired_with_output(username: str, password: str, new_password: str) tuple[int, int, str, str]

Call su - $username and authenticate the user with password, expect that the password is expired and change it to the new password and captures standard output and error.

Parameters:
  • username (str) – Username.

  • password (str) – Old, expired user password.

  • new_password (str) – New user password.

Returns:

Tuple containing [return code, command code, stdout, stderr].

Return type:

Tuple[int, int, str, str]

password_expired(username: str, password: str, new_password: str) bool

Call su - $username and authenticate the user with password, expect that the password is expired and change it to the new password.

Parameters:
  • username (str) – Username.

  • password (str) – Old, expired user password.

  • new_password (str) – New user password.

Returns:

True if password change is successful.

Return type:

bool

passkey_with_output(**kwargs) tuple[int, int, str, str]

wrapper for passkey_with_output methods

passkey(**kwargs) bool

wrapper for passkey methods

umockdev_passkey_with_output(*, username: str, device: str, ioctl: str, script: str, pin: str | int | None = None, interactive_prompt: str = 'Insert your passkey device, then press ENTER.', touch_prompt: str = 'Please touch the device.', command: str = 'exit 0', auth_method: PasskeyAuthenticationUseCases = PasskeyAuthenticationUseCases.PASSKEY_PIN) tuple[int, int, str, str]

Call su - $username and authenticate the user with passkey.

Parameters:
  • username (str) – Username

  • device (str) – Path to local umockdev device file.

  • ioctl (str) – Path to local umockdev ioctl file.

  • script (str) – Path to local umockdev script file

  • pin (str | int | None) – Passkey PIN, defaults to None

  • interactive_prompt (str) – Interactive prompt, defaults to “Insert your passkey device, then press ENTER.”

  • touch_prompt (str) – Touch prompt, defaults to “Can you touch this device”

  • command (str) – Command executed after user is authenticated, defaults to “exit 0”

  • auth_method (PasskeyAuthenticationUseCases) – Authentication method, defaults to PasskeyAuthenticationUseCases.PASSKEY_WITH_PIN

Returns:

Tuple containing [return code, command code, stdout, stderr].

Return type:

Tuple[int, int, str, str]

umockdev_passkey(*, username: str, device: str, ioctl: str, script: str, pin: str | int | None = None, command: str = 'exit 0') bool

Call su - $username and authenticate the user with passkey.

Parameters:
  • username (str) – Username

  • pin (str | int) – Passkey PIN.

  • device (str) – Path to local umockdev device file.

  • ioctl (str) – Path to local umockdev ioctl file.

  • script (str) – Path to local umockdev script file

  • command (str) – Command executed after user is authenticated, defaults to “exit 0”

Returns:

Generated passkey mapping string.

Return type:

str

Returns:

True if authentication was successful, False otherwise.

Return type:

bool

vfido_passkey_with_output(*, username: str, pin: str | int | None, interactive_prompt: str = 'Insert your passkey device, then press ENTER.', touch_prompt: str = 'Please touch the device.', command: str = 'exit 0', auth_method: PasskeyAuthenticationUseCases = PasskeyAuthenticationUseCases.PASSKEY_PIN) tuple[int, int, str, str]

Call su - $username and authenticate the user with vfido passkey

Parameters:
  • username (str) – Username

  • pin (str | int | None) – Passkey PIN, defaults to None

  • interactive_prompt (str) – Interactive prompt, defaults to “Insert your passkey device, then press ENTER.”

  • touch_prompt (str) – Touch prompt, defaults to “Please touch the device.”

  • command (str) – Command executed after user is authenticated, defaults to “exit 0”

  • auth_method (PasskeyAuthenticationUseCases) – Authentication method, defaults to PasskeyAuthenticationUseCases.PASSKEY_PIN

Returns:

Tuple containing [return code, command code, stdout, stderr].

Return type:

Tuple[int, int, str, str]

vfido_passkey(*, username: str, pin: str | int | None = None, command: str = 'exit 0') bool

Call su - $username and authenticate the user with passkey.

Parameters:
  • username (str) – Username

  • pin (str | int | None) – Passkey PIN.

  • command (str) – Command executed after user is authenticated, defaults to “exit 0”

Returns:

True if authentication was successful, False otherwise.

Return type:

bool

smartcard_with_output(username: str, pin: str, *, num_certs: int = 1, cert_selection: int = 1) ProcessResult

Wait for the user to become resolvable then authenticate via su with the smart card PIN.

Parameters:
  • username (str) – Username.

  • pin (str) – Smart card PIN.

  • num_certs (int, optional) – Number of certificates that map to the user, defaults to 1.

  • cert_selection (int, optional) – Index of the certificate to select when multiple are present, defaults to 1.

Returns:

Result of the su command.

Return type:

ProcessResult

smartcard(username: str, pin: str, *, num_certs: int = 1, cert_selection: int = 1) bool

Wait for the user to become resolvable then authenticate via su with the smart card PIN.

Parameters:
  • username (str) – Username.

  • pin (str) – Smart card PIN.

  • num_certs (int, optional) – Number of certificates that map to the user, defaults to 1.

  • cert_selection (int, optional) – Index of the certificate to select when multiple are present, defaults to 1.

Returns:

True if authentication was successful, False otherwise.

Return type:

bool

class sssd_test_framework.utils.authentication.SudoAuthenticationUtils(*args, **kwargs)

Bases: MultihostUtility[MultihostHost]

Methods for testing authentication and authorization via sudo.

Find all MultihostUtility objects in the constructor.

run(username: str, password: str | None = None, *, command: str) bool

Execute sudo command.

Parameters:
  • username (str) – Username that calls sudo.

  • password (str | None, optional) – User password, defaults to None

  • command (str) – Command to execute (make sure to properly escape any quotes).

Returns:

True if the command was successful, False if the command failed or the user can not run sudo.

Return type:

bool

run_advanced(username: str, password: str | None = None, *, parameters: list[str] | None = None, command: str) ProcessResult

Execute sudo command with parameters.

Parameters:
  • username (str) – Username that calls sudo.

  • password (str | None, optional) – User password, defaults to None

  • parameters (list[str] | None) – List of parameters to sudo.

  • command (str) – Command to execute (make sure to properly escape any quotes).

Returns:

Command result.

Return type:

ProcessResult

list(username: str, password: str | None = None, *, expected: list[str] | None = None) bool

List commands that the user can run under sudo.

Parameters:
  • username (str) – Username that runs sudo.

  • password (str | None, optional) – User password, defaults to None

  • expected (list[str] | None, optional) – List of expected commands (formatted as sudo output), defaults to None

Returns:

True if the user can run sudo and allowed commands match expected commands (if set), False otherwise.

Return type:

bool