我需要使用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代码中提供该密码(因此用户无需键入密码)?
假设您在Linux上运行,则需要了解伪tty。密码提示在tty设备上。您将需要构建一个针对伪tty的单独进程,而不是仅继承tty设备,然后您可以截获密码提示。
这是一个中等复杂的过程。
[有一个库支持某些功能:http://www.ganymed.ethz.ch/ssh2/FAQ.html。如果可能,您可能会发现阅读其光源说明。
虽然有人建议使用伪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截获它的原因。不用说,隧道明文密码是不安全的,公钥身份验证应该始终是首选的方式。