I'm trying to spawn an ssh child process using subprocess.
I'm working on Python 2.7.6 on Windows 7
here is my code:
from subprocess import *
r=Popen("ssh sshserver@localhost", stdout=PIPE)
stdout, stderr=r.communicate()
print(stdout)
print(stderr)
The outputs:
None
stdout should contain: sshserver@localhost's password:
Here's an example of working SSH code that handles the promt for yes/no on the certificate part and also when asked for a password.
#!/usr/bin/python
import pty, sys
from subprocess import Popen, PIPE, STDOUT
from time import sleep
from os import fork, waitpid, execv, read, write
class ssh():
    def __init__(self, host, execute='echo "done" > /root/testing.txt', askpass=False, user='root', password=b'SuperSecurePassword'):
        self.exec = execute
        self.host = host
        self.user = user
        self.password = password
        self.askpass = askpass
        self.run()
    def run(self):
        command = [
                '/usr/bin/ssh',
                self.user+'@'+self.host,
                '-o', 'NumberOfPasswordPrompts=1',
                self.exec,
        ]
        # PID = 0 for child, and the PID of the child for the parent    
        pid, child_fd = pty.fork()
        if not pid: # Child process
            # Replace child process with our SSH process
            execv(command[0], command)
        ## if we havn't setup pub-key authentication
        ## we can loop for a password promt and "insert" the password.
        while self.askpass:
            try:
                output = read(child_fd, 1024).strip()
            except:
                break
            lower = output.lower()
            # Write the password
            if b'password:' in lower:
                write(child_fd, self.password + b'\n')
                break
            elif b'are you sure you want to continue connecting' in lower:
                # Adding key to known_hosts
                write(child_fd, b'yes\n')
            elif b'company privacy warning' in lower:
                pass # This is an understood message
            else:
                print('Error:',output)
        waitpid(pid, 0)
The reason (and correct me if i'm wrong here) for you not being able to read the stdin straight away is because SSH runs as a subprocess under a different process ID which you need to read/attach to. 
Since you're using windows, pty will not work. there's two solutions that would work better and that's pexpect and as someone pointed out key-based authentication.
In order to achieve a key-based authentication you only need to do the following:
On your client, run: ssh-keygen
Copy your id_rsa.pub content (one line) into /home/user/.ssh/authorized_keys on the server.
And you're done. If not, go with pexpect.
import pexpect
child = pexpect.spawn('ssh [email protected]')
child.expect('Password:')
child.sendline('SuperSecretPassword')
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With