Description:
On issuing privilege escalation command (sudo) the password prompt is not received on the channel, as a result, the become password is not written on channel and privilege escalation fails.
Test Snippet to reproduce the issue: libssh_priveledge_escalation.py
# libssh_priveledge_escalation.py:
import os
from pylibsshext.session import Session
from pylibsshext.errors import LibsshSessionException
from ansible.module_utils._text import to_bytes, to_native, to_text
ssh = Session()
HOST = "<changeme>"
USER = "<changeme>"
PASSWORD = "<changeme>"
BECOME_PASSWORD = "<changeme>"
try:
ssh.connect(
host=HOST,
user=USER,
password=PASSWORD,
timeout=30,
port=22
)
except LibsshSessionException as ex:
print(str(ex))
print(ssh.is_connected)
def exec_command(cmd, in_data=None, sudoable=True):
''' run a command on the remote host '''
bufsize = 4096
try:
chan = ssh.new_channel()
except Exception as e:
text_e = to_text(e)
msg = u"Failed to open session"
if text_e:
msg += u": %s" % text_e
raise Exception(to_native(msg))
cmd = to_text(cmd, errors='surrogate_or_strict')
become_output = b''
# sudo usually requires a PTY (cf. requiretty option), therefore
# we give it one by default (pty=True in ansible.cfg), and we try
# to initialise from the calling environment when sudoable is enabled
chan.request_pty_size(terminal=to_bytes(os.getenv('TERM', 'vt100')), col=int(os.getenv('COLUMNS', 0)), row=int(os.getenv('LINES', 0)))
try:
count = chan.write(to_bytes(cmd))
print(count)
if 1:
passprompt = False
become_sucess = False
while not (become_sucess or passprompt):
print('Waiting for Privilege Escalation input')
chan.poll(timeout=9000)
chunk = chan.recv(bufsize)
print("chunk is: %s" % to_native(chunk))
if not chunk:
if b'unknown user' in become_output:
n_become_user = to_native("root")
raise Exception('user %s does not exist' % n_become_user)
else:
break
become_output += chunk
for l in become_output.splitlines(True):
print(l)
if 'password' in str(l).lower():
become_sucess = True
if passprompt:
chan.sendall(b'%s' % BECOME_PASSWORD + b'\n')
except Exception as e:
text_e = to_text(e)
msg = u"Failed to execute command"
if text_e:
msg += u": %s" % text_e
raise Exception(to_native(msg))
exec_command("sudo")
Ref: ansible-collections/ansible.netcommon#165
Description:
On issuing privilege escalation command (
sudo) the password prompt is not received on the channel, as a result, the become password is not written on channel and privilege escalation fails.Test Snippet to reproduce the issue:
libssh_priveledge_escalation.pyRef: ansible-collections/ansible.netcommon#165