Replies: 2 comments 4 replies
-
hey @simatt99 this wont be something scrapli supports "natively" I guess. but, you can for sure make it work. tl;dr -- enable auth bypass then provide a custom "on_open" function to handle your banner. this old example for Cisco WLC that acts kinda wonky is probably a pretty decent example. ps- moved to discussion for my ocd/since its not a "bug" necessarily. |
Beta Was this translation helpful? Give feedback.
-
@carlmontanari Heres that code if you were curious. This is very rough and is more of a POC than a fix. It works! but i dont have a ton of faith in it to not break at some point. My thought was just to read through the buffer until it finds either a password prompt or an auth prompt. if it fails 5 times it breaks and rolls into the normal password authentication loop. I added an additional regex to catch the authentication as well, which is what banner_acknowledge_pattern is. @timeout_wrapper
def channel_authenticate_ssh(
self, auth_password: str, auth_private_key_passphrase: str
) -> None:
"""
Handle SSH Authentication for transports that only operate "in the channel" (i.e. system)
Args:
auth_password: password to authenticate with
auth_private_key_passphrase: passphrase for ssh key if necessary
Returns:
None
Raises:
ScrapliAuthenticationFailed: if password prompt seen more than twice
ScrapliAuthenticationFailed: if passphrase prompt seen more than twice
"""
self.logger.debug("attempting in channel ssh authentication")
acknowledge_count = 0
password_count = 0
passphrase_count = 0
authenticate_buf = b""
(
password_pattern,
passphrase_pattern,
prompt_pattern,
banner_acknowledge_pattern,
) = self._pre_channel_authenticate_ssh()
with self._channel_lock():
while True:
buf = self.read()
authenticate_buf += buf.lower()
self._ssh_message_handler(output=authenticate_buf)
#testing banner acknowledgement for panOS
if not re.search(pattern=password_pattern, string=authenticate_buf):
while True:
if re.search(pattern=password_pattern, string=authenticate_buf):
self.logger.debug("found password authentication")
break
if re.search(pattern=banner_acknowledge_pattern, string=authenticate_buf):
self.logger.debug("found acknowledge banner")
self.write(channel_input="yes", redacted=False)
self.send_return()
authenticate_buf = b""
buf = self.read()
authenticate_buf += buf.lower()
break
if acknowledge_count > 5:
break
buf = self.read()
authenticate_buf = buf.lower()
acknowledge_count += 1
if re.search(
pattern=password_pattern,
string=authenticate_buf,
):
# clear the authentication buffer so we don't re-read the password prompt
authenticate_buf = b""
password_count += 1
if password_count > 3:
msg = "password prompt seen more than once, assuming auth failed"
self.logger.critical(msg)
raise ScrapliAuthenticationFailed(msg)
self.write(channel_input=auth_password, redacted=True)
self.send_return()
if re.search(
pattern=passphrase_pattern,
string=authenticate_buf,
):
# clear the authentication buffer so we don't re-read the passphrase prompt
authenticate_buf = b""
passphrase_count += 1
if passphrase_count > 2:
msg = "passphrase prompt seen more than once, assuming auth failed"
self.logger.critical(msg)
raise ScrapliAuthenticationFailed(msg)
self.write(channel_input=auth_private_key_passphrase, redacted=True)
self.send_return()
if re.search(
pattern=prompt_pattern,
string=authenticate_buf,
):
return I also had a question on this "the on-open should work but you will likely need to read from the channel to "wait" till you see the prompt to respond to". From what you said, you can control the channel from the function you pass to on_open. Does that mean you could make your own SSH authentication loop from on_open using channel methods? or would this require changing base_channel.py |
Beta Was this translation helpful? Give feedback.
-
Describe the bug
Scrapli SSH times out during connection. For some of my devices I have banner acknowledgment turned on. The acknowledgement gets asked before the SSH password is inputted. I looked through documentation and don't think theres a good way to go about this, correct me if i'm wrong.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
I expected Scrapli to detect pre SSH prompts to connect to the device.
logs
24-Jul-30 15:31:31 - DEBUG - Scrapli factory initialized
24-Jul-30 15:31:31 - INFO - Driver '<class 'scrapli.driver.network.sync_driver.NetworkDriver'>' selected from scrapli community platforms, with the following platform arguments: '{'privilege_levels': {'exec': <scrapli.driver.network.base_driver.PrivilegeLevel object at 0x7fe4bf72bdc0>, 'configuration': <scrapli.driver.network.base_driver.PrivilegeLevel object at 0x7fe4bf72bca0>}, 'default_desired_privilege_level': 'exec', 'failed_when_contains': ['Unknown command:', 'Invalid syntax.', 'Server error', 'Validation Error:'], 'textfsm_platform': 'paloalto_panos', 'genie_platform': '', 'on_open': <function default_sync_on_open at 0x7fe4bfafc700>, 'on_close': <function default_sync_on_close at 0x7fe4bfafc790>}'
24-Jul-30 15:31:31 - DEBUG - load core transport requested
24-Jul-30 15:31:31 - DEBUG - core transport 'system' loaded successfully
24-Jul-30 15:31:31 - DEBUG - generating combined network comms prompt pattern
24-Jul-30 15:31:31 - DEBUG - setting 'comms_prompt_pattern' value to '(^[\w.-]+@[\w.()-]+>\s?$)|(^[\w.-]+@[\w.()-]+#\s?$)'
24-Jul-30 15:31:31 - INFO - opening connection to '<SYSTEM_IP>' on port '22'
24-Jul-30 15:31:31 - DEBUG - opening transport connection to '<SYSTEM_IP>' on port '22'
24-Jul-30 15:31:31 - DEBUG - created transport 'open_cmd': '['ssh', '<SYSTEM_IP>', '-p', '22', '-o', 'ConnectTimeout=15', '-o', 'ServerAliveInterval=30', '-l', 'admin', '-o', 'StrictHostKeyChecking=no', '-o', 'UserKnownHostsFile=/dev/null', '-F', '/dev/null']'
24-Jul-30 15:31:31 - DEBUG - transport connection to '<SYSTEM_IP>' on port '22' opened successfully
24-Jul-30 15:31:31 - DEBUG - attempting in channel ssh authentication
24-Jul-30 15:31:35 - DEBUG - read: b"Warning: Permanently added '<SYSTEM_IP>' (ECDSA) to the list of known hosts.\n"
24-Jul-30 15:31:35 - DEBUG - read: b'This computer system is private property and may only be accessed by authorized users.\n'
24-Jul-30 15:31:35 - DEBUG - read: b''
24-Jul-30 15:31:35 - DEBUG - read: b'(admin@<SYSTEM_IP>) Do you accept and acknowledge the statement above ? (yes/no) : '
24-Jul-30 15:32:01 - CRITICAL - operation timed out, closing connection
24-Jul-30 15:32:01 - DEBUG - closing transport connection to '<SYSTEM_IP>' on port '22'
24-Jul-30 15:32:01 - CRITICAL - encountered EOF reading from transport; typically means the device closed the connection
24-Jul-30 15:32:02 - DEBUG - transport connection to '<SYSTEM_IP>' on port '22' closed successfully
24-Jul-30 15:32:02 - CRITICAL - unknown exception occured
24-Jul-30 15:32:02 - CRITICAL - Type: <class 'scrapli.exceptions.ScrapliTimeout'>
24-Jul-30 15:32:02 - CRITICAL - Value: timed out during in channel ssh authentication
24-Jul-30 15:32:02 - CRITICAL - Traceback: <traceback object at 0x7fe4bf4cca80>
this is how normal SSH interactions look like:
user@computer ~ % ssh paloAlto
This computer system is private property and may only be accessed by authorized users.
(admin@PaloAltoIP) Do you accept and acknowledge the statement above ? (yes/no) :yes
(admin@PaloAltoIP) Password:
OS (please complete the following information):
Additional context
N/A
Beta Was this translation helpful? Give feedback.
All reactions