ReactOS 0.4.15-dev-7958-gcd0bb1a
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 <matthewc.unsw.edu.au> 1999-2008
5 Copyright 2005-2011 Peter Astrand <astrand@cendio.se> for Cendio AB
6
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
19*/
20
21#include "precomp.h"
22
24extern VCHANNEL g_channels[];
25extern unsigned int g_num_channels;
26
27
28/* Output a DOMAIN_PARAMS structure (ASN.1 BER) */
29static void
30mcs_out_domain_params(STREAM s, int max_channels, int max_users, int max_tokens, int max_pdusize)
31{
33 ber_out_integer(s, max_channels);
34 ber_out_integer(s, max_users);
35 ber_out_integer(s, max_tokens);
36 ber_out_integer(s, 1); /* num_priorities */
37 ber_out_integer(s, 0); /* min_throughput */
38 ber_out_integer(s, 1); /* max_height */
39 ber_out_integer(s, max_pdusize);
40 ber_out_integer(s, 2); /* ver_protocol */
41}
42
43/* Parse a DOMAIN_PARAMS structure (ASN.1 BER) */
44static RD_BOOL
46{
47 int length;
48
51
52 return s_check(s);
53}
54
55/* Send an MCS_CONNECT_INITIAL message (ASN.1 BER) */
56static void
58{
59 int datalen = mcs_data->end - mcs_data->data;
60 int length = 9 + 3 * 34 + 4 + datalen;
61 STREAM s;
62
63 s = iso_init(length + 5);
64
66 ber_out_header(s, BER_TAG_OCTET_STRING, 1); /* calling domain */
67 out_uint8(s, 1);
68 ber_out_header(s, BER_TAG_OCTET_STRING, 1); /* called domain */
69 out_uint8(s, 1);
70
72 out_uint8(s, 0xff); /* upward flag */
73
74 mcs_out_domain_params(s, 34, 2, 0, 0xffff); /* target params */
75 mcs_out_domain_params(s, 1, 1, 1, 0x420); /* min params */
76 mcs_out_domain_params(s, 0xffff, 0xfc17, 0xffff, 0xffff); /* max params */
77
79 out_uint8p(s, mcs_data->data, datalen);
80
82 iso_send(s);
83}
84
85/* Expect a MCS_CONNECT_RESPONSE message (ASN.1 BER) */
86static RD_BOOL
88{
90 int length;
91 STREAM s;
92
93 s = iso_recv(NULL);
94 if (s == NULL)
95 return False;
96
98
100 in_uint8(s, result);
101 if (result != 0)
102 {
103 error("MCS connect: %d\n", result);
104 return False;
105 }
106
108 in_uint8s(s, length); /* connect id */
110
112
114 /*
115 if (length > mcs_data->size)
116 {
117 error("MCS data length %d, expected %d\n", length,
118 mcs_data->size);
119 length = mcs_data->size;
120 }
121
122 in_uint8a(s, mcs_data->data, length);
123 mcs_data->p = mcs_data->data;
124 mcs_data->end = mcs_data->data + length;
125 */
126 return s_check_end(s);
127}
128
129/* Send an EDrq message (ASN.1 PER) */
130static void
132{
133 STREAM s;
134
135 s = iso_init(5);
136
137 out_uint8(s, (MCS_EDRQ << 2));
138 out_uint16_be(s, 1); /* height */
139 out_uint16_be(s, 1); /* interval */
140
141 s_mark_end(s);
142 iso_send(s);
143}
144
145/* Send an AUrq message (ASN.1 PER) */
146static void
148{
149 STREAM s;
150
151 s = iso_init(1);
152
153 out_uint8(s, (MCS_AURQ << 2));
154
155 s_mark_end(s);
156 iso_send(s);
157}
158
159/* Expect a AUcf message (ASN.1 PER) */
160static RD_BOOL
162{
163 uint8 opcode, result;
164 STREAM s;
165
166 s = iso_recv(NULL);
167 if (s == NULL)
168 return False;
169
170 in_uint8(s, opcode);
171 if ((opcode >> 2) != MCS_AUCF)
172 {
173 error("expected AUcf, got %d\n", opcode);
174 return False;
175 }
176
177 in_uint8(s, result);
178 if (result != 0)
179 {
180 error("AUrq: %d\n", result);
181 return False;
182 }
183
184 if (opcode & 2)
185 in_uint16_be(s, *mcs_userid);
186
187 return s_check_end(s);
188}
189
190/* Send a CJrq message (ASN.1 PER) */
191static void
193{
194 STREAM s;
195
196 DEBUG_RDP5(("Sending CJRQ for channel #%d\n", chanid));
197
198 s = iso_init(5);
199
200 out_uint8(s, (MCS_CJRQ << 2));
202 out_uint16_be(s, chanid);
203
204 s_mark_end(s);
205 iso_send(s);
206}
207
208/* Expect a CJcf message (ASN.1 PER) */
209static RD_BOOL
211{
212 uint8 opcode, result;
213 STREAM s;
214
215 s = iso_recv(NULL);
216 if (s == NULL)
217 return False;
218
219 in_uint8(s, opcode);
220 if ((opcode >> 2) != MCS_CJCF)
221 {
222 error("expected CJcf, got %d\n", opcode);
223 return False;
224 }
225
226 in_uint8(s, result);
227 if (result != 0)
228 {
229 error("CJrq: %d\n", result);
230 return False;
231 }
232
233 in_uint8s(s, 4); /* mcs_userid, req_chanid */
234 if (opcode & 2)
235 in_uint8s(s, 2); /* join_chanid */
236
237 return s_check_end(s);
238}
239
240/* Initialise an MCS transport data packet */
241STREAM
243{
244 STREAM s;
245
246 s = iso_init(length + 8);
247 s_push_layer(s, mcs_hdr, 8);
248
249 return s;
250}
251
252/* Send an MCS transport data packet to a specific channel */
253void
255{
257
258 s_pop_layer(s, mcs_hdr);
259 length = s->end - s->p - 8;
260 length |= 0x8000;
261
262 out_uint8(s, (MCS_SDRQ << 2));
264 out_uint16_be(s, channel);
265 out_uint8(s, 0x70); /* flags */
267
268 iso_send(s);
269}
270
271/* Send an MCS transport data packet to the global channel */
272void
274{
276}
277
278/* Receive an MCS transport data packet */
279STREAM
280mcs_recv(uint16 * channel, uint8 * rdpver)
281{
282 uint8 opcode, appid, length;
283 STREAM s;
284
285 s = iso_recv(rdpver);
286 if (s == NULL)
287 return NULL;
288 if (rdpver != NULL)
289 if (*rdpver != 3)
290 return s;
291 in_uint8(s, opcode);
292 appid = opcode >> 2;
293 if (appid != MCS_SDIN)
294 {
295 if (appid != MCS_DPUM)
296 {
297 error("expected data, got %d\n", opcode);
298 }
299 return NULL;
300 }
301 in_uint8s(s, 2); /* userid */
302 in_uint16_be(s, *channel);
303 in_uint8s(s, 1); /* flags */
304 in_uint8(s, length);
305 if (length & 0x80)
306 in_uint8s(s, 1); /* second byte of length */
307 return s;
308}
309
312 RD_BOOL reconnect, uint32 * selected_protocol)
313{
314 return iso_connect(server, username, domain, password, reconnect, selected_protocol);
315}
316
319{
320 unsigned int i;
321
322 mcs_send_connect_initial(mcs_data);
323 if (!mcs_recv_connect_response(mcs_data))
324 goto error;
325
327
330 goto error;
331
333
334 if (!mcs_recv_cjcf())
335 goto error;
336
338 if (!mcs_recv_cjcf())
339 goto error;
340
341 for (i = 0; i < g_num_channels; i++)
342 {
343 mcs_send_cjrq(g_channels[i].mcs_id);
344 if (!mcs_recv_cjcf())
345 goto error;
346 }
347 return True;
348
349 error:
351 return False;
352}
353
354/* Disconnect from the MCS layer */
355void
357{
359}
360
361/* reset the state of the mcs layer */
362void
364{
365 g_mcs_userid = 0;
367}
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
RD_BOOL mcs_connect_start(char *server, char *username, char *domain, char *password, RD_BOOL reconnect, uint32 *selected_protocol)
Definition: mcs.c:311
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
unsigned int g_num_channels
Definition: channels.c:33
static void mcs_send_connect_initial(STREAM mcs_data)
Definition: mcs.c:57
uint16 g_mcs_userid
Definition: mcs.c:23
VCHANNEL g_channels[]
Definition: channels.c:32
RD_BOOL mcs_connect_finalize(STREAM mcs_data)
Definition: mcs.c:318
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 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
unsigned int uint32
Definition: types.h:32
#define False
Definition: types.h:25
int RD_BOOL
Definition: types.h:21
#define True
Definition: types.h:24
unsigned char uint8
Definition: types.h:28
#define NULL
Definition: types.h:112
GLdouble s
Definition: gl.h:2039
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
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
static WCHAR password[]
Definition: url.c:33
static WCHAR username[]
Definition: url.c:32
Definition: cookie.c:42
Definition: parse.h:23
unsigned char * end
Definition: parse.h:25
unsigned char * data
Definition: parse.h:26
static rfbScreenInfoPtr server
Definition: vnc.c:74