[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