如何在Java程序中拦截SSH密码请求

问题描述 投票:2回答:2

我需要使用ProcessBuilder和USERID / PASSWORD组合从JAVA程序中产生SSH连接。

我已经使用Ganymed,JSch,JAVA Processbuilder和Expect脚本(也包括Expect4J),JAVA ProcessBuilder和SSHPASS脚本以及SSH共享密钥的组合成功实现了SSH连接。

此时安全性不是问题,我所能做的就是能够以编程方式支持SSH连接的各种组合。

[我的问题是SSH抛出的密码提示不在STDIN / STDOUT上(我认为是在tty上)。这是我要克服的最后一个障碍。

我的问题是否有办法拦截SSH密码请求并从我的JAVA代码中提供它?

请注意,这是一个非常狭窄的问题(并且以上所有信息都是为​​了确保答案不会太广泛)。

这里是我正在尝试的示例代码:

import  java.io.*;
import  java.util.*;

public class ProcessBuilderTest {
    public  static void main(String[] args) throws IOException, Exception {

        ProcessBuilder pb = new ProcessBuilder(
                                "/usr/bin/ssh",
                                "[email protected]",
                                "export NOME='Jennifer Lawrence'; echo $NOME"
                                );


        pb.redirectErrorStream(); //redirect stderr to stdout
        Process process = pb.start();
        InputStream inputStream = process.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        String line = null;
        while((line = reader.readLine())!= null) {
            System.out.println(line);
        }
        process.waitFor();
     }
}

但是,当我运行它时,我得到了:

[memphis BuilderTest]# java ProcessBuilderTest

myuser@myserver's password: 

然后输入密码后,我得到了其余的输出:

Jennifer Lawrence

[memphis BuilderTest]# 

同样,具体问题是:是否可以使用JAVA ProcessBuilder界面(不能使用其他语言)使用PasswordAuthentication方法(不能使用其他方法)来生成外部ssh客户端(OpenSSH,Tectia SSH,SecureCRT等),是否可以拦截/捕获密码提示并响应/交互以从我的JAVA代码中提供该密码(因此用户无需键入密码)?

java ssh passwords tty
2个回答
0
投票

假设您在Linux上运行,则需要了解伪tty。密码提示在tty设备上。您将需要构建一个针对伪tty的单独进程,而不是仅继承tty设备,然后您可以截获密码提示。

这是一个中等复杂的过程。

[有一个库支持某些功能:http://www.ganymed.ethz.ch/ssh2/FAQ.html。如果可能,您可能会发现阅读其光源说明。


0
投票

虽然有人建议使用伪tty(pty)来模拟终端,但可接受的答案并不能提供有效的解决方案,也有很多类似的问题,没有有效的答案。

这里有两种解决方案,可让您在SSH中捕获“ Password:”提示并以自动方式输入密码,而无需使用SSH_ASKPASS或Expect。

为什么使用一种编程语言却可以同时使用两种-第一种选择并不理想,但是它展示了解决方案:

ProcessBuilder pb = new ProcessBuilder("/usr/bin/python", "-c", "import pty; pty.spawn(['/usr/bin/ssh', '<hostname>'])");

上面的示例利用Python pty模块将SSH包装到PTY中。尽管很简单,但是它没有提供任何灵活性来允许您修改任何终端属性,例如传递的窗口大小。

另一个更轻便的选择是在C中使用PTY包装器-“UNIX®环境中的高级编程”书中的pty工具就是这样-可以在https://github.com/abligh/pty中找到源。

然后您将以类似的方式使用它,但是引用pty工具而不是Python:

ProcessBuilder pb = new ProcessBuilder("/usr/local/bin/pty", "/usr/bin/ssh", "<hostname>");

这与Expect模拟PTY的方法相同,这就是为什么您可以使用Expect截获它的原因。不用说,隧道明文密码是不安全的,公钥身份验证应该始终是首选的方式。

© www.soinside.com 2019 - 2024. All rights reserved.