0
import traceback
import paramiko
from paramiko_expect import SSHClientInteraction

def main():
    # Set login credentials and the server prompt
    HOSTNAME = 'locallhost'
    USERNAME = 'Administrator'
    PASSWORD = 'password'
    PROMPT = r'.*>'

    # Create a new SSH client object
    client = paramiko.SSHClient()
    # Use SSH client to login
    try:
        # Set SSH key parameters to auto accept unknown hosts
        client.load_system_host_keys()
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

        # Connect to the host
        client.connect(hostname=HOSTNAME, username=USERNAME, password=PASSWORD)

        # Create a client interaction class which will interact with the host
        with SSHClientInteraction(client, timeout=10, display=True) as interact:
            interact.send('dir')
            interact.expect(PROMPT)
            cmd_output_uname = interact.current_output_clean
            print(cmd_output_uname)

    except Exception:
        traceback.print_exc()
    finally:
        try:
            client.close()
        except:
            pass

if __name__ == '__main__':
    main()

Following is the output:

Microsoft Windows [Version 6.2.9200]
(c) 2012 Microsoft Corporation. All rights reserved.

administrator@xyz C:\Users\Administrator>dir
dir ir r
Volume in drive C has no label.
Volume Serial Number is ABCD

Directory of C:\Users\Administrator

06/25/2018 06:40 PM HH;24;27;37;40mMicrosoft Windows [Version 6.2.9200] H(c) 2012 Microsoft Corporation. All rights reserved.

Hadministrator@xyz C:\Users\Administrator>dir
Hdir HHir HHr
HH HH Volume in drive C has no label.
H Volume Serial Number is ABCD

H Directory of C:\Users\Administrator

Process finished with exit code 0

I see the output is improper and repeated multiple times like this "dir", "ir", "r". Similiar code works well for linux. I have tried modifying the SSHClientInteraction class from paramiko_expect.py but not successful in fixing this issue.

I think this is a problem in reading byte stream from buffer in windows like here,

current_buffer = self.channel.recv(self.buffersize)

Any suggestions on what could be the problem and how to resolve this?

Edited: Following is the edited version as part of debugging this issue:

import paramiko
paramiko.util.log_to_file("paramiko_log", level = "DEBUG")

def main():
    # Set login credentials and the server prompt
    hostname = 'x.x.x.x'
    username = 'username'
    password = 'password'
    prompt = [".*C:.*[$>#]\\s*?"]

    # Use SSH client to login
    # Create a new SSH client object
    client = paramiko.SSHClient()

    # Set SSH key parameters to auto accept unknown hosts
    client.load_system_host_keys()
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

    # Connect to the host
    client.connect(hostname=hostname, username=username, password=password)
    ishell = client.invoke_shell() # REMOVED Chan.get_pty call from /venv/lib64/python3.6/site-packages/paramiko/client.py
    ishell.send('dir')
    aa = ishell.recv(65535).decode('utf-8')
    print(aa)
    print(repr(aa))

Exception:

67: in main
    ishell = client.invoke_shell()
/venv/lib64/python3.6/site-packages/paramiko/client.py:532: in invoke_shell
    chan.invoke_shell()
/venv/lib64/python3.6/site-packages/paramiko/channel.py:72: in _check
    return func(self, *args, **kwds)
/venv/lib64/python3.6/site-packages/paramiko/channel.py:230: in invoke_shell
    self._wait_for_event()
/venv/lib64/python3.6/site-packages/paramiko/channel.py:1208: in _wait_for_event
    raise e
E   paramiko.ssh_exception.SSHException: Channel closed.

Paramiko log:

DEB [20190905-11:43:01.110] thr=1   paramiko.transport: starting thread (client mode): 0x83355cf8
DEB [20190905-11:43:01.111] thr=1   paramiko.transport: Local version/idstring: SSH-2.0-paramiko_2.4.2
DEB [20190905-11:43:01.138] thr=1   paramiko.transport: Remote version/idstring: SSH-2.0-OpenSSH_for_Windows_8.0
INF [20190905-11:43:01.138] thr=1   paramiko.transport: Connected (version 2.0, client OpenSSH_for_Windows_8.0)
DEB [20190905-11:43:01.305] thr=1   paramiko.transport: kex algos:['curve25519-sha256', 'curve25519-sha256@libssh.org', 'ecdh-sha2-nistp256', 'ecdh-sha2-nistp384', 'ecdh-sha2-nistp521', 'diffie-hellman-group-exchange-sha256', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group14-sha256', 'diffie-hellman-group14-sha1'] server key:['rsa-sha2-512', 'rsa-sha2-256', 'ssh-rsa', 'ecdsa-sha2-nistp256', 'ssh-ed25519'] client encrypt:['chacha20-poly1305@openssh.com', 'aes128-ctr', 'aes192-ctr', 'aes256-ctr', 'aes128-gcm@openssh.com', 'aes256-gcm@openssh.com'] server encrypt:['chacha20-poly1305@openssh.com', 'aes128-ctr', 'aes192-ctr', 'aes256-ctr', 'aes128-gcm@openssh.com', 'aes256-gcm@openssh.com'] client mac:['umac-64-etm@openssh.com', 'umac-128-etm@openssh.com', 'hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'hmac-sha1-etm@openssh.com', 'umac-64@openssh.com', 'umac-128@openssh.com', 'hmac-sha2-256', 'hmac-sha2-512', 'hmac-sha1'] server mac:['umac-64-etm@openssh.com', 'umac-128-etm@openssh.com', 'hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'hmac-sha1-etm@openssh.com', 'umac-64@openssh.com', 'umac-128@openssh.com', 'hmac-sha2-256', 'hmac-sha2-512', 'hmac-sha1'] client compress:['none'] server compress:['none'] client lang:[''] server lang:[''] kex follows?False
DEB [20190905-11:43:01.305] thr=1   paramiko.transport: Kex agreed: ecdh-sha2-nistp256
DEB [20190905-11:43:01.305] thr=1   paramiko.transport: HostKey agreed: ssh-ed25519
DEB [20190905-11:43:01.305] thr=1   paramiko.transport: Cipher agreed: aes128-ctr
DEB [20190905-11:43:01.305] thr=1   paramiko.transport: MAC agreed: hmac-sha2-256
DEB [20190905-11:43:01.306] thr=1   paramiko.transport: Compression agreed: none
DEB [20190905-11:43:01.317] thr=1   paramiko.transport: kex engine KexNistp256 specified hash_algo <built-in function openssl_sha256>
DEB [20190905-11:43:01.317] thr=1   paramiko.transport: Switch to new keys ...
DEB [20190905-11:43:01.318] thr=2   paramiko.transport: Adding ssh-ed25519 host key for : b'75672d0019c35'
DEB [20190905-11:43:01.438] thr=1   paramiko.transport: userauth is OK
INF [20190905-11:43:01.453] thr=1   paramiko.transport: Authentication (password) successful!
DEB [20190905-11:43:01.454] thr=2   paramiko.transport: [chan 0] Max packet in: 32768 bytes
DEB [20190905-11:43:01.474] thr=1   paramiko.transport: Received global request "hostkeys-00@openssh.com"
DEB [20190905-11:43:01.475] thr=1   paramiko.transport: Rejecting "hostkeys-00@openssh.com" global request from server.
DEB [20190905-11:43:01.514] thr=1   paramiko.transport: [chan 0] Max packet out: 32768 bytes
DEB [20190905-11:43:01.515] thr=1   paramiko.transport: Secsh channel 0 opened.
DEB [20190905-11:43:01.516] thr=1   paramiko.transport: [chan 0] EOF sent (0)
DEB [20190905-11:49:34.620] thr=1   paramiko.transport: starting thread (client mode): 0x47786cf8
DEB [20190905-11:49:34.620] thr=1   paramiko.transport: Local version/idstring: SSH-2.0-paramiko_2.4.2
DEB [20190905-11:49:34.647] thr=1   paramiko.transport: Remote version/idstring: SSH-2.0-OpenSSH_for_Windows_8.0
INF [20190905-11:49:34.648] thr=1   paramiko.transport: Connected (version 2.0, client OpenSSH_for_Windows_8.0)
DEB [20190905-11:49:34.834] thr=1   paramiko.transport: kex algos:['curve25519-sha256', 'curve25519-sha256@libssh.org', 'ecdh-sha2-nistp256', 'ecdh-sha2-nistp384', 'ecdh-sha2-nistp521', 'diffie-hellman-group-exchange-sha256', 'diffie-hellman-group16-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group14-sha256', 'diffie-hellman-group14-sha1'] server key:['rsa-sha2-512', 'rsa-sha2-256', 'ssh-rsa', 'ecdsa-sha2-nistp256', 'ssh-ed25519'] client encrypt:['chacha20-poly1305@openssh.com', 'aes128-ctr', 'aes192-ctr', 'aes256-ctr', 'aes128-gcm@openssh.com', 'aes256-gcm@openssh.com'] server encrypt:['chacha20-poly1305@openssh.com', 'aes128-ctr', 'aes192-ctr', 'aes256-ctr', 'aes128-gcm@openssh.com', 'aes256-gcm@openssh.com'] client mac:['umac-64-etm@openssh.com', 'umac-128-etm@openssh.com', 'hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'hmac-sha1-etm@openssh.com', 'umac-64@openssh.com', 'umac-128@openssh.com', 'hmac-sha2-256', 'hmac-sha2-512', 'hmac-sha1'] server mac:['umac-64-etm@openssh.com', 'umac-128-etm@openssh.com', 'hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'hmac-sha1-etm@openssh.com', 'umac-64@openssh.com', 'umac-128@openssh.com', 'hmac-sha2-256', 'hmac-sha2-512', 'hmac-sha1'] client compress:['none'] server compress:['none'] client lang:[''] server lang:[''] kex follows?False
DEB [20190905-11:49:34.835] thr=1   paramiko.transport: Kex agreed: ecdh-sha2-nistp256
DEB [20190905-11:49:34.835] thr=1   paramiko.transport: HostKey agreed: ssh-ed25519
DEB [20190905-11:49:34.835] thr=1   paramiko.transport: Cipher agreed: aes128-ctr
DEB [20190905-11:49:34.835] thr=1   paramiko.transport: MAC agreed: hmac-sha2-256
DEB [20190905-11:49:34.835] thr=1   paramiko.transport: Compression agreed: none
DEB [20190905-11:49:34.846] thr=1   paramiko.transport: kex engine KexNistp256 specified hash_algo <built-in function openssl_sha256>
DEB [20190905-11:49:34.847] thr=1   paramiko.transport: Switch to new keys ...
DEB [20190905-11:49:34.847] thr=2   paramiko.transport: Adding ssh-ed25519 host key for : b'75672d00'
DEB [20190905-11:49:34.901] thr=1   paramiko.transport: userauth is OK
INF [20190905-11:49:34.916] thr=1   paramiko.transport: Authentication (password) successful!
DEB [20190905-11:49:34.917] thr=2   paramiko.transport: [chan 0] Max packet in: 32768 bytes
DEB [20190905-11:49:34.938] thr=1   paramiko.transport: Received global request "hostkeys-00@openssh.com"
DEB [20190905-11:49:34.938] thr=1   paramiko.transport: Rejecting "hostkeys-00@openssh.com" global request from server.
DEB [20190905-11:49:34.977] thr=1   paramiko.transport: [chan 0] Max packet out: 32768 bytes
DEB [20190905-11:49:34.977] thr=1   paramiko.transport: Secsh channel 0 opened.
DEB [20190905-11:49:34.979] thr=1   paramiko.transport: [chan 0] EOF sent (0)

Windows Server log:

8652 2019-09-01 11:27:43.561 Server listening on :: port 22.
8652 2019-09-01 11:27:43.562 Server listening on 0.0.0.0 port 22.
8528 2019-09-01 11:29:24.242 Received disconnect from x.x.x.x port 61501:11: disconnected by user
8528 2019-09-01 11:29:24.242 Disconnected from x.x.x.x port 61501
8064 2019-09-01 11:33:33.772 Server listening on :: port 22.
8064 2019-09-01 11:33:33.772 Server listening on 0.0.0.0 port 22.
Suresh Kota
  • 305
  • 1
  • 6
  • 19
  • Your code probably does not handle CR (`\r`) character and/or [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code) correctly – It other words, you are trying to implement an interactive terminal, yet you do not implement terminal emulation at all. – Martin Prikryl Aug 03 '19 at 14:07
  • See [Is there a simple way to get rid of junk values that come when you SSH using Python's Paramiko library and fetch output from CLI of a remote machine?](https://stackoverflow.com/q/33291631/850848). – Martin Prikryl Aug 03 '19 at 14:10
  • Yes, I am automating interactive session. Filtering the ANSI codes in the above link still gives me junk values in the output. I am using paramiko_expect and it already filters `r'\x1b\[([0-9,A-Z]{1,2}(;[0-9]{1,2})?(;[0-9]{3})?)?[m|K]?'` these ANSI codes and it also did not help. – Suresh Kota Aug 04 '19 at 05:12
  • So do you get a different output now after filtering the escape codes or not? I see escape codes in your output: `;24;27;37;40m` + Did you check for `\r`? – Martin Prikryl Aug 04 '19 at 14:04
  • Yes, but everything is not getting filtered. I still see the echo part with `H`, `HH` like this. – Suresh Kota Aug 04 '19 at 14:14
  • @MartinPrikryl, I have replaced `ishell = client.invoke_shell()` with `chan = client.get_transport().open_session() chan.invoke_shell()`. I still see `paramiko.ssh_exception.SSHException: Channel closed.` `chan.invoke_shell()` will again call paramiko library itself right? – Suresh Kota Sep 05 '19 at 11:12
  • And if you add `chan.get_pty()` before `chan.invoke_shell()`, it works, right? + Did you check server log file? `C:\ProgramData\ssh\logs\sshd.log` – Martin Prikryl Sep 05 '19 at 11:15
  • Yes the connection established if I include `chan.get_pty()` before `chan.invoke_shell()`. I do not see any messages in server log file `C:\ProgramData\ssh\logs\sshd.log` – Suresh Kota Sep 05 '19 at 11:36
  • There must be *something* in the log. – Martin Prikryl Sep 05 '19 at 11:37
  • The log is not updated since 4 days. I see some older messages. – Suresh Kota Sep 05 '19 at 11:39
  • I have updated the log messages in the question above. – Suresh Kota Sep 05 '19 at 11:41
  • @MartinPrikryl, Any idea on why your code is not working for me? – Suresh Kota Sep 05 '19 at 13:40
  • I have no idea. – Martin Prikryl Sep 05 '19 at 13:43
  • Is it working for you? Did you get clean output even with windows openssh? – Suresh Kota Sep 05 '19 at 13:51
  • Yes, of course. – Martin Prikryl Sep 05 '19 at 13:53
  • Then could you please answer this question. I would try and accept it. Would be helpful for others as well. – Suresh Kota Sep 05 '19 at 13:55
  • I already wrote that I have no idea why it does not work for you. And in general, as I have answered dozen times in various questions here, I strongly believe that trying to automate a shell and using expect-like functions is a bad idea. – Martin Prikryl Sep 05 '19 at 13:56
  • That's ok. What I am wondering is how come you did not get `channel closed` exception without `Chan.get_pty` – Suresh Kota Sep 05 '19 at 14:01

0 Answers0