ReactOS 0.4.15-dev-7906-g1b85a5f
mcs.c
Go to the documentation of this file.
1/* -*- c-basic-offset: 8 -*-
2 rdesktop: A Remote Desktop Protocol client.
3 Protocol services - Multipoint Communications Service
4 Copyright (C) Matthew Chapman 1999-2005
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20
21#include "rdesktop.h"
22
23/* Parse an ASN.1 BER header */
24static BOOL
25ber_parse_header(STREAM s, int tagval, int *length)
26{
27 int tag, len;
28
29 if (tagval > 0xff)
30 {
32 }
33 else
34 {
35 in_uint8(s, tag)}
36
37 if (tag != tagval)
38 {
39 error("expected tag %d, got %d\n", tagval, tag);
40 return False;
41 }
42
43 in_uint8(s, len);
44
45 if (len & 0x80)
46 {
47 len &= ~0x80;
48 *length = 0;
49 while (len--)
50 next_be(s, *length);
51 }
52 else
53 *length = len;
54
55 return s_check(s);
56}
57
58/* Output an ASN.1 BER header */
59static void
60ber_out_header(STREAM s, int tagval, int length)
61{
62 if (tagval > 0xff)
63 {
64 out_uint16_be(s, tagval);
65 }
66 else
67 {
68 out_uint8(s, tagval);
69 }
70
71 if (length >= 0x80)
72 {
73 out_uint8(s, 0x82);
75 }
76 else
78}
79
80/* Output an ASN.1 BER integer */
81static void
83{
86}
87
88/* Output a DOMAIN_PARAMS structure (ASN.1 BER) */
89static void
90mcs_out_domain_params(STREAM s, int max_channels, int max_users, int max_tokens, int max_pdusize)
91{
93 ber_out_integer(s, max_channels);
94 ber_out_integer(s, max_users);
95 ber_out_integer(s, max_tokens);
96 ber_out_integer(s, 1); /* num_priorities */
97 ber_out_integer(s, 0); /* min_throughput */
98 ber_out_integer(s, 1); /* max_height */
99 ber_out_integer(s, max_pdusize);
100 ber_out_integer(s, 2); /* ver_protocol */
101}
102
103/* Parse a DOMAIN_PARAMS structure (ASN.1 BER) */
104static BOOL
106{
107 int length;
108
111
112 return s_check(s);
113}
114
115/* Send an MCS_CONNECT_INITIAL message (ASN.1 BER) */
116static BOOL
118{
119 int datalen = (uint16)(mcs_data->end - mcs_data->data);
120 int length = 9 + 3 * 34 + 4 + datalen;
121 STREAM s;
122
123 s = iso_init(This, length + 5);
124
125 if(s == NULL)
126 return False;
127
129 ber_out_header(s, BER_TAG_OCTET_STRING, 1); /* calling domain */
130 out_uint8(s, 1);
131 ber_out_header(s, BER_TAG_OCTET_STRING, 1); /* called domain */
132 out_uint8(s, 1);
133
135 out_uint8(s, 0xff); /* upward flag */
136
137 mcs_out_domain_params(s, 34, 2, 0, 0xffff); /* target params */
138 mcs_out_domain_params(s, 1, 1, 1, 0x420); /* min params */
139 mcs_out_domain_params(s, 0xffff, 0xfc17, 0xffff, 0xffff); /* max params */
140
142 out_uint8p(s, mcs_data->data, datalen);
143
144 s_mark_end(s);
145 return iso_send(This, s);
146}
147
148/* Expect a MCS_CONNECT_RESPONSE message (ASN.1 BER) */
149static BOOL
151{
153 int length;
154 STREAM s;
155
156 s = iso_recv(This, NULL);
157 if (s == NULL)
158 return False;
159
161
163 in_uint8(s, result);
164 if (result != 0)
165 {
166 error("MCS connect: %d\n", result);
167 return False;
168 }
169
171 in_uint8s(s, length); /* connect id */
173
175
177 /*
178 if (length > mcs_data->size)
179 {
180 error("MCS data length %d, expected %d\n", length,
181 mcs_data->size);
182 length = mcs_data->size;
183 }
184
185 in_uint8a(s, mcs_data->data, length);
186 mcs_data->p = mcs_data->data;
187 mcs_data->end = mcs_data->data + length;
188 */
189 return s_check_end(s);
190}
191
192/* Send an EDrq message (ASN.1 PER) */
193static BOOL
195{
196 STREAM s;
197
198 s = iso_init(This, 5);
199
200 if(s == NULL)
201 return False;
202
203 out_uint8(s, (MCS_EDRQ << 2));
204 out_uint16_be(s, 1); /* height */
205 out_uint16_be(s, 1); /* interval */
206
207 s_mark_end(s);
208 return iso_send(This, s);
209}
210
211/* Send an AUrq message (ASN.1 PER) */
212static BOOL
214{
215 STREAM s;
216
217 s = iso_init(This, 1);
218
219 if(s == NULL)
220 return False;
221
222 out_uint8(s, (MCS_AURQ << 2));
223
224 s_mark_end(s);
225 return iso_send(This, s);
226}
227
228/* Expect a AUcf message (ASN.1 PER) */
229static BOOL
231{
232 uint8 opcode, result;
233 STREAM s;
234
235 s = iso_recv(This, NULL);
236 if (s == NULL)
237 return False;
238
239 in_uint8(s, opcode);
240 if ((opcode >> 2) != MCS_AUCF)
241 {
242 error("expected AUcf, got %d\n", opcode);
243 return False;
244 }
245
246 in_uint8(s, result);
247 if (result != 0)
248 {
249 error("AUrq: %d\n", result);
250 return False;
251 }
252
253 if (opcode & 2)
254 in_uint16_be(s, *mcs_userid);
255
256 return s_check_end(s);
257}
258
259/* Send a CJrq message (ASN.1 PER) */
260static BOOL
262{
263 STREAM s;
264
265 DEBUG_RDP5(("Sending CJRQ for channel #%d\n", chanid));
266
267 s = iso_init(This, 5);
268
269 if(s == NULL)
270 return False;
271
272 out_uint8(s, (MCS_CJRQ << 2));
273 out_uint16_be(s, This->mcs_userid);
274 out_uint16_be(s, chanid);
275
276 s_mark_end(s);
277 return iso_send(This, s);
278}
279
280/* Expect a CJcf message (ASN.1 PER) */
281static BOOL
283{
284 uint8 opcode, result;
285 STREAM s;
286
287 s = iso_recv(This, NULL);
288 if (s == NULL)
289 return False;
290
291 in_uint8(s, opcode);
292 if ((opcode >> 2) != MCS_CJCF)
293 {
294 error("expected CJcf, got %d\n", opcode);
295 return False;
296 }
297
298 in_uint8(s, result);
299 if (result != 0)
300 {
301 error("CJrq: %d\n", result);
302 return False;
303 }
304
305 in_uint8s(s, 4); /* mcs_userid, req_chanid */
306 if (opcode & 2)
307 in_uint8s(s, 2); /* join_chanid */
308
309 return s_check_end(s);
310}
311
312/* Initialise an MCS transport data packet */
313STREAM
315{
316 STREAM s;
317
318 s = iso_init(This, length + 8);
319
320 if(s == NULL)
321 return NULL;
322
323 s_push_layer(s, mcs_hdr, 8);
324
325 return s;
326}
327
328/* Send an MCS transport data packet to a specific channel */
329BOOL
331{
333
334 s_pop_layer(s, mcs_hdr);
335 length = (uint16)(s->end - s->p - 8);
336 length |= 0x8000;
337
338 out_uint8(s, (MCS_SDRQ << 2));
339 out_uint16_be(s, This->mcs_userid);
340 out_uint16_be(s, channel);
341 out_uint8(s, 0x70); /* flags */
343
344 return iso_send(This, s);
345}
346
347/* Send an MCS transport data packet to the global channel */
348BOOL
350{
352}
353
354/* Receive an MCS transport data packet */
355STREAM
356mcs_recv(RDPCLIENT * This, uint16 * channel, uint8 * rdpver)
357{
358 uint8 opcode, appid, length;
359 STREAM s;
360
361 s = iso_recv(This, rdpver);
362 if (s == NULL)
363 return NULL;
364 if (rdpver != NULL)
365 if (*rdpver != 3)
366 return s;
367 in_uint8(s, opcode);
368 appid = opcode >> 2;
369 if (appid != MCS_SDIN)
370 {
371 if (appid != MCS_DPUM)
372 {
373 error("expected data, got %d\n", opcode);
374 }
375 return NULL;
376 }
377 in_uint8s(s, 2); /* userid */
378 in_uint16_be(s, *channel);
379 in_uint8s(s, 1); /* flags */
380 in_uint8(s, length);
381 if (length & 0x80)
382 in_uint8s(s, 1); /* second byte of length */
383 return s;
384}
385
386/* Establish a connection up to the MCS layer */
387BOOL
388mcs_connect(RDPCLIENT * This, char *server, char * cookie, STREAM mcs_data)
389{
390 unsigned int i;
391
393 return False;
394
395 if (!mcs_send_connect_initial(This, mcs_data) || !mcs_recv_connect_response(This, mcs_data))
396 goto error;
397
399 goto error;
400
401 if (!mcs_recv_aucf(This, &This->mcs_userid))
402 goto error;
403
405 goto error;
406
408 goto error;
409
410 for (i = 0; i < This->num_channels; i++)
411 {
413 goto error;
414 }
415 return True;
416
417 error:
419 return False;
420}
421
422/* Establish a connection up to the MCS layer */
423BOOL
424mcs_reconnect(RDPCLIENT * This, char *server, char *cookie, STREAM mcs_data)
425{
426 unsigned int i;
427
429 return False;
430
431 if (!mcs_send_connect_initial(This, mcs_data) || !mcs_recv_connect_response(This, mcs_data))
432 goto error;
433
435 goto error;
436
437 if (!mcs_recv_aucf(This, &This->mcs_userid))
438 goto error;
439
441 goto error;
442
444 goto error;
445
446 for (i = 0; i < This->num_channels; i++)
447 {
449 goto error;
450 }
451 return True;
452
453 error:
455 return False;
456}
457
458/* Disconnect from the MCS layer */
459void
461{
463}
464
465/* reset the state of the mcs layer */
466void
468{
469 This->mcs_userid = 0;
471}
RD_BOOL ber_parse_header(STREAM s, int tagval, int *length)
Definition: asn.c:25
void ber_out_header(STREAM s, int tagval, int length)
Definition: asn.c:61
void ber_out_integer(STREAM s, int value)
Definition: asn.c:83
#define BER_TAG_RESULT
Definition: constants.h:80
#define BER_TAG_OCTET_STRING
Definition: constants.h:79
#define MCS_TAG_DOMAIN_PARAMS
Definition: constants.h:85
@ MCS_SDIN
Definition: constants.h:71
@ MCS_CJCF
Definition: constants.h:69
@ MCS_AURQ
Definition: constants.h:66
@ MCS_CJRQ
Definition: constants.h:68
@ MCS_EDRQ
Definition: constants.h:64
@ MCS_AUCF
Definition: constants.h:67
@ MCS_DPUM
Definition: constants.h:65
@ MCS_SDRQ
Definition: constants.h:70
#define MCS_CONNECT_INITIAL
Definition: constants.h:74
#define MCS_CONNECT_RESPONSE
Definition: constants.h:75
#define BER_TAG_BOOLEAN
Definition: constants.h:77
#define BER_TAG_INTEGER
Definition: constants.h:78
#define MCS_USERCHANNEL_BASE
Definition: constants.h:88
#define MCS_GLOBAL_CHANNEL
Definition: constants.h:87
void iso_reset_state(void)
Definition: iso.c:370
RD_BOOL iso_connect(char *server, char *username, char *domain, char *password, RD_BOOL reconnect, uint32 *selected_protocol)
Definition: iso.c:203
void iso_send(STREAM s)
Definition: iso.c:162
STREAM iso_init(int length)
Definition: iso.c:150
void iso_disconnect(void)
Definition: iso.c:362
STREAM iso_recv(uint8 *rdpver)
Definition: iso.c:182
static void mcs_send_cjrq(uint16 chanid)
Definition: mcs.c:192
STREAM mcs_init(int length)
Definition: mcs.c:242
void mcs_reset_state(void)
Definition: mcs.c:363
static void mcs_send_edrq(void)
Definition: mcs.c:131
static RD_BOOL mcs_recv_aucf(uint16 *mcs_userid)
Definition: mcs.c:161
STREAM mcs_recv(uint16 *channel, uint8 *rdpver)
Definition: mcs.c:280
static void mcs_send_aurq(void)
Definition: mcs.c:147
static RD_BOOL mcs_recv_connect_response(STREAM mcs_data)
Definition: mcs.c:87
void mcs_send(STREAM s)
Definition: mcs.c:273
void mcs_disconnect(void)
Definition: mcs.c:356
void mcs_send_to_channel(STREAM s, uint16 channel)
Definition: mcs.c:254
static RD_BOOL mcs_recv_cjcf(void)
Definition: mcs.c:210
static void mcs_send_connect_initial(STREAM mcs_data)
Definition: mcs.c:57
static void mcs_out_domain_params(STREAM s, int max_channels, int max_users, int max_tokens, int max_pdusize)
Definition: mcs.c:30
static RD_BOOL mcs_parse_domain_params(STREAM s)
Definition: mcs.c:45
#define s_mark_end(s)
Definition: parse.h:41
#define s_check(s)
Definition: parse.h:42
#define s_pop_layer(s, h)
Definition: parse.h:40
#define out_uint8(s, v)
Definition: parse.h:92
#define s_push_layer(s, h, n)
Definition: parse.h:39
#define out_uint16_be(s, v)
Definition: parse.h:77
#define s_check_end(s)
Definition: parse.h:44
#define in_uint8s(s, n)
Definition: parse.h:91
#define next_be(s, v)
Definition: parse.h:97
#define in_uint8(s, v)
Definition: parse.h:88
#define in_uint16_be(s, v)
Definition: parse.h:75
#define out_uint8p(s, v, n)
Definition: parse.h:93
void sec_process_mcs_data(STREAM s)
Definition: secure.c:856
#define DEBUG_RDP5(args)
Definition: rdesktop.h:141
unsigned short uint16
Definition: types.h:30
#define False
Definition: types.h:25
#define True
Definition: types.h:24
unsigned char uint8
Definition: types.h:28
#define NULL
Definition: types.h:112
unsigned int BOOL
Definition: ntddk_ex.h:94
GLdouble s
Definition: gl.h:2039
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLenum GLsizei len
Definition: glext.h:6722
GLuint64EXT * result
Definition: glext.h:11304
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
int const JOCTET unsigned int datalen
Definition: jpeglib.h:1031
#define error(str)
Definition: mkdosfs.c:1605
char * appid
Definition: mkisofs.c:161
BOOL iso_reconnect(RDPCLIENT *This, char *server, char *cookie)
Definition: iso.c:204
BOOL mcs_connect(RDPCLIENT *This, char *server, char *cookie, STREAM mcs_data)
Definition: mcs.c:388
BOOL mcs_reconnect(RDPCLIENT *This, char *server, char *cookie, STREAM mcs_data)
Definition: mcs.c:424
Definition: cookie.c:34
Definition: parse.h:23
unsigned char * end
Definition: parse.h:25
unsigned char * data
Definition: parse.h:26
Definition: ecma_167.h:138
Definition: pdh_main.c:94
static rfbScreenInfoPtr server
Definition: vnc.c:74