summaryrefslogtreecommitdiff
path: root/sshconnect2.c
diff options
context:
space:
mode:
Diffstat (limited to 'sshconnect2.c')
-rw-r--r--sshconnect2.c48
1 files changed, 38 insertions, 10 deletions
diff --git a/sshconnect2.c b/sshconnect2.c
index fe68d5c41..378b3200c 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect2.c,v 1.189 2012/06/22 12:30:26 dtucker Exp $ */ 1/* $OpenBSD: sshconnect2.c,v 1.191 2013/02/15 00:21:01 dtucker Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * Copyright (c) 2008 Damien Miller. All rights reserved. 4 * Copyright (c) 2008 Damien Miller. All rights reserved.
@@ -40,7 +40,7 @@
40#include <stdio.h> 40#include <stdio.h>
41#include <string.h> 41#include <string.h>
42#include <unistd.h> 42#include <unistd.h>
43#if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) 43#if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS)
44#include <vis.h> 44#include <vis.h>
45#endif 45#endif
46 46
@@ -304,6 +304,7 @@ struct identity {
304 char *filename; /* comment for agent-only keys */ 304 char *filename; /* comment for agent-only keys */
305 int tried; 305 int tried;
306 int isprivate; /* key points to the private key */ 306 int isprivate; /* key points to the private key */
307 int userprovided;
307}; 308};
308TAILQ_HEAD(idlist, identity); 309TAILQ_HEAD(idlist, identity);
309 310
@@ -369,7 +370,7 @@ void userauth(Authctxt *, char *);
369static int sign_and_send_pubkey(Authctxt *, Identity *); 370static int sign_and_send_pubkey(Authctxt *, Identity *);
370static void pubkey_prepare(Authctxt *); 371static void pubkey_prepare(Authctxt *);
371static void pubkey_cleanup(Authctxt *); 372static void pubkey_cleanup(Authctxt *);
372static Key *load_identity_file(char *); 373static Key *load_identity_file(char *, int);
373 374
374static Authmethod *authmethod_get(char *authlist); 375static Authmethod *authmethod_get(char *authlist);
375static Authmethod *authmethod_lookup(const char *name); 376static Authmethod *authmethod_lookup(const char *name);
@@ -1302,7 +1303,7 @@ identity_sign(Identity *id, u_char **sigp, u_int *lenp,
1302 if (id->isprivate || (id->key->flags & KEY_FLAG_EXT)) 1303 if (id->isprivate || (id->key->flags & KEY_FLAG_EXT))
1303 return (key_sign(id->key, sigp, lenp, data, datalen)); 1304 return (key_sign(id->key, sigp, lenp, data, datalen));
1304 /* load the private key from the file */ 1305 /* load the private key from the file */
1305 if ((prv = load_identity_file(id->filename)) == NULL) 1306 if ((prv = load_identity_file(id->filename, id->userprovided)) == NULL)
1306 return (-1); 1307 return (-1);
1307 ret = key_sign(prv, sigp, lenp, data, datalen); 1308 ret = key_sign(prv, sigp, lenp, data, datalen);
1308 key_free(prv); 1309 key_free(prv);
@@ -1427,7 +1428,7 @@ send_pubkey_test(Authctxt *authctxt, Identity *id)
1427} 1428}
1428 1429
1429static Key * 1430static Key *
1430load_identity_file(char *filename) 1431load_identity_file(char *filename, int userprovided)
1431{ 1432{
1432 Key *private; 1433 Key *private;
1433 char prompt[300], *passphrase; 1434 char prompt[300], *passphrase;
@@ -1435,7 +1436,8 @@ load_identity_file(char *filename)
1435 struct stat st; 1436 struct stat st;
1436 1437
1437 if (stat(filename, &st) < 0) { 1438 if (stat(filename, &st) < 0) {
1438 debug3("no such identity: %s", filename); 1439 (userprovided ? logit : debug3)("no such identity: %s: %s",
1440 filename, strerror(errno));
1439 return NULL; 1441 return NULL;
1440 } 1442 }
1441 private = key_load_private_type(KEY_UNSPEC, filename, "", NULL, &perm_ok); 1443 private = key_load_private_type(KEY_UNSPEC, filename, "", NULL, &perm_ok);
@@ -1475,7 +1477,7 @@ load_identity_file(char *filename)
1475static void 1477static void
1476pubkey_prepare(Authctxt *authctxt) 1478pubkey_prepare(Authctxt *authctxt)
1477{ 1479{
1478 Identity *id; 1480 Identity *id, *id2, *tmp;
1479 Idlist agent, files, *preferred; 1481 Idlist agent, files, *preferred;
1480 Key *key; 1482 Key *key;
1481 AuthenticationConnection *ac; 1483 AuthenticationConnection *ac;
@@ -1487,7 +1489,7 @@ pubkey_prepare(Authctxt *authctxt)
1487 preferred = &authctxt->keys; 1489 preferred = &authctxt->keys;
1488 TAILQ_INIT(preferred); /* preferred order of keys */ 1490 TAILQ_INIT(preferred); /* preferred order of keys */
1489 1491
1490 /* list of keys stored in the filesystem */ 1492 /* list of keys stored in the filesystem and PKCS#11 */
1491 for (i = 0; i < options.num_identity_files; i++) { 1493 for (i = 0; i < options.num_identity_files; i++) {
1492 if (options.identity_files[i] == NULL) 1494 if (options.identity_files[i] == NULL)
1493 continue; 1495 continue;
@@ -1500,8 +1502,32 @@ pubkey_prepare(Authctxt *authctxt)
1500 id = xcalloc(1, sizeof(*id)); 1502 id = xcalloc(1, sizeof(*id));
1501 id->key = key; 1503 id->key = key;
1502 id->filename = xstrdup(options.identity_files[i]); 1504 id->filename = xstrdup(options.identity_files[i]);
1505 id->userprovided = 1;
1503 TAILQ_INSERT_TAIL(&files, id, next); 1506 TAILQ_INSERT_TAIL(&files, id, next);
1504 } 1507 }
1508 /* Prefer PKCS11 keys that are explicitly listed */
1509 TAILQ_FOREACH_SAFE(id, &files, next, tmp) {
1510 if (id->key == NULL || (id->key->flags & KEY_FLAG_EXT) == 0)
1511 continue;
1512 found = 0;
1513 TAILQ_FOREACH(id2, &files, next) {
1514 if (id2->key == NULL ||
1515 (id2->key->flags & KEY_FLAG_EXT) != 0)
1516 continue;
1517 if (key_equal(id->key, id2->key)) {
1518 TAILQ_REMOVE(&files, id, next);
1519 TAILQ_INSERT_TAIL(preferred, id, next);
1520 found = 1;
1521 break;
1522 }
1523 }
1524 /* If IdentitiesOnly set and key not found then don't use it */
1525 if (!found && options.identities_only) {
1526 TAILQ_REMOVE(&files, id, next);
1527 bzero(id, sizeof(id));
1528 free(id);
1529 }
1530 }
1505 /* list of keys supported by the agent */ 1531 /* list of keys supported by the agent */
1506 if ((ac = ssh_get_authentication_connection())) { 1532 if ((ac = ssh_get_authentication_connection())) {
1507 for (key = ssh_get_first_identity(ac, &comment, 2); 1533 for (key = ssh_get_first_identity(ac, &comment, 2);
@@ -1541,7 +1567,8 @@ pubkey_prepare(Authctxt *authctxt)
1541 TAILQ_INSERT_TAIL(preferred, id, next); 1567 TAILQ_INSERT_TAIL(preferred, id, next);
1542 } 1568 }
1543 TAILQ_FOREACH(id, preferred, next) { 1569 TAILQ_FOREACH(id, preferred, next) {
1544 debug2("key: %s (%p)", id->filename, id->key); 1570 debug2("key: %s (%p),%s", id->filename, id->key,
1571 id->userprovided ? " explicit" : "");
1545 } 1572 }
1546} 1573}
1547 1574
@@ -1586,7 +1613,8 @@ userauth_pubkey(Authctxt *authctxt)
1586 sent = send_pubkey_test(authctxt, id); 1613 sent = send_pubkey_test(authctxt, id);
1587 } else if (id->key == NULL && id->filename) { 1614 } else if (id->key == NULL && id->filename) {
1588 debug("Trying private key: %s", id->filename); 1615 debug("Trying private key: %s", id->filename);
1589 id->key = load_identity_file(id->filename); 1616 id->key = load_identity_file(id->filename,
1617 id->userprovided);
1590 if (id->key != NULL) { 1618 if (id->key != NULL) {
1591 id->isprivate = 1; 1619 id->isprivate = 1;
1592 sent = sign_and_send_pubkey(authctxt, id); 1620 sent = sign_and_send_pubkey(authctxt, id);