I am attempting to establish a VPN connection using a ProcessBuilder in Java. However, the process seems to block, and entering my password has no effect.
I am unable to include my username and password directly in the command line because they can change over time, and for security reasons, I am sometimes prompted for a second password.
Any help is welcome
Minimalist sample :
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class VPNConnectionHandler {
public static void main(String[] args) {
String[] command = {"sudo", "openconnect", "--background", "--protocol=nc", "--user=user", "serveradress"};
try {
ProcessBuilder processBuilder = new ProcessBuilder(command);
Process process = processBuilder.start();
BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(process.getErrorStream()));
OutputStreamWriter stdOutput = new OutputStreamWriter(process.getOutputStream());
String line;
boolean passwordPrompted = false;
while ((line = stdInput.readLine()) != null || (line = stdError.readLine()) != null) {
if (line != null) {
System.out.println(line);
if (line.toLowerCase().contains("password:")) {
System.out.println("password asked");
if (!passwordPrompted) {
System.out.print("password ");
BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));
String password = consoleReader.readLine();
stdOutput.write(password + "\n");
stdOutput.flush();
passwordPrompted = true;
}
}
}
if (line == null) {
break;
}
}
int exitCode = process.waitFor();
System.out.println("Process exited with code " + exitCode);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
Using G00se idea, my concern is I don't know how to redirect the output so I can read it in Java and input via the code :
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
public class VPNConnectionManager {
public static void main(String[] args) {
String[] command = {"sudo", "openconnect", "--background", "--protocol=nc", "--user=user", "server"};
try {
ProcessBuilder processBuilder = new ProcessBuilder(command).inheritIO();
Process process = processBuilder.start();
//password request
//scanner or what ever to I can fill in the password
int exitCode = process.waitFor();
System.out.println("Process exited with code " + exitCode);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
Maybe this can help me, but no idea how to make it work here :
ProcessBuilder. Strangely it's mentioned in the title but not in the code - it will give you more control. Then, as the second step, you should read stderr in a separate thread. Are you entering a password forsudotoo? If so, try to get rid of that for this command in sudoersProcess process = processBuilder.inheritIO().start(); // END of codeWhat happens?