From 5f2e24fdc9935d049a7e4a5b6e10461e9467597f Mon Sep 17 00:00:00 2001
From: Nikos Mavrogiannopoulos <nmav@gnutls.org>
Date: Thu, 18 Jun 2015 22:38:05 +0200
Subject: [PATCH] Allow processing two passwords from stdin in non-interactive
 mode

Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org>
---
 main.c | 38 ++++++++++++++++++++++++++------------
 1 file changed, 26 insertions(+), 12 deletions(-)

diff --git a/main.c b/main.c
index 3b976d8..f853afe 100644
--- a/main.c
+++ b/main.c
@@ -85,6 +85,7 @@ static int do_passphrase_from_fsid;
 static int nocertcheck;
 static int non_inter;
 static int cookieonly;
+static int allow_stdin_read;
 
 static char *token_filename;
 static char *server_cert = NULL;
@@ -358,7 +359,7 @@ static char *convert_arg_to_utf8(char **argv, char *arg)
 #define vfprintf vfprintf_utf8
 #define is_arg_utf8(str) (0)
 
-static void read_stdin(char **string, int hidden)
+static void read_stdin(char **string, int hidden, int allow_fail)
 {
 	CONSOLE_READCONSOLE_CONTROL rcc = { sizeof(rcc), 0, 13, 0 };
 	HANDLE stdinh = GetStdHandle(STD_INPUT_HANDLE);
@@ -375,6 +376,7 @@ static void read_stdin(char **string, int hidden)
 		char *errstr = openconnect__win32_strerror(GetLastError());
 		fprintf(stderr, _("ReadConsole() failed: %s\n"), errstr);
 		free(errstr);
+		*string = NULL;
 		goto out;
 	}
 
@@ -622,7 +624,7 @@ static void print_build_opts(void)
 
 #ifndef _WIN32
 static const char default_vpncscript[] = DEFAULT_VPNCSCRIPT;
-static void read_stdin(char **string, int hidden)
+static void read_stdin(char **string, int hidden, int allow_fail)
 {
 	char *c, *buf = malloc(1025);
 	int fd = fileno(stdin);
@@ -648,8 +650,14 @@ static void read_stdin(char **string, int hidden)
 	}
 
 	if (!buf) {
-		perror(_("fgets (stdin)"));
-		exit(1);
+		if (allow_fail) {
+			*string = NULL;
+			free(buf);
+			return;
+		} else {
+			perror(_("fgets (stdin)"));
+			exit(1);
+		}
 	}
 
 	c = strchr(buf, '\n');
@@ -1160,13 +1168,14 @@ int main(int argc, char **argv)
 			cookieonly = 3;
 			break;
 		case OPT_COOKIE_ON_STDIN:
-			read_stdin(&vpninfo->cookie, 0);
+			read_stdin(&vpninfo->cookie, 0, 0);
 			/* If the cookie is empty, ignore it */
 			if (!*vpninfo->cookie)
 				vpninfo->cookie = NULL;
 			break;
 		case OPT_PASSWORD_ON_STDIN:
-			read_stdin(&password, 0);
+			read_stdin(&password, 0, 0);
+			allow_stdin_read = 1;
 			break;
 		case OPT_NO_PASSWD:
 			vpninfo->nopasswd = 1;
@@ -1708,7 +1717,7 @@ static int validate_peer_cert(void *_vpninfo, const char *reason)
 		fprintf(stderr, _("Enter '%s' to accept, '%s' to abort; anything else to view: "),
 		       _("yes"), _("no"));
 
-		read_stdin(&response, 0);
+		read_stdin(&response, 0, 0);
 		if (!response)
 			return -EINVAL;
 
@@ -1779,19 +1788,24 @@ static char *prompt_for_input(const char *prompt,
 			      struct openconnect_info *vpninfo,
 			      int hidden)
 {
-	char *response;
+	char *response = NULL;
 
 	fprintf(stderr, "%s", prompt);
 	fflush(stderr);
 
 	if (non_inter) {
-		fprintf(stderr, "***\n");
-		vpn_progress(vpninfo, PRG_ERR,
+		if (allow_stdin_read) {
+			read_stdin(&response, hidden, 1);
+		}
+		if (response == NULL) {
+			fprintf(stderr, "***\n");
+			vpn_progress(vpninfo, PRG_ERR,
 			     _("User input required in non-interactive mode\n"));
-		return NULL;
+		}
+		return response;
 	}
 
-	read_stdin(&response, hidden);
+	read_stdin(&response, hidden, 0);
 	return response;
 }
 
-- 
2.1.4