Как да доставя sudo с root парола от Java?

Опитвам се да напиша малко Java приложение, което ще презапише моя /etc/resolv.conf файл (аз съм на Ubuntu 12.04). За целта трябва да въведа паролата си root:

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

Така че процесът за това има три стъпки:

  1. Въведете sudo vim /etc/resolv.conf на терминала
  2. Терминалът ме моли да напиша паролата си root
  3. Въвеждам паролата и натискам [Enter]

От всичко, което проучих, мога да използвам следното за изпълнение на стъпка №1 по-горе:

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

Но когато това се изпълни, обвивката ще иска да подкани моя Java процес за паролата. Не съм сигурен как да изчакам това (стъпка #2 по-горе) и след това да върна паролата си обратно в обвивката (стъпка #3 по-горе). Благодаря предварително.


person IAmYourFaja    schedule 24.12.2012    source източник
comment
Мисля, че това решение трябва да работи: stackoverflow.com /questions/233217/pass-password-to-su-sudo-ssh   -  person Philip Whitehouse    schedule 24.12.2012
comment
Вместо да echo-въвеждате паролата, можете също да използвате Process.getOutputStream() и след това напишете паролата за този поток.   -  person JimmyB    schedule 24.12.2012


Отговори (2)


Опитахте ли с -S?

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

От човека:

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.
person Luigi R. Viggiano    schedule 24.12.2012

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

}

Вдъхновен от отговора на Viggiano.

person Ashish Doneriya    schedule 26.05.2017
comment
Знам, че това е старо и че беше само пример, но исках да предупредя, че е лоша практика да се поставят пароли в низове. Това води до задържане на паролата в паметта за неопределено време. Във вашия случай, тъй като сте използвали литерал, той се съхранява в паметта за живота на JVM. Трябва да държите некриптирани пароли в паметта за възможно най-кратко време и трябва да ги съхранявате възможно най-ефимерно -- обикновено се предпочита char[]. - person JakeRobb; 27.09.2018
comment
@JakeRobb как някой може да намери паролата от JVM. - person Ashish Doneriya; 01.10.2018