Skip to content

command requiring privilege escalation for linux host not working. #16

@ganeshrn

Description

@ganeshrn

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions