RDPESC: Windows Server 2008 R2 sends an extra SCARD_IOCTL after the client reconnects to an existing session with a smart card
-
Tuesday, April 17, 2012 10:30 PM
Using Windows Server 2008 R2, and an RDP client on on the remote machine, I see that the server sends an incorrect, extra, SCARD_IOCTL control when a client reconnects to an existing login session on the server. This occurs both when the client is "mstsc.exe" from Windows 7, and the "xfreerdp" client running on a Linux front-end.
I have a smart card reader (named "SCM...") plugged into the machine on which RDP client is running. After starting the RDP client, I insert the smart card into the reader. The server reads the smart card and prompts me for my PIN. I enter the PIN and then I am connected to the existing login session on the server. I wait 15 seconds, and then pull the smart card from its reader.
The following table shows the highlights from a Network Monitor trace of the "xfreerdp' client's connection to an existing session on the server.
Frame
Number
Time
Offset
(sec)
Source
Destination
Description
CompletionID
Comment
821 21.4 server client RDPESC: IOCTL_GETSTATUSCHANGEW 2 Request notification of a change for either "PnP" or "SCM..." smart card readers. 2545 45.6 server client RDPESC: IOCTL_GETSTATUSCHANGEA 7 Request notification of a change for the "SCM..." reader. 3384 48.6 server client RDPESC: IOCTL_GETSTATUSCHANGEW 3 Request notification of a change for either "PnP" or "SCM..." readers. 3391 48.679 server client RDPESC: IOCTL_TRANSMIT 2 This is incorrect! The server shouldn't send this frame before it receives an "IOCompletion" for the "GetStatusChangeW" IOCTL in frame #821. 3393 48.689 client server RDPEFS:
RDPDrDeviceIOCompletion2 The bytes returned to the server in this frame match those for a "Transmit_Return" structure. So, this frame pairs with frame #3391 rather than #821. 2 The server sends other IOCTL frames with a CompletionID of 2, and the client responds with a corresponding IOCompletion frame. Note that the CompletionIDs of 7 and 3 are not reused during this period. ~60 Pull card from reader 4281 61.734 client server RDPEFS:
RDPDrDeviceIOCompletion2 "xfreerdp" returns status for the two readers of frame #821. This is normally the correct action to take, but it causes the server to drop the virtual channel that carries smart card controls. 4283 61.734 client server RDPEFS:
RDPDrDeviceIOCompletion7 Returns status for the one "SCM" reader of frame #2545. 4286 61.734 client server RDPEFS:
RDPDrDeviceIOCompletion3 Returns status for the two readers of frame #3384. server - The server never sends any further IOCTLs after the client sends the burst of three "IOCompletions". According to Section 3.1.5.2 (titled "Processing Packet Errors") of the Microsoft document "[MS-RDPEFS]: Remote Desktop Protocol: File System Virtual Channel Extension":
Error checking for a Device I/O Response (DR_DEVICE_IOCOMPLETION):
I see this termination occur because the server never sends another IOCTL in the case of using the "xfreerdp" client.
If a response contains a CompletionId value that has not been sent or has been already
completed, the implementation SHOULD terminate the virtual channel.
The "mstsc.exe" client works around this bad server behavior by (apparently) forgetting that it received the SCARD_IOCTL_GETSTATUSCHANGE control when it receives the second IOCTL with the same CompletionID as the first IOCTL. This is shown by the fact that the "mstsc.exe" client never responds with a RDPDrDeviceIOCompletion frame with a matching CompletionID even after I pull the smart card and so change the status. However, this work-around by "mstsc.exe" introduces a race condition, The server can't be sure if the first "IOCompletion" packet that it sees with the expected "CompletionID" is due to the first or the second IOCTL that it sent.
In the case of a fresh connection session rather than a re-connection to an existing session, the server is well-behaved: it never "overwrites" an outstanding IOCTL_GETSTATUSCHANGE control with a second IOCTL. Because the server is well-behaved, the "xfreerdp" client has no problem handling multiple card removals and insertions.
I think that this behavior of Windows Server 2008 R2 should be corrected in a future release.
-- Steve Ross
All Replies
-
Wednesday, April 18, 2012 4:20 AMModerator
Hi Steve,
Thank you for your question. An engineer from the Protocols Team will contact you soon.
Bryan S. Burgin Senior Escalation Engineer Microsoft Protocol Open Specifications Team
-
Wednesday, April 18, 2012 3:07 PM
Hi Steve
I'll be assisting you with this issue. As you are able to repro the same behaviour with mstsc.exe, can you please send it's decrypted network trace to my attention to : dochelp at microsoft dot com for further analysis.
Thanks.
Tarun Chopra | Escalation Engineer | Open Specifications Support Team
-
Wednesday, April 18, 2012 10:09 PM
Tarun,
I just sent the decrypted file to you as you requested. Would you please also forward the same file to Obaid Farooqi, also of Microsoft, in reference to the issue that I described in the posting to the Windows Protocols forum at <http://social.msdn.microsoft.com/Forums/en-US/os_windowsprotocols/thread/c5e018e5-18b8-4511-825b-666a672d1787>.
Thanks,
-- Steve Ross
-
Tuesday, May 29, 2012 7:10 PM
Hi Steve
Taking your trace file (120402-sc1-pull-reinsert-card.decrypt.decrypted-only.cap) as a reference and applying filter as "RDPEFS.DrDeviceIOCompletion.CompletionID == 0x0 OR RDPEFS.DrCoreDeviceIORequest.CompletionID == 0x0 " , we got below frames. Both 380 and 627 frames were originated from TS and used same completionid i.e. 0 which triggered the alarm since TS is not supposed to send messages with same competionid as the response from client, mststc.exe, for frame 380 was pending.
Frame
NumberSource
Destination
Description
CompletionID
Comment
380
server
client
RDPESC: IOCTL_GETSTATUSCHANGEW
0
Request notification of a change for either "PnP" or "SCM..." smart card readers.
627
server
client
RDPESC: IOCTL_ACCESSSTARTEDEVENT
0
This is incorrect! The server shouldn't send this frame before it receives an "IOCompletion" for the "GetStatusChangeW" IOCTL in frame #380.
632
client
server
RDPEFS:
RDPDrDeviceIOCompletion0
The bytes returned to the server in this frame match those for a "Long_Return" structure that is associated with the ACCESSSTARTEDEVENT. So, this frame pairs with frame #627 rather than #380.
On further analysis, by applying filter as RDPEFS, we observed that the server is reconnecting the session again by triggering Protocol Initialization sequence as described in section 1.3.1 of MS-RDPEFS specification, http://msdn.microsoft.com/en-us/library/cc241312(v=prot.10).
Frame Number
Source
Destination
Description
609
server
client
CoreServerAnnounceReq
615
client
server
CoreServerClientIDConfirm
616
client
server
CoreClientNameReq
617
server
client
ServerCapabilityReq
618
server
client
CoreServerClientIDConfirm
619
client
server
ServerCapabilityRsp
620
client
server
CoreDeviceListAnnounceReq
621
server
client
CoreUserLoggedOn
622
server
client
CoreDeviceAnnounceRsp
As discussed through dochelp, per section 3.2.5.1.2 Processing a Server Announce Request Message of MS-RDPEFS specification (http://msdn.microsoft.com/en-us/library/cc241404(v=prot.10).aspx), excerpt below, client should cancel all the outstanding IOs after this reconnection and TS is allowed to reuse the completionid which you observed in frame 627.
"... If this packet appears after a sequence of other packets, it is a signal that the server has reconnected to a new session and the whole sequence has been reset. The client SHOULD treat this packet as the beginning of a new sequence. The client SHOULD also cancel all outstanding requests and release previous references to all devices".
To conclude, the behavior you observed is an expected Windows server behavior and our MS-RDPEFS specification covers it.
Thanks.
Tarun Chopra | Escalation Engineer | Open Specifications Support Team
-
Tuesday, May 29, 2012 7:25 PM
Tarun,
I agree with you analysis that the Windows Server 2008 R2 is correctly behaving as specified in MS-RDPEFS.
Thank you for all of your help.
-- Steve Ross

