summaryrefslogtreecommitdiff
path: root/usr.bin/ssh/ssh-agent.c
diff options
context:
space:
mode:
authorMarkus Friedl <markus@cvs.openbsd.org>2010-02-08 10:50:21 +0000
committerMarkus Friedl <markus@cvs.openbsd.org>2010-02-08 10:50:21 +0000
commitc5a426e3369a8674495c660c39ebd5bffb764a6f (patch)
treef5067e4cadefe54001a450458ba0d8512c2fc051 /usr.bin/ssh/ssh-agent.c
parent22e0496c0669a0c8e5b32bc387471ba9b089448b (diff)
replace our obsolete smartcard code with PKCS#11.
ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-11/v2-20/pkcs-11v2-20.pdf ssh(1) and ssh-keygen(1) use dlopen(3) directly to talk to a PKCS#11 provider (shared library) while ssh-agent(1) delegates PKCS#11 to a forked a ssh-pkcs11-helper process. PKCS#11 is currently a compile time option. feedback and ok djm@; inspired by patches from Alon Bar-Lev
Diffstat (limited to 'usr.bin/ssh/ssh-agent.c')
-rw-r--r--usr.bin/ssh/ssh-agent.c101
1 files changed, 51 insertions, 50 deletions
diff --git a/usr.bin/ssh/ssh-agent.c b/usr.bin/ssh/ssh-agent.c
index 79fcdfefa60..eec8a0a8243 100644
--- a/usr.bin/ssh/ssh-agent.c
+++ b/usr.bin/ssh/ssh-agent.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-agent.c,v 1.162 2009/09/01 14:43:17 djm Exp $ */
+/* $OpenBSD: ssh-agent.c,v 1.163 2010/02/08 10:50:20 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -66,8 +66,8 @@
#include "log.h"
#include "misc.h"
-#ifdef SMARTCARD
-#include "scard.h"
+#ifdef ENABLE_PKCS11
+#include "ssh-pkcs11.h"
#endif
typedef enum {
@@ -91,6 +91,7 @@ typedef struct identity {
TAILQ_ENTRY(identity) next;
Key *key;
char *comment;
+ char *provider;
u_int death;
u_int confirm;
} Identity;
@@ -157,6 +158,7 @@ static void
free_identity(Identity *id)
{
key_free(id->key);
+ xfree(id->provider);
xfree(id->comment);
xfree(id);
}
@@ -535,7 +537,7 @@ process_add_identity(SocketEntry *e, int version)
if (lifetime && !death)
death = time(NULL) + lifetime;
if ((id = lookup_identity(k, version)) == NULL) {
- id = xmalloc(sizeof(Identity));
+ id = xcalloc(1, sizeof(Identity));
id->key = k;
TAILQ_INSERT_TAIL(&tab->idlist, id, next);
/* Increment the number of identities. */
@@ -595,17 +597,17 @@ no_identities(SocketEntry *e, u_int type)
buffer_free(&msg);
}
-#ifdef SMARTCARD
+#ifdef ENABLE_PKCS11
static void
process_add_smartcard_key(SocketEntry *e)
{
- char *sc_reader_id = NULL, *pin;
- int i, type, version, success = 0, death = 0, confirm = 0;
- Key **keys, *k;
+ char *provider = NULL, *pin;
+ int i, type, version, count = 0, success = 0, death = 0, confirm = 0;
+ Key **keys = NULL, *k;
Identity *id;
Idtab *tab;
- sc_reader_id = buffer_get_string(&e->request, NULL);
+ provider = buffer_get_string(&e->request, NULL);
pin = buffer_get_string(&e->request, NULL);
while (buffer_len(&e->request)) {
@@ -619,30 +621,22 @@ process_add_smartcard_key(SocketEntry *e)
default:
error("process_add_smartcard_key: "
"Unknown constraint type %d", type);
- xfree(sc_reader_id);
- xfree(pin);
goto send;
}
}
if (lifetime && !death)
death = time(NULL) + lifetime;
- keys = sc_get_keys(sc_reader_id, pin);
- xfree(sc_reader_id);
- xfree(pin);
-
- if (keys == NULL || keys[0] == NULL) {
- error("sc_get_keys failed");
- goto send;
- }
- for (i = 0; keys[i] != NULL; i++) {
+ count = pkcs11_add_provider(provider, pin, &keys);
+ for (i = 0; i < count; i++) {
k = keys[i];
version = k->type == KEY_RSA1 ? 1 : 2;
tab = idtab_lookup(version);
if (lookup_identity(k, version) == NULL) {
- id = xmalloc(sizeof(Identity));
+ id = xcalloc(1, sizeof(Identity));
id->key = k;
- id->comment = sc_get_key_label(k);
+ id->provider = xstrdup(provider);
+ id->comment = xstrdup(provider); /* XXX */
id->death = death;
id->confirm = confirm;
TAILQ_INSERT_TAIL(&tab->idlist, id, next);
@@ -653,8 +647,13 @@ process_add_smartcard_key(SocketEntry *e)
}
keys[i] = NULL;
}
- xfree(keys);
send:
+ if (pin)
+ xfree(pin);
+ if (provider)
+ xfree(provider);
+ if (keys)
+ xfree(keys);
buffer_put_int(&e->output, 1);
buffer_put_char(&e->output,
success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
@@ -663,42 +662,37 @@ send:
static void
process_remove_smartcard_key(SocketEntry *e)
{
- char *sc_reader_id = NULL, *pin;
- int i, version, success = 0;
- Key **keys, *k = NULL;
- Identity *id;
+ char *provider = NULL, *pin = NULL;
+ int version, success = 0;
+ Identity *id, *nxt;
Idtab *tab;
- sc_reader_id = buffer_get_string(&e->request, NULL);
+ provider = buffer_get_string(&e->request, NULL);
pin = buffer_get_string(&e->request, NULL);
- keys = sc_get_keys(sc_reader_id, pin);
- xfree(sc_reader_id);
xfree(pin);
- if (keys == NULL || keys[0] == NULL) {
- error("sc_get_keys failed");
- goto send;
- }
- for (i = 0; keys[i] != NULL; i++) {
- k = keys[i];
- version = k->type == KEY_RSA1 ? 1 : 2;
- if ((id = lookup_identity(k, version)) != NULL) {
- tab = idtab_lookup(version);
- TAILQ_REMOVE(&tab->idlist, id, next);
- tab->nentries--;
- free_identity(id);
- success = 1;
+ for (version = 1; version < 3; version++) {
+ tab = idtab_lookup(version);
+ for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) {
+ nxt = TAILQ_NEXT(id, next);
+ if (!strcmp(provider, id->provider)) {
+ TAILQ_REMOVE(&tab->idlist, id, next);
+ free_identity(id);
+ tab->nentries--;
+ }
}
- key_free(k);
- keys[i] = NULL;
}
- xfree(keys);
-send:
+ if (pkcs11_del_provider(provider) == 0)
+ success = 1;
+ else
+ error("process_remove_smartcard_key:"
+ " pkcs11_del_provider failed");
+ xfree(provider);
buffer_put_int(&e->output, 1);
buffer_put_char(&e->output,
success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
}
-#endif /* SMARTCARD */
+#endif /* ENABLE_PKCS11 */
/* dispatch incoming messages */
@@ -783,7 +777,7 @@ process_message(SocketEntry *e)
case SSH2_AGENTC_REMOVE_ALL_IDENTITIES:
process_remove_all_identities(e, 2);
break;
-#ifdef SMARTCARD
+#ifdef ENABLE_PKCS11
case SSH_AGENTC_ADD_SMARTCARD_KEY:
case SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED:
process_add_smartcard_key(e);
@@ -791,7 +785,7 @@ process_message(SocketEntry *e)
case SSH_AGENTC_REMOVE_SMARTCARD_KEY:
process_remove_smartcard_key(e);
break;
-#endif /* SMARTCARD */
+#endif /* ENABLE_PKCS11 */
default:
/* Unknown message. Respond with failure. */
error("Unknown message %d", type);
@@ -993,6 +987,9 @@ static void
cleanup_handler(int sig)
{
cleanup_socket();
+#ifdef ENABLE_PKCS11
+ pkcs11_terminate();
+#endif
_exit(2);
}
@@ -1222,6 +1219,10 @@ main(int ac, char **av)
}
skip:
+
+#ifdef ENABLE_PKCS11
+ pkcs11_init(0);
+#endif
new_socket(AUTH_SOCKET, sock);
if (ac > 0)
parent_alive_interval = 10;