通过Python子进程SSH密码

2024-10-01 11:29:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在编写一个GUI程序来生成和监视SSH隧道,这些用户被吓得不敢使用命令行。在

不幸的是,有问题的服务器非常严格。通过rsasecurid令牌的双因素身份验证是唯一官方认可的打开SSH连接的方式。不允许使用无密码的RSA公钥/私钥身份验证。在

因此,我的程序有必要从文本输入框中读取密码并将其发送给SSH子进程。不幸的是,ssh花了很大的力气来确保密码只来自真正的键盘。在

我强烈建议不要使用第三方模块。我知道paramiko和pexpect(它们都是作为类似问题的可能解决方案而提出的),但是试图向我的用户解释如何从源代码安装Python模块太让人头疼了。在

那么:如何使用标准pythonsubprocess模块向ssh子进程发送密码?有没有办法让子进程以为我在使用TTY?是否可以使用SSH_ASKPASS来读取我的程序?在

也允许使用其他标准库模块(例如,os模块的低级命令)。在


Tags: 模块命令行用户程序服务器身份验证密码标准
1条回答
网友
1楼 · 发布于 2024-10-01 11:29:58

最后,我能够使用pty模块通过伪终端控制ssh。我在pexpect中编写了一个解决方案,然后通过查看pexpect源代码并得到this StackOverflow answer的帮助,我就可以知道该怎么做了。下面是相关代码的摘录(作为对象方法的一部分执行;因此引用了self)。在

command = [
        '/usr/bin/ssh',
        '{0}@{1}'.format(username, hostname),
        '-L', '{0}:localhost:{1}'.format(local_port, foreign_port),
        '-o', 'NumberOfPasswordPrompts=1',
        'sleep {0}'.format(SLEEP_TIME),
]

# PID = 0 for child, and the PID of the child for the parent    
self.pid, child_fd = pty.fork()

if not self.pid: # Child process
    # Replace child process with our SSH process
    os.execv(command[0], command)

while True:
    output = os.read(child_fd, 1024).strip()
    lower = output.lower()
    # Write the password
    if lower.endswith('password:'):
        os.write(child_fd, self.password_var.get() + '\n')
        break
    elif 'are you sure you want to continue connecting' in lower:
        # Adding key to known_hosts
        os.write(child_fd, 'yes\n')
    elif 'company privacy warning' in lower:
        pass # This is an understood message
    else:
        tkMessageBox.showerror("SSH Connection Failed",
            "Encountered unrecognized message when spawning "
            "the SSH tunnel: '{0}'".format(output))
        self.disconnect()

相关问题 更多 >