OpenSSH 2.5.2p2 and askass (fwd)

Mark D. Roth roth+openssh at feep.net
Tue Apr 17 00:06:32 EST 2001


On Mon Apr 16 08:52 2001 -0400, Bruce H. McIntosh wrote:
> On Sat, 14 Apr 2001, Mark D. Roth wrote:
> > There are still times when it's useful to have this functionality in
> > ssh itself.  The most common example I run into is when using
> > ChallengeResponseAuthentication and launching ssh from a window
> > manager menu button.
> 
> That's precisely the functionality I'm looking for.  I'm back to using
> ssh-1.2.27 to get it.  I'd be very keen to see this capability back into
> ssh itself, maybe along with an toggle in the config files to turn it on
> and off?

I've attached a patch for openssh-2.5.2p2 which adds support for
ssh-askpass to ssh.  Looks like it will be a little while before it
makes its way into the main code base, but feel free to use this patch
in the interim.

Please let me know if you have any questions or problems.

-- 
Mark D. Roth <roth at feep.net>
http://www.feep.net/~roth/
-------------- next part --------------
diff -urN openssh-2.5.2p2/readpass.c openssh-2.5.2p2-askpass/readpass.c
--- openssh-2.5.2p2/readpass.c	Thu Feb  8 20:11:24 2001
+++ openssh-2.5.2p2-askpass/readpass.c	Sun Apr 15 13:56:27 2001
@@ -37,6 +37,52 @@
 #include "xmalloc.h"
 #include "cli.h"
 #include "readpass.h"
+#include "ssh.h"
+#include "pathnames.h"
+
+
+static 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));
+		if (geteuid() == 0 && setuid(getuid()) == -1)
+			fatal("ssh_askpass: setuid: %s", strerror(errno));
+		execlp(askpass, askpass, msg, (char *) 0);
+		fatal("ssh_askpass: exec(%s): %s", askpass, strerror(errno));
+	}
+	close(p[1]);
+	buf[0] = '\0';
+	atomicio(read, p[0], buf, sizeof buf);
+	len = strlen(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
@@ -51,5 +97,27 @@
 char *
 read_passphrase(const char *prompt, int from_stdin)
 {
+	char *askpass = NULL;
+	int use_askpass = 0, ttyfd;
+
+	if (from_stdin) {
+		if (!isatty(STDIN_FILENO))
+			use_askpass = 1;
+	} else {
+		ttyfd = open("/dev/tty", O_RDWR);
+		if (ttyfd >= 0)
+			close(ttyfd);
+		else
+			use_askpass = 1;
+	}
+
+	if (use_askpass && getenv("DISPLAY")) {
+		if (getenv(SSH_ASKPASS_ENV))
+			askpass = getenv(SSH_ASKPASS_ENV);
+		else
+			askpass = _PATH_SSH_ASKPASS_DEFAULT;
+		return ssh_askpass(askpass, prompt);
+	}
+
 	return cli_read_passphrase(prompt, from_stdin, 0);
 }
diff -urN openssh-2.5.2p2/ssh-add.c openssh-2.5.2p2-askpass/ssh-add.c
--- openssh-2.5.2p2/ssh-add.c	Mon Mar 12 22:57:59 2001
+++ openssh-2.5.2p2-askpass/ssh-add.c	Sun Apr 15 13:53:13 2001
@@ -95,54 +95,14 @@
 		fprintf(stderr, "Failed to remove all identities.\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 (fflush(stdout) != 0)
-		error("ssh_askpass: fflush: %s", strerror(errno));
-	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)
 {
 	struct stat st;
 	Key *public;
 	Key *private;
-	char *saved_comment, *comment, *askpass = NULL;
-	char buf[1024], msg[1024];
+	char *saved_comment, *comment;
+	char msg[1024];
 	int success;
 	int interactive = isatty(STDIN_FILENO);
 	int type = KEY_RSA1;
@@ -163,31 +123,15 @@
 	}
 	key_free(public);
 
-	if (!interactive && getenv("DISPLAY")) {
-		if (getenv(SSH_ASKPASS_ENV))
-			askpass = getenv(SSH_ASKPASS_ENV);
-		else
-			askpass = _PATH_SSH_ASKPASS_DEFAULT;
-	}
-
 	/* At first, try empty passphrase */
 	private = key_new(type);
 	success = load_private_key(filename, "", private, &comment);
 	if (!success) {
 		printf("Need passphrase for %.200s\n", filename);
-		if (!interactive && askpass == NULL) {
-			xfree(saved_comment);
-			return;
-		}
-		snprintf(msg, sizeof msg, "Enter passphrase for %.200s", saved_comment);
+		snprintf(msg, sizeof msg, "Enter passphrase for %.200s: ", saved_comment);
 		for (;;) {
 			char *pass;
-			if (interactive) {
-				snprintf(buf, sizeof buf, "%s: ", msg);
-				pass = read_passphrase(buf, 1);
-			} else {
-				pass = ssh_askpass(askpass, msg);
-			}
+			pass = read_passphrase(msg, 1);
 			if (strcmp(pass, "") == 0) {
 				xfree(pass);
 				xfree(saved_comment);
@@ -198,7 +142,7 @@
 			xfree(pass);
 			if (success)
 				break;
-			strlcpy(msg, "Bad passphrase, try again", sizeof msg);
+			strlcpy(msg, "Bad passphrase, try again: ", sizeof msg);
 		}
 	}
 	xfree(comment);


More information about the openssh-unix-dev mailing list