summaryrefslogtreecommitdiff
path: root/ssh-agent.c
diff options
context:
space:
mode:
Diffstat (limited to 'ssh-agent.c')
-rw-r--r--ssh-agent.c158
1 files changed, 88 insertions, 70 deletions
diff --git a/ssh-agent.c b/ssh-agent.c
index f77dea3a6..b5c565271 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-agent.c,v 1.161 2009/03/23 19:38:04 tobias Exp $ */ 1/* $OpenBSD: ssh-agent.c,v 1.165 2010/02/26 20:29:54 djm 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,8 @@ static void
171free_identity(Identity *id) 172free_identity(Identity *id)
172{ 173{
173 key_free(id->key); 174 key_free(id->key);
175 if (id->provider != NULL)
176 xfree(id->provider);
174 xfree(id->comment); 177 xfree(id->comment);
175 xfree(id); 178 xfree(id);
176} 179}
@@ -465,6 +468,8 @@ process_add_identity(SocketEntry *e, int version)
465 int type, success = 0, death = 0, confirm = 0; 468 int type, success = 0, death = 0, confirm = 0;
466 char *type_name, *comment; 469 char *type_name, *comment;
467 Key *k = NULL; 470 Key *k = NULL;
471 u_char *cert;
472 u_int len;
468 473
469 switch (version) { 474 switch (version) {
470 case 1: 475 case 1:
@@ -495,6 +500,14 @@ process_add_identity(SocketEntry *e, int version)
495 buffer_get_bignum2(&e->request, k->dsa->pub_key); 500 buffer_get_bignum2(&e->request, k->dsa->pub_key);
496 buffer_get_bignum2(&e->request, k->dsa->priv_key); 501 buffer_get_bignum2(&e->request, k->dsa->priv_key);
497 break; 502 break;
503 case KEY_DSA_CERT:
504 cert = buffer_get_string(&e->request, &len);
505 if ((k = key_from_blob(cert, len)) == NULL)
506 fatal("Certificate parse failed");
507 xfree(cert);
508 key_add_private(k);
509 buffer_get_bignum2(&e->request, k->dsa->priv_key);
510 break;
498 case KEY_RSA: 511 case KEY_RSA:
499 k = key_new_private(type); 512 k = key_new_private(type);
500 buffer_get_bignum2(&e->request, k->rsa->n); 513 buffer_get_bignum2(&e->request, k->rsa->n);
@@ -507,6 +520,17 @@ process_add_identity(SocketEntry *e, int version)
507 /* Generate additional parameters */ 520 /* Generate additional parameters */
508 rsa_generate_additional_parameters(k->rsa); 521 rsa_generate_additional_parameters(k->rsa);
509 break; 522 break;
523 case KEY_RSA_CERT:
524 cert = buffer_get_string(&e->request, &len);
525 if ((k = key_from_blob(cert, len)) == NULL)
526 fatal("Certificate parse failed");
527 xfree(cert);
528 key_add_private(k);
529 buffer_get_bignum2(&e->request, k->rsa->d);
530 buffer_get_bignum2(&e->request, k->rsa->iqmp);
531 buffer_get_bignum2(&e->request, k->rsa->p);
532 buffer_get_bignum2(&e->request, k->rsa->q);
533 break;
510 default: 534 default:
511 buffer_clear(&e->request); 535 buffer_clear(&e->request);
512 goto send; 536 goto send;
@@ -516,6 +540,7 @@ process_add_identity(SocketEntry *e, int version)
516 /* enable blinding */ 540 /* enable blinding */
517 switch (k->type) { 541 switch (k->type) {
518 case KEY_RSA: 542 case KEY_RSA:
543 case KEY_RSA_CERT:
519 case KEY_RSA1: 544 case KEY_RSA1:
520 if (RSA_blinding_on(k->rsa, NULL) != 1) { 545 if (RSA_blinding_on(k->rsa, NULL) != 1) {
521 error("process_add_identity: RSA_blinding_on failed"); 546 error("process_add_identity: RSA_blinding_on failed");
@@ -549,7 +574,7 @@ process_add_identity(SocketEntry *e, int version)
549 if (lifetime && !death) 574 if (lifetime && !death)
550 death = time(NULL) + lifetime; 575 death = time(NULL) + lifetime;
551 if ((id = lookup_identity(k, version)) == NULL) { 576 if ((id = lookup_identity(k, version)) == NULL) {
552 id = xmalloc(sizeof(Identity)); 577 id = xcalloc(1, sizeof(Identity));
553 id->key = k; 578 id->key = k;
554 TAILQ_INSERT_TAIL(&tab->idlist, id, next); 579 TAILQ_INSERT_TAIL(&tab->idlist, id, next);
555 /* Increment the number of identities. */ 580 /* Increment the number of identities. */
@@ -609,17 +634,17 @@ no_identities(SocketEntry *e, u_int type)
609 buffer_free(&msg); 634 buffer_free(&msg);
610} 635}
611 636
612#ifdef SMARTCARD 637#ifdef ENABLE_PKCS11
613static void 638static void
614process_add_smartcard_key(SocketEntry *e) 639process_add_smartcard_key(SocketEntry *e)
615{ 640{
616 char *sc_reader_id = NULL, *pin; 641 char *provider = NULL, *pin;
617 int i, type, version, success = 0, death = 0, confirm = 0; 642 int i, type, version, count = 0, success = 0, death = 0, confirm = 0;
618 Key **keys, *k; 643 Key **keys = NULL, *k;
619 Identity *id; 644 Identity *id;
620 Idtab *tab; 645 Idtab *tab;
621 646
622 sc_reader_id = buffer_get_string(&e->request, NULL); 647 provider = buffer_get_string(&e->request, NULL);
623 pin = buffer_get_string(&e->request, NULL); 648 pin = buffer_get_string(&e->request, NULL);
624 649
625 while (buffer_len(&e->request)) { 650 while (buffer_len(&e->request)) {
@@ -633,30 +658,22 @@ process_add_smartcard_key(SocketEntry *e)
633 default: 658 default:
634 error("process_add_smartcard_key: " 659 error("process_add_smartcard_key: "
635 "Unknown constraint type %d", type); 660 "Unknown constraint type %d", type);
636 xfree(sc_reader_id);
637 xfree(pin);
638 goto send; 661 goto send;
639 } 662 }
640 } 663 }
641 if (lifetime && !death) 664 if (lifetime && !death)
642 death = time(NULL) + lifetime; 665 death = time(NULL) + lifetime;
643 666
644 keys = sc_get_keys(sc_reader_id, pin); 667 count = pkcs11_add_provider(provider, pin, &keys);
645 xfree(sc_reader_id); 668 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]; 669 k = keys[i];
654 version = k->type == KEY_RSA1 ? 1 : 2; 670 version = k->type == KEY_RSA1 ? 1 : 2;
655 tab = idtab_lookup(version); 671 tab = idtab_lookup(version);
656 if (lookup_identity(k, version) == NULL) { 672 if (lookup_identity(k, version) == NULL) {
657 id = xmalloc(sizeof(Identity)); 673 id = xcalloc(1, sizeof(Identity));
658 id->key = k; 674 id->key = k;
659 id->comment = sc_get_key_label(k); 675 id->provider = xstrdup(provider);
676 id->comment = xstrdup(provider); /* XXX */
660 id->death = death; 677 id->death = death;
661 id->confirm = confirm; 678 id->confirm = confirm;
662 TAILQ_INSERT_TAIL(&tab->idlist, id, next); 679 TAILQ_INSERT_TAIL(&tab->idlist, id, next);
@@ -667,8 +684,13 @@ process_add_smartcard_key(SocketEntry *e)
667 } 684 }
668 keys[i] = NULL; 685 keys[i] = NULL;
669 } 686 }
670 xfree(keys);
671send: 687send:
688 if (pin)
689 xfree(pin);
690 if (provider)
691 xfree(provider);
692 if (keys)
693 xfree(keys);
672 buffer_put_int(&e->output, 1); 694 buffer_put_int(&e->output, 1);
673 buffer_put_char(&e->output, 695 buffer_put_char(&e->output,
674 success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); 696 success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
@@ -677,42 +699,37 @@ send:
677static void 699static void
678process_remove_smartcard_key(SocketEntry *e) 700process_remove_smartcard_key(SocketEntry *e)
679{ 701{
680 char *sc_reader_id = NULL, *pin; 702 char *provider = NULL, *pin = NULL;
681 int i, version, success = 0; 703 int version, success = 0;
682 Key **keys, *k = NULL; 704 Identity *id, *nxt;
683 Identity *id;
684 Idtab *tab; 705 Idtab *tab;
685 706
686 sc_reader_id = buffer_get_string(&e->request, NULL); 707 provider = buffer_get_string(&e->request, NULL);
687 pin = buffer_get_string(&e->request, NULL); 708 pin = buffer_get_string(&e->request, NULL);
688 keys = sc_get_keys(sc_reader_id, pin);
689 xfree(sc_reader_id);
690 xfree(pin); 709 xfree(pin);
691 710
692 if (keys == NULL || keys[0] == NULL) { 711 for (version = 1; version < 3; version++) {
693 error("sc_get_keys failed"); 712 tab = idtab_lookup(version);
694 goto send; 713 for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) {
695 } 714 nxt = TAILQ_NEXT(id, next);
696 for (i = 0; keys[i] != NULL; i++) { 715 if (!strcmp(provider, id->provider)) {
697 k = keys[i]; 716 TAILQ_REMOVE(&tab->idlist, id, next);
698 version = k->type == KEY_RSA1 ? 1 : 2; 717 free_identity(id);
699 if ((id = lookup_identity(k, version)) != NULL) { 718 tab->nentries--;
700 tab = idtab_lookup(version); 719 }
701 TAILQ_REMOVE(&tab->idlist, id, next);
702 tab->nentries--;
703 free_identity(id);
704 success = 1;
705 } 720 }
706 key_free(k);
707 keys[i] = NULL;
708 } 721 }
709 xfree(keys); 722 if (pkcs11_del_provider(provider) == 0)
710send: 723 success = 1;
724 else
725 error("process_remove_smartcard_key:"
726 " pkcs11_del_provider failed");
727 xfree(provider);
711 buffer_put_int(&e->output, 1); 728 buffer_put_int(&e->output, 1);
712 buffer_put_char(&e->output, 729 buffer_put_char(&e->output,
713 success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); 730 success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
714} 731}
715#endif /* SMARTCARD */ 732#endif /* ENABLE_PKCS11 */
716 733
717/* dispatch incoming messages */ 734/* dispatch incoming messages */
718 735
@@ -797,7 +814,7 @@ process_message(SocketEntry *e)
797 case SSH2_AGENTC_REMOVE_ALL_IDENTITIES: 814 case SSH2_AGENTC_REMOVE_ALL_IDENTITIES:
798 process_remove_all_identities(e, 2); 815 process_remove_all_identities(e, 2);
799 break; 816 break;
800#ifdef SMARTCARD 817#ifdef ENABLE_PKCS11
801 case SSH_AGENTC_ADD_SMARTCARD_KEY: 818 case SSH_AGENTC_ADD_SMARTCARD_KEY:
802 case SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED: 819 case SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED:
803 process_add_smartcard_key(e); 820 process_add_smartcard_key(e);
@@ -805,7 +822,7 @@ process_message(SocketEntry *e)
805 case SSH_AGENTC_REMOVE_SMARTCARD_KEY: 822 case SSH_AGENTC_REMOVE_SMARTCARD_KEY:
806 process_remove_smartcard_key(e); 823 process_remove_smartcard_key(e);
807 break; 824 break;
808#endif /* SMARTCARD */ 825#endif /* ENABLE_PKCS11 */
809 default: 826 default:
810 /* Unknown message. Respond with failure. */ 827 /* Unknown message. Respond with failure. */
811 error("Unknown message %d", type); 828 error("Unknown message %d", type);
@@ -919,11 +936,11 @@ after_select(fd_set *readset, fd_set *writeset)
919 socklen_t slen; 936 socklen_t slen;
920 char buf[1024]; 937 char buf[1024];
921 int len, sock; 938 int len, sock;
922 u_int i; 939 u_int i, orig_alloc;
923 uid_t euid; 940 uid_t euid;
924 gid_t egid; 941 gid_t egid;
925 942
926 for (i = 0; i < sockets_alloc; i++) 943 for (i = 0, orig_alloc = sockets_alloc; i < orig_alloc; i++)
927 switch (sockets[i].type) { 944 switch (sockets[i].type) {
928 case AUTH_UNUSED: 945 case AUTH_UNUSED:
929 break; 946 break;
@@ -956,16 +973,13 @@ after_select(fd_set *readset, fd_set *writeset)
956 case AUTH_CONNECTION: 973 case AUTH_CONNECTION:
957 if (buffer_len(&sockets[i].output) > 0 && 974 if (buffer_len(&sockets[i].output) > 0 &&
958 FD_ISSET(sockets[i].fd, writeset)) { 975 FD_ISSET(sockets[i].fd, writeset)) {
959 do { 976 len = write(sockets[i].fd,
960 len = write(sockets[i].fd, 977 buffer_ptr(&sockets[i].output),
961 buffer_ptr(&sockets[i].output), 978 buffer_len(&sockets[i].output));
962 buffer_len(&sockets[i].output)); 979 if (len == -1 && (errno == EAGAIN ||
963 if (len == -1 && (errno == EAGAIN || 980 errno == EWOULDBLOCK ||
964 errno == EINTR || 981 errno == EINTR))
965 errno == EWOULDBLOCK)) 982 continue;
966 continue;
967 break;
968 } while (1);
969 if (len <= 0) { 983 if (len <= 0) {
970 close_socket(&sockets[i]); 984 close_socket(&sockets[i]);
971 break; 985 break;
@@ -973,14 +987,11 @@ after_select(fd_set *readset, fd_set *writeset)
973 buffer_consume(&sockets[i].output, len); 987 buffer_consume(&sockets[i].output, len);
974 } 988 }
975 if (FD_ISSET(sockets[i].fd, readset)) { 989 if (FD_ISSET(sockets[i].fd, readset)) {
976 do { 990 len = read(sockets[i].fd, buf, sizeof(buf));
977 len = read(sockets[i].fd, buf, sizeof(buf)); 991 if (len == -1 && (errno == EAGAIN ||
978 if (len == -1 && (errno == EAGAIN || 992 errno == EWOULDBLOCK ||
979 errno == EINTR || 993 errno == EINTR))
980 errno == EWOULDBLOCK)) 994 continue;
981 continue;
982 break;
983 } while (1);
984 if (len <= 0) { 995 if (len <= 0) {
985 close_socket(&sockets[i]); 996 close_socket(&sockets[i]);
986 break; 997 break;
@@ -1015,6 +1026,9 @@ static void
1015cleanup_handler(int sig) 1026cleanup_handler(int sig)
1016{ 1027{
1017 cleanup_socket(); 1028 cleanup_socket();
1029#ifdef ENABLE_PKCS11
1030 pkcs11_terminate();
1031#endif
1018 _exit(2); 1032 _exit(2);
1019} 1033}
1020 1034
@@ -1261,6 +1275,10 @@ main(int ac, char **av)
1261#endif 1275#endif
1262 1276
1263skip: 1277skip:
1278
1279#ifdef ENABLE_PKCS11
1280 pkcs11_init(0);
1281#endif
1264 new_socket(AUTH_SOCKET, sock); 1282 new_socket(AUTH_SOCKET, sock);
1265 if (ac > 0) 1283 if (ac > 0)
1266 parent_alive_interval = 10; 1284 parent_alive_interval = 10;