summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--Makefile.in2
-rw-r--r--acconfig.h2
-rw-r--r--configure.in23
-rw-r--r--ssh-add.c236
5 files changed, 155 insertions, 116 deletions
diff --git a/ChangeLog b/ChangeLog
index 15f2e16e6..528994344 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
119991115
2 - Merged OpenBSD CVS changes:
3 - [ssh-add.c] change passphrase loop logic and remove ref to
4 $DISPLAY, ok niels
5 - Changed to ssh-add.c broke askpass support. Revised it to be a little more
6 modular.
7 - Revised autoconf support for enabling/disabling askpass support.
8
119991114 919991114
2 - Solaris compilation fixes (still imcomplete) 10 - Solaris compilation fixes (still imcomplete)
3 11
diff --git a/Makefile.in b/Makefile.in
index 365df018f..93c4a0c01 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -80,7 +80,7 @@ install: all
80 ln -sf ssh $(bindir)/slogin 80 ln -sf ssh $(bindir)/slogin
81 ln -sf ssh.1 $(mandir)/man1/slogin.1 81 ln -sf ssh.1 $(mandir)/man1/slogin.1
82 82
83 if [ ! -z "@INSTALL_ASKPASS@" ] ; then \ 83 if [ "x@INSTALL_ASKPASS@" = "xyes" ] ; then \
84 install -d $(libdir) ; \ 84 install -d $(libdir) ; \
85 install -d $(libdir)/ssh ; \ 85 install -d $(libdir)/ssh ; \
86 if [ -z "@GNOME_ASKPASS@" ] ; then \ 86 if [ -z "@GNOME_ASKPASS@" ] ; then \
diff --git a/acconfig.h b/acconfig.h
index e5eca5b30..8678b7cdb 100644
--- a/acconfig.h
+++ b/acconfig.h
@@ -22,7 +22,7 @@
22#undef HAVE_LIBUTIL_LOGIN 22#undef HAVE_LIBUTIL_LOGIN
23 23
24/* Define if you *don't* want to use an external ssh-askpass */ 24/* Define if you *don't* want to use an external ssh-askpass */
25#undef DISABLE_EXTERNAL_ASKPASS 25#undef USE_EXTERNAL_ASKPASS
26 26
27@BOTTOM@ 27@BOTTOM@
28 28
diff --git a/configure.in b/configure.in
index cd0c9a3de..ace3aaaa3 100644
--- a/configure.in
+++ b/configure.in
@@ -109,11 +109,26 @@ if test -z "$RANDOM_POOL" -a -z "$EGD_POOL"; then
109fi 109fi
110 110
111dnl Check whether use wants to disable the external ssh-askpass 111dnl Check whether use wants to disable the external ssh-askpass
112INSTALL_ASKPASS="yes"
113AC_MSG_CHECKING([whether to enable external ssh-askpass support])
112AC_ARG_WITH(askpass, 114AC_ARG_WITH(askpass,
113 [ --without-askpass Disable external ssh-askpass support], 115 [ --with-askpass=yes/no Enable external ssh-askpass support (default=yes)],
114 [AC_DEFINE(DISABLE_EXTERNAL_ASKPASS)], 116 [
115 [INSTALL_ASKPASS="yes"] 117 if test x$withval = xno ; then
118 INSTALL_ASKPASS="no"
119 else
120 INSTALL_ASKPASS="yes"
121 fi
122
123 ]
116) 124)
117AC_SUBST(INSTALL_ASKPASS) 125
126if test "x$INSTALL_ASKPASS" = "xyes" ; then
127 AC_DEFINE(USE_EXTERNAL_ASKPASS)
128 AC_SUBST(INSTALL_ASKPASS)
129 AC_MSG_RESULT(yes)
130else
131 AC_MSG_RESULT(no)
132fi
118 133
119AC_OUTPUT(Makefile) 134AC_OUTPUT(Makefile)
diff --git a/ssh-add.c b/ssh-add.c
index 9ec34180f..bf3d7faea 100644
--- a/ssh-add.c
+++ b/ssh-add.c
@@ -14,13 +14,17 @@ Adds an identity to the authentication server, or removes an identity.
14*/ 14*/
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$Id: ssh-add.c,v 1.6 1999/11/12 04:46:08 damien Exp $"); 17RCSID("$Id: ssh-add.c,v 1.7 1999/11/15 03:25:30 damien Exp $");
18 18
19#include "rsa.h" 19#include "rsa.h"
20#include "ssh.h" 20#include "ssh.h"
21#include "xmalloc.h" 21#include "xmalloc.h"
22#include "authfd.h" 22#include "authfd.h"
23 23
24#ifdef USE_EXTERNAL_ASKPASS
25int askpass(const char *filename, RSA *key, const char *saved_comment, char **comment);
26#endif /* USE_EXTERNAL_ASKPASS */
27
24void 28void
25delete_file(AuthenticationConnection *ac, const char *filename) 29delete_file(AuthenticationConnection *ac, const char *filename)
26{ 30{
@@ -52,22 +56,14 @@ delete_all(AuthenticationConnection *ac)
52 fprintf(stderr, "Failed to remove all identitities.\n"); 56 fprintf(stderr, "Failed to remove all identitities.\n");
53} 57}
54 58
55#define BUFSIZE 1024
56void 59void
57add_file(AuthenticationConnection *ac, const char *filename) 60add_file(AuthenticationConnection *ac, const char *filename)
58{ 61{
59 RSA *key; 62 RSA *key;
60 RSA *public_key; 63 RSA *public_key;
61 char *saved_comment, *comment, *pass; 64 char *saved_comment, *comment;
62 int first; 65 int success;
63#ifndef DISABLE_EXTERNAL_ASKPASS 66
64 int pipes[2];
65 char buf[BUFSIZE];
66 int tmp;
67 pid_t child;
68 FILE *pipef;
69#endif /* !DISABLE_EXTERNAL_ASKPASS */
70
71 key = RSA_new(); 67 key = RSA_new();
72 public_key = RSA_new(); 68 public_key = RSA_new();
73 if (!load_public_key(filename, public_key, &saved_comment)) 69 if (!load_public_key(filename, public_key, &saved_comment))
@@ -76,109 +72,47 @@ add_file(AuthenticationConnection *ac, const char *filename)
76 return; 72 return;
77 } 73 }
78 RSA_free(public_key); 74 RSA_free(public_key);
79
80 pass = xstrdup("");
81 first = 1;
82 while (!load_private_key(filename, pass, key, &comment))
83 {
84 /* Free the old passphrase. */
85 memset(pass, 0, strlen(pass));
86 xfree(pass);
87 75
88 /* Ask for a passphrase. */ 76 /* At first, try empty passphrase */
89 if (getenv("DISPLAY") && !isatty(fileno(stdin))) 77 success = load_private_key(filename, "", key, &comment);
90 { 78 if (!success) {
91#ifndef DISABLE_EXTERNAL_ASKPASS 79 printf("Need passphrase for %s (%s).\n", filename, saved_comment);
92 if (pipe(pipes) ==-1) 80 if (!isatty(STDIN_FILENO)) {
93 { 81#ifdef USE_EXTERNAL_ASKPASS
94 fprintf(stderr, "Creating pipes failed: %s\n", strerror(errno)); 82 int prompts = 3;
95 exit(1); 83
96 } 84 while (prompts && !success)
97 if (fflush(NULL)==EOF) 85 {
98 { 86 success = askpass(filename, key, saved_comment, &comment);
99 fprintf(stderr, "Cannot flush buffers: %s\n", strerror(errno)); 87 prompts--;
100 exit(1); 88 }
101 } 89 if (!success)
102 switch (child=fork()) 90 {
103 { 91 xfree(saved_comment);
104 case -1: 92 return;
105 fprintf(stderr, "Cannot fork: %s\n", strerror(errno)); 93 }
106 exit(1); 94#else /* !USE_EXTERNAL_ASKPASS */
107 case 0:
108 close(pipes[0]);
109 if (dup2(pipes[1], 1) ==-1)
110 {
111 fprintf(stderr, "dup2 failed: %s\n", strerror(errno));
112 exit(1);
113 }
114 tmp=snprintf(buf, BUFSIZE, "Need passphrase for %s (%s)",
115 filename, saved_comment);
116 /* skip the prompt if it won't fit */
117 if (tmp < 0 || tmp >= BUFSIZE)
118 tmp=execlp(ASKPASS_PROGRAM, "ssh-askpass", 0);
119 else
120 tmp=execlp(ASKPASS_PROGRAM, "ssh-askpass", buf, 0);
121 if (tmp==-1)
122 {
123 fprintf(stderr, "Executing ssh-askpass failed: %s\n",
124 strerror(errno));
125 exit(1);
126 }
127 break;
128 default:
129 close(pipes[1]);
130 if ( (pipef=fdopen(pipes[0], "r")) ==NULL)
131 {
132 fprintf(stderr, "fdopen failed: %s\n", strerror(errno));
133 exit(1);
134 }
135 if(fgets(buf, sizeof(buf), pipef)==NULL)
136 {
137 xfree(saved_comment);
138 return;
139 }
140 fclose(pipef);
141 if (strchr(buf, '\n'))
142 *strchr(buf, '\n') = 0;
143 pass = xstrdup(buf);
144 memset(buf, 0, sizeof(buf));
145 if (waitpid(child, NULL, 0) ==-1)
146 {
147 fprintf(stderr, "Waiting for child failed: %s\n",
148 strerror(errno));
149 exit(1);
150 }
151 if (strcmp(pass, "") == 0)
152 {
153 xfree(saved_comment);
154 xfree(pass);
155 return;
156 }
157 }
158#else /* !DISABLE_EXTERNAL_ASKPASS */
159 xfree(saved_comment); 95 xfree(saved_comment);
160 return; 96 return;
161#endif /* !DISABLE_EXTERNAL_ASKPASS */ 97#endif /* USE_EXTERNAL_ASKPASS */
162 }
163 else
164 {
165 if (first)
166 printf("Need passphrase for %s (%s).\n", filename, saved_comment);
167 else
168 printf("Bad passphrase.\n");
169 pass = read_passphrase("Enter passphrase: ", 1);
170 if (strcmp(pass, "") == 0)
171 {
172 xfree(saved_comment);
173 xfree(pass);
174 return;
175 }
176 }
177 first = 0;
178 } 98 }
179 memset(pass, 0, strlen(pass));
180 xfree(pass);
181 99
100 while (!success) {
101 char *pass = read_passphrase("Enter passphrase: ", 1);
102 if (strcmp(pass, "") == 0){
103 xfree(pass);
104 xfree(saved_comment);
105 return;
106 }
107 success = load_private_key(filename, pass, key, &comment);
108 memset(pass, 0, strlen(pass));
109 xfree(pass);
110 if (success)
111 break;
112
113 printf("Bad passphrase.\n");
114 }
115 }
182 xfree(saved_comment); 116 xfree(saved_comment);
183 117
184 if (ssh_add_identity(ac, key, comment)) 118 if (ssh_add_identity(ac, key, comment))
@@ -299,3 +233,85 @@ main(int argc, char **argv)
299 ssh_close_authentication_connection(ac); 233 ssh_close_authentication_connection(ac);
300 exit(0); 234 exit(0);
301} 235}
236
237#ifdef USE_EXTERNAL_ASKPASS
238int askpass(const char *filename, RSA *key, const char *saved_comment, char **comment)
239{
240 int pipes[2];
241 char buf[1024];
242 int tmp;
243 pid_t child;
244 FILE *pipef;
245
246 /* Check that we are X11-capable */
247 if (getenv("DISPLAY") == NULL)
248 exit(1);
249
250 if (pipe(pipes) == -1) {
251 fprintf(stderr, "Creating pipes failed: %s\n", strerror(errno));
252 exit(1);
253 }
254
255 if (fflush(NULL) == EOF) {
256 fprintf(stderr, "Cannot flush buffers: %s\n", strerror(errno));
257 exit(1);
258 }
259
260 child = fork();
261 if (child == -1) {
262 fprintf(stderr, "Cannot fork: %s\n", strerror(errno));
263 exit(1);
264 }
265
266 if (child == 0) {
267 /* In child */
268
269 close(pipes[0]);
270 if (dup2(pipes[1], 1) ==-1) {
271 fprintf(stderr, "dup2 failed: %s\n", strerror(errno));
272 exit(1);
273 }
274
275 tmp = snprintf(buf, sizeof(buf), "Need passphrase for %s (%s)", filename, saved_comment);
276 /* skip the prompt if it won't fit */
277 if ((tmp < 0) || (tmp >= sizeof(buf)))
278 tmp = execlp(ASKPASS_PROGRAM, "ssh-askpass", 0);
279 else
280 tmp = execlp(ASKPASS_PROGRAM, "ssh-askpass", buf, 0);
281
282 /* Shouldn't get this far */
283 fprintf(stderr, "Executing ssh-askpass failed: %s\n", strerror(errno));
284 exit(1);
285 }
286
287 /* In parent */
288 close(pipes[1]);
289
290 if ((pipef = fdopen(pipes[0], "r")) == NULL) {
291 fprintf(stderr, "fdopen failed: %s\n", strerror(errno));
292 exit(1);
293 }
294
295 /* Read passphrase back from child, abort if none presented */
296 if(fgets(buf, sizeof(buf), pipef) == NULL)
297 exit(1);
298
299 fclose(pipef);
300
301 if (strchr(buf, '\n'))
302 *strchr(buf, '\n') = 0;
303
304 if (waitpid(child, NULL, 0) == -1) {
305 fprintf(stderr, "Waiting for child failed: %s\n",
306 strerror(errno));
307 exit(1);
308 }
309
310 /* Try password as it was presented */
311 tmp = load_private_key(filename, buf, key, comment);
312
313 memset(buf, 0, sizeof(buf));
314
315 return(tmp);
316}
317#endif /* USE_EXTERNAL_ASKPASS */