【问题标题】:ssh using python without RSA keysssh 使用没有 RSA 密钥的 python
【发布时间】:2012-05-20 06:50:32
【问题描述】:

Stackoverflow 新手,首先,你好。

我正在为我的学校开发一个小项目,该项目应该是开源 Unison 程序的自定义 gui(用 python 编写,对我来说是一个教育挑战,因为我从未使用过 python)。我们正在尝试让学生和教职员工在家里和学校同步文件夹,方法是通过尽可能少的输入启动这个程序(如果你愿意的话,请防止白痴)。该界面应该只是他们是学校用户名和密码,而 gui 包装器应该只是将用户名和密码发送到 Unison 并同步它们。

问题是 Unison 依次启动 SSh 并提示输入密码,但 python subprocess.communicate(input) 方法不会让 ssh 获取密码。我意识到 ssh 只会接受来自终端的输入,我不知道如何欺骗它。我读过一些关于使用伪终端的东西,但我仍然很难过。 RSA 密钥将是理想的解决方案,但生成它们然后将它们放置在远程服务器上仍然需要我至少使用密码登录一次,这需要解决上述问题,或者终端不是白痴证明。

def startSync(self):
    '''
    '''
    userName = self.userNameIn.get()
    userPass = self.userPassIn.get()
    localDir = "/Users/localuser/syncFolder/"
    remoteDir = " ssh://schoolServer/remotesyncFolder" #for testing purposes, I set this to my own home machine which logs into my own account if I don't provide me@myserver.net
    unisonExecRemotePath = " -servercmd /Users/RemoteMe/unison" #unison is the unix executable responsible for launching unison on the remote system
    silenceCmdPrompts = " -silent" #keeps unison from displaying directory differences and asking if its okay to sync
    executionString = "./unison" + localDir + remoteDir + unisonExecRemotePath + silenceCmdPrompts

   mainProcess = subprocess.Popen(executionString,shell = True, stdin = subprocess.PIPE)
   mainProcess.communicate(userPass)

如果我将其粘贴到终端中,执行字符串可以正常工作。如果您愿意,任何一般的 python 提示也将不胜感激。

谢谢!

Unison 用户手册:http://www.cis.upenn.edu/~bcpierce/unison/download/releases/stable/unison-manual.html

编辑:我还应该注意,虽然我目前正在 OSX 和 Linux 下进行开发,但我最终必须使这个 windows 兼容,因为我学校的大多数学生都将 windows 作为他们的主要(或唯一)机器运行。

【问题讨论】:

    标签: python ssh passwords pty unison


    【解决方案1】:

    查看pexpect

    import pexpect
    
    child = pexpect.spawn('ssh myname@host.example.com')
    child.expect('Password:')
    child.sendline(mypassword)
    child.interact()
    

    【讨论】:

    • 我只是尝试在我的项目外面用你所拥有的东西(显然是用一个实际的主机)来测试这个项目,但没有任何反应。稍作停顿,然后回到没有消息的 bash 提示符。我尝试从上面的代码中添加整个执行行,认为如果没有给出任何内容,它可能会关闭,但它会做同样的事情。
    • 确保您传递给 child.expect() 的参数与服务器给您的密码提示相匹配。此外,您可能需要在 child.sendline(mypassword) 之后调用 child.interact()。我使用 pexpect 已经有一段时间了,但它是完成这项工作的工具。
    【解决方案2】:

    如果您想向ssh 发送密码,您需要打开伪终端(pty)并使用它与它交谈,而不仅仅是使用stdin/stdout。看看pexpect 模块,它就是专门为此而设计的。

    另一种解决方案将涉及某种用于分发公钥的带外机制:例如,设置一个简单的 Web 应用程序,人们可以在其中粘贴公钥并让它代表管理 authorized_keys 文件用户的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-17
      • 1970-01-01
      • 2015-09-08
      • 2011-04-22
      • 2023-03-29
      • 2020-12-11
      • 1970-01-01
      相关资源
      最近更新 更多