none
RDPESC: Windows Server 2008 R2 sends an extra SCARD_IOCTL after the client reconnects to an existing session with a smart card

    Pertanyaan

  • 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:
    RDPDrDeviceIOCompletion
    2 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:
    RDPDrDeviceIOCompletion
    2 "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:
    RDPDrDeviceIOCompletion
    7 Returns status for the one "SCM" reader of frame #2545.
    4286 61.734 client server RDPEFS:
    RDPDrDeviceIOCompletion
    3 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):
    If a response contains a CompletionId value that has not been sent or has been already
    completed, the implementation SHOULD terminate the virtual channel.
    I see this termination occur because the server never sends another IOCTL in the case of using the "xfreerdp" client.

    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

    17 April 2012 22:30

Jawaban

  • 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
    Number

    Source

    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:
    RDPDrDeviceIOCompletion

    0

    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

    29 Mei 2012 19:10
  • 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

    29 Mei 2012 19:25

Semua Balasan

  • 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

    18 April 2012 4:20
  • 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

    18 April 2012 15:07
  • 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

    18 April 2012 22:09
  • 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
    Number

    Source

    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:
    RDPDrDeviceIOCompletion

    0

    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

    29 Mei 2012 19:10
  • 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

    29 Mei 2012 19:25