implemented reversed connection establishment
vpcd can now be configured connect to a previously started vpicc.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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 && \
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
================================================================================
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
================================================================================
|
||||
|
||||
4
virtualsmartcard/doc/vpcd_example.conf
Normal file
4
virtualsmartcard/doc/vpcd_example.conf
Normal file
@@ -0,0 +1,4 @@
|
||||
FRIENDLYNAME "Virtual PCD"
|
||||
DEVICENAME /dev/null:0x8C7B
|
||||
LIBPATH /usr/lib/pcsc/drivers/serial/libvpcd.so
|
||||
CHANNELID 0x8C7B
|
||||
@@ -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
|
||||
|
||||
@@ -22,9 +22,13 @@
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#define close(s) closesocket(s)
|
||||
#ifndef AI_NUMERICSERV
|
||||
#define AI_NUMERICSERV 0
|
||||
#endif
|
||||
typedef WORD uint16_t;
|
||||
#else
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
@@ -32,6 +36,7 @@ typedef WORD uint16_t;
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
@@ -43,28 +48,26 @@ 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);
|
||||
for (sent = 0; sent < size; sent += r) {
|
||||
r = send(sock, (void *) (buffer+sent), size-sent, 0);
|
||||
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
sent += r;
|
||||
p += 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,22 +223,36 @@ 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;
|
||||
}
|
||||
|
||||
if (hostname) {
|
||||
ctx->hostname = strdup(hostname);
|
||||
if (!ctx->hostname) {
|
||||
free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -209,6 +260,8 @@ struct vicc_ctx * vicc_init(unsigned short port)
|
||||
}
|
||||
|
||||
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 */
|
||||
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;
|
||||
/* not connected */
|
||||
return 0;
|
||||
|
||||
if (ctx->client_sock > 0) {
|
||||
/* get the atr to check if the card is still alive */
|
||||
if (vicc_getatr(ctx, &atr) <= 0)
|
||||
return 0;
|
||||
|
||||
free(atr);
|
||||
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t vicc_getatr(struct vicc_ctx *ctx, unsigned char **atr) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
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()
|
||||
|
||||
self.lenlen = lenlen
|
||||
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)
|
||||
|
||||
58
virtualsmartcard/test_vicc_with_handler_test.sh
Executable file
58
virtualsmartcard/test_vicc_with_handler_test.sh
Executable 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
|
||||
Reference in New Issue
Block a user