diff options
author | djm@openbsd.org <djm@openbsd.org> | 2015-01-14 20:05:27 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2015-01-15 21:37:34 +1100 |
commit | 141efe49542f7156cdbc2e4cd0a041d8b1aab622 (patch) | |
tree | a9142350f2b8689f4d42548ca272ed577b32a881 /ssh-add.c | |
parent | 0088c57af302cda278bd26d8c3ae81d5b6f7c289 (diff) |
upstream commit
move authfd.c and its tentacles to the new buffer/key
API; ok markus@
Diffstat (limited to 'ssh-add.c')
-rw-r--r-- | ssh-add.c | 259 |
1 files changed, 151 insertions, 108 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-add.c,v 1.115 2014/12/21 22:27:56 djm Exp $ */ | 1 | /* $OpenBSD: ssh-add.c,v 1.116 2015/01/14 20:05:27 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 |
@@ -44,6 +44,7 @@ | |||
44 | #include <openssl/evp.h> | 44 | #include <openssl/evp.h> |
45 | #include "openbsd-compat/openssl-compat.h" | 45 | #include "openbsd-compat/openssl-compat.h" |
46 | 46 | ||
47 | #include <errno.h> | ||
47 | #include <fcntl.h> | 48 | #include <fcntl.h> |
48 | #include <pwd.h> | 49 | #include <pwd.h> |
49 | #include <stdarg.h> | 50 | #include <stdarg.h> |
@@ -56,8 +57,8 @@ | |||
56 | #include "ssh.h" | 57 | #include "ssh.h" |
57 | #include "rsa.h" | 58 | #include "rsa.h" |
58 | #include "log.h" | 59 | #include "log.h" |
59 | #include "key.h" | 60 | #include "sshkey.h" |
60 | #include "buffer.h" | 61 | #include "sshbuf.h" |
61 | #include "authfd.h" | 62 | #include "authfd.h" |
62 | #include "authfile.h" | 63 | #include "authfile.h" |
63 | #include "pathnames.h" | 64 | #include "pathnames.h" |
@@ -103,22 +104,22 @@ clear_pass(void) | |||
103 | } | 104 | } |
104 | 105 | ||
105 | static int | 106 | static int |
106 | delete_file(AuthenticationConnection *ac, const char *filename, int key_only) | 107 | delete_file(int agent_fd, const char *filename, int key_only) |
107 | { | 108 | { |
108 | Key *public = NULL, *cert = NULL; | 109 | struct sshkey *public, *cert = NULL; |
109 | char *certpath = NULL, *comment = NULL; | 110 | char *certpath = NULL, *comment = NULL; |
110 | int ret = -1; | 111 | int r, ret = -1; |
111 | 112 | ||
112 | public = key_load_public(filename, &comment); | 113 | if ((r = sshkey_load_public(filename, &public, &comment)) != 0) { |
113 | if (public == NULL) { | 114 | printf("Bad key file %s: %s\n", filename, ssh_err(r)); |
114 | printf("Bad key file %s\n", filename); | ||
115 | return -1; | 115 | return -1; |
116 | } | 116 | } |
117 | if (ssh_remove_identity(ac, public)) { | 117 | if ((r = ssh_remove_identity(agent_fd, public)) == 0) { |
118 | fprintf(stderr, "Identity removed: %s (%s)\n", filename, comment); | 118 | fprintf(stderr, "Identity removed: %s (%s)\n", filename, comment); |
119 | ret = 0; | 119 | ret = 0; |
120 | } else | 120 | } else |
121 | fprintf(stderr, "Could not remove identity: %s\n", filename); | 121 | fprintf(stderr, "Could not remove identity \"%s\": %s\n", |
122 | filename, ssh_err(r)); | ||
122 | 123 | ||
123 | if (key_only) | 124 | if (key_only) |
124 | goto out; | 125 | goto out; |
@@ -127,13 +128,13 @@ delete_file(AuthenticationConnection *ac, const char *filename, int key_only) | |||
127 | free(comment); | 128 | free(comment); |
128 | comment = NULL; | 129 | comment = NULL; |
129 | xasprintf(&certpath, "%s-cert.pub", filename); | 130 | xasprintf(&certpath, "%s-cert.pub", filename); |
130 | if ((cert = key_load_public(certpath, &comment)) == NULL) | 131 | if ((r = sshkey_load_public(certpath, &cert, &comment)) == 0) |
131 | goto out; | 132 | goto out; |
132 | if (!key_equal_public(cert, public)) | 133 | if (!sshkey_equal_public(cert, public)) |
133 | fatal("Certificate %s does not match private key %s", | 134 | fatal("Certificate %s does not match private key %s", |
134 | certpath, filename); | 135 | certpath, filename); |
135 | 136 | ||
136 | if (ssh_remove_identity(ac, cert)) { | 137 | if (ssh_remove_identity(agent_fd, cert)) { |
137 | fprintf(stderr, "Identity removed: %s (%s)\n", certpath, | 138 | fprintf(stderr, "Identity removed: %s (%s)\n", certpath, |
138 | comment); | 139 | comment); |
139 | ret = 0; | 140 | ret = 0; |
@@ -142,9 +143,9 @@ delete_file(AuthenticationConnection *ac, const char *filename, int key_only) | |||
142 | 143 | ||
143 | out: | 144 | out: |
144 | if (cert != NULL) | 145 | if (cert != NULL) |
145 | key_free(cert); | 146 | sshkey_free(cert); |
146 | if (public != NULL) | 147 | if (public != NULL) |
147 | key_free(public); | 148 | sshkey_free(public); |
148 | free(certpath); | 149 | free(certpath); |
149 | free(comment); | 150 | free(comment); |
150 | 151 | ||
@@ -153,14 +154,15 @@ delete_file(AuthenticationConnection *ac, const char *filename, int key_only) | |||
153 | 154 | ||
154 | /* Send a request to remove all identities. */ | 155 | /* Send a request to remove all identities. */ |
155 | static int | 156 | static int |
156 | delete_all(AuthenticationConnection *ac) | 157 | delete_all(int agent_fd) |
157 | { | 158 | { |
158 | int ret = -1; | 159 | int ret = -1; |
159 | 160 | ||
160 | if (ssh_remove_all_identities(ac, 1)) | 161 | if (ssh_remove_all_identities(agent_fd, 1) == 0) |
161 | ret = 0; | 162 | ret = 0; |
162 | /* ignore error-code for ssh2 */ | 163 | /* ignore error-code for ssh2 */ |
163 | ssh_remove_all_identities(ac, 2); | 164 | /* XXX revisit */ |
165 | ssh_remove_all_identities(agent_fd, 2); | ||
164 | 166 | ||
165 | if (ret == 0) | 167 | if (ret == 0) |
166 | fprintf(stderr, "All identities removed.\n"); | 168 | fprintf(stderr, "All identities removed.\n"); |
@@ -171,13 +173,13 @@ delete_all(AuthenticationConnection *ac) | |||
171 | } | 173 | } |
172 | 174 | ||
173 | static int | 175 | static int |
174 | add_file(AuthenticationConnection *ac, const char *filename, int key_only) | 176 | add_file(int agent_fd, const char *filename, int key_only) |
175 | { | 177 | { |
176 | Key *private, *cert; | 178 | struct sshkey *private, *cert; |
177 | char *comment = NULL; | 179 | char *comment = NULL; |
178 | char msg[1024], *certpath = NULL; | 180 | char msg[1024], *certpath = NULL; |
179 | int r, fd, perms_ok, ret = -1; | 181 | int r, fd, ret = -1; |
180 | Buffer keyblob; | 182 | struct sshbuf *keyblob; |
181 | 183 | ||
182 | if (strcmp(filename, "-") == 0) { | 184 | if (strcmp(filename, "-") == 0) { |
183 | fd = STDIN_FILENO; | 185 | fd = STDIN_FILENO; |
@@ -192,30 +194,38 @@ add_file(AuthenticationConnection *ac, const char *filename, int key_only) | |||
192 | * will occur multiple times, so check perms first and bail if wrong. | 194 | * will occur multiple times, so check perms first and bail if wrong. |
193 | */ | 195 | */ |
194 | if (fd != STDIN_FILENO) { | 196 | if (fd != STDIN_FILENO) { |
195 | perms_ok = key_perm_ok(fd, filename); | 197 | if (sshkey_perm_ok(fd, filename) != 0) { |
196 | if (!perms_ok) { | ||
197 | close(fd); | 198 | close(fd); |
198 | return -1; | 199 | return -1; |
199 | } | 200 | } |
200 | } | 201 | } |
201 | buffer_init(&keyblob); | 202 | if ((keyblob = sshbuf_new()) == NULL) |
202 | if (!key_load_file(fd, filename, &keyblob)) { | 203 | fatal("%s: sshbuf_new failed", __func__); |
203 | buffer_free(&keyblob); | 204 | if ((r = sshkey_load_file(fd, keyblob)) != 0) { |
205 | fprintf(stderr, "Error loading key \"%s\": %s\n", | ||
206 | filename, ssh_err(r)); | ||
207 | sshbuf_free(keyblob); | ||
204 | close(fd); | 208 | close(fd); |
205 | return -1; | 209 | return -1; |
206 | } | 210 | } |
207 | close(fd); | 211 | close(fd); |
208 | 212 | ||
209 | /* At first, try empty passphrase */ | 213 | /* At first, try empty passphrase */ |
210 | if ((r = sshkey_parse_private_fileblob(&keyblob, "", filename, | 214 | if ((r = sshkey_parse_private_fileblob(keyblob, "", filename, |
211 | &private, &comment)) != 0 && r != SSH_ERR_KEY_WRONG_PASSPHRASE) | 215 | &private, &comment)) != 0 && r != SSH_ERR_KEY_WRONG_PASSPHRASE) { |
212 | fatal("Cannot parse %s: %s", filename, ssh_err(r)); | 216 | fprintf(stderr, "Error loading key \"%s\": %s\n", |
217 | filename, ssh_err(r)); | ||
218 | goto fail_load; | ||
219 | } | ||
213 | /* try last */ | 220 | /* try last */ |
214 | if (private == NULL && pass != NULL) { | 221 | if (private == NULL && pass != NULL) { |
215 | if ((r = sshkey_parse_private_fileblob(&keyblob, pass, filename, | 222 | if ((r = sshkey_parse_private_fileblob(keyblob, pass, filename, |
216 | &private, &comment)) != 0 && | 223 | &private, &comment)) != 0 && |
217 | r != SSH_ERR_KEY_WRONG_PASSPHRASE) | 224 | r != SSH_ERR_KEY_WRONG_PASSPHRASE) { |
218 | fatal("Cannot parse %s: %s", filename, ssh_err(r)); | 225 | fprintf(stderr, "Error loading key \"%s\": %s\n", |
226 | filename, ssh_err(r)); | ||
227 | goto fail_load; | ||
228 | } | ||
219 | } | 229 | } |
220 | if (comment == NULL) | 230 | if (comment == NULL) |
221 | comment = xstrdup(filename); | 231 | comment = xstrdup(filename); |
@@ -226,28 +236,30 @@ add_file(AuthenticationConnection *ac, const char *filename, int key_only) | |||
226 | comment); | 236 | comment); |
227 | for (;;) { | 237 | for (;;) { |
228 | pass = read_passphrase(msg, RP_ALLOW_STDIN); | 238 | pass = read_passphrase(msg, RP_ALLOW_STDIN); |
229 | if (strcmp(pass, "") == 0) { | 239 | if (strcmp(pass, "") == 0) |
240 | goto fail_load; | ||
241 | if ((r = sshkey_parse_private_fileblob(keyblob, pass, | ||
242 | filename, &private, NULL)) == 0) | ||
243 | break; | ||
244 | else if (r != SSH_ERR_KEY_WRONG_PASSPHRASE) { | ||
245 | fprintf(stderr, | ||
246 | "Error loading key \"%s\": %s\n", | ||
247 | filename, ssh_err(r)); | ||
248 | fail_load: | ||
230 | clear_pass(); | 249 | clear_pass(); |
231 | free(comment); | 250 | free(comment); |
232 | buffer_free(&keyblob); | 251 | sshbuf_free(keyblob); |
233 | return -1; | 252 | return -1; |
234 | } | 253 | } |
235 | if ((r = sshkey_parse_private_fileblob(&keyblob, | ||
236 | pass, filename, &private, NULL)) != 0 && | ||
237 | r != SSH_ERR_KEY_WRONG_PASSPHRASE) | ||
238 | fatal("Cannot parse %s: %s", | ||
239 | filename, ssh_err(r)); | ||
240 | if (private != NULL) | ||
241 | break; | ||
242 | clear_pass(); | 254 | clear_pass(); |
243 | snprintf(msg, sizeof msg, | 255 | snprintf(msg, sizeof msg, |
244 | "Bad passphrase, try again for %.200s: ", comment); | 256 | "Bad passphrase, try again for %.200s: ", comment); |
245 | } | 257 | } |
246 | } | 258 | } |
247 | buffer_free(&keyblob); | 259 | sshbuf_free(keyblob); |
248 | 260 | ||
249 | if (ssh_add_identity_constrained(ac, private, comment, lifetime, | 261 | if ((r = ssh_add_identity_constrained(agent_fd, private, comment, |
250 | confirm)) { | 262 | lifetime, confirm)) == 0) { |
251 | fprintf(stderr, "Identity added: %s (%s)\n", filename, comment); | 263 | fprintf(stderr, "Identity added: %s (%s)\n", filename, comment); |
252 | ret = 0; | 264 | ret = 0; |
253 | if (lifetime != 0) | 265 | if (lifetime != 0) |
@@ -257,7 +269,8 @@ add_file(AuthenticationConnection *ac, const char *filename, int key_only) | |||
257 | fprintf(stderr, | 269 | fprintf(stderr, |
258 | "The user must confirm each use of the key\n"); | 270 | "The user must confirm each use of the key\n"); |
259 | } else { | 271 | } else { |
260 | fprintf(stderr, "Could not add identity: %s\n", filename); | 272 | fprintf(stderr, "Could not add identity \"%s\": %s\n", |
273 | filename, ssh_err(r)); | ||
261 | } | 274 | } |
262 | 275 | ||
263 | /* Skip trying to load the cert if requested */ | 276 | /* Skip trying to load the cert if requested */ |
@@ -266,29 +279,39 @@ add_file(AuthenticationConnection *ac, const char *filename, int key_only) | |||
266 | 279 | ||
267 | /* Now try to add the certificate flavour too */ | 280 | /* Now try to add the certificate flavour too */ |
268 | xasprintf(&certpath, "%s-cert.pub", filename); | 281 | xasprintf(&certpath, "%s-cert.pub", filename); |
269 | if ((cert = key_load_public(certpath, NULL)) == NULL) | 282 | if ((r = sshkey_load_public(certpath, &cert, NULL)) != 0) { |
283 | if (r != SSH_ERR_SYSTEM_ERROR || errno != ENOENT) | ||
284 | error("Failed to load certificate \"%s\": %s", | ||
285 | certpath, ssh_err(r)); | ||
270 | goto out; | 286 | goto out; |
287 | } | ||
271 | 288 | ||
272 | if (!key_equal_public(cert, private)) { | 289 | if (!sshkey_equal_public(cert, private)) { |
273 | error("Certificate %s does not match private key %s", | 290 | error("Certificate %s does not match private key %s", |
274 | certpath, filename); | 291 | certpath, filename); |
275 | key_free(cert); | 292 | sshkey_free(cert); |
276 | goto out; | 293 | goto out; |
277 | } | 294 | } |
278 | 295 | ||
279 | /* Graft with private bits */ | 296 | /* Graft with private bits */ |
280 | if (key_to_certified(private, key_cert_is_legacy(cert)) != 0) { | 297 | if ((r = sshkey_to_certified(private, |
281 | error("%s: key_to_certified failed", __func__); | 298 | sshkey_cert_is_legacy(cert))) != 0) { |
282 | key_free(cert); | 299 | error("%s: sshkey_to_certified: %s", __func__, ssh_err(r)); |
300 | sshkey_free(cert); | ||
301 | goto out; | ||
302 | } | ||
303 | if ((r = sshkey_cert_copy(cert, private)) != 0) { | ||
304 | error("%s: key_cert_copy: %s", __func__, ssh_err(r)); | ||
305 | sshkey_free(cert); | ||
283 | goto out; | 306 | goto out; |
284 | } | 307 | } |
285 | key_cert_copy(cert, private); | 308 | sshkey_free(cert); |
286 | key_free(cert); | ||
287 | 309 | ||
288 | if (!ssh_add_identity_constrained(ac, private, comment, | 310 | if ((r = ssh_add_identity_constrained(agent_fd, private, comment, |
289 | lifetime, confirm)) { | 311 | lifetime, confirm)) != 0) { |
290 | error("Certificate %s (%s) add failed", certpath, | 312 | error("Certificate %s (%s) add failed: %s", certpath, |
291 | private->cert->key_id); | 313 | private->cert->key_id, ssh_err(r)); |
314 | goto out; | ||
292 | } | 315 | } |
293 | fprintf(stderr, "Certificate added: %s (%s)\n", certpath, | 316 | fprintf(stderr, "Certificate added: %s (%s)\n", certpath, |
294 | private->cert->key_id); | 317 | private->cert->key_id); |
@@ -297,19 +320,18 @@ add_file(AuthenticationConnection *ac, const char *filename, int key_only) | |||
297 | if (confirm != 0) | 320 | if (confirm != 0) |
298 | fprintf(stderr, "The user must confirm each use of the key\n"); | 321 | fprintf(stderr, "The user must confirm each use of the key\n"); |
299 | out: | 322 | out: |
300 | if (certpath != NULL) | 323 | free(certpath); |
301 | free(certpath); | ||
302 | free(comment); | 324 | free(comment); |
303 | key_free(private); | 325 | sshkey_free(private); |
304 | 326 | ||
305 | return ret; | 327 | return ret; |
306 | } | 328 | } |
307 | 329 | ||
308 | static int | 330 | static int |
309 | update_card(AuthenticationConnection *ac, int add, const char *id) | 331 | update_card(int agent_fd, int add, const char *id) |
310 | { | 332 | { |
311 | char *pin = NULL; | 333 | char *pin = NULL; |
312 | int ret = -1; | 334 | int r, ret = -1; |
313 | 335 | ||
314 | if (add) { | 336 | if (add) { |
315 | if ((pin = read_passphrase("Enter passphrase for PKCS#11: ", | 337 | if ((pin = read_passphrase("Enter passphrase for PKCS#11: ", |
@@ -317,14 +339,14 @@ update_card(AuthenticationConnection *ac, int add, const char *id) | |||
317 | return -1; | 339 | return -1; |
318 | } | 340 | } |
319 | 341 | ||
320 | if (ssh_update_card(ac, add, id, pin == NULL ? "" : pin, | 342 | if ((r = ssh_update_card(agent_fd, add, id, pin == NULL ? "" : pin, |
321 | lifetime, confirm)) { | 343 | lifetime, confirm)) == 0) { |
322 | fprintf(stderr, "Card %s: %s\n", | 344 | fprintf(stderr, "Card %s: %s\n", |
323 | add ? "added" : "removed", id); | 345 | add ? "added" : "removed", id); |
324 | ret = 0; | 346 | ret = 0; |
325 | } else { | 347 | } else { |
326 | fprintf(stderr, "Could not %s card: %s\n", | 348 | fprintf(stderr, "Could not %s card \"%s\": %s\n", |
327 | add ? "add" : "remove", id); | 349 | add ? "add" : "remove", id, ssh_err(r)); |
328 | ret = -1; | 350 | ret = -1; |
329 | } | 351 | } |
330 | free(pin); | 352 | free(pin); |
@@ -332,32 +354,42 @@ update_card(AuthenticationConnection *ac, int add, const char *id) | |||
332 | } | 354 | } |
333 | 355 | ||
334 | static int | 356 | static int |
335 | list_identities(AuthenticationConnection *ac, int do_fp) | 357 | list_identities(int agent_fd, int do_fp) |
336 | { | 358 | { |
337 | Key *key; | 359 | char *fp; |
338 | char *comment, *fp; | 360 | int version, r, had_identities = 0; |
339 | int had_identities = 0; | 361 | struct ssh_identitylist *idlist; |
340 | int version; | 362 | size_t i; |
341 | 363 | ||
342 | for (version = 1; version <= 2; version++) { | 364 | for (version = 1; version <= 2; version++) { |
343 | for (key = ssh_get_first_identity(ac, &comment, version); | 365 | if ((r = ssh_fetch_identitylist(agent_fd, version, |
344 | key != NULL; | 366 | &idlist)) != 0) { |
345 | key = ssh_get_next_identity(ac, &comment, version)) { | 367 | if (r != SSH_ERR_AGENT_NO_IDENTITIES) |
368 | fprintf(stderr, "error fetching identities for " | ||
369 | "protocol %d: %s\n", version, ssh_err(r)); | ||
370 | continue; | ||
371 | } | ||
372 | for (i = 0; i < idlist->nkeys; i++) { | ||
346 | had_identities = 1; | 373 | had_identities = 1; |
347 | if (do_fp) { | 374 | if (do_fp) { |
348 | fp = key_fingerprint(key, fingerprint_hash, | 375 | fp = sshkey_fingerprint(idlist->keys[i], |
349 | SSH_FP_DEFAULT); | 376 | fingerprint_hash, SSH_FP_DEFAULT); |
350 | printf("%d %s %s (%s)\n", | 377 | printf("%d %s %s (%s)\n", |
351 | key_size(key), fp, comment, key_type(key)); | 378 | sshkey_size(idlist->keys[i]), fp, |
379 | idlist->comments[i], | ||
380 | sshkey_type(idlist->keys[i])); | ||
352 | free(fp); | 381 | free(fp); |
353 | } else { | 382 | } else { |
354 | if (!key_write(key, stdout)) | 383 | if ((r = sshkey_write(idlist->keys[i], |
355 | fprintf(stderr, "key_write failed"); | 384 | stdout)) != 0) { |
356 | fprintf(stdout, " %s\n", comment); | 385 | fprintf(stderr, "sshkey_write: %s\n", |
386 | ssh_err(r)); | ||
387 | continue; | ||
388 | } | ||
389 | fprintf(stdout, " %s\n", idlist->comments[i]); | ||
357 | } | 390 | } |
358 | key_free(key); | ||
359 | free(comment); | ||
360 | } | 391 | } |
392 | ssh_free_identitylist(idlist); | ||
361 | } | 393 | } |
362 | if (!had_identities) { | 394 | if (!had_identities) { |
363 | printf("The agent has no identities.\n"); | 395 | printf("The agent has no identities.\n"); |
@@ -367,10 +399,10 @@ list_identities(AuthenticationConnection *ac, int do_fp) | |||
367 | } | 399 | } |
368 | 400 | ||
369 | static int | 401 | static int |
370 | lock_agent(AuthenticationConnection *ac, int lock) | 402 | lock_agent(int agent_fd, int lock) |
371 | { | 403 | { |
372 | char prompt[100], *p1, *p2; | 404 | char prompt[100], *p1, *p2; |
373 | int passok = 1, ret = -1; | 405 | int r, passok = 1, ret = -1; |
374 | 406 | ||
375 | strlcpy(prompt, "Enter lock password: ", sizeof(prompt)); | 407 | strlcpy(prompt, "Enter lock password: ", sizeof(prompt)); |
376 | p1 = read_passphrase(prompt, RP_ALLOW_STDIN); | 408 | p1 = read_passphrase(prompt, RP_ALLOW_STDIN); |
@@ -384,24 +416,28 @@ lock_agent(AuthenticationConnection *ac, int lock) | |||
384 | explicit_bzero(p2, strlen(p2)); | 416 | explicit_bzero(p2, strlen(p2)); |
385 | free(p2); | 417 | free(p2); |
386 | } | 418 | } |
387 | if (passok && ssh_lock_agent(ac, lock, p1)) { | 419 | if (passok) { |
388 | fprintf(stderr, "Agent %slocked.\n", lock ? "" : "un"); | 420 | if ((r = ssh_lock_agent(agent_fd, lock, p1)) == 0) { |
389 | ret = 0; | 421 | fprintf(stderr, "Agent %slocked.\n", lock ? "" : "un"); |
390 | } else | 422 | ret = 0; |
391 | fprintf(stderr, "Failed to %slock agent.\n", lock ? "" : "un"); | 423 | } else { |
424 | fprintf(stderr, "Failed to %slock agent: %s\n", | ||
425 | lock ? "" : "un", ssh_err(r)); | ||
426 | } | ||
427 | } | ||
392 | explicit_bzero(p1, strlen(p1)); | 428 | explicit_bzero(p1, strlen(p1)); |
393 | free(p1); | 429 | free(p1); |
394 | return (ret); | 430 | return (ret); |
395 | } | 431 | } |
396 | 432 | ||
397 | static int | 433 | static int |
398 | do_file(AuthenticationConnection *ac, int deleting, int key_only, char *file) | 434 | do_file(int agent_fd, int deleting, int key_only, char *file) |
399 | { | 435 | { |
400 | if (deleting) { | 436 | if (deleting) { |
401 | if (delete_file(ac, file, key_only) == -1) | 437 | if (delete_file(agent_fd, file, key_only) == -1) |
402 | return -1; | 438 | return -1; |
403 | } else { | 439 | } else { |
404 | if (add_file(ac, file, key_only) == -1) | 440 | if (add_file(agent_fd, file, key_only) == -1) |
405 | return -1; | 441 | return -1; |
406 | } | 442 | } |
407 | return 0; | 443 | return 0; |
@@ -431,9 +467,9 @@ main(int argc, char **argv) | |||
431 | { | 467 | { |
432 | extern char *optarg; | 468 | extern char *optarg; |
433 | extern int optind; | 469 | extern int optind; |
434 | AuthenticationConnection *ac = NULL; | 470 | int agent_fd; |
435 | char *pkcs11provider = NULL; | 471 | char *pkcs11provider = NULL; |
436 | int i, ch, deleting = 0, ret = 0, key_only = 0; | 472 | int r, i, ch, deleting = 0, ret = 0, key_only = 0; |
437 | int xflag = 0, lflag = 0, Dflag = 0; | 473 | int xflag = 0, lflag = 0, Dflag = 0; |
438 | 474 | ||
439 | /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ | 475 | /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ |
@@ -448,13 +484,19 @@ main(int argc, char **argv) | |||
448 | 484 | ||
449 | setvbuf(stdout, NULL, _IOLBF, 0); | 485 | setvbuf(stdout, NULL, _IOLBF, 0); |
450 | 486 | ||
451 | /* At first, get a connection to the authentication agent. */ | 487 | /* First, get a connection to the authentication agent. */ |
452 | ac = ssh_get_authentication_connection(); | 488 | switch (r = ssh_get_authentication_socket(&agent_fd)) { |
453 | if (ac == NULL) { | 489 | case 0: |
454 | fprintf(stderr, | 490 | break; |
455 | "Could not open a connection to your authentication agent.\n"); | 491 | case SSH_ERR_AGENT_NOT_PRESENT: |
492 | fprintf(stderr, "Could not open a connection to your " | ||
493 | "authentication agent.\n"); | ||
494 | exit(2); | ||
495 | default: | ||
496 | fprintf(stderr, "Error connecting to agent: %s\n", ssh_err(r)); | ||
456 | exit(2); | 497 | exit(2); |
457 | } | 498 | } |
499 | |||
458 | while ((ch = getopt(argc, argv, "klLcdDxXE:e:s:t:")) != -1) { | 500 | while ((ch = getopt(argc, argv, "klLcdDxXE:e:s:t:")) != -1) { |
459 | switch (ch) { | 501 | switch (ch) { |
460 | case 'E': | 502 | case 'E': |
@@ -510,15 +552,15 @@ main(int argc, char **argv) | |||
510 | if ((xflag != 0) + (lflag != 0) + (Dflag != 0) > 1) | 552 | if ((xflag != 0) + (lflag != 0) + (Dflag != 0) > 1) |
511 | fatal("Invalid combination of actions"); | 553 | fatal("Invalid combination of actions"); |
512 | else if (xflag) { | 554 | else if (xflag) { |
513 | if (lock_agent(ac, xflag == 'x' ? 1 : 0) == -1) | 555 | if (lock_agent(agent_fd, xflag == 'x' ? 1 : 0) == -1) |
514 | ret = 1; | 556 | ret = 1; |
515 | goto done; | 557 | goto done; |
516 | } else if (lflag) { | 558 | } else if (lflag) { |
517 | if (list_identities(ac, lflag == 'l' ? 1 : 0) == -1) | 559 | if (list_identities(agent_fd, lflag == 'l' ? 1 : 0) == -1) |
518 | ret = 1; | 560 | ret = 1; |
519 | goto done; | 561 | goto done; |
520 | } else if (Dflag) { | 562 | } else if (Dflag) { |
521 | if (delete_all(ac) == -1) | 563 | if (delete_all(agent_fd) == -1) |
522 | ret = 1; | 564 | ret = 1; |
523 | goto done; | 565 | goto done; |
524 | } | 566 | } |
@@ -526,7 +568,7 @@ main(int argc, char **argv) | |||
526 | argc -= optind; | 568 | argc -= optind; |
527 | argv += optind; | 569 | argv += optind; |
528 | if (pkcs11provider != NULL) { | 570 | if (pkcs11provider != NULL) { |
529 | if (update_card(ac, !deleting, pkcs11provider) == -1) | 571 | if (update_card(agent_fd, !deleting, pkcs11provider) == -1) |
530 | ret = 1; | 572 | ret = 1; |
531 | goto done; | 573 | goto done; |
532 | } | 574 | } |
@@ -548,7 +590,7 @@ main(int argc, char **argv) | |||
548 | default_files[i]); | 590 | default_files[i]); |
549 | if (stat(buf, &st) < 0) | 591 | if (stat(buf, &st) < 0) |
550 | continue; | 592 | continue; |
551 | if (do_file(ac, deleting, key_only, buf) == -1) | 593 | if (do_file(agent_fd, deleting, key_only, buf) == -1) |
552 | ret = 1; | 594 | ret = 1; |
553 | else | 595 | else |
554 | count++; | 596 | count++; |
@@ -557,13 +599,14 @@ main(int argc, char **argv) | |||
557 | ret = 1; | 599 | ret = 1; |
558 | } else { | 600 | } else { |
559 | for (i = 0; i < argc; i++) { | 601 | for (i = 0; i < argc; i++) { |
560 | if (do_file(ac, deleting, key_only, argv[i]) == -1) | 602 | if (do_file(agent_fd, deleting, key_only, |
603 | argv[i]) == -1) | ||
561 | ret = 1; | 604 | ret = 1; |
562 | } | 605 | } |
563 | } | 606 | } |
564 | clear_pass(); | 607 | clear_pass(); |
565 | 608 | ||
566 | done: | 609 | done: |
567 | ssh_close_authentication_connection(ac); | 610 | ssh_close_authentication_socket(agent_fd); |
568 | return ret; | 611 | return ret; |
569 | } | 612 | } |