一尘不染

Python + SSH密码认证(没有外部库或公共/专用密钥)?

python

因此,我知道您可以Pexpect用来解决问题,但除了Python3随附的库之外,我不想依赖其他库来解决问题。

我也知道生成公共密钥并允许它们在远程主机上是理想的,但这就是我打算使用此脚本的目的(在正确的位置设置密钥等)。

到目前为止,在SO社区的大量帮助下,我已经“靠我自己”了。我有点卡住检查分叉的子伪终端是否完成了它应该执行的操作。意思是我可以告诉SSH是否已完成执行,因为只要该run()功能运行,它就会一直存在。

(只要在run()操作中,我pid_exists将一直返回True。而且,如果我run()快速退出,则SSH会话将没有足够的时间去执行应该做的事情)

#!/usr/bin/python

import pty, sys
from subprocess import Popen, PIPE, STDOUT
from time import sleep
from os.path import expanduser, abspath
from os import walk, setsid, fork, waitpid, execv, read, write, kill

def pid_exists(pid):
    """Check whether pid exists in the current process table."""
    if pid < 0:
        return False
    try:
        kill(pid, 0)
    except (OSError, e):
        return e.errno == errno.EPERMRM
    else:
        return True

class ssh():
    def __init__(self, host, execute='echo "done" > /root/testing.txt', user='root', password=b'SuperPassword'):
        self.exec = execute
        self.host = host
        self.user = user
        self.password = password
        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)

        while True:
            output = read(child_fd, 1024).strip()
            print(output)
            lower = output.lower()
            # Write the password
            if b'password:' in lower:
                write(child_fd, self.password + b'\n')
                break
            elif 'are you sure you want to continue connecting' in lower:
                # Adding key to known_hosts
                write(child_fd, b'yes\n')
            elif 'company privacy warning' in lower:
                pass # This is an understood message
            else:
                print('Error:',output)

        sleep(5)
        print(pid_exists(pid))

ssh('10.10.10.1')

我找不到太多(或任何)有关如何获取Python打开并通过管道传送给我的伪伪终端的执行过程的信息。


阅读 287

收藏
2021-01-20

共1个答案

一尘不染

叹了口气..再有一个Google可以免除所有人的麻烦。

os.waitpid(pid, 0)
2021-01-20