version 1.162, 2009/09/01 14:43:17 |
version 1.163, 2010/02/08 10:50:20 |
|
|
#include "log.h" |
#include "log.h" |
#include "misc.h" |
#include "misc.h" |
|
|
#ifdef SMARTCARD |
#ifdef ENABLE_PKCS11 |
#include "scard.h" |
#include "ssh-pkcs11.h" |
#endif |
#endif |
|
|
typedef enum { |
typedef enum { |
|
|
TAILQ_ENTRY(identity) next; |
TAILQ_ENTRY(identity) next; |
Key *key; |
Key *key; |
char *comment; |
char *comment; |
|
char *provider; |
u_int death; |
u_int death; |
u_int confirm; |
u_int confirm; |
} Identity; |
} Identity; |
|
|
free_identity(Identity *id) |
free_identity(Identity *id) |
{ |
{ |
key_free(id->key); |
key_free(id->key); |
|
xfree(id->provider); |
xfree(id->comment); |
xfree(id->comment); |
xfree(id); |
xfree(id); |
} |
} |
|
|
if (lifetime && !death) |
if (lifetime && !death) |
death = time(NULL) + lifetime; |
death = time(NULL) + lifetime; |
if ((id = lookup_identity(k, version)) == NULL) { |
if ((id = lookup_identity(k, version)) == NULL) { |
id = xmalloc(sizeof(Identity)); |
id = xcalloc(1, sizeof(Identity)); |
id->key = k; |
id->key = k; |
TAILQ_INSERT_TAIL(&tab->idlist, id, next); |
TAILQ_INSERT_TAIL(&tab->idlist, id, next); |
/* Increment the number of identities. */ |
/* Increment the number of identities. */ |
|
|
buffer_free(&msg); |
buffer_free(&msg); |
} |
} |
|
|
#ifdef SMARTCARD |
#ifdef ENABLE_PKCS11 |
static void |
static void |
process_add_smartcard_key(SocketEntry *e) |
process_add_smartcard_key(SocketEntry *e) |
{ |
{ |
char *sc_reader_id = NULL, *pin; |
char *provider = NULL, *pin; |
int i, type, version, success = 0, death = 0, confirm = 0; |
int i, type, version, count = 0, success = 0, death = 0, confirm = 0; |
Key **keys, *k; |
Key **keys = NULL, *k; |
Identity *id; |
Identity *id; |
Idtab *tab; |
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); |
pin = buffer_get_string(&e->request, NULL); |
|
|
while (buffer_len(&e->request)) { |
while (buffer_len(&e->request)) { |
|
|
default: |
default: |
error("process_add_smartcard_key: " |
error("process_add_smartcard_key: " |
"Unknown constraint type %d", type); |
"Unknown constraint type %d", type); |
xfree(sc_reader_id); |
|
xfree(pin); |
|
goto send; |
goto send; |
} |
} |
} |
} |
if (lifetime && !death) |
if (lifetime && !death) |
death = time(NULL) + lifetime; |
death = time(NULL) + lifetime; |
|
|
keys = sc_get_keys(sc_reader_id, pin); |
count = pkcs11_add_provider(provider, pin, &keys); |
xfree(sc_reader_id); |
for (i = 0; i < count; i++) { |
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]; |
k = keys[i]; |
version = k->type == KEY_RSA1 ? 1 : 2; |
version = k->type == KEY_RSA1 ? 1 : 2; |
tab = idtab_lookup(version); |
tab = idtab_lookup(version); |
if (lookup_identity(k, version) == NULL) { |
if (lookup_identity(k, version) == NULL) { |
id = xmalloc(sizeof(Identity)); |
id = xcalloc(1, sizeof(Identity)); |
id->key = k; |
id->key = k; |
id->comment = sc_get_key_label(k); |
id->provider = xstrdup(provider); |
|
id->comment = xstrdup(provider); /* XXX */ |
id->death = death; |
id->death = death; |
id->confirm = confirm; |
id->confirm = confirm; |
TAILQ_INSERT_TAIL(&tab->idlist, id, next); |
TAILQ_INSERT_TAIL(&tab->idlist, id, next); |
|
|
} |
} |
keys[i] = NULL; |
keys[i] = NULL; |
} |
} |
xfree(keys); |
|
send: |
send: |
|
if (pin) |
|
xfree(pin); |
|
if (provider) |
|
xfree(provider); |
|
if (keys) |
|
xfree(keys); |
buffer_put_int(&e->output, 1); |
buffer_put_int(&e->output, 1); |
buffer_put_char(&e->output, |
buffer_put_char(&e->output, |
success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); |
success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); |
|
|
static void |
static void |
process_remove_smartcard_key(SocketEntry *e) |
process_remove_smartcard_key(SocketEntry *e) |
{ |
{ |
char *sc_reader_id = NULL, *pin; |
char *provider = NULL, *pin = NULL; |
int i, version, success = 0; |
int version, success = 0; |
Key **keys, *k = NULL; |
Identity *id, *nxt; |
Identity *id; |
|
Idtab *tab; |
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); |
pin = buffer_get_string(&e->request, NULL); |
keys = sc_get_keys(sc_reader_id, pin); |
|
xfree(sc_reader_id); |
|
xfree(pin); |
xfree(pin); |
|
|
if (keys == NULL || keys[0] == NULL) { |
for (version = 1; version < 3; version++) { |
error("sc_get_keys failed"); |
tab = idtab_lookup(version); |
goto send; |
for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) { |
} |
nxt = TAILQ_NEXT(id, next); |
for (i = 0; keys[i] != NULL; i++) { |
if (!strcmp(provider, id->provider)) { |
k = keys[i]; |
TAILQ_REMOVE(&tab->idlist, id, next); |
version = k->type == KEY_RSA1 ? 1 : 2; |
free_identity(id); |
if ((id = lookup_identity(k, version)) != NULL) { |
tab->nentries--; |
tab = idtab_lookup(version); |
} |
TAILQ_REMOVE(&tab->idlist, id, next); |
|
tab->nentries--; |
|
free_identity(id); |
|
success = 1; |
|
} |
} |
key_free(k); |
|
keys[i] = NULL; |
|
} |
} |
xfree(keys); |
if (pkcs11_del_provider(provider) == 0) |
send: |
success = 1; |
|
else |
|
error("process_remove_smartcard_key:" |
|
" pkcs11_del_provider failed"); |
|
xfree(provider); |
buffer_put_int(&e->output, 1); |
buffer_put_int(&e->output, 1); |
buffer_put_char(&e->output, |
buffer_put_char(&e->output, |
success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); |
success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); |
} |
} |
#endif /* SMARTCARD */ |
#endif /* ENABLE_PKCS11 */ |
|
|
/* dispatch incoming messages */ |
/* dispatch incoming messages */ |
|
|
|
|
case SSH2_AGENTC_REMOVE_ALL_IDENTITIES: |
case SSH2_AGENTC_REMOVE_ALL_IDENTITIES: |
process_remove_all_identities(e, 2); |
process_remove_all_identities(e, 2); |
break; |
break; |
#ifdef SMARTCARD |
#ifdef ENABLE_PKCS11 |
case SSH_AGENTC_ADD_SMARTCARD_KEY: |
case SSH_AGENTC_ADD_SMARTCARD_KEY: |
case SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED: |
case SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED: |
process_add_smartcard_key(e); |
process_add_smartcard_key(e); |
|
|
case SSH_AGENTC_REMOVE_SMARTCARD_KEY: |
case SSH_AGENTC_REMOVE_SMARTCARD_KEY: |
process_remove_smartcard_key(e); |
process_remove_smartcard_key(e); |
break; |
break; |
#endif /* SMARTCARD */ |
#endif /* ENABLE_PKCS11 */ |
default: |
default: |
/* Unknown message. Respond with failure. */ |
/* Unknown message. Respond with failure. */ |
error("Unknown message %d", type); |
error("Unknown message %d", type); |
|
|
cleanup_handler(int sig) |
cleanup_handler(int sig) |
{ |
{ |
cleanup_socket(); |
cleanup_socket(); |
|
#ifdef ENABLE_PKCS11 |
|
pkcs11_terminate(); |
|
#endif |
_exit(2); |
_exit(2); |
} |
} |
|
|
|
|
} |
} |
|
|
skip: |
skip: |
|
|
|
#ifdef ENABLE_PKCS11 |
|
pkcs11_init(0); |
|
#endif |
new_socket(AUTH_SOCKET, sock); |
new_socket(AUTH_SOCKET, sock); |
if (ac > 0) |
if (ac > 0) |
parent_alive_interval = 10; |
parent_alive_interval = 10; |