我需要使用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",
"nyuser@myserver.com",
"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]#
同样,具体问题是: 有没有办法使用PasswordAuthentication方法生成外部ssh客户端(OpenSSH,Tectia SSH,SecureCRT等)(没有其他方法可以使用)进程使用JAVA ProcessBuilder接口(不能使用其他语言),拦截/捕获密码提示并响应/交互从我的JAVA代码提供该密码(因此用户不需要输入密码)?
答案 0 :(得分:0)
假设您在Linux上运行,您需要了解伪ttys。密码提示位于tty设备上。您将需要构建一个针对伪tty运行的单独进程,而不是仅继承您的tty设备,然后您可以拦截密码提示。
这是一个中等复杂的过程。
有一个图书馆支持其中一些:http://www.ganymed.ethz.ch/ssh2/FAQ.html。如果可用,你可能会发现阅读它的来源是有启发性的。
答案 1 :(得分: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
工具就是这样-来源可以在{{3}中找到}。
然后,您将以类似的方式使用它,但是引用pty
工具而不是Python:
ProcessBuilder pb = new ProcessBuilder("/usr/local/bin/pty", "/usr/bin/ssh", "<hostname>");
这与Expect用于模拟PTY的方法相同,这就是为什么您能够使用Expect拦截它的原因。不用说,隧道明文密码是不安全的,公钥身份验证应该始终是首选方法。