Как программно передать ввод в Java keytool?

Я пытаюсь исправить проблему в проекте с открытым исходным кодом https://github.com/jcabi/jcabi-ssl-maven-plugin.

Проблема возникает в методе com.jcabi.ssl.maven.plugin.Keytool#genkey:

@Loggable(Loggable.DEBUG)
public void genkey() throws IOException {
    final Process proc = this.proc(
        "-genkeypair",
        "-alias",
        "localhost",
        "-keyalg",
        "RSA",
        "-keysize",
        "2048",
        "-keypass",
        this.password
    ).start(); // Here we launch the keytool
    final PrintWriter writer = new PrintWriter(
        new OutputStreamWriter(proc.getOutputStream())
    );
    writer.print("localhost\n"); // These and other writer.print(...) statements 
    writer.print("ACME Co.\n"); // write answers to questions of keytool
    writer.print("software developers\n");
    writer.print("San Francisco\n");
    writer.print("California\n");
    writer.print("US\n");
    writer.print("yes\n");
    writer.close();
    new VerboseProcess(proc).stdout();
    Logger.info(
        this,
        "Keystore created in '%s' (%s)",
        this.keystore,
        FileUtils.byteCountToDisplaySize(this.keystore.length())
    );
}

Целью этого кода является

  1. запустить программу Java keytool и
  2. ответить на его вопросы в командной строке.

Первый шаг включает в себя программный вызов, как "C:\Program Files\Java\jdk1.8.0\jre\bin\keytool" -genkeypair -alias localhost -keyalg RSA -keysize 2048 -keypass some-password -storetype jks -noprompt -storepass some-password -keystore C:\Users\DP118M\AppData\Local\Temp\junit4133348108660376680\keystore.jks,

Затем keytool задает вам несколько вопросов (см. Ниже, перевод с немецкого):

What is your name?
  [Unknown]:  A
What is the name of your organizational unit?
  [Unknown]:  A
What is the name of your organisation?
  [Unknown]:  A
What is the name of your city or county?
  [Unknown]:  A
What is the name of your state?
  [Unknown]:  A
What is the country code of your organizational unit?
  [Unknown]:  A
Is CN=A, OU=A, O=A, L=A, ST=A, C=A correct?
  [No]:  Yes

Вместо того, чтобы вводить ответы (A выше) вручную, код выше использует writer.print(...); заявления.

Но они, очевидно, не работают, потому что когда я запускаю тест, который включает использование keytool (например, com.jcabi.ssl.maven.plugin.CacertsTest#importCertificatesFromKeystore), я получаю следующую ошибку:

java.lang.IllegalArgumentException: Non-zero exit code 1: Keytool Error: java.lang.RuntimeException: Too many repeated attempts. Program will be terminated.
\n
    at com.jcabi.log.VerboseProcess.stdout(VerboseProcess.java:220)
    at com.jcabi.log.VerboseProcess.stdout(VerboseProcess.java:158)
    at com.jcabi.ssl.maven.plugin.Keytool.genkey(Keytool.java:116)
    at com.jcabi.ssl.maven.plugin.Keystore.activate(Keystore.java:121)
    at com.jcabi.ssl.maven.plugin.CacertsTest.importsCertificatesFromKeystore(CacertsTest.java:64)

Я предполагаю, что основной причиной этой проблемы является то, что writer.print(...); заявления не доставляют свои тексты в keytool.

Как я могу это исправить (убедитесь, что в com.jcabi.ssl.maven.plugin.Keytool#genkey метод сообщения, написанные writer.print(...); правильно доставлены keytool)

Обновление 1 (28.12.2014 мск):

Я думаю, что нашел причину. Я запускаю свой тест на Windows, поэтому звонки, как writer.print("localhost\n"); должны быть заменены writer.print("localhost" + System.getProperty("line.separator"));,

Это просто.

Но есть и другая часть. Разработчики этого кода, очевидно, работали над англоязычной версией keytool, поэтому в конце она ожидает yes (см. последний вопрос в примере вывода keytool выше).

Поэтому есть утверждение

writer.print("yes\n");

Но я использую немецкую версию Windows, поэтому в моем случае правильный ответ не yes, но Ja,

Если я изменяю код следующим образом, он работает (тест не проходит):

final String newLine = System.getProperty("line.separator");
writer.print("localhost" + newLine);
writer.print("ACME Co." + newLine);
writer.print("software developers" + newLine);
writer.print("San Francisco" + newLine);
writer.print("California" + newLine);
writer.print("US" + newLine);
writer.print("Ja" + newLine);

Я ценю советы о том, как заставить эту часть кода работать на операционных системах с любым языком (как избежать жесткого кодирования yes а также Ja).

0 ответов

Другие вопросы по тегам