[ rdesktop-Bugs-2777237 ] rdesktop with smartcard

"SourceForge.net" <[email protected]>
Newsgroups gmane.network.rdesktop.devel
Message-ID <[email protected]>
Bugs item #2777237, was opened at 2009-04-21 09:02
Message generated for change (Comment added) made by nobody
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=381347&aid=2777237&group_id=24366

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: Authentication
Group: None
Status: Open
Resolution: None
Priority: 5
Private: No
Submitted By: rahulkr (rahulravindran)
Assigned to: Nobody/Anonymous (nobody)
Summary: rdesktop with smartcard

Initial Comment:
i have installed rdesktop 1.6 which has smart card option in linux OS.i plugin the usb smart card reader
and started pcscd deamon then i invoke the rdesktop with scard option the rdesktop recognized the
smart card which is inserted in the smart card reader.But problem is when i unplug the smart card and plug it again (while rdesktop still running) then rdesktop does not recognized the smart card.
Please help me.I have no clue what is happening but this procedure work perfectly with windows

----------------------------------------------------------------------

Comment By: Nobody/Anonymous (nobody)
Date: 2010-08-07 07:07

Message:
Hai! I am also facing the same problem, " A running rdesktop session not
recognizing smartcard once unplugged". I am also using rdesktop 1.6 on
centos 5.3 and trying to connect with aladdin etoken 72 pro java -
smartcard.  I did not tried kvogel's patch till now, but will try for sure.
I am looking for a new/related patches regarding this problem as its been a
year and I hope someone has found a stable patch for this, please give
details if you know any?

----------------------------------------------------------------------

Comment By: Nobody/Anonymous (nobody)
Date: 2009-12-22 16:07

Message:
kvogel's patch does not work for me against a w2k8r2 machine joined to a
domain.  In fact, it kills smartcard redirection entirely.

The dwTimeout workaround works better, but there is a lot of freezing of
the session when it initially connects, presumably due to an increase in
calls to the smartcard reader.  I have not enabled debugging yet to probe
further.  It is unclear to me, also, why the timeout in the first context
when joined to a domain is 0xfffffff, while all other timeouts are
0x000000.

----------------------------------------------------------------------

Comment By: Karl Vogel (kvogel)
Date: 2009-08-19 11:41

Message:
Added the scard.c patch to the patch tracker as ID: 2840243

https://sourceforge.net/tracker/?func=detail&aid=2840243&group_id=24366&atid=381349


----------------------------------------------------------------------

Comment By: Karl Vogel (kvogel)
Date: 2009-08-19 11:36

Message:
The issue seems to be caused by winlogon.exe - When the computer is joined
to a domain, it issues extra smart card calls. The first call is
SCardAccessStartedEvent() to check if the service is up. This should return
a HANDLE which the clients wait on.
If the SCardAccessStartedEvent() is delayed.. so that a normal smart card
apps makes API calls before the SCardAccessStartedEvent() from winlogon.exe
is done, it locks up the service.

It was found that returning an error from SCardAccessStartedEvent()
somehow makes everything work. It's unclear why this is, it might speed up
/ skip some initialization in winlogon.exe causing everything to work.

By patching rdesktop like:
Index: scard.c
===================================================================
--- scard.c	(revision 1505)
+++ scard.c	(working copy)
@@ -2162,7 +2162,7 @@
 {
 	DEBUG_SCARD(("SCARD: SCardAccessStartedEvent()\n"));
 	out_uint8s(out, 8);
-	return SCARD_S_SUCCESS;
+	return SCARD_E_INVALID_HANDLE;
 }

====

I got it to work for me.

I was also able to create a test app that shows the difference between
rdesktop and the windows terminal services client. Starting this test app
on rdesktop makes it wait until the timeout on the Wait event, whereas on a
windows terminal services client, it immediately returns.

#include <windows.h>

typedef HANDLE (*FNPTR)(void);
int main(int argc, char *argv[])
{
	FNPTR SCardAccessStartedEvent;
	HANDLE x;
	HRESULT dwRet;
	HINSTANCE hLibrary= LoadLibrary("winscard.dll");
	if (hLibrary == NULL) {
		printf("LoadLib failed\n");
		exit(1);
	}

	SCardAccessStartedEvent= (FNPTR)GetProcAddress(hLibrary,
"SCardAccessStartedEvent");
	if (SCardAccessStartedEvent == NULL) {
		printf("Proc error\n");
		exit(1);
	}

	x= SCardAccessStartedEvent();	
	printf("SCardAccessStartedEvent return: %x (%d)\n", x, x);
	dwRet= WaitForSingleObject(x, 50000);
	printf("Wait return: %x (%d)\n", dwRet, dwRet);

	FreeLibrary(hLibrary);
	return 0;
}


For now, I haven't been able to find why it acts differently. There isn't
any extra IOCTL calls happening for that call on the terminal services
client.



----------------------------------------------------------------------

Comment By: Nobody/Anonymous (nobody)
Date: 2009-08-14 09:11

Message:
The pcsc-lite winscard_clnt.c mentions:

/**
 * @brief Creates an Application Context to the PC/SC Resource Manager.
 *
 * This must be the first WinSCard function called in a PC/SC application.
 * Each thread of an application shall use its own SCARDCONTEXT.

The rdesktop client uses worker threads to handle scard requests (it
reuses or spawns new threads if non are available). This violates the 1
SCARDCONTEXT per thread restriction. Unfortunately it's not certain this is
really the issue and it is a rather big change.

NOTE: I got it to work for machines joined to a domain by forcing the
first SCardGetStatusChange() call to use a timeout of 1 (normally it's
INFINITE). Not quite sure why it works though.

ie. add something like this to the top of SCardGetStatusChange() in
scard.c :

static int _count=0;

if (_count == 0) {
  dwTimeout=1;
 _count++;
}



----------------------------------------------------------------------

Comment By: Nobody/Anonymous (nobody)
Date: 2009-07-07 13:46

Message:
I have 2 logs made with a svn version rdesktop patched with patch 2815251.

With a machine not joined to a domain:

SCARD: SCardAccessStartedEvent()
SCARD: SCardAccessStartedEvent()
SCARD: ctx   a: SCardGetStatusChange(timeout: 0x00000000, count: 1)
SCARD: ctx   a:    "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00000000, current state: 0x00000000
SCARD: ctx   a:   "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00110012
SCARD: ctx   a: SCardGetStatusChange(timeout: 0x00000000, count: 1)
SCARD: ctx   a:    "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00000000, current state: 0x00000000
SCARD: ctx   a:   "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00110012
SCARD: ctx   a: SCardGetStatusChange(timeout: 0x00000000, count: 1)
SCARD: ctx   a:    "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00000000, current state: 0x00000000
SCARD: ctx   a:   "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00120022
SCARD: ctx   b: SCardGetStatusChange(timeout: 0x00000000, count: 1)
SCARD: ctx   b:    "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00000000, current state: 0x00000000
SCARD: ctx   b:   "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00120022
SCARD: ctx   b: SCardGetStatusChange(timeout: 0x00000000, count: 1)
SCARD: ctx   b:    "ACS ACR38U 00 00" user: (nil), state: 0x00000022,
event: 0x00000022, current state: 0x00120022
SCARD: ctx   b:   "ACS ACR38U 00 00" user: (nil), state: 0x00120022,
event: 0x00140022
SCARD: ctx   b: SCardConnect(share: 0x00000002, proto: 0x00000003, reader:
"ACS ACR38U 00 00")
SCARD: ctx   a: SCardGetStatusChange(timeout: 0x00000000, count: 1)
SCARD: ctx   a:    "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00000000, current state: 0x00000000
SCARD: ctx   a:   "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00120122
SCARD: hcard   A: SCardTransmit(send: 5 bytes, recv: 30 bytes)
SCARD: -> Success (30 bytes)
SCARD: hcard   A: SCardTransmit(send: 9 bytes, recv: 2 bytes)
SCARD: -> Success (2 bytes)
SCARD: hcard   A: SCardTransmit(send: 5 bytes, recv: 246 bytes)
SCARD: -> Success (2 bytes)
SCARD: hcard   A: SCardTransmit(send: 5 bytes, recv: 246 bytes)
SCARD: -> Success (39 bytes)
SCARD: hcard   A: SCardTransmit(send: 9 bytes, recv: 2 bytes)
SCARD: -> Success (2 bytes)
SCARD: hcard   A: SCardTransmit(send: 11 bytes, recv: 2 bytes)
SCARD: -> Success (2 bytes)
SCARD: hcard   A: SCardTransmit(send: 5 bytes, recv: 246 bytes)
SCARD: -> Success (2 bytes)
SCARD: hcard   A: SCardTransmit(send: 5 bytes, recv: 246 bytes)
SCARD: -> Success (43 bytes)
SCARD: hcard   A: SCardTransmit(send: 11 bytes, recv: 2 bytes)
SCARD: ctx   a: SCardGetStatusChange(timeout: 0x00000000, count: 1)
SCARD: ctx   a:    "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00000000, current state: 0x00000000
SCARD: ctx   a:   "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00120122
SCARD: -> Success (2 bytes)
SCARD: hcard   A: SCardTransmit(send: 5 bytes, recv: 18 bytes)
SCARD: -> Success (18 bytes)
SCARD: ctx   b: hcard   A: SCardDisconnect(disposition: 0x00000000)
SCARD: ctx   a: SCardGetStatusChange(timeout: 0x00000000, count: 1)
SCARD: ctx   a:    "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00000000, current state: 0x00000000
SCARD: ctx   a:   "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00120022
SCARD: ctx   a: SCardGetStatusChange(timeout: 0x00000000, count: 1)
SCARD: ctx   a:    "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00000000, current state: 0x00000000
SCARD: ctx   a:   "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00120022
SCARD: ctx   a: SCardGetStatusChange(timeout: 0x00000000, count: 1)
SCARD: ctx   a:    "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00000000, current state: 0x00000000
SCARD: ctx   a:   "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00120022
SCARD: ctx   a: SCardGetStatusChange(timeout: 0x00000000, count: 1)
SCARD: ctx   a:    "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00000000, current state: 0x00000000
SCARD: ctx   a:   "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00120022
SCARD: ctx   a: SCardGetStatusChange(timeout: 0x00000000, count: 1)
SCARD: ctx   a:    "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00000000, current state: 0x00000000
SCARD: ctx   a:   "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00120022
SCARD: ctx   a: SCardGetStatusChange(timeout: 0x00000000, count: 1)
SCARD: ctx   a:    "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00000000, current state: 0x00000000
SCARD: ctx   a:   "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00120022
SCARD: ctx   a: SCardGetStatusChange(timeout: 0x00000000, count: 1)
SCARD: ctx   a:    "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00000000, current state: 0x00000000
SCARD: ctx   a:   "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00120022
SCARD: ctx   a: SCardGetStatusChange(timeout: 0x00000000, count: 1)
SCARD: ctx   a:    "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00000000, current state: 0x00000000
SCARD: ctx   a:   "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00130012
SCARD: ctx   a: SCardGetStatusChange(timeout: 0x00000000, count: 1)
SCARD: ctx   a:    "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00000000, current state: 0x00000000
SCARD: ctx   a:   "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00130012
SCARD: ctx   a: SCardGetStatusChange(timeout: 0x00000000, count: 1)
SCARD: ctx   a:    "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00000000, current state: 0x00000000
SCARD: ctx   a:   "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00130012
SCARD: ctx   a: SCardGetStatusChange(timeout: 0x00000000, count: 1)
SCARD: ctx   a:    "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00000000, current state: 0x00000000
SCARD: ctx   a:   "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00130012


With a machine joined to a domain:

SCARD: SCardAccessStartedEvent()
SCARD: ctx   a: SCardGetStatusChange(timeout: 0xffffffff, count: 2)
SCARD: ctx   a:    "\\?PnP?\Notification" user: (nil), state: 0x00000001,
event: 0x00000000, current state: 0x00000000
SCARD: ctx   a:    "ACS ACR38U 00 00" user: (nil), state: 0x00000010,
event: 0x00000000, current state: 0x00000010
SCARD: SCardAccessStartedEvent()
SCARD: ctx   b: SCardGetStatusChange(timeout: 0x00000000, count: 1)
SCARD: ctx   b:    "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00000000, current state: 0x00000000
SCARD: ctx   b:   "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x000f0012
SCARD: ctx   b: SCardGetStatusChange(timeout: 0x00000000, count: 1)
SCARD: ctx   b:    "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00000000, current state: 0x00000000
SCARD: ctx   b:   "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x000f0012
SCARD: ctx   b: SCardGetStatusChange(timeout: 0x00000000, count: 1)
SCARD: ctx   b:    "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00000000, current state: 0x00000000
SCARD: ctx   b:   "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x000f0012
SCARD: ctx   b: SCardGetStatusChange(timeout: 0x00000000, count: 1)
SCARD: ctx   b:    "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00000000, current state: 0x00000000
SCARD: ctx   b:   "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x000f0012
SCARD: ctx   b: SCardGetStatusChange(timeout: 0x00000000, count: 1)
SCARD: ctx   b:    "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x00000000, current state: 0x00000000
SCARD: ctx   b:   "ACS ACR38U 00 00" user: (nil), state: 0x00000000,
event: 0x000f0012
SCARD: ctx   a:   "\\?PnP?\Notification" user: (nil), state: 0x00000000,
event: 0x00000001
SCARD: ctx   a:   "ACS ACR38U 00 00" user: (nil), state: 0x00000010,
event: 0x00100022


----------------------------------------------------------------------

Comment By: rahulkr (rahulravindran)
Date: 2009-07-02 05:09

Message:
Thanks for the patch.I will look in to it.Currently i am not working on
this.if i get time i really like to work this.

----------------------------------------------------------------------

Comment By: Nobody/Anonymous (nobody)
Date: 2009-07-01 15:02

Message:
See patch 2815251 -
http://sourceforge.net/tracker/?func=detail&aid=2815251&group_id=24366&atid=381349

This patch may help you. I made it so that I could diff smart card debug
output between working and non-working rdesktop builds. It may apply
against 1.6.0 - but I made it against the CVS HEAD. There are multiple
rdesktop threads calling the pcsc-lite API, and I think this is part of the
problem (and the reason that it doesn't always work or fail the same way).
The changed debug output that this patch produces may make this more clear
to you.

The Microsoft RDP documentation may help you with your virtual channel
queries; I have been assured by the core developers that it is legally safe
for the project if you use this documentation. Virtual channels are handled
by rdpdr.c; I have not investigated the connections between that and
scard.c.

Thanks for your work on this problem. It's also a problem for me, but it
seems you are getting farther than I have, and that you have more time to
spend on it than I do.

----------------------------------------------------------------------

Comment By: rahulkr (rahulravindran)
Date: 2009-07-01 05:18

Message:
Actually real problem i had with aladdin etoken 72 pro java - smartcard.I
was able to solve the plugin-plugout issue by controlling the behaviour of
the thread i.e with help of udev rules.But it is not consistent.I added
some code in the TS_SCARDGETCHANGE() function to work this issue but it is
not perfect.Now u says that this virtual channel has a problem.What is this
virtual channel?How communication happen on this channel?.Because I explore
various files related to rdesktop but fail to get the problem source.

----------------------------------------------------------------------

Comment By: Nobody/Anonymous (nobody)
Date: 2009-06-30 14:27

Message:
I continue my search.  The update of pcsc-lite avoid a segmentation fault
and seems to be a little more stable but sometime (inpredictable...).

I'm looking now at the filesystem virtual channel used from smartcard
messages transmission.  Is it possible that ad problems (and the deadlock
in scard.c) come from there?  The filesystem virtual channel is implemented
in rdpdr.c (the channel is called rdpdr).

----------------------------------------------------------------------

Comment By: Nobody/Anonymous (nobody)
Date: 2009-06-25 13:11

Message:
As said in an other post on this mailing list, the upgrade of pcsclite
help.  I have updated pcsc-lite to version 1.5.4 (the latest one) and now
the hotplug works with AD but for a limited numbers of times...

The problems seems to be on the pcscd side.

----------------------------------------------------------------------

Comment By: Nobody/Anonymous (nobody)
Date: 2009-06-25 10:28

Message:
Uncommenting the block of code managing the hotplug allow the smart-card to
works perfectly with a MS Windows   that is not inside a MS domain.  

I start trying to debug with a MS Windows machine inside a domain and
found that the problem come from a deadlock in thread_function.  The
smart-card thread is locked on pthread_cond_wait without being waked up. 
The problem is not reproducible with MSTSC.EXE on MS Windows.  Certainly a
bug somewhere in rdesktop but why AD integration has an impact on rdesktop?
 Didn't understand up to now.

----------------------------------------------------------------------

Comment By: Nobody/Anonymous (nobody)
Date: 2009-06-23 15:04

Message:
I whish to add some extra information.

We had the same problem and we have discovered an interaction with MS
Active Directory.  When the windows machine on which we want to connect is
outside any domain, redirection and insert/eject events works perfectly. 
When the machine is added to the domain, we have the same problem.

The problem occurs with out-of-the box policies on Windows 2003 and
Windows 2008 server with the default policies.  And I have found no policy
directly inpacting RDP in these default policies.  So, up-to-now I have no
extra-idea or workaround.

----------------------------------------------------------------------

Comment By: Nobody/Anonymous (nobody)
Date: 2009-05-30 20:06

Message:
there is some code in the scard.c which enables the "hotplug" feature, it's
disabled, but when i enabled i was able to hotplug the card in the reader,
i'm just not sure if it is buggy...

----------------------------------------------------------------------

Comment By: rahulkr (rahulravindran)
Date: 2009-04-23 12:48

Message:
Is there any patch for this ?

----------------------------------------------------------------------

Comment By: Nobody/Anonymous (nobody)
Date: 2009-04-23 12:45

Message:
Is there any patch ready for this problem?

----------------------------------------------------------------------

Comment By: Nobody/Anonymous (nobody)
Date: 2009-04-21 13:18

Message:
You haven't done anything wrong. There is a bug in rdesktop. The set of
users using both rdesktop and smart cards is growing but still small; the
subset of those users who can hack on the smartcard support is even
smaller. So bugs in this area are not fixed very quickly.

The workaround is to set your terminal server to not log people off as
soon as they disconnect. Then when you remove the smartcard (for whatever
reason), you can disconnect without logging out of Windows by closing the
rdesktop client, and restart rdesktop with the smart card inserted, to
reconnect to the terminal server. Then you'll start your Windows session
where you left it off, with the smartcard working.

----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=381347&aid=2777237&group_id=24366

------------------------------------------------------------------------------
This SF.net email is sponsored by 

Make an app they can't live without
Enter the BlackBerry Developer Challenge
http://p.sf.net/sfu/RIM-dev2dev
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.