⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scard.c

📁 LInux 下的远程桌面工具 Rdesktop
💻 C
📖 第 1 页 / 共 5 页
字号:
/*   rdesktop: A Remote Desktop Protocol client.   Smart Card support   Copyright (C) Alexi Volkov <alexi@myrealbox.com> 2006   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.   This program 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 General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include <stdio.h>#include <unistd.h>#include <fcntl.h>#include <strings.h>#include <sys/types.h>#include <time.h>#ifndef MAKE_PROTO#ifdef __APPLE__#include <PCSC/wintypes.h>#include <PCSC/pcsclite.h>#include <PCSC/winscard.h>#else#include <wintypes.h>#include <pcsclite.h>#include <winscard.h>#endif /* PCSC_OSX */#include "rdesktop.h"#include "scard.h"/* variable segment */#define SCARD_MAX_MEM 102400#define SCARD_AUTOALLOCATE -1#define	OUT_STREAM_SIZE	4096#ifdef B_ENDIAN#define swap32(x)	((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) |	\			(((x) & 0xff0000) >> 8) | (((x) & 0xff000000) >> 24))#define	swap16(x)	((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8))#else#define	swap32(x)	(x)#define	swap16(x)	(x)#endifstatic pthread_mutex_t **scard_mutex = NULL;static uint32 curDevice = 0, curId = 0, curBytesOut = 0;static PSCNameMapRec nameMapList = NULL;static int nameMapCount = 0;static pthread_t queueHandler;static pthread_mutex_t queueAccess;static pthread_cond_t queueEmpty;static pthread_mutex_t hcardAccess;static PMEM_HANDLE threadListHandle = NULL;static PThreadListElement threadList = NULL;static PSCThreadData queueFirst = NULL, queueLast = NULL;static int threadCount = 0;static PSCHCardRec hcardFirst = NULL;static void *queue_handler_function(void *data);/* code segment */#endif /* MAKE_PROTO */voidscardSetInfo(uint32 device, uint32 id, uint32 bytes_out){	curDevice = device;	curId = id;	curBytesOut = bytes_out;}#ifndef MAKE_PROTOstatic RD_NTSTATUSscard_create(uint32 device_id, uint32 accessmask, uint32 sharemode, uint32 create_disposition,	     uint32 flags_and_attributes, char *filename, RD_NTHANDLE * phandle){	return RD_STATUS_SUCCESS;}static RD_NTSTATUSscard_close(RD_NTHANDLE handle){	return RD_STATUS_SUCCESS;}static RD_NTSTATUSscard_read(RD_NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result){	return RD_STATUS_SUCCESS;}static RD_NTSTATUSscard_write(RD_NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result){	return RD_STATUS_SUCCESS;}#endif /* MAKE_PROTO *//* Enumeration of devices from rdesktop.c        *//* returns numer of units found and initialized. *//* optarg looks like ':"ReaderName=ReaderAlias"' *//* when it arrives to this function.             */intscard_enum_devices(uint32 * id, char *optarg){	char *name = optarg + 1;	char *alias;	int count = 0;	PSCNameMapRec tmpMap;	MYPCSC_DWORD rv;	SCARDCONTEXT hContext;	/* code segment  */	rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);	if (rv != SCARD_S_SUCCESS)	{		error("scard_enum_devices: PCSC service not available\n");		return 0;	}	else		rv = SCardReleaseContext(hContext);	count = 0;	if (0 != pthread_mutex_init(&queueAccess, NULL))	{		error("scard_enum_devices: Can't initialize queue access mutex\n");		return 0;	}	if (0 != pthread_cond_init(&queueEmpty, NULL))	{		error("scard_enum_devices: Can't initialize queue control cv\n");		return 0;	}	if (0 != pthread_mutex_init(&hcardAccess, NULL))	{		error("scard_enum_devices: Can't initialize hcard list access mutex\n");		return 0;	}	if (0 !=	    pthread_create(&queueHandler, NULL, (void *(*)(void *)) queue_handler_function, NULL))	{		error("scard_enum_devices: Can't create queue handling Thread\n");		return 0;	}	strncpy(g_rdpdr_device[*id].name, "SCARD\0\0\0", 8);	toupper_str(g_rdpdr_device[*id].name);	g_rdpdr_device[*id].local_path = "/dev/scard";	g_rdpdr_device[*id].pdevice_data = NULL;	g_rdpdr_device[*id].handle = 0;	g_rdpdr_device[*id].device_type = DEVICE_TYPE_SCARD;	count++;	(*id)++;	if (*optarg == ':')	{		while ((optarg = next_arg(name, ',')) && *id < RDPDR_MAX_DEVICES)		{			int len;			char *vendor = NULL;			alias = next_arg(name, '=');			vendor = next_arg(alias, ';');			if (strlen(name) > 0)			{				if (!strlen(alias))				{					alias = name;					vendor = "\0";				}				printf("Static/aliased Device:\n");				printf("  Lin name: [%s]\n", name);				printf("  Win name: [%s]\n", alias);				printf("  Vendor  : [%s]\n", vendor);				nameMapCount++;				if (nameMapList == NULL)					nameMapList = xmalloc(nameMapCount * sizeof(TSCNameMapRec));				else					nameMapList =						xrealloc(nameMapList,							 nameMapCount * sizeof(TSCNameMapRec));				tmpMap = nameMapList + nameMapCount - 1;				len = strlen(alias);				strncpy(tmpMap->alias, alias, (len > 127) ? (127) : (len));				len = strlen(name);				strncpy(tmpMap->name, name, (len > 127) ? (127) : (len));				if (vendor)				{					len = strlen(vendor);					if (len > 0)					{						memset(tmpMap->vendor, 0, 128);						strncpy(tmpMap->vendor, vendor,							(len > 127) ? (127) : (len));					}					else						tmpMap->vendor[0] = '\0';				}				else					tmpMap->vendor[0] = '\0';			}			name = optarg;		}	}	return count;}#ifndef MAKE_PROTO/* ---------------------------------- *//* These two functions depend heavily on the actual implementation of the smart * card handle in PC/SC Lite 1.3.1. Here are the salient bits: * * From winscard.c:331, in SCardConnect: *         *phCard = RFCreateReaderHandle(rContext); * * RFCreateReaderHandle (readerfactory.c:1161) creates a random short (16-bit * integer) and makes sure it's unique. Then it adds it to * rContext->dwIdentity. * * From readerfactory.c:173, in RFAddReader: *         (sReadersContexts[dwContext])->dwIdentity = *               (dwContext + 1) << (sizeof(DWORD) / 2) * 8; * * dwContext must be less than PCSCLITE_MAX_READERS_CONTEXTS, which is defined * to be 16 in the 1.3.1 release.  * * The use of "(sizeof(DWORD) / 2) * 8" is what makes conversion necessary in * order to use 64-bit card handles when talking to PC/SC Lite, and 32-bit card * handles when talking with the server, without losing any data: a card handle * made by a 32-bit PC/SC Lite looks like 0x00014d32, where the 4d32 is the * random 16 bits, 01 is the reader context index + 1, and it's left-shifted by  * 16 bits (sizeof(DWORD) == 4, divided by 2 is 2, times 8 is 16.) But a 64-bit * PC/SC Lite makes a card handle that looks like 0x0000000100004d32. The * reader context index+1 is left-shifted 32 bits because sizeof(DWORD) is 8, * not 4. This means the handle won't fit in 32 bits. (The multiplication by 8 * is because sizeofs are in bytes, but saying how many places to left-shift is * speaking in bits.) * * So then. Maximum value of dwContext+1 is 17; we'll say this fits in a byte * to be loose and have plenty of room. This is then left-shifted by * sizeof(DWORD) / 2 * 8 - which in this file is sizeof(MYPCSC_DWORD) / 2 * 8. * * At any rate, if we take the handle as passed from PC/SC Lite, right-shift by * sizeof(MYPCSC_DWORD) / 2, left-shift by sizeof(SERVER_DWORD) / 2, and add * the lower two bytes of the value (the random number), we can fit all the * information into 32 bits without losing any. Of course, any time we want to * hand that back to PC/SC Lite, we'll have to expand it again. (And if * sizeof(MYPCSC_DWORD) == sizeof(SERVER_DWORD), we're essentially doing * nothing, which will not break anything.) * * * - jared.jennings@eglin.af.mil, 2 Aug 2006 */static MYPCSC_SCARDHANDLEscHandleToMyPCSC(SERVER_SCARDHANDLE server){	return (((MYPCSC_SCARDHANDLE) server >> (sizeof(SERVER_DWORD) * 8 / 2) & 0xffff)		<< (sizeof(MYPCSC_DWORD) * 8 / 2)) + (server & 0xffff);}static SERVER_SCARDHANDLEscHandleToServer(MYPCSC_SCARDHANDLE mypcsc){	return ((mypcsc >> (sizeof(MYPCSC_DWORD) * 8 / 2) & 0xffff)		<< (sizeof(SERVER_DWORD) * 8 / 2)) + (mypcsc & 0xffff);}/* ---------------------------------- */static void *SC_xmalloc(PMEM_HANDLE * memHandle, unsigned int size){	PMEM_HANDLE handle = NULL;	if (size > 0 && memHandle)	{		handle = xmalloc(size + sizeof(MEM_HANDLE));		if (handle)		{			handle->prevHandle = NULL;			handle->nextHandle = NULL;			handle->dataSize = size;			if (*memHandle)			{				handle->prevHandle = *memHandle;				(*memHandle)->nextHandle = handle;			}			*memHandle = handle;			return handle + 1;		}		else			return NULL;	}	else		return NULL;}static voidSC_xfree(PMEM_HANDLE * handle, void *memptr){	if (memptr != NULL)	{		PMEM_HANDLE lcHandle = (PMEM_HANDLE) memptr - 1;		if (lcHandle->dataSize > 0)		{			memset(memptr, 0, lcHandle->dataSize);			if (lcHandle->nextHandle)				lcHandle->nextHandle->prevHandle = lcHandle->prevHandle;			if (lcHandle->prevHandle)				lcHandle->prevHandle->nextHandle = lcHandle->nextHandle;			if (*handle == lcHandle)			{				if (lcHandle->prevHandle)					*handle = lcHandle->prevHandle;				else					*handle = lcHandle->nextHandle;			}			xfree(lcHandle);		}	}}static voidSC_xfreeallmemory(PMEM_HANDLE * handle){	if (handle && (*handle))	{		if ((*handle)->prevHandle)		{			(*handle)->prevHandle->nextHandle = NULL;			SC_xfreeallmemory(&((*handle)->prevHandle));		}		if ((*handle)->nextHandle)		{			(*handle)->nextHandle->prevHandle = NULL;			SC_xfreeallmemory(&((*handle)->nextHandle));		}		memset(*handle, 0, (*handle)->dataSize + sizeof(MEM_HANDLE));		xfree(*handle);		*handle = NULL;	}}/* ---------------------------------- */static char *getName(char *alias){	int i;	PSCNameMapRec tmpMap;	for (i = 0, tmpMap = nameMapList; i < nameMapCount; i++, tmpMap++)	{		if (strcmp(tmpMap->alias, alias) == 0)			return tmpMap->name;	}	return alias;}static char *getVendor(char *name){	int i;	PSCNameMapRec tmpMap;	for (i = 0, tmpMap = nameMapList; i < nameMapCount; i++, tmpMap++)	{		if (strcmp(tmpMap->name, name) == 0)			return tmpMap->vendor;	}	return NULL;}static char *getAlias(char *name){	int i;	PSCNameMapRec tmpMap;	for (i = 0, tmpMap = nameMapList; i < nameMapCount; i++, tmpMap++)	{		if (strcmp(tmpMap->name, name) == 0)			return tmpMap->alias;	}	return name;}static inthasAlias(char *name){	int i;	PSCNameMapRec tmpMap;	for (i = 0, tmpMap = nameMapList; i < nameMapCount; i++, tmpMap++)	{		if (strcmp(tmpMap->name, name) == 0)			return 1;	}	return 0;}static voidinRepos(STREAM in, unsigned int read){	SERVER_DWORD add = 4 - read % 4;	if (add < 4 && add > 0)	{		in_uint8s(in, add);	}}static voidoutRepos(STREAM out, unsigned int written){	SERVER_DWORD add = (4 - written % 4) % 4;	if (add > 0)	{		out_uint8s(out, add);	}}static voidoutBufferStartWithLimit(STREAM out, int length, int highLimit){	int header = (length < 0) ? (0) : ((length > highLimit) ? (highLimit) : (length));	out_uint32_le(out, header);	out_uint32_le(out, 0x00000001);	/* Magic DWORD - any non zero */}static voidoutBufferStart(STREAM out, int length){	outBufferStartWithLimit(out, length, 0x7FFFFFFF);}static voidoutBufferFinishWithLimit(STREAM out, char *buffer, unsigned int length, unsigned int highLimit){	int header = (length < 0) ? (0) : ((length > highLimit) ? (highLimit) : (length));	out_uint32_le(out, header);	if (length <= 0)	{		out_uint32_le(out, 0x00000000);	}	else	{		if (header < length)			length = header;		out_uint8p(out, buffer, length);		outRepos(out, length);	}}static voidoutBufferFinish(STREAM out, char *buffer, unsigned int length){	outBufferFinishWithLimit(out, buffer, length, 0x7FFFFFFF);}static voidoutForceAlignment(STREAM out, unsigned int seed){	SERVER_DWORD add = (seed - (out->p - out->data) % seed) % seed;	if (add > 0)		out_uint8s(out, add);}static unsigned int

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -