2013-12-09 154 views
0

所以我知道你可以使用Pexpect来解决这个问题,但我不想依赖额外的库来解决除Python3提供的问题以外的其他问题。Python + SSH密码验证(无需外部库或公钥/私钥)?

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

这是我从SO社区获得的一大堆帮助之后获得的“我自己的”。 我很困难检查分叉的子伪终端是否执行了它应该与否。这意味着我可以判断SSH是否执行完毕,因为只要run()函数正在运行,它就会持续运行。

(我pid_exists将返回True,只要它的run()的操作中。如果我退出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打开并传输给我的伪伪终端的执行过程的信息。 我可以或应该参与子过程:https://stackoverflow.com/a/12235442/929999或有其他方法吗?

回答