summaryrefslogtreecommitdiff
path: root/ssh-add.c
diff options
context:
space:
mode:
Diffstat (limited to 'ssh-add.c')
-rw-r--r--ssh-add.c92
1 files changed, 69 insertions, 23 deletions
diff --git a/ssh-add.c b/ssh-add.c
index a40198ab5..936dc2128 100644
--- a/ssh-add.c
+++ b/ssh-add.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-add.c,v 1.155 2020/03/16 02:17:02 dtucker Exp $ */ 1/* $OpenBSD: ssh-add.c,v 1.157 2020/08/31 04:33:17 djm 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
@@ -67,6 +67,7 @@
67#include "ssherr.h" 67#include "ssherr.h"
68#include "digest.h" 68#include "digest.h"
69#include "ssh-sk.h" 69#include "ssh-sk.h"
70#include "sk-api.h"
70 71
71/* argv0 */ 72/* argv0 */
72extern char *__progname; 73extern char *__progname;
@@ -111,25 +112,69 @@ clear_pass(void)
111} 112}
112 113
113static int 114static int
115delete_one(int agent_fd, const struct sshkey *key, const char *comment,
116 const char *path, int qflag)
117{
118 int r;
119
120 if ((r = ssh_remove_identity(agent_fd, key)) != 0) {
121 fprintf(stderr, "Could not remove identity \"%s\": %s\n",
122 path, ssh_err(r));
123 return r;
124 }
125 if (!qflag) {
126 fprintf(stderr, "Identity removed: %s %s (%s)\n", path,
127 sshkey_type(key), comment);
128 }
129 return 0;
130}
131
132static int
133delete_stdin(int agent_fd, int qflag)
134{
135 char *line = NULL, *cp;
136 size_t linesize = 0;
137 struct sshkey *key = NULL;
138 int lnum = 0, r, ret = -1;
139
140 while (getline(&line, &linesize, stdin) != -1) {
141 lnum++;
142 sshkey_free(key);
143 key = NULL;
144 line[strcspn(line, "\n")] = '\0';
145 cp = line + strspn(line, " \t");
146 if (*cp == '#' || *cp == '\0')
147 continue;
148 if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
149 fatal("%s: sshkey_new", __func__);
150 if ((r = sshkey_read(key, &cp)) != 0) {
151 error("(stdin):%d: invalid key: %s", lnum, ssh_err(r));
152 continue;
153 }
154 if (delete_one(agent_fd, key, cp, "(stdin)", qflag) == 0)
155 ret = 0;
156 }
157 sshkey_free(key);
158 free(line);
159 return ret;
160}
161
162static int
114delete_file(int agent_fd, const char *filename, int key_only, int qflag) 163delete_file(int agent_fd, const char *filename, int key_only, int qflag)
115{ 164{
116 struct sshkey *public, *cert = NULL; 165 struct sshkey *public, *cert = NULL;
117 char *certpath = NULL, *comment = NULL; 166 char *certpath = NULL, *comment = NULL;
118 int r, ret = -1; 167 int r, ret = -1;
119 168
169 if (strcmp(filename, "-") == 0)
170 return delete_stdin(agent_fd, qflag);
171
120 if ((r = sshkey_load_public(filename, &public, &comment)) != 0) { 172 if ((r = sshkey_load_public(filename, &public, &comment)) != 0) {
121 printf("Bad key file %s: %s\n", filename, ssh_err(r)); 173 printf("Bad key file %s: %s\n", filename, ssh_err(r));
122 return -1; 174 return -1;
123 } 175 }
124 if ((r = ssh_remove_identity(agent_fd, public)) == 0) { 176 if (delete_one(agent_fd, public, comment, filename, qflag) == 0)
125 if (!qflag) {
126 fprintf(stderr, "Identity removed: %s (%s)\n",
127 filename, comment);
128 }
129 ret = 0; 177 ret = 0;
130 } else
131 fprintf(stderr, "Could not remove identity \"%s\": %s\n",
132 filename, ssh_err(r));
133 178
134 if (key_only) 179 if (key_only)
135 goto out; 180 goto out;
@@ -149,15 +194,8 @@ delete_file(int agent_fd, const char *filename, int key_only, int qflag)
149 fatal("Certificate %s does not match private key %s", 194 fatal("Certificate %s does not match private key %s",
150 certpath, filename); 195 certpath, filename);
151 196
152 if ((r = ssh_remove_identity(agent_fd, cert)) == 0) { 197 if (delete_one(agent_fd, cert, comment, certpath, qflag) == 0)
153 if (!qflag) {
154 fprintf(stderr, "Identity removed: %s (%s)\n",
155 certpath, comment);
156 }
157 ret = 0; 198 ret = 0;
158 } else
159 fprintf(stderr, "Could not remove identity \"%s\": %s\n",
160 certpath, ssh_err(r));
161 199
162 out: 200 out:
163 sshkey_free(cert); 201 sshkey_free(cert);
@@ -311,12 +349,20 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag,
311 ssh_free_identitylist(idlist); 349 ssh_free_identitylist(idlist);
312 } 350 }
313 351
314 if (!sshkey_is_sk(private)) 352 if (sshkey_is_sk(private)) {
315 skprovider = NULL; /* Don't send constraint for other keys */ 353 if (skprovider == NULL) {
316 else if (skprovider == NULL) { 354 fprintf(stderr, "Cannot load FIDO key %s "
317 fprintf(stderr, "Cannot load authenticator-hosted key %s " 355 "without provider\n", filename);
318 "without provider\n", filename); 356 goto out;
319 goto out; 357 }
358 if ((private->sk_flags & SSH_SK_USER_VERIFICATION_REQD) != 0) {
359 fprintf(stderr, "FIDO verify-required key %s is not "
360 "currently supported by ssh-agent\n", filename);
361 goto out;
362 }
363 } else {
364 /* Don't send provider constraint for other keys */
365 skprovider = NULL;
320 } 366 }
321 367
322 if ((r = ssh_add_identity_constrained(agent_fd, private, comment, 368 if ((r = ssh_add_identity_constrained(agent_fd, private, comment,