FreeRDP
Loading...
Searching...
No Matches
TestServerChannels.c
1
20#include <winpr/crt.h>
21#include <winpr/wtsapi.h>
22
23#include <freerdp/peer.h>
24#include <freerdp/constants.h>
25#include <freerdp/channels/channels.h>
26#include <freerdp/channels/wtsvc.h>
27
28#include "../mcs.h"
29#include "../rdp.h"
30
31#define TEST_SVC_CHANNEL_ID 1004
32
33static BOOL recv_pdu(freerdp_peer* client, const BYTE* data, size_t size)
34{
35 return client->ReceiveChannelData(client, TEST_SVC_CHANNEL_ID, data, size,
36 CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, size);
37}
38
39/* A DYNVC PDU that ends before its ChannelId field must be rejected, see
40 * [MS-RDPEDYC] 2.2.2. */
41static BOOL test_truncated_dynvc_pdu(void)
42{
43 BOOL rc = FALSE;
44 HANDLE vcm = INVALID_HANDLE_VALUE;
45
46 freerdp_peer* client = calloc(1, sizeof(freerdp_peer));
47 if (!client)
48 return FALSE;
49
50 client->ContextSize = sizeof(rdpContext);
51 if (!freerdp_peer_context_new(client))
52 goto fail;
53
54 rdpMcs* mcs = client->context->rdp->mcs;
55 mcs->channelCount = 1;
56 (void)strncpy(mcs->channels[0].Name, DRDYNVC_SVC_CHANNEL_NAME, CHANNEL_NAME_LEN);
57 mcs->channels[0].ChannelId = TEST_SVC_CHANNEL_ID;
58 mcs->channels[0].joined = TRUE;
59
60 vcm = WTSOpenServerA((LPSTR)client->context);
61 if (!vcm || (vcm == INVALID_HANDLE_VALUE))
62 goto fail;
63
64 if (!WTSVirtualChannelManagerOpen(vcm))
65 goto fail;
66
67 /* DYNVC_CAPS_RSP, moves the drdynvc channel to DRDYNVC_STATE_READY */
68 const BYTE capsRsp[] = { 0x50, 0x00, 0x01, 0x00 };
69 if (!recv_pdu(client, capsRsp, sizeof(capsRsp)))
70 goto fail;
71
72 HANDLE dvc = WTSVirtualChannelOpenEx(1, "testdvc", WTS_CHANNEL_OPTION_DYNAMIC);
73 if (!dvc)
74 goto fail;
75
76 /* DYNVC_CREATE_RSP for ChannelId 1, HRESULT 0 */
77 const BYTE createRsp[] = { 0x10, 0x01, 0x00, 0x00, 0x00, 0x00 };
78 if (!recv_pdu(client, createRsp, sizeof(createRsp)))
79 goto fail;
80
81 /* Same PDU truncated to its header byte: the ChannelId is no longer part of
82 * the received data. */
83 const BYTE truncated[] = { 0x10 };
84 if (recv_pdu(client, truncated, sizeof(truncated)))
85 {
86 (void)fprintf(stderr, "truncated DYNVC PDU accepted\n");
87 goto fail;
88 }
89
90 rc = TRUE;
91fail:
92 if (vcm != INVALID_HANDLE_VALUE)
93 WTSCloseServer(vcm);
94 freerdp_peer_context_free(client);
95 free(client);
96 return rc;
97}
98
99int TestServerChannels(WINPR_ATTR_UNUSED int argc, WINPR_ATTR_UNUSED char* argv[])
100{
101 WTSRegisterWtsApiFunctionTable(FreeRDP_InitWtsApi());
102
103 if (!test_truncated_dynvc_pdu())
104 return -1;
105
106 return 0;
107}