From 291178d1394232edd75bf8d6f1b7127d88f394ad Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sun, 14 Jul 2013 23:03:43 +0200 Subject: [PATCH] implemented reversed connection establishment vpcd can now be configured connect to a previously started vpicc. --- pcsc-relay/src/vpcd-driver.c | 2 +- virtualsmartcard/Makefile.am | 2 +- virtualsmartcard/doc/Makefile.am | 2 +- virtualsmartcard/doc/README.txt | 33 +++-- virtualsmartcard/doc/README.txt.in | 33 +++-- virtualsmartcard/doc/vpcd_example.conf | 4 + virtualsmartcard/src/vpcd/ifd-vpcd.c | 41 +++++- virtualsmartcard/src/vpcd/vpcd.c | 139 +++++++++++++----- virtualsmartcard/src/vpcd/vpcd.h | 17 ++- virtualsmartcard/src/vpicc/vicc.in | 14 +- .../virtualsmartcard/VirtualSmartcard.py | 49 ++++-- .../test_vicc_with_handler_test.sh | 58 ++++++++ 12 files changed, 312 insertions(+), 82 deletions(-) create mode 100644 virtualsmartcard/doc/vpcd_example.conf create mode 100755 virtualsmartcard/test_vicc_with_handler_test.sh diff --git a/pcsc-relay/src/vpcd-driver.c b/pcsc-relay/src/vpcd-driver.c index 795f5e9..b0cea8f 100644 --- a/pcsc-relay/src/vpcd-driver.c +++ b/pcsc-relay/src/vpcd-driver.c @@ -41,7 +41,7 @@ static int vpcd_connect(driver_data_t **driver_data) return 0; - ctx = vicc_init(vpcdport); + ctx = vicc_init(NULL, vpcdport); if (!ctx) { RELAY_ERROR("Could not initialize connection to virtual ICC\n"); return 0; diff --git a/virtualsmartcard/Makefile.am b/virtualsmartcard/Makefile.am index ca0fab4..40f9816 100644 --- a/virtualsmartcard/Makefile.am +++ b/virtualsmartcard/Makefile.am @@ -1,7 +1,7 @@ ACLOCAL_AMFLAGS = -I m4 SUBDIRS = src doc npa-example-data -EXTRA_DIST = test_vicc_with_npa-tool.sh +EXTRA_DIST = test_vicc_with_npa-tool.sh test_vicc_with_handler_test.sh distcheck-hook: test -d .svn && \ diff --git a/virtualsmartcard/doc/Makefile.am b/virtualsmartcard/doc/Makefile.am index d138143..2c5a337 100644 --- a/virtualsmartcard/doc/Makefile.am +++ b/virtualsmartcard/doc/Makefile.am @@ -18,7 +18,7 @@ do_subst = $(SED) \ -e 's,[@]abs_top_srcdir[@],$(abs_top_srcdir),g' \ -e 's,[@]top_srcdir[@],$(top_srcdir),g' -EXTRA_DIST = README.txt.in README.txt autotools.txt.in questions.txt.in autotools.txt questions.txt download.txt.in download.txt relay-note.txt +EXTRA_DIST = README.txt.in README.txt autotools.txt.in questions.txt.in autotools.txt questions.txt download.txt.in download.txt relay-note.txt vpcd_example.conf dist_noinst_SCRIPTS = generate_modules.py diff --git a/virtualsmartcard/doc/README.txt b/virtualsmartcard/doc/README.txt index 466e523..cb6b8d0 100644 --- a/virtualsmartcard/doc/README.txt +++ b/virtualsmartcard/doc/README.txt @@ -74,19 +74,34 @@ The |vpcd| depends on PCSC-Lite_. Running the Virtual Smart Card ******************************************************************************** -Fitxt you need to make sure that :command:`pcscd` loads the |vpcd|. You might -need to run :command:`update-reader.conf` to update its configuration file. -Then :command:`pcscd -f -d` should say something like "Attempting startup of -Virtual PCD" +The configuration file from |vpcd| is usually placed into +:file:`/etc/reader.conf.d/`. The PC/SC daemon should read it and load the +|vpcd| on startup. In debug mode :command:`pcscd -f -d` should say something +like "Attempting startup of Virtual PCD". For older versions of PCSC-Lite you +need to run :command:`update-reader.conf` to update :command:`pcscd`'s main +configuration file. -Now you can run :command:`vicc` which connects to the |vpcd|. The command -:command:`vicc --help` gives an overview about the command line options. +By default, |vpcd| opens a socket for |vpicc| and waits for incoming +connections. The port to open should be specified in ``CHANNELID`` and +``DEVICENAME``: + +.. literalinclude:: vpcd_example.conf + :emphasize-lines: 2,4 + +If the first part of the ``DEVICENAME`` is different from ``/dev/null``, |vpcd| +will use this string as a hostname to connect to a waiting |vpicc|. |vpicc| +needs to be started with the ``--reversed`` flag in this case. + +The command :command:`vicc --help` gives an overview about the command line +options of |vpicc|. .. program-output:: vicc --help -You should now be able to access the |vpicc| through the PC/SC API via -|vpcd|/:command:`pcscd`. You can use the :command:`opensc-explorer` or -:command:`pcsc_scan` for testing. +When |vpcd| and |vpicc| are connected you should be able to access the card +through the PC/SC API via :command:`pcscd`. You can use the +:command:`opensc-explorer` or :command:`pcsc_scan` for testing. In +Virtual Smart Card's root directory we also provide scripts for testing with +:ref:`libnpa` and PCSC-Lite's smart card reader driver tester. ================================================================================ diff --git a/virtualsmartcard/doc/README.txt.in b/virtualsmartcard/doc/README.txt.in index 4e6fb1e..f67eaba 100644 --- a/virtualsmartcard/doc/README.txt.in +++ b/virtualsmartcard/doc/README.txt.in @@ -74,19 +74,34 @@ The |vpcd| depends on PCSC-Lite_. Running the @PACKAGE_NAME@ ******************************************************************************** -Fitxt you need to make sure that :command:`pcscd` loads the |vpcd|. You might -need to run :command:`update-reader.conf` to update its configuration file. -Then :command:`pcscd -f -d` should say something like "Attempting startup of -Virtual PCD" +The configuration file from |vpcd| is usually placed into +:file:`/etc/reader.conf.d/`. The PC/SC daemon should read it and load the +|vpcd| on startup. In debug mode :command:`pcscd -f -d` should say something +like "Attempting startup of Virtual PCD". For older versions of PCSC-Lite you +need to run :command:`update-reader.conf` to update :command:`pcscd`'s main +configuration file. -Now you can run :command:`vicc` which connects to the |vpcd|. The command -:command:`vicc --help` gives an overview about the command line options. +By default, |vpcd| opens a socket for |vpicc| and waits for incoming +connections. The port to open should be specified in ``CHANNELID`` and +``DEVICENAME``: + +.. literalinclude:: vpcd_example.conf + :emphasize-lines: 2,4 + +If the first part of the ``DEVICENAME`` is different from ``/dev/null``, |vpcd| +will use this string as a hostname to connect to a waiting |vpicc|. |vpicc| +needs to be started with the ``--reversed`` flag in this case. + +The command :command:`vicc --help` gives an overview about the command line +options of |vpicc|. .. program-output:: vicc --help -You should now be able to access the |vpicc| through the PC/SC API via -|vpcd|/:command:`pcscd`. You can use the :command:`opensc-explorer` or -:command:`pcsc_scan` for testing. +When |vpcd| and |vpicc| are connected you should be able to access the card +through the PC/SC API via :command:`pcscd`. You can use the +:command:`opensc-explorer` or :command:`pcsc_scan` for testing. In +@PACKAGE_NAME@'s root directory we also provide scripts for testing with +:ref:`libnpa` and PCSC-Lite's smart card reader driver tester. ================================================================================ diff --git a/virtualsmartcard/doc/vpcd_example.conf b/virtualsmartcard/doc/vpcd_example.conf new file mode 100644 index 0000000..1a3dcce --- /dev/null +++ b/virtualsmartcard/doc/vpcd_example.conf @@ -0,0 +1,4 @@ +FRIENDLYNAME "Virtual PCD" +DEVICENAME /dev/null:0x8C7B +LIBPATH /usr/lib/pcsc/drivers/serial/libvpcd.so +CHANNELID 0x8C7B diff --git a/virtualsmartcard/src/vpcd/ifd-vpcd.c b/virtualsmartcard/src/vpcd/ifd-vpcd.c index aee0f71..ca48a07 100644 --- a/virtualsmartcard/src/vpcd/ifd-vpcd.c +++ b/virtualsmartcard/src/vpcd/ifd-vpcd.c @@ -14,6 +14,8 @@ 1) static struct vicc_ctx *ctx[VICC_MAX_SLOTS]; +static char *hostname = NULL; +static const char openport[] = "/dev/null"; RESPONSECODE IFDHCreateChannel (DWORD Lun, DWORD Channel) @@ -22,12 +24,17 @@ IFDHCreateChannel (DWORD Lun, DWORD Channel) if (slot >= VICC_MAX_SLOTS) { return IFD_COMMUNICATION_ERROR; } - ctx[slot] = vicc_init(Channel+slot); + if (!hostname) + Log2(PCSC_LOG_INFO, "Waiting for virtual ICC on port %hu", + (unsigned short) (Channel+slot)); + ctx[slot] = vicc_init(hostname, Channel+slot); if (!ctx[slot]) { Log1(PCSC_LOG_ERROR, "Could not initialize connection to virtual ICC"); return IFD_COMMUNICATION_ERROR; } - Log2(PCSC_LOG_INFO, "Waiting for virtual ICC on port %hu", (unsigned short) Channel+slot); + if (hostname) + Log3(PCSC_LOG_INFO, "Connected to virtual ICC on %s port %hu", + hostname, (unsigned short) (Channel+slot)); return IFD_SUCCESS; } @@ -35,27 +42,51 @@ IFDHCreateChannel (DWORD Lun, DWORD Channel) RESPONSECODE IFDHCreateChannelByName (DWORD Lun, LPSTR DeviceName) { + RESPONSECODE r = IFD_NOT_SUPPORTED; char *dots; + char _hostname[MAX_READERNAME]; + size_t hostname_len; unsigned long int port = VPCDPORT; dots = strchr(DeviceName, ':'); if (dots) { /* a port has been specified behind the device name */ - /* skip '+' */ + hostname_len = dots - DeviceName; + if (strlen(openport) != hostname_len + || strncmp(DeviceName, openport, hostname_len) != 0) { + /* a hostname other than /dev/null has been specified, + * so we connect initialize hostname to connect to vicc */ + if (hostname_len < sizeof _hostname) + memcpy(_hostname, DeviceName, hostname_len); + else { + Log3(PCSC_LOG_ERROR, "Not enough memory to hold hostname (have %u, need %u)", sizeof _hostname, hostname_len); + goto err; + } + _hostname[hostname_len] = '\0'; + hostname = _hostname; + } + + /* skip the ':' */ dots++; errno = 0; port = strtoul(dots, NULL, 0); if (errno) { Log2(PCSC_LOG_ERROR, "Could not parse port: %s", dots); - return IFD_NO_SUCH_DEVICE; + goto err; } } else { Log1(PCSC_LOG_INFO, "Using default port."); } - return IFDHCreateChannel (Lun, port); + r = IFDHCreateChannel (Lun, port); + +err: + /* set hostname back to default in case it has been changed */ + hostname = NULL; + + return r; } RESPONSECODE diff --git a/virtualsmartcard/src/vpcd/vpcd.c b/virtualsmartcard/src/vpcd/vpcd.c index 95eebe2..e12c605 100644 --- a/virtualsmartcard/src/vpcd/vpcd.c +++ b/virtualsmartcard/src/vpcd/vpcd.c @@ -22,9 +22,13 @@ #include #include #define close(s) closesocket(s) +#ifndef AI_NUMERICSERV +#define AI_NUMERICSERV 0 +#endif typedef WORD uint16_t; #else #include +#include #include #include #include @@ -32,6 +36,7 @@ typedef WORD uint16_t; #endif #include +#include #include #include #include @@ -43,29 +48,27 @@ typedef WORD uint16_t; #define VPCD_CTRL_RESET 2 #define VPCD_CTRL_ATR 4 -ssize_t sendToVICC(struct vicc_ctx *ctx, size_t size, const unsigned char *buffer); -ssize_t recvFromVICC(struct vicc_ctx *ctx, unsigned char **buffer); +static ssize_t sendToVICC(struct vicc_ctx *ctx, size_t size, const unsigned char *buffer); +static ssize_t recvFromVICC(struct vicc_ctx *ctx, unsigned char **buffer); static ssize_t sendall(int sock, const void *buffer, size_t size); static ssize_t recvall(int sock, void *buffer, size_t size); static int opensock(unsigned short port); +static int connectsock(const char *hostname, unsigned short port); ssize_t sendall(int sock, const void *buffer, size_t size) { - size_t sent = 0; + size_t sent; ssize_t r; - const unsigned char *p = buffer; - while (sent < size) { - r = send(sock, (void *) p, size-sent, 0); - if (r < 0) - return r; + for (sent = 0; sent < size; sent += r) { + r = send(sock, (void *) (buffer+sent), size-sent, 0); - sent += r; - p += r; - } + if (r < 0) + return r; + } return sent; } @@ -74,7 +77,7 @@ ssize_t recvall(int sock, void *buffer, size_t size) { return recv(sock, buffer, size, MSG_WAITALL); } -int opensock(unsigned short port) +static int opensock(unsigned short port) { int sock; socklen_t yes = 1; @@ -102,6 +105,40 @@ int opensock(unsigned short port) return sock; } +static int connectsock(const char *hostname, unsigned short port) +{ + struct addrinfo hints, *res = NULL, *cur; + int sock = -1; + char _port[10]; + + if (snprintf(_port, sizeof _port, "%hu", port) < 0) + goto err; + _port[(sizeof _port) -1] = '\0'; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_NUMERICSERV; + + if (getaddrinfo(hostname, _port, &hints, &res) != 0) + goto err; + + for (cur = res; cur; cur = cur->ai_next) { + sock = socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol); + if (sock < 0) + continue; + + if (connect(sock, cur->ai_addr, cur->ai_addrlen) != -1) + break; + + close(sock); + } + +err: + freeaddrinfo(res); + return sock; +} + int waitforclient(int server, long secs, long usecs) { fd_set rfds; @@ -132,7 +169,7 @@ int waitforclient(int server, long secs, long usecs) return 0; } -ssize_t sendToVICC(struct vicc_ctx *ctx, size_t length, const unsigned char* buffer) +static ssize_t sendToVICC(struct vicc_ctx *ctx, size_t length, const unsigned char* buffer) { ssize_t r; uint16_t size; @@ -155,7 +192,7 @@ ssize_t sendToVICC(struct vicc_ctx *ctx, size_t length, const unsigned char* buf return r; } -ssize_t recvFromVICC(struct vicc_ctx *ctx, unsigned char **buffer) +static ssize_t recvFromVICC(struct vicc_ctx *ctx, unsigned char **buffer) { ssize_t r; uint16_t size; @@ -186,29 +223,45 @@ ssize_t recvFromVICC(struct vicc_ctx *ctx, unsigned char **buffer) int vicc_eject(struct vicc_ctx *ctx) { + int r = 0; if (ctx && ctx->client_sock > 0) { - ctx->client_sock = close(ctx->client_sock); - if (ctx->client_sock < 0) { - return -1; + if (close(ctx->client_sock) < 0) { + r -= 1; } + ctx->client_sock = -1; } - return 0; + return r; } -struct vicc_ctx * vicc_init(unsigned short port) +struct vicc_ctx * vicc_init(const char *hostname, unsigned short port) { struct vicc_ctx *ctx = malloc(sizeof *ctx); if (!ctx) { return NULL; } - ctx->server_sock = opensock(port); - if (ctx->server_sock < 0) { - free(ctx); - return NULL; - } + if (hostname) { + ctx->hostname = strdup(hostname); + if (!ctx->hostname) { + free(ctx); + return NULL; + } - ctx->client_sock = -1; + ctx->server_sock = -1; + + ctx->client_sock = connectsock(hostname, port); + } else { + ctx->hostname = NULL; + + ctx->server_sock = opensock(port); + if (ctx->server_sock < 0) { + free(ctx); + return NULL; + } + + ctx->client_sock = -1; + } + ctx->port = port; return ctx; } @@ -217,6 +270,7 @@ int vicc_exit(struct vicc_ctx *ctx) { int r = vicc_eject(ctx); if (ctx) { + free(ctx->hostname); if (ctx->server_sock > 0) { ctx->server_sock = close(ctx->server_sock); if (ctx->server_sock < 0) { @@ -248,23 +302,30 @@ ssize_t vicc_transmit(struct vicc_ctx *ctx, int vicc_present(struct vicc_ctx *ctx) { unsigned char *atr = NULL; - if (ctx->client_sock <= 0) - /* return immediately */ - ctx->client_sock = waitforclient(ctx->server_sock, 0, 0); + if (ctx->client_sock < 0) { + if (ctx->server_sock) { + /* server mode, try to accept a client */ + ctx->client_sock = waitforclient(ctx->server_sock, 0, 0); + if (!ctx->client_sock) { + ctx->client_sock = -1; + } + } else { + /* client mode, try to connect (again) */ + ctx->client_sock = connectsock(ctx->hostname, ctx->port); + } + } if (ctx->client_sock < 0) - return -1; - - if (ctx->client_sock > 0) { - if (vicc_getatr(ctx, &atr) <= 0) - return 0; - - free(atr); - - return 1; - } else { + /* not connected */ return 0; - } + + /* get the atr to check if the card is still alive */ + if (vicc_getatr(ctx, &atr) <= 0) + return 0; + + free(atr); + + return 1; } ssize_t vicc_getatr(struct vicc_ctx *ctx, unsigned char **atr) { diff --git a/virtualsmartcard/src/vpcd/vpcd.h b/virtualsmartcard/src/vpcd/vpcd.h index ea8be80..ce5aa86 100644 --- a/virtualsmartcard/src/vpcd/vpcd.h +++ b/virtualsmartcard/src/vpcd/vpcd.h @@ -29,6 +29,8 @@ typedef int ssize_t; struct vicc_ctx { int server_sock; int client_sock; + char *hostname; + unsigned short port; }; #ifdef __cplusplus @@ -39,7 +41,20 @@ extern "C" { /** Standard port of the virtual smart card reader */ #define VPCDPORT 35963 -struct vicc_ctx * vicc_init(unsigned short port); +/** + * @brief Initialize the module + * + * @param[in] hostname Set hostname to something different to NULL if you want + * to connect the vpcd to a socket opened by vicc. + * Otherwise (default behavior) the vpcd will open a port + * for vicc + * @param[in] port Port to connect to or to open (see \a hostname) + * + * @return On success, the call returns the initialized context + * On error, NULL is returned. + */ +struct vicc_ctx * vicc_init(const char *hostname, unsigned short port); + int vicc_exit(struct vicc_ctx *ctx); int vicc_eject(struct vicc_ctx *ctx); diff --git a/virtualsmartcard/src/vpicc/vicc.in b/virtualsmartcard/src/vpicc/vicc.in index 61ae1c2..170467e 100644 --- a/virtualsmartcard/src/vpicc/vicc.in +++ b/virtualsmartcard/src/vpicc/vicc.in @@ -49,12 +49,15 @@ parser.add_argument("-H", "--hostname", action="store", type=str, default='localhost', - help="address of the vpcd (default: %(default)s)") + help="specifiy vpcd's host name if vicc shall connect to it. (default: %(default)s)") parser.add_argument("-P", "--port", action="store", type=int, default=35963, - help="port of the vpcd (default: %(default)s)") + help="port of connection establishment (default: %(default)s)") +parser.add_argument("-R", "--reversed", + action="store_true", + help="use reversed connection mode. vicc will wait for an incoming connection from vpcd. (default: %(default)s)") parser.add_argument('--version', action='version', version='%(prog)s @PACKAGE_VERSION@') relay = parser.add_argument_group('Relaying a local smart card (`--type=relay`)') @@ -118,8 +121,13 @@ elif args.verbose == 3: else: logginglevel = logging.DEBUG +if args.reversed: + hostname = None +else: + hostname = args.hostname + vicc = VirtualICC(args.file, args.type, - args.hostname, args.port, readernum=args.reader, + hostname, args.port, readernum=args.reader, ef_cardaccess=ef_cardaccess_data, ef_cardsecurity=ef_cardsecurity_data, ca_key=ca_key_data, cvca=cvca, disable_checks=args.disable_ta_checks, logginglevel=logginglevel) vicc.run() diff --git a/virtualsmartcard/src/vpicc/virtualsmartcard/VirtualSmartcard.py b/virtualsmartcard/src/vpicc/virtualsmartcard/VirtualSmartcard.py index 05e8d7f..3b39226 100644 --- a/virtualsmartcard/src/vpicc/virtualsmartcard/VirtualSmartcard.py +++ b/virtualsmartcard/src/vpicc/virtualsmartcard/VirtualSmartcard.py @@ -630,7 +630,7 @@ class VirtualICC(object): the vpcd, which forwards it to the application. """ - def __init__(self, filename, card_type, host, port, lenlen=3, readernum=None, ef_cardsecurity=None, ef_cardaccess=None, ca_key=None, cvca=None, disable_checks=False, logginglevel=logging.INFO): + def __init__(self, filename, card_type, host, port, readernum=None, ef_cardsecurity=None, ef_cardaccess=None, ca_key=None, cvca=None, disable_checks=False, logginglevel=logging.INFO): from os.path import exists logging.basicConfig(level = logginglevel, @@ -670,16 +670,28 @@ class VirtualICC(object): self.type = card_type #Connect to the VPCD - try: - self.sock = self.connectToPort(host, port) - self.sock.settimeout(None) - except socket.error as e: - logging.error("Failed to open socket: %s", str(e)) - logging.error("Is pcscd running at %s? Is vpcd loaded? Is a firewall blocking port %u?", - host, port) - sys.exit() - - self.lenlen = lenlen + self.host = host + if host: + # use normal connection mode + try: + self.sock = self.connectToPort(host, port) + self.sock.settimeout(None) + self.server_sock = None + except socket.error as e: + logging.error("Failed to open socket: %s", str(e)) + logging.error("Is pcscd running at %s? Is vpcd loaded? Is a firewall blocking port %u?", + host, port) + sys.exit() + else: + # use reversed connection mode + try: + (self.sock, self.server_sock, host) = self.openPort(port) + self.sock.settimeout(None) + except socket.error as e: + logging.error("Failed to open socket: %s", str(e)) + logging.error("Is pcscd running? Is vpcd loaded and in reversed connection mode? Is a firewall blocking port %u?", + port) + sys.exit() logging.info("Connected to virtual PCD at %s:%u", host, port) @@ -700,10 +712,19 @@ class VirtualICC(object): sock.connect((host, port)) return sock + @staticmethod + def openPort(port): + server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + server_socket.bind(('localhost', port)) + server_socket.listen(0) + logging.info("Waiting for vpcd on port " + str(port)) + (client_socket, address) = server_socket.accept() + return (client_socket, server_socket, address[0]) + def __sendToVPICC(self, msg): """ Send a message to the vpcd """ - #size = inttostring(len(msg), self.lenlen) - self.sock.send(struct.pack('!H', len(msg)) + msg) + self.sock.sendall(struct.pack('!H', len(msg)) + msg) def __recvFromVPICC(self): """ Receive a message from the vpcd """ @@ -760,6 +781,8 @@ class VirtualICC(object): def stop(self): self.sock.close() + if self.server_sock: + self.server_sock.close() if self.filename != None: self.cardGenerator.setCard(self.os.mf, self.os.SAM) self.cardGenerator.saveCard(self.filename) diff --git a/virtualsmartcard/test_vicc_with_handler_test.sh b/virtualsmartcard/test_vicc_with_handler_test.sh new file mode 100755 index 0000000..9cb2e1a --- /dev/null +++ b/virtualsmartcard/test_vicc_with_handler_test.sh @@ -0,0 +1,58 @@ +#! /bin/sh + +HANDLER_TEST="${HANDLER_TEST:=handler_test}" + +if test -z "$VICC" +then + if test -r ../virtualsmartcard/src/vpicc/vicc.in -a -n "`which python`" + then + VICC="python ../virtualsmartcard/src/vpicc/vicc.in" + elif test -x ../virtualsmartcard/src/vpicc/vicc + then + VICC=../virtualsmartcard/src/vpicc/vicc + elif test -n "`which vicc`" + then + VICC=vicc + else + echo "vicc not found" + exit 1 + fi +fi + +if test -z "$HANDLER_TEST" +then + if test -n "`which handler_test`" + then + HANDLER_TEST=handler_test + else + echo "handler_test not found" + exit 1 + fi +fi + +for flag in -A -T +do + $VICC --type handler_test --port 35963 --reversed >/dev/null 2>&1 & + VICC_PID=$! + if test $? -ne 0 + then + echo "could not start vicc" + exit 1 + fi + + sleep 1 + + $HANDLER_TEST \ + -l src/vpcd/.libs/libvpcd.so \ + -1 -2 -3 -4 $flag \ + -d localhost:35963 + HANDLER_TEST_RESULT=$? + + kill $VICC_PID 2>/dev/null + + if test $HANDLER_TEST_RESULT -ne 0 + then + echo "could not perform test" + exit 1 + fi +done