summaryrefslogtreecommitdiff
path: root/ssh-add.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>1999-11-25 00:26:21 +1100
committerDamien Miller <djm@mindrot.org>1999-11-25 00:26:21 +1100
commit95def09838fc61b37b6ea7cd5c234a465b4b129b (patch)
tree042744f76f40a326b873cb1c3690a6d7d966bc3e /ssh-add.c
parent4d2f15f895f4c795afc008aeff3fd2ceffbc44f4 (diff)
- Merged very large OpenBSD source code reformat
- OpenBSD CVS updates - [channels.c cipher.c compat.c log-client.c scp.c serverloop.c] [ssh.h sshd.8 sshd.c] syslog changes: * Unified Logmessage for all auth-types, for success and for failed * Standard connections get only ONE line in the LOG when level==LOG: Auth-attempts are logged only, if authentication is: a) successfull or b) with passwd or c) we had more than AUTH_FAIL_LOG failues * many log() became verbose() * old behaviour with level=VERBOSE - [readconf.c readconf.h ssh.1 ssh.h sshconnect.c sshd.c] tranfer s/key challenge/response data in SSH_SMSG_AUTH_TIS_CHALLENGE messages. allows use of s/key in windows (ttssh, securecrt) and ssh-1.2.27 clients without 'ssh -v', ok: niels@ - [sshd.8] -V, for fallback to openssh in SSH2 compatibility mode - [sshd.c] fix sigchld race; cjc5@po.cwru.edu
Diffstat (limited to 'ssh-add.c')
-rw-r--r--ssh-add.c515
1 files changed, 248 insertions, 267 deletions
diff --git a/ssh-add.c b/ssh-add.c
index a95914417..f94dcdabb 100644
--- a/ssh-add.c
+++ b/ssh-add.c
@@ -1,20 +1,13 @@
1/* 1/*
2 2 * Author: Tatu Ylonen <ylo@cs.hut.fi>
3ssh-add.c 3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 4 * All rights reserved
5Author: Tatu Ylonen <ylo@cs.hut.fi> 5 * Created: Thu Apr 6 00:52:24 1995 ylo
6 6 * Adds an identity to the authentication server, or removes an identity.
7Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 7 */
8 All rights reserved
9
10Created: Thu Apr 6 00:52:24 1995 ylo
11
12Adds an identity to the authentication server, or removes an identity.
13
14*/
15 8
16#include "includes.h" 9#include "includes.h"
17RCSID("$Id: ssh-add.c,v 1.12 1999/11/23 00:24:32 damien Exp $"); 10RCSID("$Id: ssh-add.c,v 1.13 1999/11/24 13:26:22 damien Exp $");
18 11
19#include "rsa.h" 12#include "rsa.h"
20#include "ssh.h" 13#include "ssh.h"
@@ -35,291 +28,279 @@ const char *__progname = "ssh-add";
35void 28void
36delete_file(AuthenticationConnection *ac, const char *filename) 29delete_file(AuthenticationConnection *ac, const char *filename)
37{ 30{
38 RSA *key; 31 RSA *key;
39 char *comment; 32 char *comment;
40 33
41 key = RSA_new(); 34 key = RSA_new();
42 if (!load_public_key(filename, key, &comment)) 35 if (!load_public_key(filename, key, &comment)) {
43 { 36 printf("Bad key file %s: %s\n", filename, strerror(errno));
44 printf("Bad key file %s: %s\n", filename, strerror(errno)); 37 return;
45 return; 38 }
46 } 39 if (ssh_remove_identity(ac, key))
47 40 fprintf(stderr, "Identity removed: %s (%s)\n", filename, comment);
48 if (ssh_remove_identity(ac, key)) 41 else
49 fprintf(stderr, "Identity removed: %s (%s)\n", filename, comment); 42 fprintf(stderr, "Could not remove identity: %s\n", filename);
50 else 43 RSA_free(key);
51 fprintf(stderr, "Could not remove identity: %s\n", filename); 44 xfree(comment);
52 RSA_free(key);
53 xfree(comment);
54} 45}
55 46
56void 47void
57delete_all(AuthenticationConnection *ac) 48delete_all(AuthenticationConnection *ac)
58{ 49{
59 /* Send a request to remove all identities. */ 50 /* Send a request to remove all identities. */
60 if (ssh_remove_all_identities(ac)) 51 if (ssh_remove_all_identities(ac))
61 fprintf(stderr, "All identities removed.\n"); 52 fprintf(stderr, "All identities removed.\n");
62 else 53 else
63 fprintf(stderr, "Failed to remove all identitities.\n"); 54 fprintf(stderr, "Failed to remove all identitities.\n");
64} 55}
65 56
66void 57void
67add_file(AuthenticationConnection *ac, const char *filename) 58add_file(AuthenticationConnection *ac, const char *filename)
68{ 59{
69 RSA *key; 60 RSA *key;
70 RSA *public_key; 61 RSA *public_key;
71 char *saved_comment, *comment; 62 char *saved_comment, *comment;
72 int success; 63 int success;
73 64
74 key = RSA_new(); 65 key = RSA_new();
75 public_key = RSA_new(); 66 public_key = RSA_new();
76 if (!load_public_key(filename, public_key, &saved_comment)) 67 if (!load_public_key(filename, public_key, &saved_comment)) {
77 { 68 printf("Bad key file %s: %s\n", filename, strerror(errno));
78 printf("Bad key file %s: %s\n", filename, strerror(errno)); 69 return;
79 return; 70 }
80 } 71 RSA_free(public_key);
81 RSA_free(public_key);
82
83 /* At first, try empty passphrase */
84 success = load_private_key(filename, "", key, &comment);
85 if (!success) {
86 printf("Need passphrase for %s (%s).\n", filename, saved_comment);
87 if (!isatty(STDIN_FILENO)) {
88#ifdef USE_EXTERNAL_ASKPASS
89 int prompts = 3;
90 72
91 while (prompts && !success) 73 /* At first, try empty passphrase */
92 { 74 success = load_private_key(filename, "", key, &comment);
93 success = askpass(filename, key, saved_comment, &comment); 75 if (!success) {
94 prompts--; 76 printf("Need passphrase for %s (%s).\n", filename, saved_comment);
95 } 77 if (!isatty(STDIN_FILENO)) {
96 if (!success) 78#ifdef USE_EXTERNAL_ASKPASS
97 { 79 int prompts = 3;
98 xfree(saved_comment); 80 while (prompts && !success) {
99 return; 81 success = askpass(filename, key, saved_comment, &comment);
100 } 82 prompts--;
83 }
84 if (!success) {
85 xfree(saved_comment);
86 return;
87 }
101#else /* !USE_EXTERNAL_ASKPASS */ 88#else /* !USE_EXTERNAL_ASKPASS */
102 xfree(saved_comment); 89 xfree(saved_comment);
103 return; 90 return;
104#endif /* USE_EXTERNAL_ASKPASS */ 91#endif /* USE_EXTERNAL_ASKPASS */
105 } 92 }
106 93
107 while (!success) { 94 while (!success) {
108 char *pass = read_passphrase("Enter passphrase: ", 1); 95 char *pass = read_passphrase("Enter passphrase: ", 1);
109 if (strcmp(pass, "") == 0){ 96 if (strcmp(pass, "") == 0) {
110 xfree(pass); 97 xfree(pass);
111 xfree(saved_comment); 98 xfree(saved_comment);
112 return; 99 return;
113 } 100 }
114 success = load_private_key(filename, pass, key, &comment); 101 success = load_private_key(filename, pass, key, &comment);
115 memset(pass, 0, strlen(pass)); 102 memset(pass, 0, strlen(pass));
116 xfree(pass); 103 xfree(pass);
117 if (success) 104 if (success)
118 break; 105 break;
119 printf("Bad passphrase.\n"); 106 printf("Bad passphrase.\n");
120 } 107 }
121 } 108 }
122 xfree(saved_comment); 109 xfree(saved_comment);
123 110
124 if (ssh_add_identity(ac, key, comment)) 111 if (ssh_add_identity(ac, key, comment))
125 fprintf(stderr, "Identity added: %s (%s)\n", filename, comment); 112 fprintf(stderr, "Identity added: %s (%s)\n", filename, comment);
126 else 113 else
127 fprintf(stderr, "Could not add identity: %s\n", filename); 114 fprintf(stderr, "Could not add identity: %s\n", filename);
128 RSA_free(key); 115 RSA_free(key);
129 xfree(comment); 116 xfree(comment);
130} 117}
131 118
132void 119void
133list_identities(AuthenticationConnection *ac, int fp) 120list_identities(AuthenticationConnection *ac, int fp)
134{ 121{
135 BIGNUM *e, *n; 122 BIGNUM *e, *n;
136 int status; 123 int status;
137 char *comment; 124 char *comment;
138 int had_identities; 125 int had_identities;
139 126
140 e = BN_new(); 127 e = BN_new();
141 n = BN_new(); 128 n = BN_new();
142 had_identities = 0; 129 had_identities = 0;
143 for (status = ssh_get_first_identity(ac, e, n, &comment); 130 for (status = ssh_get_first_identity(ac, e, n, &comment);
144 status; 131 status;
145 status = ssh_get_next_identity(ac, e, n, &comment)) 132 status = ssh_get_next_identity(ac, e, n, &comment)) {
146 { 133 unsigned int bits = BN_num_bits(n);
147 unsigned int bits = BN_num_bits(n); 134 had_identities = 1;
148 had_identities = 1; 135 if (fp) {
149 if (fp) { 136 printf("%d %s %s\n", bits, fingerprint(e, n), comment);
150 printf("%d %s %s\n", bits, fingerprint(e, n), comment); 137 } else {
151 } else { 138 char *ebuf, *nbuf;
152 char *ebuf, *nbuf; 139 ebuf = BN_bn2dec(e);
153 ebuf = BN_bn2dec(e); 140 if (ebuf == NULL) {
154 if (ebuf == NULL) { 141 error("list_identities: BN_bn2dec(e) failed.");
155 error("list_identities: BN_bn2dec(e) failed."); 142 } else {
156 }else{ 143 nbuf = BN_bn2dec(n);
157 nbuf = BN_bn2dec(n); 144 if (nbuf == NULL) {
158 if (nbuf == NULL) { 145 error("list_identities: BN_bn2dec(n) failed.");
159 error("list_identities: BN_bn2dec(n) failed."); 146 } else {
160 }else{ 147 printf("%d %s %s %s\n", bits, ebuf, nbuf, comment);
161 printf("%d %s %s %s\n", bits, ebuf, nbuf, comment); 148 free(nbuf);
162 free(nbuf); 149 }
163 } 150 free(ebuf);
164 free(ebuf); 151 }
152 }
153 xfree(comment);
165 } 154 }
166 } 155 BN_clear_free(e);
167 xfree(comment); 156 BN_clear_free(n);
168 } 157 if (!had_identities)
169 BN_clear_free(e); 158 printf("The agent has no identities.\n");
170 BN_clear_free(n);
171 if (!had_identities)
172 printf("The agent has no identities.\n");
173} 159}
174 160
175int 161int
176main(int argc, char **argv) 162main(int argc, char **argv)
177{ 163{
178 AuthenticationConnection *ac = NULL; 164 AuthenticationConnection *ac = NULL;
179 struct passwd *pw; 165 struct passwd *pw;
180 char buf[1024]; 166 char buf[1024];
181 int no_files = 1; 167 int no_files = 1;
182 int i; 168 int i;
183 int deleting = 0; 169 int deleting = 0;
184 170
185 /* check if RSA support exists */ 171 /* check if RSA support exists */
186 if (rsa_alive() == 0) { 172 if (rsa_alive() == 0) {
187 fprintf(stderr, 173 extern char *__progname;
188 "%s: no RSA support in libssl and libcrypto. See ssl(8).\n", 174
189 __progname); 175 fprintf(stderr,
190 exit(1); 176 "%s: no RSA support in libssl and libcrypto. See ssl(8).\n",
191 } 177 __progname);
192 178 exit(1);
193 /* At first, get a connection to the authentication agent. */
194 ac = ssh_get_authentication_connection();
195 if (ac == NULL) {
196 fprintf(stderr, "Could not open a connection to your authentication agent.\n");
197 exit(1);
198 }
199
200 for (i = 1; i < argc; i++)
201 {
202 if ((strcmp(argv[i], "-l") == 0) ||
203 (strcmp(argv[i], "-L") == 0))
204 {
205 list_identities(ac, argv[i][1] == 'l' ? 1 : 0);
206 no_files = 0; /* Don't default-add/delete if -l. */
207 continue;
208 } 179 }
209 if (strcmp(argv[i], "-d") == 0) 180 /* At first, get a connection to the authentication agent. */
210 { 181 ac = ssh_get_authentication_connection();
211 deleting = 1; 182 if (ac == NULL) {
212 continue; 183 fprintf(stderr, "Could not open a connection to your authentication agent.\n");
184 exit(1);
213 } 185 }
214 if (strcmp(argv[i], "-D") == 0) 186 for (i = 1; i < argc; i++) {
215 { 187 if ((strcmp(argv[i], "-l") == 0) ||
216 delete_all(ac); 188 (strcmp(argv[i], "-L") == 0)) {
217 no_files = 0; 189 list_identities(ac, argv[i][1] == 'l' ? 1 : 0);
218 continue; 190 /* Don't default-add/delete if -l. */
191 no_files = 0;
192 continue;
193 }
194 if (strcmp(argv[i], "-d") == 0) {
195 deleting = 1;
196 continue;
197 }
198 if (strcmp(argv[i], "-D") == 0) {
199 delete_all(ac);
200 no_files = 0;
201 continue;
202 }
203 no_files = 0;
204 if (deleting)
205 delete_file(ac, argv[i]);
206 else
207 add_file(ac, argv[i]);
219 } 208 }
220 no_files = 0; 209 if (no_files) {
221 if (deleting) 210 pw = getpwuid(getuid());
222 delete_file(ac, argv[i]); 211 if (!pw) {
223 else 212 fprintf(stderr, "No user found with uid %d\n", (int) getuid());
224 add_file(ac, argv[i]); 213 ssh_close_authentication_connection(ac);
225 } 214 exit(1);
226 if (no_files) 215 }
227 { 216 snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, SSH_CLIENT_IDENTITY);
228 pw = getpwuid(getuid()); 217 if (deleting)
229 if (!pw) 218 delete_file(ac, buf);
230 { 219 else
231 fprintf(stderr, "No user found with uid %d\n", (int)getuid()); 220 add_file(ac, buf);
232 ssh_close_authentication_connection(ac);
233 exit(1);
234 } 221 }
235 snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, SSH_CLIENT_IDENTITY); 222 ssh_close_authentication_connection(ac);
236 if (deleting) 223 exit(0);
237 delete_file(ac, buf);
238 else
239 add_file(ac, buf);
240 }
241 ssh_close_authentication_connection(ac);
242 exit(0);
243} 224}
244 225
245#ifdef USE_EXTERNAL_ASKPASS 226#ifdef USE_EXTERNAL_ASKPASS
246int askpass(const char *filename, RSA *key, const char *saved_comment, char **comment) 227int askpass(const char *filename, RSA *key, const char *saved_comment, char **comment)
247{ 228{
248 int pipes[2]; 229 int pipes[2];
249 char buf[1024]; 230 char buf[1024];
250 int tmp; 231 int tmp;
251 pid_t child; 232 pid_t child;
252 FILE *pipef; 233 FILE *pipef;
253 234
254 /* Check that we are X11-capable */ 235 /* Check that we are X11-capable */
255 if (getenv("DISPLAY") == NULL) 236 if (getenv("DISPLAY") == NULL)
256 exit(1); 237 exit(1);
257 238
258 if (pipe(pipes) == -1) { 239 if (pipe(pipes) == -1) {
259 fprintf(stderr, "Creating pipes failed: %s\n", strerror(errno)); 240 fprintf(stderr, "Creating pipes failed: %s\n", strerror(errno));
260 exit(1); 241 exit(1);
261 } 242 }
262 243
263 if (fflush(NULL) == EOF) { 244 if (fflush(NULL) == EOF) {
264 fprintf(stderr, "Cannot flush buffers: %s\n", strerror(errno)); 245 fprintf(stderr, "Cannot flush buffers: %s\n", strerror(errno));
265 exit(1); 246 exit(1);
266 } 247 }
267 248
268 child = fork(); 249 child = fork();
269 if (child == -1) { 250 if (child == -1) {
270 fprintf(stderr, "Cannot fork: %s\n", strerror(errno)); 251 fprintf(stderr, "Cannot fork: %s\n", strerror(errno));
271 exit(1); 252 exit(1);
272 } 253 }
273 254
274 if (child == 0) { 255 if (child == 0) {
275 /* In child */ 256 /* In child */
276 257
277 close(pipes[0]); 258 close(pipes[0]);
278 if (dup2(pipes[1], 1) ==-1) { 259 if (dup2(pipes[1], 1) ==-1) {
279 fprintf(stderr, "dup2 failed: %s\n", strerror(errno)); 260 fprintf(stderr, "dup2 failed: %s\n", strerror(errno));
280 exit(1); 261 exit(1);
281 } 262 }
282 263
283 tmp = snprintf(buf, sizeof(buf), "Need passphrase for %s", saved_comment); 264 tmp = snprintf(buf, sizeof(buf), "Need passphrase for %s", saved_comment);
284 /* skip the prompt if it won't fit */ 265 /* skip the prompt if it won't fit */
285 if ((tmp < 0) || (tmp >= sizeof(buf))) 266 if ((tmp < 0) || (tmp >= sizeof(buf)))
286 tmp = execlp(ASKPASS_PROGRAM, "ssh-askpass", 0); 267 tmp = execlp(ASKPASS_PROGRAM, "ssh-askpass", 0);
287 else 268 else
288 tmp = execlp(ASKPASS_PROGRAM, "ssh-askpass", buf, 0); 269 tmp = execlp(ASKPASS_PROGRAM, "ssh-askpass", buf, 0);
289 270
290 /* Shouldn't get this far */ 271 /* Shouldn't get this far */
291 fprintf(stderr, "Executing ssh-askpass failed: %s\n", strerror(errno)); 272 fprintf(stderr, "Executing ssh-askpass failed: %s\n", strerror(errno));
292 exit(1); 273 exit(1);
293 } 274 }
294 275
295 /* In parent */ 276 /* In parent */
296 close(pipes[1]); 277 close(pipes[1]);
297 278
298 if ((pipef = fdopen(pipes[0], "r")) == NULL) { 279 if ((pipef = fdopen(pipes[0], "r")) == NULL) {
299 fprintf(stderr, "fdopen failed: %s\n", strerror(errno)); 280 fprintf(stderr, "fdopen failed: %s\n", strerror(errno));
300 exit(1); 281 exit(1);
301 } 282 }
302 283
303 /* Read passphrase back from child, abort if none presented */ 284 /* Read passphrase back from child, abort if none presented */
304 if(fgets(buf, sizeof(buf), pipef) == NULL) 285 if(fgets(buf, sizeof(buf), pipef) == NULL)
305 exit(1); 286 exit(1);
306 287
307 fclose(pipef); 288 fclose(pipef);
308 289
309 if (strchr(buf, '\n')) 290 if (strchr(buf, '\n'))
310 *strchr(buf, '\n') = 0; 291 *strchr(buf, '\n') = 0;
311 292
312 if (waitpid(child, NULL, 0) == -1) { 293 if (waitpid(child, NULL, 0) == -1) {
313 fprintf(stderr, "Waiting for child failed: %s\n", 294 fprintf(stderr, "Waiting for child failed: %s\n",
314 strerror(errno)); 295 strerror(errno));
315 exit(1); 296 exit(1);
316 } 297 }
317 298
318 /* Try password as it was presented */ 299 /* Try password as it was presented */
319 tmp = load_private_key(filename, buf, key, comment); 300 tmp = load_private_key(filename, buf, key, comment);
320 301
321 memset(buf, 0, sizeof(buf)); 302 memset(buf, 0, sizeof(buf));
322 303
323 return(tmp); 304 return(tmp);
324} 305}
325#endif /* USE_EXTERNAL_ASKPASS */ 306#endif /* USE_EXTERNAL_ASKPASS */