diff options
Diffstat (limited to 'ssh-add.c')
-rw-r--r-- | ssh-add.c | 109 |
1 files changed, 53 insertions, 56 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-add.c,v 1.128 2016/02/15 09:47:49 dtucker Exp $ */ | 1 | /* $OpenBSD: ssh-add.c,v 1.134 2017/08/29 09:42:29 dlg Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -55,7 +55,6 @@ | |||
55 | 55 | ||
56 | #include "xmalloc.h" | 56 | #include "xmalloc.h" |
57 | #include "ssh.h" | 57 | #include "ssh.h" |
58 | #include "rsa.h" | ||
59 | #include "log.h" | 58 | #include "log.h" |
60 | #include "sshkey.h" | 59 | #include "sshkey.h" |
61 | #include "sshbuf.h" | 60 | #include "sshbuf.h" |
@@ -79,9 +78,6 @@ static char *default_files[] = { | |||
79 | #endif | 78 | #endif |
80 | #endif /* WITH_OPENSSL */ | 79 | #endif /* WITH_OPENSSL */ |
81 | _PATH_SSH_CLIENT_ID_ED25519, | 80 | _PATH_SSH_CLIENT_ID_ED25519, |
82 | #ifdef WITH_SSH1 | ||
83 | _PATH_SSH_CLIENT_IDENTITY, | ||
84 | #endif | ||
85 | NULL | 81 | NULL |
86 | }; | 82 | }; |
87 | 83 | ||
@@ -106,7 +102,7 @@ clear_pass(void) | |||
106 | } | 102 | } |
107 | 103 | ||
108 | static int | 104 | static int |
109 | delete_file(int agent_fd, const char *filename, int key_only) | 105 | delete_file(int agent_fd, const char *filename, int key_only, int qflag) |
110 | { | 106 | { |
111 | struct sshkey *public, *cert = NULL; | 107 | struct sshkey *public, *cert = NULL; |
112 | char *certpath = NULL, *comment = NULL; | 108 | char *certpath = NULL, *comment = NULL; |
@@ -117,7 +113,10 @@ delete_file(int agent_fd, const char *filename, int key_only) | |||
117 | return -1; | 113 | return -1; |
118 | } | 114 | } |
119 | if ((r = ssh_remove_identity(agent_fd, public)) == 0) { | 115 | if ((r = ssh_remove_identity(agent_fd, public)) == 0) { |
120 | fprintf(stderr, "Identity removed: %s (%s)\n", filename, comment); | 116 | if (!qflag) { |
117 | fprintf(stderr, "Identity removed: %s (%s)\n", | ||
118 | filename, comment); | ||
119 | } | ||
121 | ret = 0; | 120 | ret = 0; |
122 | } else | 121 | } else |
123 | fprintf(stderr, "Could not remove identity \"%s\": %s\n", | 122 | fprintf(stderr, "Could not remove identity \"%s\": %s\n", |
@@ -142,8 +141,10 @@ delete_file(int agent_fd, const char *filename, int key_only) | |||
142 | certpath, filename); | 141 | certpath, filename); |
143 | 142 | ||
144 | if ((r = ssh_remove_identity(agent_fd, cert)) == 0) { | 143 | if ((r = ssh_remove_identity(agent_fd, cert)) == 0) { |
145 | fprintf(stderr, "Identity removed: %s (%s)\n", certpath, | 144 | if (!qflag) { |
146 | comment); | 145 | fprintf(stderr, "Identity removed: %s (%s)\n", |
146 | certpath, comment); | ||
147 | } | ||
147 | ret = 0; | 148 | ret = 0; |
148 | } else | 149 | } else |
149 | fprintf(stderr, "Could not remove identity \"%s\": %s\n", | 150 | fprintf(stderr, "Could not remove identity \"%s\": %s\n", |
@@ -164,6 +165,11 @@ delete_all(int agent_fd) | |||
164 | { | 165 | { |
165 | int ret = -1; | 166 | int ret = -1; |
166 | 167 | ||
168 | /* | ||
169 | * Since the agent might be forwarded, old or non-OpenSSH, when asked | ||
170 | * to remove all keys, attempt to remove both protocol v.1 and v.2 | ||
171 | * keys. | ||
172 | */ | ||
167 | if (ssh_remove_all_identities(agent_fd, 2) == 0) | 173 | if (ssh_remove_all_identities(agent_fd, 2) == 0) |
168 | ret = 0; | 174 | ret = 0; |
169 | /* ignore error-code for ssh1 */ | 175 | /* ignore error-code for ssh1 */ |
@@ -178,7 +184,7 @@ delete_all(int agent_fd) | |||
178 | } | 184 | } |
179 | 185 | ||
180 | static int | 186 | static int |
181 | add_file(int agent_fd, const char *filename, int key_only) | 187 | add_file(int agent_fd, const char *filename, int key_only, int qflag) |
182 | { | 188 | { |
183 | struct sshkey *private, *cert; | 189 | struct sshkey *private, *cert; |
184 | char *comment = NULL; | 190 | char *comment = NULL; |
@@ -304,7 +310,7 @@ add_file(int agent_fd, const char *filename, int key_only) | |||
304 | goto out; | 310 | goto out; |
305 | } | 311 | } |
306 | if ((r = sshkey_cert_copy(cert, private)) != 0) { | 312 | if ((r = sshkey_cert_copy(cert, private)) != 0) { |
307 | error("%s: key_cert_copy: %s", __func__, ssh_err(r)); | 313 | error("%s: sshkey_cert_copy: %s", __func__, ssh_err(r)); |
308 | sshkey_free(cert); | 314 | sshkey_free(cert); |
309 | goto out; | 315 | goto out; |
310 | } | 316 | } |
@@ -360,50 +366,36 @@ static int | |||
360 | list_identities(int agent_fd, int do_fp) | 366 | list_identities(int agent_fd, int do_fp) |
361 | { | 367 | { |
362 | char *fp; | 368 | char *fp; |
363 | int r, had_identities = 0; | 369 | int r; |
364 | struct ssh_identitylist *idlist; | 370 | struct ssh_identitylist *idlist; |
365 | size_t i; | 371 | size_t i; |
366 | #ifdef WITH_SSH1 | ||
367 | int version = 1; | ||
368 | #else | ||
369 | int version = 2; | ||
370 | #endif | ||
371 | 372 | ||
372 | for (; version <= 2; version++) { | 373 | if ((r = ssh_fetch_identitylist(agent_fd, &idlist)) != 0) { |
373 | if ((r = ssh_fetch_identitylist(agent_fd, version, | 374 | if (r != SSH_ERR_AGENT_NO_IDENTITIES) |
374 | &idlist)) != 0) { | 375 | fprintf(stderr, "error fetching identities: %s\n", |
375 | if (r != SSH_ERR_AGENT_NO_IDENTITIES) | 376 | ssh_err(r)); |
376 | fprintf(stderr, "error fetching identities for " | 377 | else |
377 | "protocol %d: %s\n", version, ssh_err(r)); | 378 | printf("The agent has no identities.\n"); |
378 | continue; | 379 | return -1; |
379 | } | 380 | } |
380 | for (i = 0; i < idlist->nkeys; i++) { | 381 | for (i = 0; i < idlist->nkeys; i++) { |
381 | had_identities = 1; | 382 | if (do_fp) { |
382 | if (do_fp) { | 383 | fp = sshkey_fingerprint(idlist->keys[i], |
383 | fp = sshkey_fingerprint(idlist->keys[i], | 384 | fingerprint_hash, SSH_FP_DEFAULT); |
384 | fingerprint_hash, SSH_FP_DEFAULT); | 385 | printf("%u %s %s (%s)\n", sshkey_size(idlist->keys[i]), |
385 | printf("%u %s %s (%s)\n", | 386 | fp == NULL ? "(null)" : fp, idlist->comments[i], |
386 | sshkey_size(idlist->keys[i]), | 387 | sshkey_type(idlist->keys[i])); |
387 | fp == NULL ? "(null)" : fp, | 388 | free(fp); |
388 | idlist->comments[i], | 389 | } else { |
389 | sshkey_type(idlist->keys[i])); | 390 | if ((r = sshkey_write(idlist->keys[i], stdout)) != 0) { |
390 | free(fp); | 391 | fprintf(stderr, "sshkey_write: %s\n", |
391 | } else { | 392 | ssh_err(r)); |
392 | if ((r = sshkey_write(idlist->keys[i], | 393 | continue; |
393 | stdout)) != 0) { | ||
394 | fprintf(stderr, "sshkey_write: %s\n", | ||
395 | ssh_err(r)); | ||
396 | continue; | ||
397 | } | ||
398 | fprintf(stdout, " %s\n", idlist->comments[i]); | ||
399 | } | 394 | } |
395 | fprintf(stdout, " %s\n", idlist->comments[i]); | ||
400 | } | 396 | } |
401 | ssh_free_identitylist(idlist); | ||
402 | } | ||
403 | if (!had_identities) { | ||
404 | printf("The agent has no identities.\n"); | ||
405 | return -1; | ||
406 | } | 397 | } |
398 | ssh_free_identitylist(idlist); | ||
407 | return 0; | 399 | return 0; |
408 | } | 400 | } |
409 | 401 | ||
@@ -440,13 +432,13 @@ lock_agent(int agent_fd, int lock) | |||
440 | } | 432 | } |
441 | 433 | ||
442 | static int | 434 | static int |
443 | do_file(int agent_fd, int deleting, int key_only, char *file) | 435 | do_file(int agent_fd, int deleting, int key_only, char *file, int qflag) |
444 | { | 436 | { |
445 | if (deleting) { | 437 | if (deleting) { |
446 | if (delete_file(agent_fd, file, key_only) == -1) | 438 | if (delete_file(agent_fd, file, key_only, qflag) == -1) |
447 | return -1; | 439 | return -1; |
448 | } else { | 440 | } else { |
449 | if (add_file(agent_fd, file, key_only) == -1) | 441 | if (add_file(agent_fd, file, key_only, qflag) == -1) |
450 | return -1; | 442 | return -1; |
451 | } | 443 | } |
452 | return 0; | 444 | return 0; |
@@ -469,6 +461,7 @@ usage(void) | |||
469 | fprintf(stderr, " -X Unlock agent.\n"); | 461 | fprintf(stderr, " -X Unlock agent.\n"); |
470 | fprintf(stderr, " -s pkcs11 Add keys from PKCS#11 provider.\n"); | 462 | fprintf(stderr, " -s pkcs11 Add keys from PKCS#11 provider.\n"); |
471 | fprintf(stderr, " -e pkcs11 Remove keys provided by PKCS#11 provider.\n"); | 463 | fprintf(stderr, " -e pkcs11 Remove keys provided by PKCS#11 provider.\n"); |
464 | fprintf(stderr, " -q Be quiet after a successful operation.\n"); | ||
472 | } | 465 | } |
473 | 466 | ||
474 | int | 467 | int |
@@ -479,7 +472,7 @@ main(int argc, char **argv) | |||
479 | int agent_fd; | 472 | int agent_fd; |
480 | char *pkcs11provider = NULL; | 473 | char *pkcs11provider = NULL; |
481 | int r, i, ch, deleting = 0, ret = 0, key_only = 0; | 474 | int r, i, ch, deleting = 0, ret = 0, key_only = 0; |
482 | int xflag = 0, lflag = 0, Dflag = 0; | 475 | int xflag = 0, lflag = 0, Dflag = 0, qflag = 0; |
483 | 476 | ||
484 | ssh_malloc_init(); /* must be called before any mallocs */ | 477 | ssh_malloc_init(); /* must be called before any mallocs */ |
485 | /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ | 478 | /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ |
@@ -507,7 +500,7 @@ main(int argc, char **argv) | |||
507 | exit(2); | 500 | exit(2); |
508 | } | 501 | } |
509 | 502 | ||
510 | while ((ch = getopt(argc, argv, "klLcdDxXE:e:s:t:")) != -1) { | 503 | while ((ch = getopt(argc, argv, "klLcdDxXE:e:qs:t:")) != -1) { |
511 | switch (ch) { | 504 | switch (ch) { |
512 | case 'E': | 505 | case 'E': |
513 | fingerprint_hash = ssh_digest_alg_by_name(optarg); | 506 | fingerprint_hash = ssh_digest_alg_by_name(optarg); |
@@ -552,6 +545,9 @@ main(int argc, char **argv) | |||
552 | goto done; | 545 | goto done; |
553 | } | 546 | } |
554 | break; | 547 | break; |
548 | case 'q': | ||
549 | qflag = 1; | ||
550 | break; | ||
555 | default: | 551 | default: |
556 | usage(); | 552 | usage(); |
557 | ret = 1; | 553 | ret = 1; |
@@ -600,7 +596,8 @@ main(int argc, char **argv) | |||
600 | default_files[i]); | 596 | default_files[i]); |
601 | if (stat(buf, &st) < 0) | 597 | if (stat(buf, &st) < 0) |
602 | continue; | 598 | continue; |
603 | if (do_file(agent_fd, deleting, key_only, buf) == -1) | 599 | if (do_file(agent_fd, deleting, key_only, buf, |
600 | qflag) == -1) | ||
604 | ret = 1; | 601 | ret = 1; |
605 | else | 602 | else |
606 | count++; | 603 | count++; |
@@ -610,7 +607,7 @@ main(int argc, char **argv) | |||
610 | } else { | 607 | } else { |
611 | for (i = 0; i < argc; i++) { | 608 | for (i = 0; i < argc; i++) { |
612 | if (do_file(agent_fd, deleting, key_only, | 609 | if (do_file(agent_fd, deleting, key_only, |
613 | argv[i]) == -1) | 610 | argv[i], qflag) == -1) |
614 | ret = 1; | 611 | ret = 1; |
615 | } | 612 | } |
616 | } | 613 | } |