javabashprocessscp

Scp process invoked from Daemon thread fails with missing /dev/tty


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?


Solution

  • 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:

    See also How to pass password to scp command used in bash script?