[David Huggins-Daines <dhd at plcom.on.ca>] Bug#52414: ssh-add uses ssh-askpass, but ssh doesn't

Philip Hands phil at hands.com
Sat Dec 11 04:13:20 EST 1999


Damien,

Here's a forwarded bug for you.

Cheers, Phil.
--[[message/rfc822]]
Subject: Bug#52414: ssh-add uses ssh-askpass, but ssh doesn't
Reply-To: David Huggins-Daines <dhd at plcom.on.ca>, 52414 at bugs.debian.org
Resent-From: David Huggins-Daines <dhd at plcom.on.ca>
Resent-To: debian-bugs-dist at lists.debian.org
Resent-CC: Philip Hands <phil at hands.com>
Resent-Date: Fri, 10 Dec 1999 04:18:07 GMT
Resent-Message-ID: <handler.52414.B.94479901811999 at bugs.debian.org>
Resent-Sender: owner at bugs.debian.org
Date: Thu, 9 Dec 1999 23:10:16 -0500
From: David Huggins-Daines <dhd at plcom.on.ca>
To: submit at bugs.debian.org
Message-ID: <19991209231016.A9982 at elgin.plcom.on.ca>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii

Package: ssh
Version: 1.2pre16-1
Severity: normal

Hi,

OpenSSH's 'ssh' program doesn't seem to mimic the non-free SSH's behaviour
of calling ssh-askpass when it's not possible to read the pass{phrase,word}
from a terminal.

This is rather inconvenient for things like pcl-cvs in Emacs.  Here's a patch
that makes OpenSSH act more like the non-free one:

diff -ur openssh-1.2pre16/readpass.c openssh-1.2pre16.patched/readpass.c
--- openssh-1.2pre16/readpass.c	Wed Nov 24 19:54:59 1999
+++ openssh-1.2pre16.patched/readpass.c	Thu Dec  9 22:34:23 1999
@@ -38,6 +38,47 @@
 	kill(getpid(), sig);
 }
 
+/* Calls the external program specified to read a passphrase (usually
+   used to invoke ssh-askpass when running with $DISPLAY but no TTY) */
+
+char *
+ssh_askpass(const char *askpass, const char *msg)
+{
+	pid_t pid;
+	size_t len;
+	char *nl, *pass;
+	int p[2], status;
+	char buf[1024];
+
+	if (askpass == NULL)
+		fatal("internal error: askpass undefined");
+	if (pipe(p) < 0)
+		fatal("ssh_askpass: pipe: %s", strerror(errno));
+	if ((pid = fork()) < 0)
+		fatal("ssh_askpass: fork: %s", strerror(errno));
+	if (pid == 0) {
+		close(p[0]);
+		if (dup2(p[1], STDOUT_FILENO) < 0)
+			fatal("ssh_askpass: dup2: %s", strerror(errno));
+		execlp(askpass, askpass, msg, (char *) 0);
+		fatal("ssh_askpass: exec(%s): %s", askpass, strerror(errno));
+	}
+	close(p[1]);
+	len = read(p[0], buf, sizeof buf);
+	close(p[0]);
+	while (waitpid(pid, &status, 0) < 0)
+		if (errno != EINTR)
+			break;
+	if (len <= 1)
+		return xstrdup("");
+	nl = strchr(buf, '\n');
+	if (nl)
+		*nl = '\0';
+	pass = xstrdup(buf);
+	memset(buf, 0, sizeof(buf));
+	return pass;
+}
+
 /*
  * Reads a passphrase from /dev/tty with echo turned off.  Returns the
  * passphrase (allocated with xmalloc).  Exits if EOF is encountered. The
diff -ur openssh-1.2pre16/ssh-add.c openssh-1.2pre16.patched/ssh-add.c
--- openssh-1.2pre16/ssh-add.c	Sun Dec  5 19:47:29 1999
+++ openssh-1.2pre16.patched/ssh-add.c	Thu Dec  9 22:11:03 1999
@@ -50,44 +50,6 @@
 		fprintf(stderr, "Failed to remove all identitities.\n");
 }
 
-char *
-ssh_askpass(char *askpass, char *msg)
-{
-	pid_t pid;
-	size_t len;
-	char *nl, *pass;
-	int p[2], status;
-	char buf[1024];
-
-	if (askpass == NULL)
-		fatal("internal error: askpass undefined");
-	if (pipe(p) < 0)
-		fatal("ssh_askpass: pipe: %s", strerror(errno));
-	if ((pid = fork()) < 0)
-		fatal("ssh_askpass: fork: %s", strerror(errno));
-	if (pid == 0) {
-		close(p[0]);
-		if (dup2(p[1], STDOUT_FILENO) < 0)
-			fatal("ssh_askpass: dup2: %s", strerror(errno));
-		execlp(askpass, askpass, msg, (char *) 0);
-		fatal("ssh_askpass: exec(%s): %s", askpass, strerror(errno));
-	}
-	close(p[1]);
-	len = read(p[0], buf, sizeof buf);
-	close(p[0]);
-	while (waitpid(pid, &status, 0) < 0)
-		if (errno != EINTR)
-			break;
-	if (len <= 1)
-		return xstrdup("");
-	nl = strchr(buf, '\n');
-	if (nl)
-		*nl = '\0';
-	pass = xstrdup(buf);
-	memset(buf, 0, sizeof(buf));
-	return pass;
-}
-
 void
 add_file(AuthenticationConnection *ac, const char *filename)
 {
diff -ur openssh-1.2pre16/ssh.c openssh-1.2pre16.patched/ssh.c
--- openssh-1.2pre16/ssh.c	Thu Dec  9 22:29:24 1999
+++ openssh-1.2pre16.patched/ssh.c	Thu Dec  9 23:03:19 1999
@@ -81,6 +81,9 @@
 /* Original real UID. */
 uid_t original_real_uid;
 
+/* Flag indicating whether we should try to use ssh-askpass or not */
+int use_askpass = 0;
+
 /* Prints a help message to the user.  This function never returns. */
 
 void
@@ -430,10 +433,20 @@
 
 	/* Do not allocate a tty if stdin is not a tty. */
 	if (!isatty(fileno(stdin))) {
+		FILE *dummy;
 		if (tty_flag)
 			fprintf(stderr, "Pseudo-terminal will not be allocated because stdin is not a terminal.\n");
 		tty_flag = 0;
+
+		/* Now to check if we should be using askpass */
+		if ((dummy = fopen("/dev/tty", "r"))) {
+			fclose(dummy);
+		} else {
+			if (getenv("DISPLAY"))
+				use_askpass = 1;
+		}
 	}
+
 	/* Get user data. */
 	pw = getpwuid(original_real_uid);
 	if (!pw) {
diff -ur openssh-1.2pre16/ssh.h openssh-1.2pre16.patched/ssh.h
--- openssh-1.2pre16/ssh.h	Thu Dec  9 22:29:24 1999
+++ openssh-1.2pre16.patched/ssh.h	Thu Dec  9 22:14:30 1999
@@ -429,6 +429,12 @@
 char   *read_passphrase(const char *prompt, int from_stdin);
 
 /*
+ * Attempts to call the ssh-askpass program to read a passphrase when
+ * there is no tty and $DISPLAY is set.
+ */
+char	*ssh_askpass(const char *askpass, const char *msg);
+
+/*
  * Saves the authentication (private) key in a file, encrypting it with
  * passphrase.  The identification of the file (lowest 64 bits of n) will
  * precede the key to provide identification of the key without needing a
diff -ur openssh-1.2pre16/sshconnect.c openssh-1.2pre16.patched/sshconnect.c
--- openssh-1.2pre16/sshconnect.c	Mon Dec  6 23:38:32 1999
+++ openssh-1.2pre16.patched/sshconnect.c	Thu Dec  9 23:00:54 1999
@@ -36,6 +36,9 @@
 
 extern Options options;
 
+/* Needed to determine whether to use ssh-askpass or not */
+extern int use_askpass;
+
 /*
  * Connect to the given ssh server using a proxy command.
  */
@@ -538,9 +541,16 @@
 		char buf[300];
 		snprintf(buf, sizeof buf, "Enter passphrase for RSA key '%.100s': ",
 		    comment);
-		if (!options.batch_mode)
-			passphrase = read_passphrase(buf, 0);
-		else {
+		if (!options.batch_mode) {
+			if (use_askpass) {
+				const char * askpass;
+				if ((askpass = getenv(SSH_ASKPASS_ENV)))
+					passphrase = ssh_askpass(askpass, buf);
+				else
+					passphrase = ssh_askpass(SSH_ASKPASS_DEFAULT, buf);
+			} else
+				passphrase = read_passphrase(buf, 0);
+		} else {
 			debug("Will not query passphrase for %.100s in batch mode.",
 			      comment);
 			passphrase = xstrdup("");
@@ -921,7 +931,14 @@
 	for (i = 0; i < options.number_of_password_prompts; i++) {
 		if (i != 0)
 			error("Permission denied, please try again.");
-		response = read_passphrase("Response: ", 0);
+		if (use_askpass) {
+			const char * askpass;
+			if ((askpass = getenv(SSH_ASKPASS_ENV)))
+				response = ssh_askpass(askpass, "Response: ");
+			else
+				response = ssh_askpass(SSH_ASKPASS_DEFAULT, "Response: ");
+		} else
+			response = read_passphrase("Response: ", 0);
 		packet_start(SSH_CMSG_AUTH_TIS_RESPONSE);
 		packet_put_string(response, strlen(response));
 		memset(response, 0, strlen(response));
@@ -954,7 +971,14 @@
 	for (i = 0; i < options.number_of_password_prompts; i++) {
 		if (i != 0)
 			error("Permission denied, please try again.");
-		password = read_passphrase(prompt, 0);
+		if (use_askpass) {
+			const char * askpass;
+			if ((askpass = getenv(SSH_ASKPASS_ENV)))
+				password = ssh_askpass(askpass, prompt);
+			else
+				password = ssh_askpass(SSH_ASKPASS_DEFAULT, prompt);
+		} else
+			password = read_passphrase(prompt, 0);
 		packet_start(SSH_CMSG_AUTH_PASSWORD);
 		packet_put_string(password, strlen(password));
 		memset(password, 0, strlen(password));

Cheers


--[[text/plain]]





More information about the openssh-unix-dev mailing list