如何在Windows系统中通过stdin输入密码给ssh?

6

在阅读了这个问题和我的答案之后,我希望在Windows上做类似的事情。

我的Linux解决方案是这样的:

#!/bin/bash
[[ $1 =~ password: ]] && cat || SSH_ASKPASS="$0" DISPLAY=nothing:0 exec setsid "$@"

我如何在Windows上做类似的事情,比如我可以从Windows 命令提示符或批处理文件中使用这样的东西:

C:> echo password | pass ssh user@host ...

注意事项:

  • ssh 是使用 crwsync 的免费版本进行安装的。它使用 Cygwin DLLs,但不需要 Cygwin 安装。
  • 解决方案不应需要进一步的依赖项:它可以在典型的 Windows 命令提示符 或批处理文件中运行。

我正在寻找以上问题的答案,即使答案是“无法完成”。我知道我可以使用密钥(及其相关优点)或其他工具,如 Python/Paramiko、PuTTY plink 等等。我知道我可以在 Cygwin 环境中完成。但我不想这样做……我需要在普通的 Windows 命令提示符或批处理文件中完成,而不会产生额外的依赖,因为如果可能的话,这将减少现有的依赖关系。

以下是我目前的进展:

@echo off
echo.%1 | findstr /C:"password">nul
if errorlevel 1 (
  set SSH_ASKPASS="%0"
  set DISPLAY="nothing:0"
  %*
) else (
  findstr "^"
)

这个想法是将它保存为,比如说pass.bat,然后像这样使用它:
C:> echo password | pass.bat ssh user@host ...

发生的情况是SSH会话被启动,但ssh仍然会交互式地提示输入密码。我认为,在理论上,脚本是可以正常工作的,因为以下内容有效:
C:> echo mypassword | pass.bat pass.bat "password"
mypassword

据我所知,底层的Cygwin DLL应该能够看到Windows环境,因此SSH_ASKPASS的设置应该会传播到ssh中。我认为问题在于ssh连接到了终端。根据man ssh的说明,如果ssh需要密码短语,它将从当前终端读取密码短语,如果它是从终端运行的。这就是为什么我在Linux示例中使用setsid的原因。我认为需要一种在Windows中将进程与终端分离的方法,但我不确定是否有这样的方法(我尝试过start /B)。所以我陷入了困境 - 我不知道足够了解脚本编写Windows的知识来知道什么应该起作用。任何使用本地Windows技术(即批处理或PowerShell)并且不需要任何不可用于基本Windows的内容的解决方案都将受到欢迎。
这个解决方案将被一个跨平台应用程序使用,我正在开发这个应用程序,需要使用SSH与外部服务进行交互。当前的原型版本是Python,并且已经连接到启动ssh作为子进程。Linux版本已经使用了上述方法,因此我希望有一个不需要重新设计应用程序的Windows解决方案。
1个回答

0

SSH 永远不会从标准输入读取密码。我建议使用 sshpass 工具,这是这个任务的标准工具。另一个常见的解决方案是使用 expect 脚本(在 Cygwin 和 Linux 上的使用方式相同)。


我确实说过我知道那些东西,而且我特别在寻找 本地的Windows解决方案,如果有的话。 - starfry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接