Question

I am need to spawn a SSH connection from a JAVA program using ProcessBuilder and a USERID/PASSWORD combination.

I have already successfully implemented SSH connections using Ganymed, JSch, a combination of JAVA Processbuilder and Expect scripting (Expect4J also), JAVA ProcessBuilder and SSHPASS script and SSH Shared Key.

Security is NOT a concern at this point in time and all I am after is to be able to support programmatically all kinds of combinations for SSH connection.

My problem is the Password prompt that SSH throws somewhere that is not on STDIN/STDOUT (on a tty I believe). This is my last hurdle to overcome.

My question is there a way to intercept SSH password request and provide it from my JAVA code?

Please, note this is a very narrow question (and all the above information was to guarantee the answer would not be too broad).

Here is a sample code of what I am trying:

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();
     }
}

But, when I run it I got this:

[memphis BuilderTest]# java ProcessBuilderTest

myuser@myserver's password: 

and after I type the password, I got the rest of the output:

Jennifer Lawrence

[memphis BuilderTest]# 

Again, the specific question is: Is there a way to spawn an external ssh client (OpenSSH, Tectia SSH, SecureCRT, etc) using PasswordAuthentication method (no other method can be used) process using JAVA ProcessBuilder interface (no other language can be used), intercept/capture the password prompt and respond/interact providing that password from my JAVA code (so the user does not need to type it)?

Was it helpful?

Solution

You need to learn about pseudo-ttys, assuming that you are operating on Linux. The password prompt is on the tty device. You will need to build a separate process running against a pseudo-tty instead of just inheriting your tty device, and then you can intercept the password prompt.

This is a moderately complex process.

There is a library that supports some of this: http://www.ganymed.ethz.ch/ssh2/FAQ.html. You might find reading its source illuminating if it is available.

OTHER TIPS

While it has been suggested that a pseudo-tty (pty) is required to simulate a terminal, the accepted answer doesn't provide a working solution - there are also lots of similar questions with no working answers.

Here are two solutions that allow you to capture the "Password:" prompt in SSH and enter the password in an automated way without using SSH_ASKPASS or Expect.

Why use one programming language when you can use two - the first option isn't ideal, but it demonstrates the solution:

ProcessBuilder pb = new ProcessBuilder("/usr/bin/python", "-c", "import pty; pty.spawn(['/usr/bin/ssh', '<hostname>'])");

The above example makes use of the Python pty module to wrap SSH into a PTY. Although it is simple, it doesn't provide any flexibility to allow you to modify any terminal properties like the passed window size.

The other more lightweight option is to use a PTY wrapper in C - the pty tool from the "Advanced Programming in the UNIX® Environment" book is just this - the source can be found at https://github.com/abligh/pty.

You will then use it in a similar way, but referencing the pty tool instead of Python:

ProcessBuilder pb = new ProcessBuilder("/usr/local/bin/pty", "/usr/bin/ssh", "<hostname>");

This is the same approach that Expect uses to simulate a PTY, which is why you are able to intercept it using Expect. It goes without saying that tunneled clear text passwords are insecure and public key authentication should always be the preferred way of doing this.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top