Skip to content

Commit

Permalink
utils: added password_with_output to authentication.py to capture ssh…
Browse files Browse the repository at this point in the history
… output
  • Loading branch information
Dan Lavu committed Feb 16, 2024
1 parent 6e92e58 commit 6141760
Showing 1 changed file with 56 additions and 15 deletions.
71 changes: 56 additions & 15 deletions sssd_test_framework/utils/authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -413,23 +413,42 @@ def __init__(self, host: MultihostHost) -> None:
self.opts = "-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
"""SSH CLI options."""

def password(self, username: str, password: str) -> bool:
def password_with_output(self, username: str, password: str) -> tuple[int, int, str, str]:
"""
SSH to the remote host and authenticate the user with password.
SSH to the remote host and authenticate the user with password and captures standard output and error.
:param username: Username.
:type username: str
:param password: User password.
:type password: str
:return: True if authentication was successful, False otherwise.
:rtype: bool
:return: Tuple containing [except return code, command exit code, stdout, stderr].
:rtype: Tuple[int, int, str, str]
"""

result = self.host.ssh.expect_nobody(
rf"""
# Disable debug output
exp_internal 0
proc exitmsg {{ msg code }} {{
# Send EOF, if we are in the prompt
send \x04;
# Wait for the exit code
lassign [wait] pid spawnid os_error_flag rc
puts ""
puts "expect result: $msg"
puts "expect exit code: $code"
puts "expect spawn exit code: $rc"
exit $code
}}
# It takes some time to get authentication failure
set timeout {DEFAULT_AUTHENTICATION_TIMEOUT}
set prompt "\n.*\[#\$>\] $"
log_user 1
log_file /tmp/expect.log
spawn ssh {self.opts} \
-o PreferredAuthentications=password \
Expand All @@ -438,27 +457,49 @@ def password(self, username: str, password: str) -> bool:
expect {{
"password:" {{send "{password}\n"}}
timeout {{puts "expect result: Unexpected output"; exit 201}}
eof {{puts "expect result: Unexpected end of file"; exit 202}}
timeout {{exitmsg "Unexpected output" 201}}
eof {{exitmsg "Unexpected end of file" 202}}
}}
expect {{
-re $prompt {{puts "expect result: Password authentication successful"; exit 0}}
"{username}@localhost: Permission denied" {{puts "expect result: Authentication failure"; exit 1}}
"Connection closed by UNKNOWN port 65535" {{puts "expect result: Connection closed"; exit 2}}
timeout {{puts "expect result: Unexpected output"; exit 201}}
eof {{puts "expect result: Unexpected end of file"; exit 202}}
-re $prompt {{exitmsg "Password authentication successful" 0}}
"{username}@localhost: Permission denied" {{exitmsg "Authentication failure" 1}}
"Connection closed by UNKNOWN port 65535" {{exitmsg "Connection closed" 2}}
timeout {{exitmsg "Unexpected output" 201}}
eof {{exitmsg "Unexpected end of file" 202}}
}}
puts "expect result: Unexpected code path"
exit 203
"""
exitmsg "Unexpected code path" 203
""",
verbose=False,
)

if result.rc > 200:
raise ExpectScriptError(result.rc)

return result.rc == 0
expect_data = result.stdout_lines[-3:]

# Get command exit code.
cmdrc = int(expect_data[2].split(":")[1].strip())

# Alter stdout, first line is spawned command, the last three are our expect output.
stdout = "\n".join(result.stdout_lines[1:-3])

return result.rc, cmdrc, stdout, result.stderr

def password(self, username: str, password: str) -> bool:
"""
SSH to the remote host and authenticate the user with password.
:param username: Username.
:type username: str
:param password: User password.
:type password: str
:return: True if authentication was successful, False otherwise.
:rtype: bool
"""
rc, _, _, _ = self.password_with_output(username, password)
return rc == 0

def password_expired(self, username: str, password: str, new_password: str) -> bool:
"""
Expand Down

0 comments on commit 6141760

Please sign in to comment.