summaryrefslogtreecommitdiff
path: root/ssh-add.c
diff options
context:
space:
mode:
Diffstat (limited to 'ssh-add.c')
-rw-r--r--ssh-add.c109
1 files changed, 53 insertions, 56 deletions
diff --git a/ssh-add.c b/ssh-add.c
index fb9a53e64..2afd48330 100644
--- a/ssh-add.c
+++ b/ssh-add.c
@@ -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
108static int 104static int
109delete_file(int agent_fd, const char *filename, int key_only) 105delete_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
180static int 186static int
181add_file(int agent_fd, const char *filename, int key_only) 187add_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
360list_identities(int agent_fd, int do_fp) 366list_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
442static int 434static int
443do_file(int agent_fd, int deleting, int key_only, char *file) 435do_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
474int 467int
@@ -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 }