I have a daemon in java, that I am running via jsvc. Most of the daemon works fine, however I have been having trouble getting it to transfer files via SCP. Due to the setup of the computers I will be transferring files to, I am required to use public key authentication. However this appears to require that the parent process be associated with a terminal, failing if there isn't. It never seems to get to the stage of actually asking for the password, failing before then.
Java Code Snippet, creating process
String[] command = { "scp", "-v", "-o", "PubkeyAuthentication=no",
localFile.getAbsolutePath(),
username + "@" + destinationIP + ":" + destinationPath };
ProcessBuilder builder = new ProcessBuilder(command);
builder.redirectErrorStream(true);
Process scpProcess = builder.start();
Providing password
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;
}
}
Log file snippet with verbose SCP output
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).
As far as I can tell, what is happening is that the created process inherits the tty from the parent process, which is unset due to jsvc running it as a daemon. However I require this process to run as a Daemon, and cannot change that.
Does anyone know how I can force the process to run with a tty, so that it doesn't do this - while still being capable of accessing the input/output/error streams from the parent java program? Failing that, does anyone know a different way to get the SCP transfer to work, that uses password authentication? Does anyone have any other ideas for a solution to this problem?
All OpenSSH binaries, including the scp
, are built to prevent an automated password/passphrase input. An insistence on TTY is one of the measures.
Two solutions:
sshpass
to fake TTY. See the sshpass man page.See also How to pass password to scp command used in bash script?