diff --git a/ChangeLog b/ChangeLog index 374be9208..7eacb0ec3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,9 @@ - markus@cvs.openbsd.org 2001/07/04 22:47:19 [ssh-agent.c] ignore SIGPIPE when debugging, too + - markus@cvs.openbsd.org 2001/07/04 23:13:10 + [scard.c scard.h ssh-agent.c] + handle card removal more gracefully, add sc_close() to scard.h 20010711 - (djm) dirname(3) may modify its argument on glibc and other systems. @@ -5982,4 +5985,4 @@ - Wrote replacements for strlcpy and mkdtemp - Released 1.0pre1 -$Id: ChangeLog,v 1.1387 2001/07/14 02:12:55 djm Exp $ +$Id: ChangeLog,v 1.1388 2001/07/14 02:13:26 djm Exp $ diff --git a/scard.c b/scard.c index 4f038ddac..721e021fb 100644 --- a/scard.c +++ b/scard.c @@ -24,7 +24,7 @@ #ifdef SMARTCARD #include "includes.h" -RCSID("$OpenBSD: scard.c,v 1.4 2001/07/02 22:40:17 markus Exp $"); +RCSID("$OpenBSD: scard.c,v 1.5 2001/07/04 23:13:09 markus Exp $"); #include #include @@ -43,31 +43,31 @@ RCSID("$OpenBSD: scard.c,v 1.4 2001/07/02 22:40:17 markus Exp $"); #define MAX_BUF_SIZE 256 static int sc_fd = -1; -static int sc_reader_num = 0; +static int sc_reader_num = -1; static int cla = 0x00; /* class */ /* interface to libsectok */ static int -sc_open(int num) +sc_open(void) { u_char atr[256]; int sw; if (sc_fd >= 0) return sc_fd; - sc_reader_num = num; - sc_fd = sectok_open(sc_reader_num, 0, NULL); + sc_fd = sectok_open(sc_reader_num, 0, &sw); if (sc_fd < 0) { - error("sectok_open failed %d", sc_fd); - return sc_fd; + error("sectok_open failed: %s", sectok_get_sw(sw)); + return -1; } if (sectok_reset(sc_fd, 0, atr, &sw) <= 0) { error("sectok_reset failed: %s", sectok_get_sw(sw)); sc_fd = -1; return sc_fd; } + debug("sc_open ok %d", sc_fd); return sc_fd; } @@ -85,10 +85,12 @@ sc_enable_applet(void) if (sectok_selectfile(sc_fd, cla, root_fid, &sw) < 0) { error("sectok_selectfile root_fid failed: %s", sectok_get_sw(sw)); + sc_close(); return -1; } if (sectok_selectfile(sc_fd, cla, contID, &sw) < 0) { error("sectok_selectfile failed: %s", sectok_get_sw(sw)); + sc_close(); return -1; } /* send appled id */ @@ -98,6 +100,21 @@ sc_enable_applet(void) sectok_apdu(sc_fd, cla, 0xa4, 0x04, 0, aid_len, aid, 0, NULL, &sw); if (!sectok_swOK(sw)) { error("sectok_apdu failed: %s", sectok_get_sw(sw)); + sc_close(); + return -1; + } + return 0; +} + +static int +sc_init(void) +{ + if (sc_open() < 0) { + error("sc_open failed"); + return -1; + } + if (sc_enable_applet() < 0) { + error("sc_enable_applet failed"); return -1; } return 0; @@ -112,11 +129,16 @@ sc_read_pubkey(Key * k) len = sw = 0; + if (sc_fd < 0) + if (sc_init() < 0) + return -1; + /* get key size */ sectok_apdu(sc_fd, CLA_SSH, INS_GET_KEYLENGTH, 0, 0, 0, NULL, sizeof(buf), buf, &sw); if (!sectok_swOK(sw)) { error("could not obtain key length: %s", sectok_get_sw(sw)); + sc_close(); return -1; } len = (buf[0] << 8) | buf[1]; @@ -136,6 +158,7 @@ sc_read_pubkey(Key * k) if (BN_bin2bn(n, len, k->rsa->n) == NULL) { error("c_read_pubkey: BN_bin2bn failed"); xfree(n); + sc_close(); return -1; } xfree(n); @@ -164,6 +187,9 @@ sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa, int padding) debug("sc_private_decrypt called"); olen = len = sw = 0; + if (sc_fd < 0) + if (sc_init() < 0) + goto err; if (padding != RSA_PKCS1_PADDING) goto err; @@ -174,6 +200,7 @@ sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa, int padding) if (!sectok_swOK(sw)) { error("sc_private_decrypt: INS_DECRYPT failed: %s", sectok_get_sw(sw)); + sc_close(); goto err; } sectok_apdu(sc_fd, CLA_SSH, INS_GET_RESPONSE, 0, 0, 0, NULL, @@ -181,6 +208,7 @@ sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa, int padding) if (!sectok_swOK(sw)) { error("sc_private_decrypt: INS_GET_RESPONSE failed: %s", sectok_get_sw(sw)); + sc_close(); goto err; } olen = RSA_padding_check_PKCS1_type_2(to, len, padded + 1, len - 1, @@ -198,6 +226,9 @@ sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa, int padding) int sw, len; len = sw = 0; + if (sc_fd < 0) + if (sc_init() < 0) + goto err; if (padding != RSA_PKCS1_PADDING) goto err; @@ -213,6 +244,7 @@ sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa, int padding) if (!sectok_swOK(sw)) { error("sc_private_decrypt: INS_DECRYPT failed: %s", sectok_get_sw(sw)); + sc_close(); goto err; } sectok_apdu(sc_fd, CLA_SSH, INS_GET_RESPONSE, 0, 0, 0, NULL, @@ -220,6 +252,7 @@ sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa, int padding) if (!sectok_swOK(sw)) { error("sc_private_decrypt: INS_GET_RESPONSE failed: %s", sectok_get_sw(sw)); + sc_close(); goto err; } err: @@ -282,19 +315,21 @@ sc_get_engine(void) return smart_engine; } +void +sc_close(void) +{ + if (sc_fd >= 0) { + sectok_close(sc_fd); + sc_fd = -1; + } +} + Key * -sc_get_key(int sc_reader_num) +sc_get_key(int num) { Key *k; - if (sc_open(sc_reader_num) < 0) { - error("sc_open failed"); - return NULL; - } - if (sc_enable_applet() < 0) { - error("sc_enable_applet failed"); - return NULL; - } + sc_reader_num = num; k = key_new(KEY_RSA); if (k == NULL) { return NULL; @@ -305,5 +340,6 @@ sc_get_key(int sc_reader_num) return NULL; } return k; + sc_close(); } #endif diff --git a/scard.h b/scard.h index 480be0764..a4303c379 100644 --- a/scard.h +++ b/scard.h @@ -22,7 +22,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* $OpenBSD: scard.h,v 1.3 2001/06/26 17:27:24 markus Exp $ */ +/* $OpenBSD: scard.h,v 1.4 2001/07/04 23:13:10 markus Exp $ */ #include @@ -31,5 +31,6 @@ Key *sc_get_key(int); ENGINE *sc_get_engine(void); +void sc_close(void); #endif diff --git a/ssh-agent.c b/ssh-agent.c index 392d1a0cd..61e79c5fc 100644 --- a/ssh-agent.c +++ b/ssh-agent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-agent.c,v 1.61 2001/07/04 22:47:19 markus Exp $ */ +/* $OpenBSD: ssh-agent.c,v 1.62 2001/07/04 23:13:10 markus Exp $ */ /* * Author: Tatu Ylonen @@ -36,7 +36,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh-agent.c,v 1.61 2001/07/04 22:47:19 markus Exp $"); +RCSID("$OpenBSD: ssh-agent.c,v 1.62 2001/07/04 23:13:10 markus Exp $"); #include #include @@ -536,6 +536,7 @@ process_remove_smartcard_key(SocketEntry *e) success = 1; } key_free(k); + sc_close(); } buffer_put_int(&e->output, 1);