Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
ganeshrn opened this issue Jan 21, 2020 · 0 comments
Open
Labels
bug Something isn't working
Milestone

Comments

@ganeshrn
Copy link
Member

ganeshrn commented Jan 21, 2020

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants