summaryrefslogtreecommitdiff
path: root/ssh-agent.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2010-02-12 09:21:02 +1100
committerDamien Miller <djm@mindrot.org>2010-02-12 09:21:02 +1100
commit7ea845e48df6d34a333ebbe79380cba0938d02a5 (patch)
tree44ab0d3fdfe0560b7ca92f5747e9dd5d012aea18 /ssh-agent.c
parent17751bcab25681d341442fdc2386a30a6bea345e (diff)
- markus@cvs.openbsd.org 2010/02/08 10:50:20
[pathnames.h readconf.c readconf.h scp.1 sftp.1 ssh-add.1 ssh-add.c] [ssh-agent.c ssh-keygen.1 ssh-keygen.c ssh.1 ssh.c ssh_config.5] 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 'ssh-agent.c')
-rw-r--r--ssh-agent.c101
1 files changed, 51 insertions, 50 deletions
diff --git a/ssh-agent.c b/ssh-agent.c
index df3a87d9a..f745c2513 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-agent.c,v 1.162 2009/09/01 14:43:17 djm Exp $ */ 1/* $OpenBSD: ssh-agent.c,v 1.163 2010/02/08 10:50:20 markus 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
@@ -76,8 +76,8 @@
76#include "log.h" 76#include "log.h"
77#include "misc.h" 77#include "misc.h"
78 78
79#ifdef SMARTCARD 79#ifdef ENABLE_PKCS11
80#include "scard.h" 80#include "ssh-pkcs11.h"
81#endif 81#endif
82 82
83#if defined(HAVE_SYS_PRCTL_H) 83#if defined(HAVE_SYS_PRCTL_H)
@@ -105,6 +105,7 @@ typedef struct identity {
105 TAILQ_ENTRY(identity) next; 105 TAILQ_ENTRY(identity) next;
106 Key *key; 106 Key *key;
107 char *comment; 107 char *comment;
108 char *provider;
108 u_int death; 109 u_int death;
109 u_int confirm; 110 u_int confirm;
110} Identity; 111} Identity;
@@ -171,6 +172,7 @@ static void
171free_identity(Identity *id) 172free_identity(Identity *id)
172{ 173{
173 key_free(id->key); 174 key_free(id->key);
175 xfree(id->provider);
174 xfree(id->comment); 176 xfree(id->comment);
175 xfree(id); 177 xfree(id);
176} 178}
@@ -549,7 +551,7 @@ process_add_identity(SocketEntry *e, int version)
549 if (lifetime && !death) 551 if (lifetime && !death)
550 death = time(NULL) + lifetime; 552 death = time(NULL) + lifetime;
551 if ((id = lookup_identity(k, version)) == NULL) { 553 if ((id = lookup_identity(k, version)) == NULL) {
552 id = xmalloc(sizeof(Identity)); 554 id = xcalloc(1, sizeof(Identity));
553 id->key = k; 555 id->key = k;
554 TAILQ_INSERT_TAIL(&tab->idlist, id, next); 556 TAILQ_INSERT_TAIL(&tab->idlist, id, next);
555 /* Increment the number of identities. */ 557 /* Increment the number of identities. */
@@ -609,17 +611,17 @@ no_identities(SocketEntry *e, u_int type)
609 buffer_free(&msg); 611 buffer_free(&msg);
610} 612}
611 613
612#ifdef SMARTCARD 614#ifdef ENABLE_PKCS11
613static void 615static void
614process_add_smartcard_key(SocketEntry *e) 616process_add_smartcard_key(SocketEntry *e)
615{ 617{
616 char *sc_reader_id = NULL, *pin; 618 char *provider = NULL, *pin;
617 int i, type, version, success = 0, death = 0, confirm = 0; 619 int i, type, version, count = 0, success = 0, death = 0, confirm = 0;
618 Key **keys, *k; 620 Key **keys = NULL, *k;
619 Identity *id; 621 Identity *id;
620 Idtab *tab; 622 Idtab *tab;
621 623
622 sc_reader_id = buffer_get_string(&e->request, NULL); 624 provider = buffer_get_string(&e->request, NULL);
623 pin = buffer_get_string(&e->request, NULL); 625 pin = buffer_get_string(&e->request, NULL);
624 626
625 while (buffer_len(&e->request)) { 627 while (buffer_len(&e->request)) {
@@ -633,30 +635,22 @@ process_add_smartcard_key(SocketEntry *e)
633 default: 635 default:
634 error("process_add_smartcard_key: " 636 error("process_add_smartcard_key: "
635 "Unknown constraint type %d", type); 637 "Unknown constraint type %d", type);
636 xfree(sc_reader_id);
637 xfree(pin);
638 goto send; 638 goto send;
639 } 639 }
640 } 640 }
641 if (lifetime && !death) 641 if (lifetime && !death)
642 death = time(NULL) + lifetime; 642 death = time(NULL) + lifetime;
643 643
644 keys = sc_get_keys(sc_reader_id, pin); 644 count = pkcs11_add_provider(provider, pin, &keys);
645 xfree(sc_reader_id); 645 for (i = 0; i < count; i++) {
646 xfree(pin);
647
648 if (keys == NULL || keys[0] == NULL) {
649 error("sc_get_keys failed");
650 goto send;
651 }
652 for (i = 0; keys[i] != NULL; i++) {
653 k = keys[i]; 646 k = keys[i];
654 version = k->type == KEY_RSA1 ? 1 : 2; 647 version = k->type == KEY_RSA1 ? 1 : 2;
655 tab = idtab_lookup(version); 648 tab = idtab_lookup(version);
656 if (lookup_identity(k, version) == NULL) { 649 if (lookup_identity(k, version) == NULL) {
657 id = xmalloc(sizeof(Identity)); 650 id = xcalloc(1, sizeof(Identity));
658 id->key = k; 651 id->key = k;
659 id->comment = sc_get_key_label(k); 652 id->provider = xstrdup(provider);
653 id->comment = xstrdup(provider); /* XXX */
660 id->death = death; 654 id->death = death;
661 id->confirm = confirm; 655 id->confirm = confirm;
662 TAILQ_INSERT_TAIL(&tab->idlist, id, next); 656 TAILQ_INSERT_TAIL(&tab->idlist, id, next);
@@ -667,8 +661,13 @@ process_add_smartcard_key(SocketEntry *e)
667 } 661 }
668 keys[i] = NULL; 662 keys[i] = NULL;
669 } 663 }
670 xfree(keys);
671send: 664send:
665 if (pin)
666 xfree(pin);
667 if (provider)
668 xfree(provider);
669 if (keys)
670 xfree(keys);
672 buffer_put_int(&e->output, 1); 671 buffer_put_int(&e->output, 1);
673 buffer_put_char(&e->output, 672 buffer_put_char(&e->output,
674 success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); 673 success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
@@ -677,42 +676,37 @@ send:
677static void 676static void
678process_remove_smartcard_key(SocketEntry *e) 677process_remove_smartcard_key(SocketEntry *e)
679{ 678{
680 char *sc_reader_id = NULL, *pin; 679 char *provider = NULL, *pin = NULL;
681 int i, version, success = 0; 680 int version, success = 0;
682 Key **keys, *k = NULL; 681 Identity *id, *nxt;
683 Identity *id;
684 Idtab *tab; 682 Idtab *tab;
685 683
686 sc_reader_id = buffer_get_string(&e->request, NULL); 684 provider = buffer_get_string(&e->request, NULL);
687 pin = buffer_get_string(&e->request, NULL); 685 pin = buffer_get_string(&e->request, NULL);
688 keys = sc_get_keys(sc_reader_id, pin);
689 xfree(sc_reader_id);
690 xfree(pin); 686 xfree(pin);
691 687
692 if (keys == NULL || keys[0] == NULL) { 688 for (version = 1; version < 3; version++) {
693 error("sc_get_keys failed"); 689 tab = idtab_lookup(version);
694 goto send; 690 for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) {
695 } 691 nxt = TAILQ_NEXT(id, next);
696 for (i = 0; keys[i] != NULL; i++) { 692 if (!strcmp(provider, id->provider)) {
697 k = keys[i]; 693 TAILQ_REMOVE(&tab->idlist, id, next);
698 version = k->type == KEY_RSA1 ? 1 : 2; 694 free_identity(id);
699 if ((id = lookup_identity(k, version)) != NULL) { 695 tab->nentries--;
700 tab = idtab_lookup(version); 696 }
701 TAILQ_REMOVE(&tab->idlist, id, next);
702 tab->nentries--;
703 free_identity(id);
704 success = 1;
705 } 697 }
706 key_free(k);
707 keys[i] = NULL;
708 } 698 }
709 xfree(keys); 699 if (pkcs11_del_provider(provider) == 0)
710send: 700 success = 1;
701 else
702 error("process_remove_smartcard_key:"
703 " pkcs11_del_provider failed");
704 xfree(provider);
711 buffer_put_int(&e->output, 1); 705 buffer_put_int(&e->output, 1);
712 buffer_put_char(&e->output, 706 buffer_put_char(&e->output,
713 success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); 707 success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
714} 708}
715#endif /* SMARTCARD */ 709#endif /* ENABLE_PKCS11 */
716 710
717/* dispatch incoming messages */ 711/* dispatch incoming messages */
718 712
@@ -797,7 +791,7 @@ process_message(SocketEntry *e)
797 case SSH2_AGENTC_REMOVE_ALL_IDENTITIES: 791 case SSH2_AGENTC_REMOVE_ALL_IDENTITIES:
798 process_remove_all_identities(e, 2); 792 process_remove_all_identities(e, 2);
799 break; 793 break;
800#ifdef SMARTCARD 794#ifdef ENABLE_PKCS11
801 case SSH_AGENTC_ADD_SMARTCARD_KEY: 795 case SSH_AGENTC_ADD_SMARTCARD_KEY:
802 case SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED: 796 case SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED:
803 process_add_smartcard_key(e); 797 process_add_smartcard_key(e);
@@ -805,7 +799,7 @@ process_message(SocketEntry *e)
805 case SSH_AGENTC_REMOVE_SMARTCARD_KEY: 799 case SSH_AGENTC_REMOVE_SMARTCARD_KEY:
806 process_remove_smartcard_key(e); 800 process_remove_smartcard_key(e);
807 break; 801 break;
808#endif /* SMARTCARD */ 802#endif /* ENABLE_PKCS11 */
809 default: 803 default:
810 /* Unknown message. Respond with failure. */ 804 /* Unknown message. Respond with failure. */
811 error("Unknown message %d", type); 805 error("Unknown message %d", type);
@@ -1009,6 +1003,9 @@ static void
1009cleanup_handler(int sig) 1003cleanup_handler(int sig)
1010{ 1004{
1011 cleanup_socket(); 1005 cleanup_socket();
1006#ifdef ENABLE_PKCS11
1007 pkcs11_terminate();
1008#endif
1012 _exit(2); 1009 _exit(2);
1013} 1010}
1014 1011
@@ -1255,6 +1252,10 @@ main(int ac, char **av)
1255#endif 1252#endif
1256 1253
1257skip: 1254skip:
1255
1256#ifdef ENABLE_PKCS11
1257 pkcs11_init(0);
1258#endif
1258 new_socket(AUTH_SOCKET, sock); 1259 new_socket(AUTH_SOCKET, sock);
1259 if (ac > 0) 1260 if (ac > 0)
1260 parent_alive_interval = 10; 1261 parent_alive_interval = 10;