CVS: rdesktop scard.c,1.25,1.26 scard.h,1.5,1.6

Michael Gernoth <[email protected]> Tue, 30 Oct 2007 06:09:39 -0700
Newsgroups gmane.network.rdesktop.cvs
Message-ID <[email protected]>
Update of /cvsroot/rdesktop/rdesktop
In directory sc8-pr-cvs9.sourceforge.net:/tmp/cvs-serv19591

Modified Files:
	scard.c scard.h 
Log Message:
Smartcard fixes (bigendian support, locking, bugfixes) from
Paul Winder <[email protected]>


Index: scard.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/scard.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -C2 -d -r1.25 -r1.26
*** scard.c	28 Oct 2007 16:49:45 -0000	1.25
--- scard.c	30 Oct 2007 13:09:37 -0000	1.26
***************
*** 44,47 ****
--- 44,57 ----
  #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)
+ #endif
+ 
  static pthread_mutex_t **scard_mutex = NULL;
  
***************
*** 52,56 ****
  static pthread_t queueHandler;
  static pthread_mutex_t queueAccess;
! static pthread_mutex_t queueEmpty;
  static pthread_mutex_t hcardAccess;
  
--- 62,66 ----
  static pthread_t queueHandler;
  static pthread_mutex_t queueAccess;
! static pthread_cond_t queueEmpty;
  static pthread_mutex_t hcardAccess;
  
***************
*** 139,145 ****
  	}
  
! 	if (0 != pthread_mutex_init(&queueEmpty, NULL))
  	{
! 		error("scard_enum_devices: Can't initialize queue control mutex\n");
  		return 0;
  	}
--- 149,155 ----
  	}
  
! 	if (0 != pthread_cond_init(&queueEmpty, NULL))
  	{
! 		error("scard_enum_devices: Can't initialize queue control cv\n");
  		return 0;
  	}
***************
*** 611,615 ****
  	else
  	{
! 		DEBUG_SCARD(("SCARD: -> Success (context: 0x%08x)\n", (unsigned) hContext));
  	}
  
--- 621,625 ----
  	else
  	{
! 		DEBUG_SCARD(("SCARD: -> Success (context: 0x%08lx)\n", hContext));
  	}
  
***************
*** 1054,1057 ****
--- 1064,1072 ----
  			SERVER_DWORD dataLength;
  
+ 			/* Do endian swaps... */
+ 			cur->dwCurrentState = swap32(cur->dwCurrentState);
+ 			cur->dwEventState = swap32(cur->dwEventState);
+ 			cur->cbAtr = swap32(cur->cbAtr);
+ 
  			/* reset Current state hign bytes; */
  			*curState = cur->dwCurrentState;
***************
*** 1161,1164 ****
--- 1176,1184 ----
  			     (unsigned) cur->dwEventState));
  
+ 		/* Do endian swaps... */
+ 		cur->dwCurrentState = swap32(cur->dwCurrentState);
+ 		cur->dwEventState = swap32(cur->dwEventState);
+ 		cur->cbAtr = swap32(cur->cbAtr);
+ 
  		out_uint8p(out, (void *) ((unsigned char **) cur + 2),
  			   sizeof(SERVER_SCARD_READERSTATE_A) - 2 * sizeof(unsigned char *));
***************
*** 1226,1229 ****
--- 1246,1251 ----
  	for (i = 0, cur = pAtrMasks; i < atrMaskCount; i++, cur++)
  	{
+ 		cur->cbAtr = swap32(cur->cbAtr);
+ 
  		DEBUG_SCARD(("SCARD:    ATR: "));
  		for (j = 0; j < pAtrMasks->cbAtr; j++)
***************
*** 1252,1259 ****
  	if (!ResArray)
  		return SC_returnNoMemoryError(&lcHandle, in, out);
- 	memcpy(ResArray, rsArray, readerCount * sizeof(SERVER_SCARD_READERSTATE_A));
  
  	for (i = 0, rsCur = rsArray; i < readerCount; i++, rsCur++)
  	{
  		inReaderName(&lcHandle, in, (char **) &rsCur->szReader, wide);
  		DEBUG_SCARD(("SCARD:    \"%s\"\n", rsCur->szReader ? rsCur->szReader : "NULL"));
--- 1274,1285 ----
  	if (!ResArray)
  		return SC_returnNoMemoryError(&lcHandle, in, out);
  
  	for (i = 0, rsCur = rsArray; i < readerCount; i++, rsCur++)
  	{
+ 		/* Do endian swaps... */
+ 		rsCur->dwCurrentState = swap32(rsCur->dwCurrentState);
+ 		rsCur->dwEventState = swap32(rsCur->dwEventState);
+ 		rsCur->cbAtr = swap32(rsCur->cbAtr);
+ 
  		inReaderName(&lcHandle, in, (char **) &rsCur->szReader, wide);
  		DEBUG_SCARD(("SCARD:    \"%s\"\n", rsCur->szReader ? rsCur->szReader : "NULL"));
***************
*** 1262,1265 ****
--- 1288,1292 ----
  			     (unsigned) rsCur->dwEventState));
  	}
+ 	memcpy(ResArray, rsArray, readerCount * sizeof(SERVER_SCARD_READERSTATE_A));
  
  	/* FIXME segfault here. */
***************
*** 1310,1315 ****
  	out_uint32_le(out, readerCount);
  
! 	for (i = 0, rsCur = rsArray; i < readerCount; i++, rsCur++)
  	{
  		out_uint8p(out, (void *) ((unsigned char **) rsCur + 2),
  			   sizeof(SCARD_READERSTATE_A) - 2 * sizeof(unsigned char *));
--- 1337,1347 ----
  	out_uint32_le(out, readerCount);
  
! 	for (i = 0, rsCur = ResArray; i < readerCount; i++, rsCur++)
  	{
+ 		/* Do endian swaps... */
+ 		rsCur->dwCurrentState = swap32(rsCur->dwCurrentState);
+ 		rsCur->dwEventState = swap32(rsCur->dwEventState);
+ 		rsCur->cbAtr = swap32(rsCur->cbAtr);
+ 
  		out_uint8p(out, (void *) ((unsigned char **) rsCur + 2),
  			   sizeof(SCARD_READERSTATE_A) - 2 * sizeof(unsigned char *));
***************
*** 1389,1395 ****
  	srcBytes = ((unsigned char *) src + sizeof(MYPCSC_SCARD_IO_REQUEST));
  	dstBytes = ((unsigned char *) dst + sizeof(SERVER_SCARD_IO_REQUEST));
! 	dst->dwProtocol = src->dwProtocol;
! 	dst->cbPciLength = src->cbPciLength
! 		- sizeof(MYPCSC_SCARD_IO_REQUEST) + sizeof(SERVER_SCARD_IO_REQUEST);
  	memcpy(dstBytes, srcBytes, bytesToCopy);
  }
--- 1421,1427 ----
  	srcBytes = ((unsigned char *) src + sizeof(MYPCSC_SCARD_IO_REQUEST));
  	dstBytes = ((unsigned char *) dst + sizeof(SERVER_SCARD_IO_REQUEST));
! 	dst->dwProtocol = swap32((uint32_t)src->dwProtocol);
! 	dst->cbPciLength = swap32((uint32_t)src->cbPciLength
! 		- sizeof(MYPCSC_SCARD_IO_REQUEST) + sizeof(SERVER_SCARD_IO_REQUEST));
  	memcpy(dstBytes, srcBytes, bytesToCopy);
  }
***************
*** 1402,1407 ****
  	srcBytes = ((unsigned char *) src + sizeof(SERVER_SCARD_IO_REQUEST));
  	dstBytes = ((unsigned char *) dst + sizeof(MYPCSC_SCARD_IO_REQUEST));
! 	dst->dwProtocol = src->dwProtocol;
! 	dst->cbPciLength = src->cbPciLength
  		- sizeof(SERVER_SCARD_IO_REQUEST) + sizeof(MYPCSC_SCARD_IO_REQUEST);
  	memcpy(dstBytes, srcBytes, bytesToCopy);
--- 1434,1439 ----
  	srcBytes = ((unsigned char *) src + sizeof(SERVER_SCARD_IO_REQUEST));
  	dstBytes = ((unsigned char *) dst + sizeof(MYPCSC_SCARD_IO_REQUEST));
! 	dst->dwProtocol = swap32(src->dwProtocol);
! 	dst->cbPciLength = src->cbPciLength	/* already correct endian */
  		- sizeof(SERVER_SCARD_IO_REQUEST) + sizeof(MYPCSC_SCARD_IO_REQUEST);
  	memcpy(dstBytes, srcBytes, bytesToCopy);
***************
*** 1564,1568 ****
  		DEBUG_SCARD(("SCARD: -> Success (%d bytes)\n", (int) cbRecvLength));
  #if 0
! 		if ((pioRecvPci != NULL) && (pioRecvPci->cbPciLength > 0))
  		{
  			out_uint32_le(out, (DWORD) pioRecvPci);	/* if not NULL, this 4 bytes indicates that pioRecvPci is present */
--- 1596,1600 ----
  		DEBUG_SCARD(("SCARD: -> Success (%d bytes)\n", (int) cbRecvLength));
  #if 0
! 		if ((pioRecvPci != NULL) && (mypioRecvPci->cbPciLength > 0))
  		{
  			out_uint32_le(out, (DWORD) pioRecvPci);	/* if not NULL, this 4 bytes indicates that pioRecvPci is present */
***************
*** 1575,1582 ****
  
  #if 0
! 		if ((pioRecvPci) && (pioRecvPci->cbPciLength > 0))
  		{
! 			out_uint32_le(out, pioRecvPci->dwProtocol);
! 			int len = pioRecvPci->cbPciLength - sizeof(pioRecvPci);
  			outBufferStartWithLimit(out, len, 12);
  			outBufferFinishWithLimit(out,
--- 1607,1614 ----
  
  #if 0
! 		if ((pioRecvPci) && (mypioRecvPci->cbPciLength > 0))
  		{
! 			out_uint32_le(out, mypioRecvPci->dwProtocol);
! 			int len = mypioRecvPci->cbPciLength - sizeof(mypioRecvPci);
  			outBufferStartWithLimit(out, len, 12);
  			outBufferFinishWithLimit(out,
***************
*** 1621,1624 ****
--- 1653,1665 ----
  		dwAtrLen = SCARD_MAX_MEM;
  
+ #if 1
+ 	/*
+ 	 * Active client sometimes sends a readerlen *just* big enough
+ 	 * SCardStatus doesn't seem to like this. This is a workaround,
+ 	 * aka hack!
+ 	 */
+ 	dwReaderLen = 200;
+ #endif
+ 
  	readerName = SC_xmalloc(&lcHandle, dwReaderLen + 2);
  	if (!readerName)
***************
*** 2383,2387 ****
  			queueFirst = data;
  
! 		pthread_mutex_unlock(&queueEmpty);
  		pthread_mutex_unlock(&queueAccess);
  	}
--- 2424,2428 ----
  			queueFirst = data;
  
! 		pthread_cond_broadcast(&queueEmpty);
  		pthread_mutex_unlock(&queueAccess);
  	}
***************
*** 2403,2419 ****
  {
  	PSCThreadData Result = NULL;
  	pthread_mutex_lock(&queueAccess);
! 	if (queueFirst != NULL)
  	{
! 		Result = queueFirst;
! 		queueFirst = queueFirst->next;
! 		if (!queueFirst)
! 		{
! 			queueLast = NULL;
! 			pthread_mutex_trylock(&queueEmpty);
! 		}
! 		Result->next = NULL;
  	}
  	pthread_mutex_unlock(&queueAccess);
  	return Result;
  }
--- 2444,2463 ----
  {
  	PSCThreadData Result = NULL;
+ 
  	pthread_mutex_lock(&queueAccess);
! 
! 	while (queueFirst == NULL)
! 		pthread_cond_wait(&queueEmpty, &queueAccess);
! 
! 	Result = queueFirst;
! 	queueFirst = queueFirst->next;
! 	if (!queueFirst)
  	{
! 		queueLast = NULL;
  	}
+ 	Result->next = NULL;
+ 
  	pthread_mutex_unlock(&queueAccess);
+ 
  	return Result;
  }
***************
*** 2433,2446 ****
  thread_function(PThreadListElement listElement)
  {
! 	if ((listElement != NULL) && (listElement->data != NULL))
  	{
! 		while (1)
! 		{
! 			pthread_mutex_lock(&listElement->nodata);
! 			SC_deviceControl(listElement->data);
! 			listElement->data = NULL;
! 			pthread_mutex_unlock(&listElement->busy);
! 		}
  	}
  	pthread_exit(NULL);
  	return NULL;
--- 2477,2492 ----
  thread_function(PThreadListElement listElement)
  {
! 	pthread_mutex_lock(&listElement->busy);
! 	while (1)
  	{
! 		while (listElement->data == NULL)
! 			pthread_cond_wait(&listElement->nodata,
! 			    &listElement->busy);
! 
! 		SC_deviceControl(listElement->data);
! 		listElement->data = NULL;
  	}
+ 	pthread_mutex_unlock(&listElement->busy);
+ 
  	pthread_exit(NULL);
  	return NULL;
***************
*** 2451,2469 ****
  {
  	int Result = 0;
! 	PThreadListElement cur = threadList, last = threadList;
  
! 	while (cur)
! 	{
! 		if (0 == pthread_mutex_trylock(&cur->busy))
! 		{
  			cur->data = data;
! 			pthread_mutex_unlock(&cur->nodata);
  			return;
  		}
- 		else
- 		{
- 			last = cur;
- 			cur = cur->next;
- 		}
  	}
  
--- 2497,2517 ----
  {
  	int Result = 0;
! 	PThreadListElement cur;
  
! 	for (cur = threadList; cur != NULL; cur = cur->next) {
! 		if (cur->data == NULL) {
! 			pthread_mutex_lock(&cur->busy);
! 			/* double check with lock held.... */
! 			if (cur->data != NULL) {
! 				pthread_mutex_unlock(&cur->busy);
! 				continue;
! 			}
! 			
! 			/* Wake up thread */
  			cur->data = data;
! 			pthread_cond_broadcast(&cur->nodata);
! 			pthread_mutex_unlock(&cur->busy);
  			return;
  		}
  	}
  
***************
*** 2474,2483 ****
  	threadCount++;
  
- 	cur->next = NULL;
  	pthread_mutex_init(&cur->busy, NULL);
! 	pthread_mutex_init(&cur->nodata, NULL);
! 	pthread_mutex_trylock(&cur->busy);
  	cur->data = data;
- 	pthread_mutex_unlock(&cur->nodata);
  
  	Result = pthread_create(&cur->thread, NULL, (void *(*)(void *)) thread_function, cur);
--- 2522,2528 ----
  	threadCount++;
  
  	pthread_mutex_init(&cur->busy, NULL);
! 	pthread_cond_init(&cur->nodata, NULL);
  	cur->data = data;
  
  	Result = pthread_create(&cur->thread, NULL, (void *(*)(void *)) thread_function, cur);
***************
*** 2489,2496 ****
  		data = NULL;
  	}
! 	else if (last)
! 		last->next = cur;
! 	else
! 		threadList = cur;
  }
  
--- 2534,2539 ----
  		data = NULL;
  	}
! 	cur->next = threadList;
! 	threadList = cur;
  }
  
***************
*** 2502,2525 ****
  	{
  		cur_data = SC_getNextInQueue();
! 		if (cur_data != NULL)
  		{
! 			switch (cur_data->request)
! 			{
! 				case SC_ESTABLISH_CONTEXT:
! 				case SC_RELEASE_CONTEXT:
! 					{
! 						SC_deviceControl(cur_data);
! 						break;
! 					}
! 				default:
! 					{
! 						SC_handleRequest(cur_data);
! 						break;
! 					}
! 			}
! 			cur_data = NULL;
  		}
- 		else
- 			pthread_mutex_lock(&queueEmpty);
  	}
  	return NULL;
--- 2545,2562 ----
  	{
  		cur_data = SC_getNextInQueue();
! 		switch (cur_data->request)
  		{
! 			case SC_ESTABLISH_CONTEXT:
! 			case SC_RELEASE_CONTEXT:
! 				{
! 					SC_deviceControl(cur_data);
! 					break;
! 				}
! 			default:
! 				{
! 					SC_handleRequest(cur_data);
! 					break;
! 				}
  		}
  	}
  	return NULL;

Index: scard.h
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/scard.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** scard.h	18 Sep 2007 06:46:39 -0000	1.5
--- scard.h	30 Oct 2007 13:09:37 -0000	1.6
***************
*** 169,173 ****
  	pthread_t thread;
  	pthread_mutex_t busy;
! 	pthread_mutex_t nodata;
  	PSCThreadData data;
  	struct _TThreadListElement *next;
--- 169,173 ----
  	pthread_t thread;
  	pthread_mutex_t busy;
! 	pthread_cond_t nodata;
  	PSCThreadData data;
  	struct _TThreadListElement *next;


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/