Password from open filedescriptor

Peter Åstrand astrand at lysator.liu.se
Mon Apr 22 19:10:59 EST 2002


The included patch adds a new option to the ssh client:

-d fd   Read the password from file descriptor fd. If you use 0 for fd,
        the passphrase will be read from stdin. 

This is basically the same as GPG:s parameter --passphrase-fd. 

Flames about why this is a bad idea goes into /dev/null. I really need to 
do this. There are lots of ugly Expect-hacks out there, but I want a more 
clean solution. 

diff -bur openssh-3.1p1.org/readconf.c openssh-3.1p1/readconf.c
--- openssh-3.1p1.org/readconf.c	Tue Feb  5 02:26:35 2002
+++ openssh-3.1p1/readconf.c	Mon Apr 22 09:56:31 2002
@@ -776,6 +776,7 @@
 	options->port = -1;
 	options->connection_attempts = -1;
 	options->number_of_password_prompts = -1;
+	options->password_from_fd = -1;
 	options->cipher = -1;
 	options->ciphers = NULL;
 	options->macs = NULL;
diff -bur openssh-3.1p1.org/readconf.h openssh-3.1p1/readconf.h
--- openssh-3.1p1.org/readconf.h	Tue Mar  5 02:53:05 2002
+++ openssh-3.1p1/readconf.h	Mon Apr 22 10:24:06 2002
@@ -70,6 +70,7 @@
 					 * giving up */
 	int     number_of_password_prompts;	/* Max number of password
 						 * prompts. */
+	int     password_from_fd; /* Read password from file descriptor */
 	int     cipher;		/* Cipher to use. */
 	char   *ciphers;	/* SSH2 ciphers in order of preference. */
 	char   *macs;		/* SSH2 macs in order of preference. */
diff -bur openssh-3.1p1.org/readpass.c openssh-3.1p1/readpass.c
--- openssh-3.1p1.org/readpass.c	Wed Feb 13 04:05:23 2002
+++ openssh-3.1p1/readpass.c	Mon Apr 22 10:27:49 2002
@@ -124,4 +124,29 @@
 	ret = xstrdup(buf);
 	memset(buf, 'x', sizeof buf);
 	return ret;
+}
+
+char *
+read_password_from_fd(int fd)
+{
+    ssize_t nr;
+    int i = 0;
+    char ch, *buf;
+
+    buf = xmalloc(1024);
+
+    while (1) {
+	nr = read(fd, &ch, 1);
+	if (nr == -1) 
+	    fatal("error while reading password from filedescriptor: %.100s", strerror(errno));
+
+	if (nr == 0 || ch == '\n' || ch == '\r' || i >= 1024) 
+	    break;
+
+	buf[i++] = ch;
+    }
+
+    buf[i] = '\0';
+
+    return buf;
 }
diff -bur openssh-3.1p1.org/readpass.h openssh-3.1p1/readpass.h
--- openssh-3.1p1.org/readpass.h	Wed Jul  4 06:46:58 2001
+++ openssh-3.1p1/readpass.h	Mon Apr 22 10:19:53 2002
@@ -16,3 +16,4 @@
 #define RP_ALLOW_STDIN		0x0002
 
 char	*read_passphrase(const char *, int);
+char    *read_password_from_fd(int fd);
diff -bur openssh-3.1p1.org/ssh.1 openssh-3.1p1/ssh.1
--- openssh-3.1p1.org/ssh.1	Tue Feb 19 05:27:24 2002
+++ openssh-3.1p1/ssh.1	Mon Apr 22 10:34:59 2002
@@ -51,6 +51,7 @@
 .Op Fl afgknqstvxACNPTX1246
 .Op Fl b Ar bind_address
 .Op Fl c Ar cipher_spec
+.Op Fl d Ar fd
 .Op Fl e Ar escape_char
 .Op Fl i Ar identity_file
 .Op Fl l Ar login_name
@@ -415,6 +416,10 @@
 See
 .Cm Ciphers
 for more information.
+.It Fl d Ar fd
+Read the password from file descriptor fd. If you use 0 for fd, the
+passphrase will be read from stdin. Don't use this option if you can
+avoid it.
 .It Fl e Ar ch|^ch|none
 Sets the escape character for sessions with a pty (default:
 .Ql ~ ) .
diff -bur openssh-3.1p1.org/ssh.c openssh-3.1p1/ssh.c
--- openssh-3.1p1.org/ssh.c	Tue Feb 19 05:20:58 2002
+++ openssh-3.1p1/ssh.c	Mon Apr 22 10:13:55 2002
@@ -312,7 +312,7 @@
 
 again:
 	while ((opt = getopt(ac, av,
-	    "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:NPR:TVX")) != -1) {
+	    "1246ab:c:e:d:fgi:kl:m:no:p:qstvxACD:F:I:L:NPR:TVX")) != -1) {
 		switch (opt) {
 		case '1':
 			options.protocol = SSH_PROTO_1;
@@ -522,6 +522,9 @@
 			break;
 		case 'F':
 			config = optarg;
+			break;
+		case 'd':
+			options.password_from_fd = atoi(optarg);
 			break;
 		default:
 			usage();
diff -bur openssh-3.1p1.org/sshconnect2.c openssh-3.1p1/sshconnect2.c
--- openssh-3.1p1.org/sshconnect2.c	Tue Feb 26 19:15:10 2002
+++ openssh-3.1p1/sshconnect2.c	Mon Apr 22 10:28:28 2002
@@ -435,6 +435,7 @@
 	return 1;
 }
 
+
 int
 userauth_passwd(Authctxt *authctxt)
 {
@@ -442,6 +443,12 @@
 	char prompt[80];
 	char *password;
 
+	if (options.password_from_fd != -1) {
+		if (attempt++ >= 1)
+			return 0;
+		
+		password = read_password_from_fd(options.password_from_fd);
+	} else {
 	if (attempt++ >= options.number_of_password_prompts)
 		return 0;
 
@@ -451,6 +458,8 @@
 	snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
 	    authctxt->server_user, authctxt->host);
 	password = read_passphrase(prompt, 0);
+	} 
+	
 	packet_start(SSH2_MSG_USERAUTH_REQUEST);
 	packet_put_cstring(authctxt->server_user);
 	packet_put_cstring(authctxt->service);

-- 
/Peter Åstrand <astrand at lysator.liu.se>






More information about the openssh-unix-dev mailing list