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 11dd3e720..8015b1bdf 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 key = options.identity_keys[i]; 1494 key = options.identity_keys[i];
1493 if (key && key->type == KEY_RSA1) 1495 if (key && key->type == KEY_RSA1)
@@ -1498,8 +1500,32 @@ pubkey_prepare(Authctxt *authctxt)
1498 id = xcalloc(1, sizeof(*id)); 1500 id = xcalloc(1, sizeof(*id));
1499 id->key = key; 1501 id->key = key;
1500 id->filename = xstrdup(options.identity_files[i]); 1502 id->filename = xstrdup(options.identity_files[i]);
1503 id->userprovided = 1;
1501 TAILQ_INSERT_TAIL(&files, id, next); 1504 TAILQ_INSERT_TAIL(&files, id, next);
1502 } 1505 }
1506 /* Prefer PKCS11 keys that are explicitly listed */
1507 TAILQ_FOREACH_SAFE(id, &files, next, tmp) {
1508 if (id->key == NULL || (id->key->flags & KEY_FLAG_EXT) == 0)
1509 continue;
1510 found = 0;
1511 TAILQ_FOREACH(id2, &files, next) {
1512 if (id2->key == NULL ||
1513 (id2->key->flags & KEY_FLAG_EXT) != 0)
1514 continue;
1515 if (key_equal(id->key, id2->key)) {
1516 TAILQ_REMOVE(&files, id, next);
1517 TAILQ_INSERT_TAIL(preferred, id, next);
1518 found = 1;
1519 break;
1520 }
1521 }
1522 /* If IdentitiesOnly set and key not found then don't use it */
1523 if (!found && options.identities_only) {
1524 TAILQ_REMOVE(&files, id, next);
1525 bzero(id, sizeof(id));
1526 free(id);
1527 }
1528 }
1503 /* list of keys supported by the agent */ 1529 /* list of keys supported by the agent */
1504 if ((ac = ssh_get_authentication_connection())) { 1530 if ((ac = ssh_get_authentication_connection())) {
1505 for (key = ssh_get_first_identity(ac, &comment, 2); 1531 for (key = ssh_get_first_identity(ac, &comment, 2);
@@ -1539,7 +1565,8 @@ pubkey_prepare(Authctxt *authctxt)
1539 TAILQ_INSERT_TAIL(preferred, id, next); 1565 TAILQ_INSERT_TAIL(preferred, id, next);
1540 } 1566 }
1541 TAILQ_FOREACH(id, preferred, next) { 1567 TAILQ_FOREACH(id, preferred, next) {
1542 debug2("key: %s (%p)", id->filename, id->key); 1568 debug2("key: %s (%p),%s", id->filename, id->key,
1569 id->userprovided ? " explicit" : "");
1543 } 1570 }
1544} 1571}
1545 1572
@@ -1584,7 +1611,8 @@ userauth_pubkey(Authctxt *authctxt)
1584 sent = send_pubkey_test(authctxt, id); 1611 sent = send_pubkey_test(authctxt, id);
1585 } else if (id->key == NULL) { 1612 } else if (id->key == NULL) {
1586 debug("Trying private key: %s", id->filename); 1613 debug("Trying private key: %s", id->filename);
1587 id->key = load_identity_file(id->filename); 1614 id->key = load_identity_file(id->filename,
1615 id->userprovided);
1588 if (id->key != NULL) { 1616 if (id->key != NULL) {
1589 id->isprivate = 1; 1617 id->isprivate = 1;
1590 sent = sign_and_send_pubkey(authctxt, id); 1618 sent = sign_and_send_pubkey(authctxt, id);