ReactOS  0.4.12-dev-36-g472787f
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 
24 extern VCHANNEL g_channels[];
25 extern unsigned int g_num_channels;
26 
27 
28 /* Output a DOMAIN_PARAMS structure (ASN.1 BER) */
29 static void
30 mcs_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) */
44 static RD_BOOL
46 {
47  int length;
48 
50  in_uint8s(s, length);
51 
52  return s_check(s);
53 }
54 
55 /* Send an MCS_CONNECT_INITIAL message (ASN.1 BER) */
56 static 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 
81  s_mark_end(s);
82  iso_send(s);
83 }
84 
85 /* Expect a MCS_CONNECT_RESPONSE message (ASN.1 BER) */
86 static RD_BOOL
88 {
89  uint8 result;
90  int length;
91  STREAM s;
92 
93  s = iso_recv(NULL);
94  if (s == NULL)
95  return False;
96 
98 
99  ber_parse_header(s, BER_TAG_RESULT, &length);
100  in_uint8(s, result);
101  if (result != 0)
102  {
103  error("MCS connect: %d\n", result);
104  return False;
105  }
106 
107  ber_parse_header(s, BER_TAG_INTEGER, &length);
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) */
130 static 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) */
146 static 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) */
160 static RD_BOOL
161 mcs_recv_aucf(uint16 * mcs_userid)
162 {
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) */
191 static 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) */
209 static RD_BOOL
211 {
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 */
241 STREAM
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 */
253 void
255 {
256  uint16 length;
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 */
266  out_uint16_be(s, length);
267 
268  iso_send(s);
269 }
270 
271 /* Send an MCS transport data packet to the global channel */
272 void
274 {
276 }
277 
278 /* Receive an MCS transport data packet */
279 STREAM
280 mcs_recv(uint16 * channel, uint8 * rdpver)
281 {
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 
310 RD_BOOL
311 mcs_connect_start(char *server, char *username, char *domain, char *password,
312  RD_BOOL reconnect, uint32 * selected_protocol)
313 {
314  return iso_connect(server, username, domain, password, reconnect, selected_protocol);
315 }
316 
317 RD_BOOL
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 
326  mcs_send_edrq();
327 
328  mcs_send_aurq();
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:
350  iso_disconnect();
351  return False;
352 }
353 
354 /* Disconnect from the MCS layer */
355 void
357 {
358  iso_disconnect();
359 }
360 
361 /* reset the state of the mcs layer */
362 void
364 {
365  g_mcs_userid = 0;
366  iso_reset_state();
367 }
#define out_uint8p(s, v, n)
Definition: parse.h:93
static void mcs_send_aurq(void)
Definition: mcs.c:147
static rfbScreenInfoPtr server
Definition: vnc.c:74
#define error(str)
Definition: mkdosfs.c:1605
void mcs_send_to_channel(STREAM s, uint16 channel)
Definition: mcs.c:254
unsigned int uint32
Definition: types.h:32
#define MCS_CONNECT_INITIAL
Definition: constants.h:74
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint 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 GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint GLenum GLfloat GLenum GLint GLenum GLsizei GLenum GLboolean GLenum GLdouble GLenum GLfloat GLenum GLenum GLfloat GLenum GLenum GLdouble GLenum GLenum GLint GLenum GLenum GLint GLenum GLuint GLenum GLvoid const GLubyte GLenum GLenum GLenum GLint GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLvoid GLenum GLint GLenum GLint GLenum GLenum GLint GLuint GLdouble GLfloat GLint GLshort GLubyte GLenum GLuint GLenum const GLfloat GLenum const GLint GLenum GLenum const GLfloat GLenum GLenum const GLint GLfloat const GLfloat GLenum opcode
Definition: glfuncs.h:172
static RD_BOOL mcs_recv_connect_response(STREAM mcs_data)
Definition: mcs.c:87
RD_BOOL mcs_connect_start(char *server, char *username, char *domain, char *password, RD_BOOL reconnect, uint32 *selected_protocol)
Definition: mcs.c:311
unsigned char * data
Definition: parse.h:26
int const JOCTET unsigned int datalen
Definition: jpeglib.h:1027
static void mcs_send_connect_initial(STREAM mcs_data)
Definition: mcs.c:57
VCHANNEL g_channels[]
Definition: channels.c:32
#define MCS_TAG_DOMAIN_PARAMS
Definition: constants.h:85
#define s_check(s)
Definition: parse.h:42
uint16 g_mcs_userid
Definition: mcs.c:23
#define MCS_GLOBAL_CHANNEL
Definition: constants.h:87
#define out_uint8(s, v)
Definition: parse.h:92
void mcs_reset_state(void)
Definition: mcs.c:363
GLenum GLclampf GLint i
Definition: glfuncs.h:14
static void mcs_out_domain_params(STREAM s, int max_channels, int max_users, int max_tokens, int max_pdusize)
Definition: mcs.c:30
void iso_disconnect(void)
Definition: iso.c:362
#define s_pop_layer(s, h)
Definition: parse.h:40
char * appid
Definition: mkisofs.c:161
smooth NULL
Definition: ftsmooth.c:416
#define in_uint8s(s, n)
Definition: parse.h:91
int RD_BOOL
Definition: types.h:21
unsigned int g_num_channels
Definition: channels.c:33
STREAM iso_init(int length)
Definition: iso.c:150
#define s_check_end(s)
Definition: parse.h:44
static void ber_out_header(STREAM s, int tagval, int length)
Definition: mcs.c:60
static WCHAR username[]
Definition: url.c:32
#define True
Definition: types.h:24
#define False
Definition: types.h:25
static void mcs_send_cjrq(uint16 chanid)
Definition: mcs.c:192
#define MCS_USERCHANNEL_BASE
Definition: constants.h:88
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
STREAM iso_recv(uint8 *rdpver)
Definition: iso.c:182
static void mcs_send_edrq(void)
Definition: mcs.c:131
void iso_send(STREAM s)
Definition: iso.c:162
unsigned char * end
Definition: parse.h:25
unsigned char uint8
Definition: types.h:28
static void ber_out_integer(STREAM s, int value)
Definition: mcs.c:82
#define BER_TAG_INTEGER
Definition: constants.h:78
static RD_BOOL mcs_recv_aucf(uint16 *mcs_userid)
Definition: mcs.c:161
STREAM mcs_init(int length)
Definition: mcs.c:242
RD_BOOL iso_connect(char *server, char *username, char *domain, char *password, RD_BOOL reconnect, uint32 *selected_protocol)
Definition: iso.c:203
Definition: parse.h:22
T1_FIELD_DICT_PRIVATE password
Definition: t1tokens.h:64
#define MCS_CONNECT_RESPONSE
Definition: constants.h:75
STREAM mcs_recv(uint16 *channel, uint8 *rdpver)
Definition: mcs.c:280
static RD_BOOL mcs_recv_cjcf(void)
Definition: mcs.c:210
GLdouble s
Definition: gl.h:2039
void sec_process_mcs_data(STREAM s)
Definition: secure.c:856
#define BER_TAG_RESULT
Definition: constants.h:80
RD_BOOL mcs_connect_finalize(STREAM mcs_data)
Definition: mcs.c:318
static BOOL ber_parse_header(STREAM s, int tagval, int *length)
Definition: mcs.c:25
#define s_push_layer(s, h, n)
Definition: parse.h:39
#define BER_TAG_OCTET_STRING
Definition: constants.h:79
#define DEBUG_RDP5(args)
Definition: rdesktop.h:141
static RD_BOOL mcs_parse_domain_params(STREAM s)
Definition: mcs.c:45
void iso_reset_state(void)
Definition: iso.c:370
unsigned short uint16
Definition: types.h:30
#define in_uint8(s, v)
Definition: parse.h:88
unsigned char * p
Definition: parse.h:24
#define out_uint16_be(s, v)
Definition: parse.h:77
void mcs_send(STREAM s)
Definition: mcs.c:273
#define BER_TAG_BOOLEAN
Definition: constants.h:77
#define s_mark_end(s)
Definition: parse.h:41
GLuint64EXT * result
Definition: glext.h:11304
void mcs_disconnect(void)
Definition: mcs.c:356
#define in_uint16_be(s, v)
Definition: parse.h:75