<commit_before>/*
 * reader-pcsc.c: Reader driver for PC/SC interface
 *
 * Copyright (C) 2002  <NAME> <<EMAIL>>
 * Copyright (C) 2009,2010 <NAME> <<EMAIL>>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#if HAVE_CONFIG_H
#include "config.h"
#endif

#ifdef ENABLE_PCSC	/* empty file without pcsc */

#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#ifdef _WIN32
#include <winsock2.h>
#else
#include <arpa/inet.h>
#endif

#include "common/libscdl.h"
#include "internal.h"
#include "internal-winscard.h"
#include "card-sc-hsm.h"

#include "pace.h"

#ifdef HAVE_PCSCLITE_H
#if !defined (__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED < 101000
#define HAVE_PCSCLITE 1
#endif
#endif

#define SCARD_CLASS_SYSTEM     0x7fff
#define SCARD_ATTR_VALUE(Class, Tag) ((((ULONG)(Class)) << 16) | ((ULONG)(Tag)))

#ifndef SCARD_ATTR_DEVICE_FRIENDLY_NAME_A
#define SCARD_ATTR_DEVICE_FRIENDLY_NAME_A SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0003)
#endif

#ifndef SCARD_ATTR_DEVICE_SYSTEM_NAME_A
#define SCARD_ATTR_DEVICE_SYSTEM_NAME_A SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0004)
#endif

#define SCARD_CLASS_VENDOR_INFO 1

#ifndef SCARD_ATTR_VENDOR_NAME
#define SCARD_ATTR_VENDOR_NAME SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_INFO, 0x0100) /**< Vendor name. */
#endif

#ifndef SCARD_ATTR_VENDOR_IFD_TYPE
#define SCARD_ATTR_VENDOR_IFD_TYPE SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_INFO, 0x0101) /**< Vendor-supplied interface device type (model designation of reader). */
#endif

#ifndef SCARD_ATTR_VENDOR_IFD_VERSION
#define SCARD_ATTR_VENDOR_IFD_VERSION SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_INFO, 0x0102) /**< Vendor-supplied interface device version (DWORD in the form 0xMMmmbbbb where MM = major version, mm = minor version, and bbbb = build number). */
#endif

/* Logging */
#define PCSC_TRACE(reader, desc, rv) do { sc_log(reader->ctx, "%s:" desc ": 0x%08lx\n", reader->name, (unsigned long)((ULONG)rv)); } while (0)
#define PCSC_LOG(ctx, desc, rv) do { sc_log(ctx, desc ": 0x%08lx\n", (unsigned long)((ULONG)rv)); } while (0)

/* #define APDU_LOG_FILE "apdulog" */
#ifdef APDU_LOG_FILE
void APDU_LOG(u8 *rbuf, uint16_t rsize)
{
	static FILE *fd = NULL;
	u8 *lenb = (u8*)&rsize;

	if (fd == NULL) {
		fd = fopen(APDU_LOG_FILE, "w");
	}
	/* First two bytes denote the length */
	(void) fwrite(lenb, 2, 1, fd);
	(void) fwrite(rbuf, rsize, 1, fd);
	fflush(fd);
}
#else
#define APDU_LOG(rbuf, rsize)
#endif

struct pcsc_global_private_data {
	int cardmod;
	SCARDCONTEXT pcsc_ctx;
	SCARDCONTEXT pcsc_wait_ctx;
	int enable_pinpad;
	int fixed_pinlength;
	int enable_pace;
	size_t force_max_recv_size;
	size_t force_max_send_size;
	int connect_exclusive;
	DWORD disconnect_action;
	DWORD transaction_end_action;
	DWORD reconnect_action;
	const char *provider_library;
	void *dlhandle;
	SCardEstablishContext_t SCardEstablishContext;
	SCardReleaseContext_t SCardReleaseContext;
	SCardConnect_t SCardConnect;
	SCardReconnect_t SCardReconnect;
	SCardDisconnect_t SCardDisconnect;
	SCardBeginTransaction_t SCardBeginTransaction;
	SCardEndTransaction_t SCardEndTransaction;
	SCardStatus_t SCardStatus;
	SCardGetStatusChange_t SCardGetStatusChange;
	SCardCancel_t SCardCancel;
	SCardControlOLD_t SCardControlOLD;
	SCardControl_t SCardControl;
	SCardTransmit_t SCardTransmit;
	SCardListReaders_t SCardListReaders;
	SCardGetAttrib_t SCardGetAttrib;

	sc_reader_t *attached_reader;
	sc_reader_t *removed_reader;
};

struct pcsc_private_data {
	struct pcsc_global_private_data *gpriv;
	SCARDHANDLE pcsc_card;
	SCARD_READERSTATE reader_state;
	DWORD verify_ioctl;
	DWORD verify_ioctl_start;
	DWORD verify_ioctl_finish;

	DWORD modify_ioctl;
	DWORD modify_ioctl_start;
	DWORD modify_ioctl_finish;

	DWORD pace_ioctl;

	DWORD pin_properties_ioctl;

	DWORD get_tlv_properties;

	int locked;
};

static int pcsc_detect_card_presence(sc_reader_t *reader);
static int pcsc_reconnect(sc_reader_t * reader, DWORD action);
static int pcsc_connect(sc_reader_t *reader);

static DWORD pcsc_reset_action(const char *str)
{
	if (!strcmp(str, "reset"))
		return SCARD_RESET_CARD;
	else if (!strcmp(str, "unpower"))
		return SCARD_UNPOWER_CARD;
	else
		return SCARD_LEAVE_CARD;
}

static int pcsc_to_opensc_error(LONG rv)
{
	switch (rv) {
	case SCARD_S_SUCCESS:
		return SC_SUCCESS;
	case SCARD_W_REMOVED_CARD:
		return SC_ERROR_CARD_REMOVED;
	case SCARD_E_NOT_TRANSACTED:
		return SC_ERROR_TRANSMIT_FAILED;
	case SCARD_W_UNRESPONSIVE_CARD:
		return SC_ERROR_CARD_UNRESPONSIVE;
	case SCARD_W_UNPOWERED_CARD:
		return SC_ERROR_CARD_UNRESPONSIVE;
	case SCARD_E_SHARING_VIOLATION:
		return SC_ERROR_READER_LOCKED;
	case SCARD_E_NO_READERS_AVAILABLE:
		return SC_ERROR_NO_READERS_FOUND;
	case SCARD_E_UNKNOWN_READER:
		return SC_ERROR_READER_DETACHED;<commit_msg>Allow compilation with older PC/SC<commit_after>/*
 * reader-pcsc.c: Reader driver for PC/SC interface
 *
 * Copyright (C) 2002  <NAME> <<EMAIL>>
 * Copyright (C) 2009,2010 <NAME> <<EMAIL>>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#if HAVE_CONFIG_H
#include "config.h"
#endif

#ifdef ENABLE_PCSC	/* empty file without pcsc */

#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#ifdef _WIN32
#include <winsock2.h>
#else
#include <arpa/inet.h>
#endif

#include "common/libscdl.h"
#include "internal.h"
#include "internal-winscard.h"
#include "card-sc-hsm.h"

#include "pace.h"

#ifdef HAVE_PCSCLITE_H
#if !defined (__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED < 101000
#define HAVE_PCSCLITE 1
#endif
#endif

#define SCARD_CLASS_SYSTEM     0x7fff
#define SCARD_ATTR_VALUE(Class, Tag) ((((ULONG)(Class)) << 16) | ((ULONG)(Tag)))

#ifndef SCARD_ATTR_DEVICE_FRIENDLY_NAME_A
#define SCARD_ATTR_DEVICE_FRIENDLY_NAME_A SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0003)
#endif

#ifndef SCARD_ATTR_DEVICE_SYSTEM_NAME_A
#define SCARD_ATTR_DEVICE_SYSTEM_NAME_A SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0004)
#endif

#define SCARD_CLASS_VENDOR_INFO 1

#ifndef SCARD_ATTR_VENDOR_NAME
#define SCARD_ATTR_VENDOR_NAME SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_INFO, 0x0100) /**< Vendor name. */
#endif

#ifndef SCARD_ATTR_VENDOR_IFD_TYPE
#define SCARD_ATTR_VENDOR_IFD_TYPE SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_INFO, 0x0101) /**< Vendor-supplied interface device type (model designation of reader). */
#endif

#ifndef SCARD_ATTR_VENDOR_IFD_VERSION
#define SCARD_ATTR_VENDOR_IFD_VERSION SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_INFO, 0x0102) /**< Vendor-supplied interface device version (DWORD in the form 0xMMmmbbbb where MM = major version, mm = minor version, and bbbb = build number). */
#endif

/* Logging */
#define PCSC_TRACE(reader, desc, rv) do { sc_log(reader->ctx, "%s:" desc ": 0x%08lx\n", reader->name, (unsigned long)((ULONG)rv)); } while (0)
#define PCSC_LOG(ctx, desc, rv) do { sc_log(ctx, desc ": 0x%08lx\n", (unsigned long)((ULONG)rv)); } while (0)

/* #define APDU_LOG_FILE "apdulog" */
#ifdef APDU_LOG_FILE
void APDU_LOG(u8 *rbuf, uint16_t rsize)
{
	static FILE *fd = NULL;
	u8 *lenb = (u8*)&rsize;

	if (fd == NULL) {
		fd = fopen(APDU_LOG_FILE, "w");
	}
	/* First two bytes denote the length */
	(void) fwrite(lenb, 2, 1, fd);
	(void) fwrite(rbuf, rsize, 1, fd);
	fflush(fd);
}
#else
#define APDU_LOG(rbuf, rsize)
#endif

struct pcsc_global_private_data {
	int cardmod;
	SCARDCONTEXT pcsc_ctx;
	SCARDCONTEXT pcsc_wait_ctx;
	int enable_pinpad;
	int fixed_pinlength;
	int enable_pace;
	size_t force_max_recv_size;
	size_t force_max_send_size;
	int connect_exclusive;
	DWORD disconnect_action;
	DWORD transaction_end_action;
	DWORD reconnect_action;
	const char *provider_library;
	void *dlhandle;
	SCardEstablishContext_t SCardEstablishContext;
	SCardReleaseContext_t SCardReleaseContext;
	SCardConnect_t SCardConnect;
	SCardReconnect_t SCardReconnect;
	SCardDisconnect_t SCardDisconnect;
	SCardBeginTransaction_t SCardBeginTransaction;
	SCardEndTransaction_t SCardEndTransaction;
	SCardStatus_t SCardStatus;
	SCardGetStatusChange_t SCardGetStatusChange;
	SCardCancel_t SCardCancel;
	SCardControlOLD_t SCardControlOLD;
	SCardControl_t SCardControl;
	SCardTransmit_t SCardTransmit;
	SCardListReaders_t SCardListReaders;
	SCardGetAttrib_t SCardGetAttrib;

	sc_reader_t *attached_reader;
	sc_reader_t *removed_reader;
};

struct pcsc_private_data {
	struct pcsc_global_private_data *gpriv;
	SCARDHANDLE pcsc_card;
	SCARD_READERSTATE reader_state;
	DWORD verify_ioctl;
	DWORD verify_ioctl_start;
	DWORD verify_ioctl_finish;

	DWORD modify_ioctl;
	DWORD modify_ioctl_start;
	DWORD modify_ioctl_finish;

	DWORD pace_ioctl;

	DWORD pin_properties_ioctl;

	DWORD get_tlv_properties;

	int locked;
};

static int pcsc_detect_card_presence(sc_reader_t *reader);
static int pcsc_reconnect(sc_reader_t * reader, DWORD action);
static int pcsc_connect(sc_reader_t *reader);

static DWORD pcsc_reset_action(const char *str)
{
	if (!strcmp(str, "reset"))
		return SCARD_RESET_CARD;
	else if (!strcmp(str, "unpower"))
		return SCARD_UNPOWER_CARD;
	else
		return SCARD_LEAVE_CARD;
}

static int pcsc_to_opensc_error(LONG rv)
{
	switch (rv) {
	case SCARD_S_SUCCESS:
		return SC_SUCCESS;
	case SCARD_W_REMOVED_CARD:
		return SC_ERROR_CARD_REMOVED;
	case SCARD_E_NOT_TRANSACTED:
		return SC_ERROR_TRANSMIT_FAILED;
	case SCARD_W_UNRESPONSIVE_CARD:
		return SC_ERROR_CARD_UNRESPONSIVE;
	case SCARD_W_UNPOWERED_CARD:
		return SC_ERROR_CARD_UNRESPONSIVE;
	case SCARD_E_SHARING_VIOLATION:
		return SC_ERROR_READER_LOCKED;
#ifdef SCARD_E_NO_READERS_AVAILABLE
	case SCARD_E_NO_READERS_AVAILABLE:
		return SC_ERROR_NO_READERS_FOUND;
#endif
	case SCARD_E_UNKNOWN_READER:
		return SC_ERROR_READER_DETACHED;
{'fraction_non_alphanumeric': 0.08620689655172414, 'fraction_numerical': 0.015508118956394819, 'mean_word_length': 6.236303630363036, 'pattern_counts': {'":': 4, '<': 39, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4982662', 'n_tokens_mistral': 4256, 'n_tokens_neox': 4152, 'n_words': 998}