FreeRDP
Loading...
Searching...
No Matches
TestMcs.c
1
18#include <winpr/crt.h>
19#include <winpr/stream.h>
20
21#include <freerdp/peer.h>
22#include <freerdp/transport_io.h>
23
24#include "../mcs.h"
25#include "../rdp.h"
26
27#define TPKT_X224_HEADER_LENGTH 7
28#define DISCONNECT_PROVIDER_ULTIMATUM_LENGTH 9
29
30static BYTE captured[DISCONNECT_PROVIDER_ULTIMATUM_LENGTH] = WINPR_C_ARRAY_INIT;
31static size_t capturedLength = 0;
32
33static int capture_write_pdu(WINPR_ATTR_UNUSED rdpTransport* transport, wStream* s)
34{
35 const size_t length = Stream_GetPosition(s);
36 if (length > sizeof(captured))
37 return -1;
38
39 memcpy(captured, Stream_Buffer(s), length);
40 capturedLength = length;
41 return (int)length;
42}
43
44/* [MS-RDPBCGR] 2.2.2.3 gives 21 80 for rn-user-requested (3), the other values
45 * follow from the aligned PER encoding of the 3 bit reason. */
46static BOOL test_disconnect_provider_ultimatum(rdpMcs* mcs, enum Disconnect_Ultimatum reason,
47 BYTE b1, BYTE b2)
48{
49 capturedLength = 0;
50 if (!mcs_send_disconnect_provider_ultimatum(mcs, reason))
51 {
52 (void)fprintf(stderr, "failed to send reason %d\n", reason);
53 return FALSE;
54 }
55
56 if (capturedLength != DISCONNECT_PROVIDER_ULTIMATUM_LENGTH)
57 {
58 (void)fprintf(stderr, "reason %d: unexpected length %" PRIuz "\n", reason, capturedLength);
59 return FALSE;
60 }
61
62 if ((captured[TPKT_X224_HEADER_LENGTH] != b1) || (captured[TPKT_X224_HEADER_LENGTH + 1] != b2))
63 {
64 (void)fprintf(stderr,
65 "reason %d: got %02" PRIx8 " %02" PRIx8 ", expected %02" PRIx8 " %02" PRIx8
66 "\n",
67 reason, captured[TPKT_X224_HEADER_LENGTH],
68 captured[TPKT_X224_HEADER_LENGTH + 1], b1, b2);
69 return FALSE;
70 }
71
72 wStream sbuffer = WINPR_C_ARRAY_INIT;
73 wStream* s = Stream_StaticConstInit(&sbuffer, captured, capturedLength);
74 if (!Stream_SetPosition(s, TPKT_X224_HEADER_LENGTH + 1))
75 return FALSE;
76
77 int decoded = -1;
78 if (!mcs_recv_disconnect_provider_ultimatum(mcs, s, &decoded))
79 {
80 (void)fprintf(stderr, "failed to receive reason %d\n", reason);
81 return FALSE;
82 }
83
84 if (decoded != (int)reason)
85 {
86 (void)fprintf(stderr, "reason %d decoded as %d\n", reason, decoded);
87 return FALSE;
88 }
89
90 return TRUE;
91}
92
93int TestMcs(WINPR_ATTR_UNUSED int argc, WINPR_ATTR_UNUSED char* argv[])
94{
95 int rc = -1;
96
97 freerdp_peer* client = calloc(1, sizeof(freerdp_peer));
98 if (!client)
99 return -1;
100
101 client->ContextSize = sizeof(rdpContext);
102 if (!freerdp_peer_context_new(client))
103 goto fail;
104
105 {
106 const rdpTransportIo* io = freerdp_get_io_callbacks(client->context);
107 if (!io)
108 goto fail;
109
110 rdpTransportIo capture = *io;
111 capture.WritePdu = capture_write_pdu;
112 if (!freerdp_set_io_callbacks(client->context, &capture))
113 goto fail;
114 }
115
116 {
117 rdpMcs* mcs = client->context->rdp->mcs;
118 if (!test_disconnect_provider_ultimatum(mcs, Disconnect_Ultimatum_domain_disconnected, 0x20,
119 0x00))
120 goto fail;
121 if (!test_disconnect_provider_ultimatum(mcs, Disconnect_Ultimatum_provider_initiated, 0x20,
122 0x80))
123 goto fail;
124 if (!test_disconnect_provider_ultimatum(mcs, Disconnect_Ultimatum_token_purged, 0x21, 0x00))
125 goto fail;
126 if (!test_disconnect_provider_ultimatum(mcs, Disconnect_Ultimatum_user_requested, 0x21,
127 0x80))
128 goto fail;
129 if (!test_disconnect_provider_ultimatum(mcs, Disconnect_Ultimatum_channel_purged, 0x22,
130 0x00))
131 goto fail;
132 }
133
134 rc = 0;
135fail:
136 freerdp_peer_context_free(client);
137 free(client);
138 return rc;
139}