/[rdesktop]/sourceforge.net/trunk/rdesktop/mcs.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /sourceforge.net/trunk/rdesktop/mcs.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 30 - (hide annotations)
Fri Sep 14 13:51:38 2001 UTC (22 years, 8 months ago) by matty
File MIME type: text/plain
File size: 7378 byte(s)
Portability fixes, including elimination of variable argument macros.
Rudimentary configure script.
Miscellaneous cleanups.

1 matty 3 /*
2     rdesktop: A Remote Desktop Protocol client.
3     Protocol services - Multipoint Communications Service
4 matty 30 Copyright (C) Matthew Chapman 1999-2001
5 matty 3
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
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19     */
20    
21 matty 10 #include "rdesktop.h"
22 matty 3
23 matty 10 uint16 mcs_userid;
24    
25     /* Parse an ASN.1 BER header */
26 matty 25 static BOOL
27     ber_parse_header(STREAM s, int tagval, int *length)
28 matty 3 {
29 matty 10 int tag, len;
30 matty 3
31 matty 10 if (tagval > 0xff)
32 matty 3 {
33 matty 10 in_uint16_be(s, tag);
34 matty 3 }
35 matty 10 else
36 matty 3 {
37 matty 24 in_uint8(s, tag)}
38 matty 3
39 matty 10 if (tag != tagval)
40 matty 3 {
41 matty 30 error("expected tag %d, got %d\n", tagval, tag);
42 matty 10 return False;
43 matty 3 }
44    
45 matty 10 in_uint8(s, len);
46 matty 3
47 matty 10 if (len & 0x80)
48 matty 3 {
49 matty 10 len &= ~0x80;
50     *length = 0;
51     while (len--)
52     next_be(s, *length);
53 matty 3 }
54 matty 24 else
55     *length = len;
56 matty 3
57 matty 10 return s_check(s);
58 matty 3 }
59    
60 matty 10 /* Output an ASN.1 BER header */
61 matty 25 static void
62     ber_out_header(STREAM s, int tagval, int length)
63 matty 3 {
64 matty 10 if (tagval > 0xff)
65 matty 3 {
66 matty 10 out_uint16_be(s, tagval);
67 matty 3 }
68 matty 10 else
69     {
70     out_uint8(s, tagval);
71     }
72 matty 3
73 matty 10 if (length >= 0x80)
74 matty 3 {
75 matty 10 out_uint8(s, 0x82);
76     out_uint16_be(s, length);
77 matty 3 }
78 matty 24 else
79     out_uint8(s, length);
80 matty 3 }
81    
82 matty 10 /* Output an ASN.1 BER integer */
83 matty 25 static void
84     ber_out_integer(STREAM s, int value)
85 matty 3 {
86 matty 10 ber_out_header(s, BER_TAG_INTEGER, 2);
87     out_uint16_be(s, value);
88 matty 3 }
89    
90 matty 10 /* Output a DOMAIN_PARAMS structure (ASN.1 BER) */
91 matty 25 static void
92     mcs_out_domain_params(STREAM s, int max_channels, int max_users,
93     int max_tokens, int max_pdusize)
94 matty 3 {
95 matty 10 ber_out_header(s, MCS_TAG_DOMAIN_PARAMS, 32);
96     ber_out_integer(s, max_channels);
97     ber_out_integer(s, max_users);
98     ber_out_integer(s, max_tokens);
99 matty 24 ber_out_integer(s, 1); /* num_priorities */
100     ber_out_integer(s, 0); /* min_throughput */
101     ber_out_integer(s, 1); /* max_height */
102 matty 10 ber_out_integer(s, max_pdusize);
103 matty 24 ber_out_integer(s, 2); /* ver_protocol */
104 matty 3 }
105    
106 matty 10 /* Parse a DOMAIN_PARAMS structure (ASN.1 BER) */
107 matty 25 static BOOL
108     mcs_parse_domain_params(STREAM s)
109 matty 3 {
110 matty 10 int length;
111 matty 3
112 matty 10 ber_parse_header(s, MCS_TAG_DOMAIN_PARAMS, &length);
113     in_uint8s(s, length);
114    
115     return s_check(s);
116 matty 3 }
117    
118 matty 10 /* Send an MCS_CONNECT_INITIAL message (ASN.1 BER) */
119 matty 25 static void
120     mcs_send_connect_initial(STREAM mcs_data)
121 matty 3 {
122 matty 10 int datalen = mcs_data->end - mcs_data->data;
123 matty 24 int length = 7 + 3 * 34 + 4 + datalen;
124 matty 10 STREAM s;
125 matty 3
126 matty 10 s = iso_init(length + 5);
127 matty 3
128 matty 10 ber_out_header(s, MCS_CONNECT_INITIAL, length);
129 matty 24 ber_out_header(s, BER_TAG_OCTET_STRING, 0); /* calling domain */
130     ber_out_header(s, BER_TAG_OCTET_STRING, 0); /* called domain */
131 matty 3
132 matty 10 ber_out_header(s, BER_TAG_BOOLEAN, 1);
133 matty 24 out_uint8(s, 0xff); /* upward flag */
134 matty 3
135 matty 24 mcs_out_domain_params(s, 2, 2, 0, 0xffff); /* target params */
136     mcs_out_domain_params(s, 1, 1, 1, 0x420); /* min params */
137     mcs_out_domain_params(s, 0xffff, 0xfc17, 0xffff, 0xffff); /* max params */
138 matty 3
139 matty 10 ber_out_header(s, BER_TAG_OCTET_STRING, datalen);
140     out_uint8p(s, mcs_data->data, datalen);
141 matty 3
142 matty 10 s_mark_end(s);
143     iso_send(s);
144 matty 3 }
145    
146 matty 10 /* Expect a MCS_CONNECT_RESPONSE message (ASN.1 BER) */
147 matty 25 static BOOL
148     mcs_recv_connect_response(STREAM mcs_data)
149 matty 3 {
150 matty 10 uint8 result;
151     int length;
152     STREAM s;
153 matty 3
154 matty 10 s = iso_recv();
155     if (s == NULL)
156 matty 7 return False;
157    
158 matty 10 ber_parse_header(s, MCS_CONNECT_RESPONSE, &length);
159 matty 3
160 matty 10 ber_parse_header(s, BER_TAG_RESULT, &length);
161     in_uint8(s, result);
162     if (result != 0)
163 matty 7 {
164 matty 30 error("MCS connect: %d\n", result);
165 matty 3 return False;
166     }
167    
168 matty 10 ber_parse_header(s, BER_TAG_INTEGER, &length);
169 matty 24 in_uint8s(s, length); /* connect id */
170 matty 10 mcs_parse_domain_params(s);
171    
172     ber_parse_header(s, BER_TAG_OCTET_STRING, &length);
173     if (length > mcs_data->size)
174 matty 3 {
175 matty 30 error("MCS data length %d\n", length);
176 matty 10 length = mcs_data->size;
177 matty 3 }
178    
179 matty 10 in_uint8a(s, mcs_data->data, length);
180     mcs_data->p = mcs_data->data;
181     mcs_data->end = mcs_data->data + length;
182 matty 3
183 matty 10 return s_check_end(s);
184 matty 3 }
185    
186 matty 10 /* Send an EDrq message (ASN.1 PER) */
187 matty 25 static void
188     mcs_send_edrq()
189 matty 3 {
190 matty 10 STREAM s;
191 matty 3
192 matty 10 s = iso_init(5);
193 matty 3
194 matty 10 out_uint8(s, (MCS_EDRQ << 2));
195 matty 24 out_uint16_be(s, 1); /* height */
196     out_uint16_be(s, 1); /* interval */
197 matty 3
198 matty 10 s_mark_end(s);
199     iso_send(s);
200 matty 3 }
201    
202 matty 10 /* Send an AUrq message (ASN.1 PER) */
203 matty 25 static void
204     mcs_send_aurq()
205 matty 3 {
206 matty 10 STREAM s;
207 matty 3
208 matty 10 s = iso_init(1);
209 matty 3
210 matty 10 out_uint8(s, (MCS_AURQ << 2));
211 matty 3
212 matty 10 s_mark_end(s);
213     iso_send(s);
214 matty 3 }
215    
216 matty 10 /* Expect a AUcf message (ASN.1 PER) */
217 matty 25 static BOOL
218     mcs_recv_aucf(uint16 *mcs_userid)
219 matty 3 {
220 matty 10 uint8 opcode, result;
221     STREAM s;
222 matty 3
223 matty 10 s = iso_recv();
224     if (s == NULL)
225 matty 3 return False;
226    
227 matty 10 in_uint8(s, opcode);
228     if ((opcode >> 2) != MCS_AUCF)
229 matty 3 {
230 matty 30 error("expected AUcf, got %d\n", opcode);
231 matty 3 return False;
232     }
233    
234 matty 10 in_uint8(s, result);
235     if (result != 0)
236     {
237 matty 30 error("AUrq: %d\n", result);
238 matty 10 return False;
239     }
240 matty 3
241 matty 10 if (opcode & 2)
242     in_uint16_be(s, *mcs_userid);
243 matty 3
244 matty 10 return s_check_end(s);
245 matty 3 }
246    
247 matty 10 /* Send a CJrq message (ASN.1 PER) */
248 matty 25 static void
249     mcs_send_cjrq(uint16 chanid)
250 matty 3 {
251 matty 10 STREAM s;
252 matty 3
253 matty 10 s = iso_init(5);
254 matty 3
255 matty 10 out_uint8(s, (MCS_CJRQ << 2));
256     out_uint16_be(s, mcs_userid);
257     out_uint16_be(s, chanid);
258    
259     s_mark_end(s);
260     iso_send(s);
261 matty 3 }
262    
263 matty 10 /* Expect a CJcf message (ASN.1 PER) */
264 matty 25 static BOOL
265     mcs_recv_cjcf()
266 matty 3 {
267 matty 10 uint8 opcode, result;
268     STREAM s;
269 matty 3
270 matty 10 s = iso_recv();
271     if (s == NULL)
272     return False;
273 matty 3
274 matty 10 in_uint8(s, opcode);
275     if ((opcode >> 2) != MCS_CJCF)
276     {
277 matty 30 error("expected CJcf, got %d\n", opcode);
278 matty 10 return False;
279     }
280 matty 3
281 matty 10 in_uint8(s, result);
282     if (result != 0)
283 matty 3 {
284 matty 30 error("CJrq: %d\n", result);
285 matty 3 return False;
286     }
287    
288 matty 24 in_uint8s(s, 4); /* mcs_userid, req_chanid */
289 matty 10 if (opcode & 2)
290 matty 24 in_uint8s(s, 2); /* join_chanid */
291 matty 3
292 matty 10 return s_check_end(s);
293 matty 3 }
294    
295 matty 10 /* Initialise an MCS transport data packet */
296 matty 25 STREAM
297     mcs_init(int length)
298 matty 3 {
299 matty 10 STREAM s;
300 matty 3
301 matty 10 s = iso_init(length + 8);
302     s_push_layer(s, mcs_hdr, 8);
303 matty 3
304 matty 10 return s;
305 matty 3 }
306    
307 matty 10 /* Send an MCS transport data packet */
308 matty 25 void
309     mcs_send(STREAM s)
310 matty 3 {
311 matty 10 uint16 length;
312 matty 3
313 matty 10 s_pop_layer(s, mcs_hdr);
314     length = s->end - s->p - 8;
315     length |= 0x8000;
316 matty 3
317 matty 10 out_uint8(s, (MCS_SDRQ << 2));
318     out_uint16_be(s, mcs_userid);
319     out_uint16_be(s, MCS_GLOBAL_CHANNEL);
320 matty 24 out_uint8(s, 0x70); /* flags */
321 matty 10 out_uint16_be(s, length);
322 matty 3
323 matty 10 iso_send(s);
324 matty 3 }
325    
326 matty 10 /* Receive an MCS transport data packet */
327 matty 25 STREAM
328     mcs_recv()
329 matty 3 {
330 matty 10 uint8 opcode, appid, length;
331     STREAM s;
332 matty 3
333 matty 10 s = iso_recv();
334     if (s == NULL)
335     return NULL;
336    
337     in_uint8(s, opcode);
338     appid = opcode >> 2;
339     if (appid != MCS_SDIN)
340 matty 3 {
341 matty 10 if (appid != MCS_DPUM)
342     {
343 matty 30 error("expected data, got %d\n", opcode);
344 matty 10 }
345     return NULL;
346 matty 3 }
347    
348 matty 24 in_uint8s(s, 5); /* userid, chanid, flags */
349 matty 10 in_uint8(s, length);
350     if (length & 0x80)
351 matty 24 in_uint8s(s, 1); /* second byte of length */
352 matty 3
353 matty 10 return s;
354 matty 3 }
355    
356 matty 10 /* Establish a connection up to the MCS layer */
357 matty 25 BOOL
358     mcs_connect(char *server, STREAM mcs_data)
359 matty 3 {
360 matty 10 if (!iso_connect(server))
361 matty 3 return False;
362    
363 matty 10 mcs_send_connect_initial(mcs_data);
364     if (!mcs_recv_connect_response(mcs_data))
365     goto error;
366 matty 3
367 matty 10 mcs_send_edrq();
368 matty 3
369 matty 10 mcs_send_aurq();
370     if (!mcs_recv_aucf(&mcs_userid))
371     goto error;
372 matty 3
373 matty 10 mcs_send_cjrq(mcs_userid + 1001);
374     if (!mcs_recv_cjcf())
375     goto error;
376 matty 3
377 matty 10 mcs_send_cjrq(MCS_GLOBAL_CHANNEL);
378     if (!mcs_recv_cjcf())
379     goto error;
380 matty 3
381 matty 10 return True;
382 matty 7
383 matty 24 error:
384 matty 10 iso_disconnect();
385     return False;
386 matty 3 }
387 matty 7
388 matty 10 /* Disconnect from the MCS layer */
389 matty 25 void
390     mcs_disconnect()
391 matty 10 {
392     iso_disconnect();
393     }

  ViewVC Help
Powered by ViewVC 1.1.26