implemented reversed connection establishment

vpcd can now be configured connect to a previously started vpicc.
This commit is contained in:
Frank Morgner
2013-07-14 23:03:43 +02:00
parent ce77625a60
commit 291178d139
12 changed files with 312 additions and 82 deletions

View File

@@ -41,7 +41,7 @@ static int vpcd_connect(driver_data_t **driver_data)
return 0; return 0;
ctx = vicc_init(vpcdport); ctx = vicc_init(NULL, vpcdport);
if (!ctx) { if (!ctx) {
RELAY_ERROR("Could not initialize connection to virtual ICC\n"); RELAY_ERROR("Could not initialize connection to virtual ICC\n");
return 0; return 0;

View File

@@ -1,7 +1,7 @@
ACLOCAL_AMFLAGS = -I m4 ACLOCAL_AMFLAGS = -I m4
SUBDIRS = src doc npa-example-data 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: distcheck-hook:
test -d .svn && \ test -d .svn && \

View File

@@ -18,7 +18,7 @@ do_subst = $(SED) \
-e 's,[@]abs_top_srcdir[@],$(abs_top_srcdir),g' \ -e 's,[@]abs_top_srcdir[@],$(abs_top_srcdir),g' \
-e 's,[@]top_srcdir[@],$(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 dist_noinst_SCRIPTS = generate_modules.py

View File

@@ -74,19 +74,34 @@ The |vpcd| depends on PCSC-Lite_.
Running the Virtual Smart Card Running the Virtual Smart Card
******************************************************************************** ********************************************************************************
Fitxt you need to make sure that :command:`pcscd` loads the |vpcd|. You might The configuration file from |vpcd| is usually placed into
need to run :command:`update-reader.conf` to update its configuration file. :file:`/etc/reader.conf.d/`. The PC/SC daemon should read it and load the
Then :command:`pcscd -f -d` should say something like "Attempting startup of |vpcd| on startup. In debug mode :command:`pcscd -f -d` should say something
Virtual PCD" 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 By default, |vpcd| opens a socket for |vpicc| and waits for incoming
:command:`vicc --help` gives an overview about the command line options. 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 .. program-output:: vicc --help
You should now be able to access the |vpicc| through the PC/SC API via When |vpcd| and |vpicc| are connected you should be able to access the card
|vpcd|/:command:`pcscd`. You can use the :command:`opensc-explorer` or through the PC/SC API via :command:`pcscd`. You can use the
:command:`pcsc_scan` for testing. :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.
================================================================================ ================================================================================

View File

@@ -74,19 +74,34 @@ The |vpcd| depends on PCSC-Lite_.
Running the @PACKAGE_NAME@ Running the @PACKAGE_NAME@
******************************************************************************** ********************************************************************************
Fitxt you need to make sure that :command:`pcscd` loads the |vpcd|. You might The configuration file from |vpcd| is usually placed into
need to run :command:`update-reader.conf` to update its configuration file. :file:`/etc/reader.conf.d/`. The PC/SC daemon should read it and load the
Then :command:`pcscd -f -d` should say something like "Attempting startup of |vpcd| on startup. In debug mode :command:`pcscd -f -d` should say something
Virtual PCD" 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 By default, |vpcd| opens a socket for |vpicc| and waits for incoming
:command:`vicc --help` gives an overview about the command line options. 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 .. program-output:: vicc --help
You should now be able to access the |vpicc| through the PC/SC API via When |vpcd| and |vpicc| are connected you should be able to access the card
|vpcd|/:command:`pcscd`. You can use the :command:`opensc-explorer` or through the PC/SC API via :command:`pcscd`. You can use the
:command:`pcsc_scan` for testing. :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.
================================================================================ ================================================================================

View File

@@ -0,0 +1,4 @@
FRIENDLYNAME "Virtual PCD"
DEVICENAME /dev/null:0x8C7B
LIBPATH /usr/lib/pcsc/drivers/serial/libvpcd.so
CHANNELID 0x8C7B

View File

@@ -14,6 +14,8 @@
1) 1)
static struct vicc_ctx *ctx[VICC_MAX_SLOTS]; static struct vicc_ctx *ctx[VICC_MAX_SLOTS];
static char *hostname = NULL;
static const char openport[] = "/dev/null";
RESPONSECODE RESPONSECODE
IFDHCreateChannel (DWORD Lun, DWORD Channel) IFDHCreateChannel (DWORD Lun, DWORD Channel)
@@ -22,12 +24,17 @@ IFDHCreateChannel (DWORD Lun, DWORD Channel)
if (slot >= VICC_MAX_SLOTS) { if (slot >= VICC_MAX_SLOTS) {
return IFD_COMMUNICATION_ERROR; 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]) { if (!ctx[slot]) {
Log1(PCSC_LOG_ERROR, "Could not initialize connection to virtual ICC"); Log1(PCSC_LOG_ERROR, "Could not initialize connection to virtual ICC");
return IFD_COMMUNICATION_ERROR; 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; return IFD_SUCCESS;
} }
@@ -35,27 +42,51 @@ IFDHCreateChannel (DWORD Lun, DWORD Channel)
RESPONSECODE RESPONSECODE
IFDHCreateChannelByName (DWORD Lun, LPSTR DeviceName) IFDHCreateChannelByName (DWORD Lun, LPSTR DeviceName)
{ {
RESPONSECODE r = IFD_NOT_SUPPORTED;
char *dots; char *dots;
char _hostname[MAX_READERNAME];
size_t hostname_len;
unsigned long int port = VPCDPORT; unsigned long int port = VPCDPORT;
dots = strchr(DeviceName, ':'); dots = strchr(DeviceName, ':');
if (dots) { if (dots) {
/* a port has been specified behind the device name */ /* 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++; dots++;
errno = 0; errno = 0;
port = strtoul(dots, NULL, 0); port = strtoul(dots, NULL, 0);
if (errno) { if (errno) {
Log2(PCSC_LOG_ERROR, "Could not parse port: %s", dots); Log2(PCSC_LOG_ERROR, "Could not parse port: %s", dots);
return IFD_NO_SUCH_DEVICE; goto err;
} }
} else { } else {
Log1(PCSC_LOG_INFO, "Using default port."); 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 RESPONSECODE

View File

@@ -22,9 +22,13 @@
#include <winsock2.h> #include <winsock2.h>
#include <ws2tcpip.h> #include <ws2tcpip.h>
#define close(s) closesocket(s) #define close(s) closesocket(s)
#ifndef AI_NUMERICSERV
#define AI_NUMERICSERV 0
#endif
typedef WORD uint16_t; typedef WORD uint16_t;
#else #else
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netdb.h>
#include <stdint.h> #include <stdint.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/time.h> #include <sys/time.h>
@@ -32,6 +36,7 @@ typedef WORD uint16_t;
#endif #endif
#include <errno.h> #include <errno.h>
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/types.h> #include <sys/types.h>
@@ -43,29 +48,27 @@ typedef WORD uint16_t;
#define VPCD_CTRL_RESET 2 #define VPCD_CTRL_RESET 2
#define VPCD_CTRL_ATR 4 #define VPCD_CTRL_ATR 4
ssize_t sendToVICC(struct vicc_ctx *ctx, size_t size, const unsigned char *buffer); static 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 recvFromVICC(struct vicc_ctx *ctx, unsigned char **buffer);
static ssize_t sendall(int sock, const void *buffer, size_t size); static ssize_t sendall(int sock, const void *buffer, size_t size);
static ssize_t recvall(int sock, void *buffer, size_t size); static ssize_t recvall(int sock, void *buffer, size_t size);
static int opensock(unsigned short port); 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) ssize_t sendall(int sock, const void *buffer, size_t size)
{ {
size_t sent = 0; size_t sent;
ssize_t r; ssize_t r;
const unsigned char *p = buffer;
while (sent < size) { for (sent = 0; sent < size; sent += r) {
r = send(sock, (void *) p, size-sent, 0); r = send(sock, (void *) (buffer+sent), size-sent, 0);
if (r < 0)
return r;
sent += r; if (r < 0)
p += r; return r;
} }
return sent; return sent;
} }
@@ -74,7 +77,7 @@ ssize_t recvall(int sock, void *buffer, size_t size) {
return recv(sock, buffer, size, MSG_WAITALL); return recv(sock, buffer, size, MSG_WAITALL);
} }
int opensock(unsigned short port) static int opensock(unsigned short port)
{ {
int sock; int sock;
socklen_t yes = 1; socklen_t yes = 1;
@@ -102,6 +105,40 @@ int opensock(unsigned short port)
return sock; 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) int waitforclient(int server, long secs, long usecs)
{ {
fd_set rfds; fd_set rfds;
@@ -132,7 +169,7 @@ int waitforclient(int server, long secs, long usecs)
return 0; 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; ssize_t r;
uint16_t size; uint16_t size;
@@ -155,7 +192,7 @@ ssize_t sendToVICC(struct vicc_ctx *ctx, size_t length, const unsigned char* buf
return r; 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; ssize_t r;
uint16_t size; 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 vicc_eject(struct vicc_ctx *ctx)
{ {
int r = 0;
if (ctx && ctx->client_sock > 0) { if (ctx && ctx->client_sock > 0) {
ctx->client_sock = close(ctx->client_sock); if (close(ctx->client_sock) < 0) {
if (ctx->client_sock < 0) { r -= 1;
return -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); struct vicc_ctx *ctx = malloc(sizeof *ctx);
if (!ctx) { if (!ctx) {
return NULL; return NULL;
} }
ctx->server_sock = opensock(port); if (hostname) {
if (ctx->server_sock < 0) { ctx->hostname = strdup(hostname);
free(ctx); if (!ctx->hostname) {
return NULL; 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; return ctx;
} }
@@ -217,6 +270,7 @@ int vicc_exit(struct vicc_ctx *ctx)
{ {
int r = vicc_eject(ctx); int r = vicc_eject(ctx);
if (ctx) { if (ctx) {
free(ctx->hostname);
if (ctx->server_sock > 0) { if (ctx->server_sock > 0) {
ctx->server_sock = close(ctx->server_sock); ctx->server_sock = close(ctx->server_sock);
if (ctx->server_sock < 0) { if (ctx->server_sock < 0) {
@@ -248,23 +302,30 @@ ssize_t vicc_transmit(struct vicc_ctx *ctx,
int vicc_present(struct vicc_ctx *ctx) { int vicc_present(struct vicc_ctx *ctx) {
unsigned char *atr = NULL; unsigned char *atr = NULL;
if (ctx->client_sock <= 0) if (ctx->client_sock < 0) {
/* return immediately */ if (ctx->server_sock) {
ctx->client_sock = waitforclient(ctx->server_sock, 0, 0); /* 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) if (ctx->client_sock < 0)
return -1; /* not connected */
if (ctx->client_sock > 0) {
if (vicc_getatr(ctx, &atr) <= 0)
return 0;
free(atr);
return 1;
} else {
return 0; 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) { ssize_t vicc_getatr(struct vicc_ctx *ctx, unsigned char **atr) {

View File

@@ -29,6 +29,8 @@ typedef int ssize_t;
struct vicc_ctx { struct vicc_ctx {
int server_sock; int server_sock;
int client_sock; int client_sock;
char *hostname;
unsigned short port;
}; };
#ifdef __cplusplus #ifdef __cplusplus
@@ -39,7 +41,20 @@ extern "C" {
/** Standard port of the virtual smart card reader */ /** Standard port of the virtual smart card reader */
#define VPCDPORT 35963 #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_exit(struct vicc_ctx *ctx);
int vicc_eject(struct vicc_ctx *ctx); int vicc_eject(struct vicc_ctx *ctx);

View File

@@ -49,12 +49,15 @@ parser.add_argument("-H", "--hostname",
action="store", action="store",
type=str, type=str,
default='localhost', 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", parser.add_argument("-P", "--port",
action="store", action="store",
type=int, type=int,
default=35963, 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@') parser.add_argument('--version', action='version', version='%(prog)s @PACKAGE_VERSION@')
relay = parser.add_argument_group('Relaying a local smart card (`--type=relay`)') relay = parser.add_argument_group('Relaying a local smart card (`--type=relay`)')
@@ -118,8 +121,13 @@ elif args.verbose == 3:
else: else:
logginglevel = logging.DEBUG logginglevel = logging.DEBUG
if args.reversed:
hostname = None
else:
hostname = args.hostname
vicc = VirtualICC(args.file, args.type, 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, 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) ca_key=ca_key_data, cvca=cvca, disable_checks=args.disable_ta_checks, logginglevel=logginglevel)
vicc.run() vicc.run()

View File

@@ -630,7 +630,7 @@ class VirtualICC(object):
the vpcd, which forwards it to the application. 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 from os.path import exists
logging.basicConfig(level = logginglevel, logging.basicConfig(level = logginglevel,
@@ -670,16 +670,28 @@ class VirtualICC(object):
self.type = card_type self.type = card_type
#Connect to the VPCD #Connect to the VPCD
try: self.host = host
self.sock = self.connectToPort(host, port) if host:
self.sock.settimeout(None) # use normal connection mode
except socket.error as e: try:
logging.error("Failed to open socket: %s", str(e)) self.sock = self.connectToPort(host, port)
logging.error("Is pcscd running at %s? Is vpcd loaded? Is a firewall blocking port %u?", self.sock.settimeout(None)
host, port) self.server_sock = None
sys.exit() except socket.error as e:
logging.error("Failed to open socket: %s", str(e))
self.lenlen = lenlen 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) logging.info("Connected to virtual PCD at %s:%u", host, port)
@@ -700,10 +712,19 @@ class VirtualICC(object):
sock.connect((host, port)) sock.connect((host, port))
return sock 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): def __sendToVPICC(self, msg):
""" Send a message to the vpcd """ """ Send a message to the vpcd """
#size = inttostring(len(msg), self.lenlen) self.sock.sendall(struct.pack('!H', len(msg)) + msg)
self.sock.send(struct.pack('!H', len(msg)) + msg)
def __recvFromVPICC(self): def __recvFromVPICC(self):
""" Receive a message from the vpcd """ """ Receive a message from the vpcd """
@@ -760,6 +781,8 @@ class VirtualICC(object):
def stop(self): def stop(self):
self.sock.close() self.sock.close()
if self.server_sock:
self.server_sock.close()
if self.filename != None: if self.filename != None:
self.cardGenerator.setCard(self.os.mf, self.os.SAM) self.cardGenerator.setCard(self.os.mf, self.os.SAM)
self.cardGenerator.saveCard(self.filename) self.cardGenerator.saveCard(self.filename)

View File

@@ -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