我有一个java守护进程,我通过jsvc运行。大多数守护进程工作正常,但我在让它通过 SCP 传输文件时遇到了麻烦。由于我将要传输文件的计算机的设置,我需要使用公钥身份验证。然而,这似乎要求父进程与终端关联,如果没有,则会失败。它似乎从未达到实际要求密码的阶段,在此之前就失败了。
Java 代码片段,创建过程
String[] command = { "scp", "-v", "-o", "PubkeyAuthentication=no",
localFile.getAbsolutePath(),
username + "@" + destinationIP + ":" + destinationPath };
ProcessBuilder builder = new ProcessBuilder(command);
builder.redirectErrorStream(true);
Process scpProcess = builder.start();
提供密码
InputStream inStream = scpProcess.getInputStream();
InputStreamReader inReader = new InputStreamReader(inStream);
bInReader = new BufferedReader(inReader);
String recievedLine = null;
StringBuilder recievedLines = new StringBuilder();
boolean passwordFlag = false;
while ((recievedLine = bInReader.readLine()) != null) {
recievedLines.append(recievedLine + "\n");
// send password to the scp program
if (recievedLine.contains("password:")) {
OutputStream outStream = scpProcess.getOutputStream();
OutputStreamWriter outWriter = new OutputStreamWriter(
outStream);
bOutWriter = new BufferedWriter(outWriter);
bOutWriter.write(password + "\n");
bOutWriter.flush();
passwordFlag = true;
break;
}
}
带有详细 SCP 输出的日志文件片段
debug1: read_passphrase: can't open /dev/tty: No such device or address
debug1: Authentications that can continue: publickey,password,keyboard-interactive
Permission denied, please try again.
debug1: read_passphrase: can't open /dev/tty: No such device or address
debug1: Authentications that can continue: publickey,password,keyboard-interactive
Permission denied, please try again.
debug1: read_passphrase: can't open /dev/tty: No such device or address
debug1: Authentications that can continue: publickey,password,keyboard-interactive
debug1: No more authentication methods to try.
Permission denied (publickey,password,keyboard-interactive).
据我所知,所发生的情况是创建的进程从父进程继承了 tty,由于 jsvc 将其作为守护进程运行,因此未设置该 tty。但是我要求这个进程作为守护进程运行,并且无法更改它。
有谁知道我如何强制进程使用 tty 运行,这样它就不会这样做 - 同时仍然能够从父 java 程序访问输入/输出/错误流?如果做不到这一点,有谁知道使用密码身份验证来使 SCP 传输正常工作的不同方法吗?有没有人有任何其他想法来解决这个问题?
所有 OpenSSH 二进制文件(包括
scp
)都是为了防止自动密码/密码输入而构建的。坚持使用 TTY 是措施之一。
两种解决方案:
sshpass
来伪造 TTY。请参阅 sshpass 手册页。