I am using OpenSSL in my c++ app, The problem is if I use exec("Open ssl command")
Then it will execute that particular command , but actually this command is repsonsive,I mean it further asks you "Are you sure you want to do this Y/N?"
I don't know how to cater this scenario.How can I use java or C++ to run a command line which is responsive,Any help would be appreciated.
Thanks
-
Can you tell me what you are trying to do??require_once– require_once2012-12-09 20:28:26 +00:00Commented Dec 9, 2012 at 20:28
-
1@ZainShah120 I am trying to use OpenSSL to create certificates..I want to give OpenSSL command a user interface..user1765876– user17658762012-12-09 20:29:22 +00:00Commented Dec 9, 2012 at 20:29
-
1Maybe this can help: superuser.com/questions/375078/…JGaarsdal– JGaarsdal2012-12-15 19:33:59 +00:00Commented Dec 15, 2012 at 19:33
-
@JesperGaarsdal it only helps in creating batch fileuser1765876– user17658762012-12-16 13:09:47 +00:00Commented Dec 16, 2012 at 13:09
-
IMHO you should use the OpenSSL libs rather than shell out, as described here: stackoverflow.com/questions/256405/…Alastair McCormack– Alastair McCormack2012-12-22 00:07:12 +00:00Commented Dec 22, 2012 at 0:07
3 Answers
Easy enough in Java. Just:
- Get the Process handle.
- Read the Process' input stream for prompts written to stdout.
- Respond to prompts by writing to the Process' output stream.
Here's a quick Groovy sample because it's even easier than Java:
def cmd = ... // the command you want to run
def process = cmd.execute()
def processStdout = new Scanner(process.inputStream)
def processStdin = process.outputStream
def outputLine = processStdout.nextLine()
if (outputLine == 'some prompt written to stdout') {
processStdin << 'your response\n'
}
If you can't follow the Groovy, I can expand it to Java.
Note that this sample doesn't handle the potentially important tasks of ensuring the stdout and stderr of the nested process are fully consumed to prevent blocking, nor does it handle ensuring the process exits cleanly.
Update: Here's that same thing in Java:
import java.io.OutputStream;
import java.util.Scanner;
public class SubprocessIO {
public static void main(String[] args) throws Exception {
String[] cmd = { ... your command as a series of strings ... };
Process process = Runtime.getRuntime().exec(cmd);
Scanner processStdout = new Scanner(process.getInputStream());
OutputStream processStdin = process.getOutputStream();
String outputLine = processStdout.nextLine();
if (outputLine.equals("some prompt written to stdout")) {
processStdin.write("your response\n".getBytes());
processStdin.flush();
}
}
}
I forgot to make a note on the first go-round that the \n in the response is crucial, assuming the app is expecting you to enter something and then press Enter. Also, you're probably better off using the line.separator system property
6 Comments
your response in the examples.stdout in order to continue the process.stdout.Basically you just need to make sure you enter all required information on the commandline, and use -batch to avoid further questions, for example:
openssl ca -days 3650 -out client.crt -in client.csr -config \path\to\configs -batch -passin pass:PASSWORD -key password
If this does not work for any specific openssl command, please specify it in your question which command you need to execute.
2 Comments
For openssl the answer by Wimmel is the right approach. Depending on your exact use case, you may want to prepare or construct a configuration file that contains recurring parameters and specify the varying parameters (and a pointer to the config file) on the command line. The -batch option, that is available at least with the common openssl commands for managing certificates will ensure that no interactivity occurs - if you have specified insufficient parameters the commands will fail.
For running the command and evaluating its results, you still need the corresponding functionality. In Java you use the ProcessBuilder and Process classes. In C++ there is no standard way to do this (the system() function is too limited for most uses), so you need to use platform-specific C functions (e.g. CreateProcess, posix_spawn or fork/exec) or find a suitable C++ library.
But for directly answering interactive questions programmatically these interfaces may be insufficient. Interactive dialog may be quite complicated. Typically this is not as simple as treating all input and output as a simple character stream. Details depend on the platform and program, but you may need something like expect (see http://en.wikipedia.org/wiki/Expect) to deal with this.
Update: of course the approach to invoke an external CLI for all of this is not necessarily the best and introduces a whole new set of extraneous side-issues. You may be better off using a suitable cryptographic API (for example BouncyCastle http://www.bouncycastle.org/)