4

I'm trying to write a small Java app that will overwrite my /etc/resolv.conf file (I'm on Ubuntu 12.04). To do so, I need to supply my root password:

myUser@myMachine:~$ sudo vim /etc/resolv.conf 
[sudo] password for myUser: *****

So the process for doing this has three steps:

  1. Type sudo vim /etc/resolv.conf at terminal
  2. Terminal asks me to type my root password
  3. I enter the password and press [Enter]

From everything I've researched, I could use the following for performing step #1 above:

try {
    String installTrickledCmd = "sudo vim /etc/resolv.conf";
    Runtime runtime = Runtime.getRuntime();
    Process proc = runtime.exec(installTrickledCmd);
}
catch(Throwable throwable) {
    throw new RuntimeException(throwable);
}

But when this executes, the shell will want to prompt my Java process for the password. I'm not sure how to wait for this (step #2 above) and then to supply my password back to the shell (step #3 above). Thanks in advance.

IAmYourFaja
  • 50,141
  • 159
  • 435
  • 728
  • 1
    I think this solution should work: http://stackoverflow.com/questions/233217/pass-password-to-su-sudo-ssh – Philip Whitehouse Dec 24 '12 at 00:26
  • 1
    Instead of `echo`-ing the password you can also use [`Process.getOutputStream()`](http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Process.html#getOutputStream%28%29) and then write the password to that stream. – JimmyB Dec 24 '12 at 00:30

2 Answers2

9

Have you tried with -S ?

$echo mypassword | sudo -S vim /etc/resolv.conf

From man:

The -S (stdin) option causes sudo to read the password from the standard input 
instead of the terminal device.  The password must be followed by a newline 
character.
Luigi R. Viggiano
  • 8,103
  • 6
  • 46
  • 60
0
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;

public class Test1 {

  public static void main(String[] args) throws Exception {
    String[] cmd = {"sudo","-S", "ls"};
    System.out.println(runSudoCommand(cmd));
  }

  private static int runSudoCommand(String[] command) throws Exception {

    Runtime runtime =Runtime.getRuntime();
    Process process = runtime.exec(command);
    OutputStream os = process.getOutputStream();
    os.write("harekrishna\n".getBytes());
    os.flush();
    os.close();
    process.waitFor();
    String output = readFile(process.getInputStream());
    if (output != null && !output.isEmpty()) {
      System.out.println(output);
    }
    String error = readFile(process.getErrorStream());
    if (error != null && !error.isEmpty()) {
      System.out.println(error);
    }
    return process.exitValue();
  }

  private static String readFile(InputStream inputStream) throws Exception {
    if (inputStream == null) {
      return "";
    }
    StringBuilder sb = new StringBuilder();
    BufferedReader bufferedReader = null;
    try {
      bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
      String line = bufferedReader.readLine();
      while (line != null) {
        sb.append(line);
        line = bufferedReader.readLine();
      }
      return sb.toString();
    } finally {
      if (bufferedReader != null) {
        bufferedReader.close();
      }
    }
  }

}

Inspired from Viggiano answer.

Ashish Doneriya
  • 1,155
  • 10
  • 15
  • 1
    I know this is old, and that it was just a sample, but I wanted to warn that it's bad practice to put passwords in Strings. This results in the password behind held in memory indefinitely. In your case, because you used a literal, it's held in memory for the lifetime of the JVM. You should hold unencrypted passwords in memory for as short a time as possible, and you should store it as ephemerally as possible -- typically, char[] is preferred. – JakeRobb Sep 27 '18 at 18:54
  • @JakeRobb how somebody could find the password from JVM. – Ashish Doneriya Oct 01 '18 at 07:41