/[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 9 - (hide annotations)
Tue Jul 25 12:34:29 2000 UTC (23 years, 9 months ago) by matty
File MIME type: text/plain
File size: 14284 byte(s)
Committing some awesome progress I made while overseas - this commit
really embodies a huge number of changes. We are now able to talk quite
fluently to a French NT Terminal Server - in normal usage only minor
font issues remain (handling of TEXT2 order is not perfect).

The next major hurdle is encryption, and it will be quite a big hurdle
- there seems to be some quite nasty session key stuff.

1 matty 3 /*
2     rdesktop: A Remote Desktop Protocol client.
3     Protocol services - Multipoint Communications Service
4     Copyright (C) Matthew Chapman 1999-2000
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
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     #include "includes.h"
22    
23     /* Establish a connection up to the MCS layer */
24     HCONN mcs_connect(char *server)
25     {
26     HCONN conn;
27     MCS_CONNECT_RESPONSE mcr;
28     MCS_AUCF aucf;
29    
30     if ((conn = iso_connect(server)) == NULL)
31     return NULL;
32    
33     mcs_send_connect_initial(conn);
34     if (!iso_recv(conn) || !mcs_io_connect_response(&conn->in, &mcr))
35     {
36 matty 9 ERROR("MCS error, expected Connect-Response\n");
37 matty 3 iso_disconnect(conn);
38     return NULL;
39     }
40    
41     if (mcr.result != 0)
42     {
43 matty 9 ERROR("MCS-Connect-Initial failed, result %d\n", mcr.result);
44 matty 3 iso_disconnect(conn);
45     return NULL;
46     }
47    
48     mcs_send_edrq(conn);
49    
50     mcs_send_aurq(conn);
51     if (!iso_recv(conn) || !mcs_io_aucf(&conn->in, &aucf))
52     {
53 matty 9 ERROR("MCS error, expected AUcf\n");
54 matty 3 mcs_disconnect(conn);
55     return NULL;
56     }
57    
58     if (aucf.result != 0)
59     {
60 matty 9 ERROR("AUrq failed, result %d\n", mcr.result);
61 matty 3 mcs_disconnect(conn);
62     return NULL;
63     }
64    
65     conn->mcs_userid = aucf.userid;
66    
67     if (!mcs_join_channel(conn, aucf.userid + 1001)
68     || !mcs_join_channel(conn, MCS_GLOBAL_CHANNEL))
69     {
70     mcs_disconnect(conn);
71     return NULL;
72     }
73    
74     return conn;
75     }
76    
77     BOOL mcs_join_channel(HCONN conn, uint16 chanid)
78     {
79     MCS_CJCF cjcf;
80    
81     mcs_send_cjrq(conn, chanid);
82     if (!iso_recv(conn) || !mcs_io_cjcf(&conn->in, &cjcf))
83     {
84 matty 9 ERROR("MCS error, expected CJcf\n");
85 matty 3 return False;
86     }
87    
88     if (cjcf.result != 0)
89     {
90 matty 9 ERROR("CJrq failed, result %d\n", cjcf.result);
91 matty 3 return False;
92     }
93    
94     return True;
95     }
96    
97     /* Disconnect from the MCS layer */
98     void mcs_disconnect(HCONN conn)
99     {
100     /* Not complete */
101     iso_disconnect(conn);
102     }
103    
104     /* Send a Connect-Initial message */
105     void mcs_send_connect_initial(HCONN conn)
106     {
107     MCS_CONNECT_INITIAL mci;
108    
109     iso_init(conn);
110     mcs_make_connect_initial(&mci);
111     mcs_io_connect_initial(&conn->out, &mci);
112     MARK_END(conn->out);
113     iso_send(conn);
114     }
115    
116     /* Send a EDrq message */
117     void mcs_send_edrq(HCONN conn)
118     {
119     MCS_EDRQ edrq;
120    
121     iso_init(conn);
122     edrq.height = edrq.interval = 1;
123     mcs_io_edrq(&conn->out, &edrq);
124     MARK_END(conn->out);
125     iso_send(conn);
126     }
127    
128     /* Send a AUrq message */
129     void mcs_send_aurq(HCONN conn)
130     {
131     MCS_AURQ aurq;
132    
133     iso_init(conn);
134     mcs_io_aurq(&conn->out, &aurq);
135     MARK_END(conn->out);
136     iso_send(conn);
137     }
138    
139     /* Send a CJrq message */
140     void mcs_send_cjrq(HCONN conn, uint16 chanid)
141     {
142     MCS_CJRQ cjrq;
143    
144     iso_init(conn);
145     cjrq.userid = conn->mcs_userid;
146     cjrq.chanid = chanid;
147     mcs_io_cjrq(&conn->out, &cjrq);
148     MARK_END(conn->out);
149     iso_send(conn);
150     }
151    
152     /* Initialise MCS transport data packet */
153     void mcs_init_data(HCONN conn)
154     {
155     iso_init(conn);
156     PUSH_LAYER(conn->out, mcs_offset, 8);
157     }
158    
159     /* Transmit MCS transport data packet */
160     void mcs_send_data(HCONN conn, uint16 chanid, BOOL request)
161     {
162     MCS_DATA dt;
163    
164     POP_LAYER(conn->out, mcs_offset);
165     dt.userid = conn->mcs_userid;
166     dt.chanid = chanid;
167     dt.flags = 0x70;
168     dt.length = conn->out.end - conn->out.offset - 8;
169     mcs_io_data(&conn->out, &dt, request);
170     iso_send(conn);
171     }
172    
173     /* Receive a message on the MCS layer */
174     BOOL mcs_recv(HCONN conn, BOOL request)
175     {
176     MCS_DATA data;
177    
178 matty 7 if (!iso_recv(conn) || !mcs_io_data(&conn->in, &data, request))
179     return False;
180    
181     conn->in.rdp_offset = conn->in.offset;
182     return True;
183 matty 3 }
184    
185     /* Initialise a DOMAIN_PARAMS structure */
186     void mcs_make_domain_params(DOMAIN_PARAMS *dp, uint16 max_channels,
187     uint16 max_users, uint16 max_tokens, uint16 max_pdusize)
188     {
189     dp->max_channels = max_channels;
190     dp->max_users = max_users;
191     dp->max_tokens = max_tokens;
192     dp->num_priorities = 1;
193     dp->min_throughput = 0;
194     dp->max_height = 1;
195     dp->max_pdusize = max_pdusize;
196     dp->ver_protocol = 2;
197     }
198    
199     /* RDP-specific 'user data'. Let's just get this right for now - to be
200     decoded later. */
201     char precanned_connect_userdata[] = {
202     0x00,0x05,0x00,0x14,0x7c,0x00,0x01,0x80,0x9e,0x00,0x08,0x00,0x10,0x00,
203     0x01,0xc0,0x00,0x44,0x75,0x63,0x61,0x80,0x90,0x01,0xc0,0x88,0x00,0x01,
204     0x00,0x08,0x00,0x80,0x02,0xe0,0x01,0x01,0xca,0x03,0xaa,0x09,0x04,0x00,
205     0x00,0xa3,0x01,0x00,0x00,0x52,0x00,0x45,0x00,0x53,0x00,0x31,0x00,0x2d,
206     0x00,0x4e,0x00,0x45,0x00,0x57,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
207     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,
208     0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
209     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
210     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
211     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
212     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
213 matty 9 0x00,0x01,0xca,0x00,0x00,0x02,0xc0,0x08,0x00,
214     /* encryption disabled */ 0x00,0x00,0x00,0x00 };
215 matty 3
216 matty 9 char precanned_connect_userdata_e[] = {
217     0x00,
218     0x05,0x00,0x14,0x7c,0x00,0x01,0x80,0x9e,0x00,0x08,0x00,0x10,0x00,0x01,0xc0,0x00,
219     0x44,0x75,0x63,0x61,0x80,0x90,0x01,0xc0,0x88,0x00,0x01,0x00,0x08,0x00,0x80,0x02,
220     0xe0,0x01,0x01,0xca,0x03,0xaa,0x09,0x04,0x00,0x00,0xa3,0x01,0x00,0x00,0x57,0x00,
221     0x49,0x00,0x4e,0x00,0x39,0x00,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
222     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,
223     0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
224     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
225     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
226     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
227     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xca,0x00,0x00,0x02,0xc0,
228     0x08,0x00,0x01,0x00,0x00,0x00
229     };
230    
231     char domain_data[] = {0x01};
232    
233 matty 3 /* Initialise a MCS_CONNECT_INITIAL structure */
234     void mcs_make_connect_initial(MCS_CONNECT_INITIAL *mci)
235     {
236 matty 9 mci->calling_domain.length = 1;
237     mci->calling_domain.data = domain_data;
238 matty 3
239 matty 9 mci->called_domain.length = 1;
240     mci->called_domain.data = domain_data;
241 matty 3
242     mci->upward_flag = 0xff;
243    
244     mcs_make_domain_params(&mci->target_params, 2, 2, 0, 0xffff);
245     mcs_make_domain_params(&mci->minimum_params, 1, 1, 1, 0x420);
246     mcs_make_domain_params(&mci->maximum_params, 0xffff, 0xfc17, 0xffff,
247     0xffff);
248    
249     mci->user_data.length = sizeof(precanned_connect_userdata);
250     mci->user_data.data = precanned_connect_userdata;
251    
252     mci->length = 2*2 + 3 + 3*34 + 4 + mci->user_data.length;
253     }
254    
255     /* Marshall/demarshall an ASN.1 BER header */
256     BOOL ber_io_header(STREAM s, BOOL islong, int tagval, int *length)
257     {
258     uint16 word_tag;
259     uint8 byte_tag;
260     uint16 word_len;
261     uint8 byte_len;
262     uint8 byte_int;
263     int tag;
264     BOOL res;
265    
266     /* Read/write tag */
267 matty 7 if (islong)
268     {
269 matty 3 word_tag = tagval;
270     res = msb_io_uint16(s, &word_tag);
271     tag = word_tag;
272 matty 7 }
273     else
274     {
275 matty 3 byte_tag = tagval;
276     res = prs_io_uint8(s, &byte_tag);
277     tag = byte_tag;
278     }
279    
280 matty 7 if (!res || (tag != tagval))
281     {
282 matty 9 ERROR("Invalid ASN.1 tag\n");
283 matty 3 return False;
284     }
285    
286     /* Read/write length */
287     if (s->marshall)
288     {
289     if (*length >= 0x80)
290     {
291     byte_len = 0x82;
292     word_len = (uint16)*length;
293     res = prs_io_uint8(s, &byte_len);
294     res = res ? msb_io_uint16(s, &word_len) : False;
295     }
296     else
297     {
298     byte_len = (uint8)*length;
299     res = prs_io_uint8(s, &byte_len);
300     }
301     }
302     else
303     {
304     if (!prs_io_uint8(s, &byte_len))
305     return False;
306    
307     if (byte_len & 0x80)
308     {
309     byte_len &= ~0x80;
310     *length = 0;
311     while (byte_len--)
312     {
313     if (!prs_io_uint8(s, &byte_int))
314     return False;
315    
316     *length <<= 8;
317     *length += byte_int;
318     }
319     }
320     else *length = byte_len;
321     }
322    
323     return res;
324     }
325    
326     /* Marshall/demarshall an octet string (ASN.1 BER) */
327     BOOL ber_io_octet_string(STREAM s, OCTET_STRING *os)
328     {
329     if (!ber_io_header(s, False, 4, &os->length))
330     return False;
331    
332     if (os->length > s->end - s->offset)
333     return False;
334    
335     if (s->marshall)
336     {
337     memcpy(s->data + s->offset, os->data, os->length);
338     }
339     else
340     {
341     os->data = malloc(os->length);
342     memcpy(os->data, s->data + s->offset, os->length);
343     }
344    
345     s->offset += os->length;
346     return True;
347     }
348    
349     /* Marshall/demarshall an integer (ASN.1 BER) */
350     BOOL ber_io_integer(STREAM s, uint16 *word_int)
351     {
352     int length = 2;
353     uint8 byte_int;
354     BOOL res;
355    
356     if (!ber_io_header(s, False, 2, &length))
357     return False;
358    
359     if (s->marshall)
360     {
361     res = msb_io_uint16(s, word_int);
362     }
363     else
364     {
365     *word_int = 0;
366     while (length--)
367     {
368     if (!prs_io_uint8(s, &byte_int))
369     return False;
370    
371     *word_int <<= 8;
372     *word_int += byte_int;
373     }
374     }
375    
376     return res;
377     }
378    
379     /* Marshall/demarshall a simple uint8 type (ASN.1 BER) */
380     BOOL ber_io_uint8(STREAM s, uint8 *i, int tagval)
381     {
382     int length = 1;
383    
384     if (!ber_io_header(s, False, tagval, &length))
385     return False;
386    
387     if (length != 1)
388     {
389 matty 9 ERROR("Wrong length for simple type\n");
390 matty 3 return False;
391     }
392    
393     return prs_io_uint8(s, i);
394     }
395    
396     /* Marshall/demarshall a DOMAIN_PARAMS structure (ASN.1 BER) */
397     BOOL mcs_io_domain_params(STREAM s, DOMAIN_PARAMS *dp)
398     {
399     int length = 32;
400     BOOL res;
401    
402     res = ber_io_header(s, False, 0x30, &length);
403     res = res ? ber_io_integer(s, &dp->max_channels ) : False;
404     res = res ? ber_io_integer(s, &dp->max_users ) : False;
405     res = res ? ber_io_integer(s, &dp->max_tokens ) : False;
406     res = res ? ber_io_integer(s, &dp->num_priorities) : False;
407     res = res ? ber_io_integer(s, &dp->min_throughput) : False;
408     res = res ? ber_io_integer(s, &dp->max_height ) : False;
409     res = res ? ber_io_integer(s, &dp->max_pdusize ) : False;
410     res = res ? ber_io_integer(s, &dp->ver_protocol ) : False;
411    
412     return res;
413     }
414    
415     /* Marshall/demarshall a MCS_CONNECT_INITIAL structure (ASN.1 BER) */
416     BOOL mcs_io_connect_initial(STREAM s, MCS_CONNECT_INITIAL *mci)
417     {
418     BOOL res;
419    
420     res = ber_io_header(s, True, 0x7f65, &mci->length);
421     res = res ? ber_io_octet_string (s, &mci->calling_domain) : False;
422     res = res ? ber_io_octet_string (s, &mci->called_domain ) : False;
423     res = res ? ber_io_uint8 (s, &mci->upward_flag, 1) : False;
424     res = res ? mcs_io_domain_params(s, &mci->target_params ) : False;
425     res = res ? mcs_io_domain_params(s, &mci->minimum_params) : False;
426     res = res ? mcs_io_domain_params(s, &mci->maximum_params) : False;
427     res = res ? ber_io_octet_string (s, &mci->user_data ) : False;
428    
429     return res;
430     }
431    
432     /* Marshall/demarshall a MCS_CONNECT_RESPONSE structure (ASN.1 BER) */
433     BOOL mcs_io_connect_response(STREAM s, MCS_CONNECT_RESPONSE *mcr)
434     {
435     BOOL res;
436    
437     res = ber_io_header(s, True, 0x7f66, &mcr->length);
438     res = res ? ber_io_uint8 (s, &mcr->result, 10 ) : False;
439     res = res ? ber_io_integer (s, &mcr->connect_id ) : False;
440     res = res ? mcs_io_domain_params(s, &mcr->domain_params) : False;
441     res = res ? ber_io_octet_string (s, &mcr->user_data ) : False;
442    
443     return res;
444     }
445    
446     /* Marshall/demarshall an EDrq structure (ASN.1 PER) */
447     BOOL mcs_io_edrq(STREAM s, MCS_EDRQ *edrq)
448     {
449     uint8 opcode = (1) << 2;
450     uint8 pkt_opcode = opcode;
451     BOOL res;
452    
453     res = prs_io_uint8(s, &pkt_opcode);
454     if (pkt_opcode != opcode)
455     {
456 matty 9 ERROR("Expected EDrq, received %x\n", pkt_opcode);
457 matty 3 return False;
458     }
459    
460     res = res ? msb_io_uint16(s, &edrq->height ) : False;
461     res = res ? msb_io_uint16(s, &edrq->interval) : False;
462    
463     return res;
464     }
465    
466     /* Marshall/demarshall an AUrq structure (ASN.1 PER) */
467     BOOL mcs_io_aurq(STREAM s, MCS_AURQ *aurq)
468     {
469     uint8 opcode = (10) << 2;
470     uint8 pkt_opcode = opcode;
471     BOOL res;
472    
473     res = prs_io_uint8(s, &pkt_opcode);
474     if (pkt_opcode != opcode)
475     {
476 matty 9 ERROR("Expected AUrq, received %x\n", pkt_opcode);
477 matty 3 return False;
478     }
479    
480     return res;
481     }
482    
483     /* Marshall/demarshall an AUcf structure (ASN.1 PER) */
484     BOOL mcs_io_aucf(STREAM s, MCS_AUCF *aucf)
485     {
486     uint8 opcode = (11) << 2;
487     uint8 pkt_opcode = opcode | 2;
488     BOOL res;
489    
490     res = prs_io_uint8(s, &pkt_opcode);
491     if ((pkt_opcode & 0xfc) != opcode)
492     {
493 matty 9 ERROR("Expected AUcf, received %x\n", pkt_opcode);
494 matty 3 return False;
495     }
496    
497     res = res ? prs_io_uint8 (s, &aucf->result) : False;
498     if (pkt_opcode & 2)
499     res = res ? msb_io_uint16(s, &aucf->userid) : False;
500    
501     return res;
502     }
503    
504     /* Marshall/demarshall an CJrq structure (ASN.1 PER) */
505     BOOL mcs_io_cjrq(STREAM s, MCS_CJRQ *cjrq)
506     {
507     uint8 opcode = (14) << 2;
508     uint8 pkt_opcode = opcode;
509     BOOL res;
510    
511     res = prs_io_uint8(s, &pkt_opcode);
512     if (pkt_opcode != opcode)
513     {
514 matty 9 ERROR("Expected CJrq, received %x\n", pkt_opcode);
515 matty 3 return False;
516     }
517    
518     res = res ? msb_io_uint16(s, &cjrq->userid) : False;
519     res = res ? msb_io_uint16(s, &cjrq->chanid) : False;
520    
521     return res;
522     }
523    
524     /* Marshall/demarshall an CJcf structure (ASN.1 PER) */
525     BOOL mcs_io_cjcf(STREAM s, MCS_CJCF *cjcf)
526     {
527     uint8 opcode = (15) << 2;
528     uint8 pkt_opcode = opcode | 2;
529     BOOL res;
530    
531     res = prs_io_uint8(s, &pkt_opcode);
532     if ((pkt_opcode & 0xfc) != opcode)
533     {
534 matty 9 ERROR("Expected CJcf, received %x\n", pkt_opcode);
535 matty 3 return False;
536     }
537    
538     res = res ? prs_io_uint8 (s, &cjcf->result) : False;
539     res = res ? msb_io_uint16(s, &cjcf->userid) : False;
540     res = res ? msb_io_uint16(s, &cjcf->req_chanid) : False;
541     if (pkt_opcode & 2)
542     res = res ? msb_io_uint16(s, &cjcf->join_chanid) : False;
543    
544     return res;
545     }
546    
547     /* Marshall/demarshall an SDrq or SDin packet (ASN.1 PER) */
548     BOOL mcs_io_data(STREAM s, MCS_DATA *dt, BOOL request)
549     {
550     uint8 opcode = (request ? 25 : 26) << 2;
551     uint8 pkt_opcode = opcode;
552 matty 7 uint8 byte1, byte2;
553 matty 3 BOOL res;
554    
555     res = prs_io_uint8(s, &pkt_opcode);
556     if (pkt_opcode != opcode)
557     {
558 matty 9 ERROR("Expected MCS data, received %x\n", pkt_opcode);
559 matty 3 return False;
560     }
561    
562     res = res ? msb_io_uint16(s, &dt->userid) : False;
563     res = res ? msb_io_uint16(s, &dt->chanid) : False;
564     res = res ? prs_io_uint8 (s, &dt->flags ) : False;
565    
566 matty 7 if (s->marshall)
567     {
568 matty 9 dt->length |= 0x8000;
569 matty 7 res = res ? msb_io_uint16(s, &dt->length) : False;
570     }
571     else
572     {
573     res = res ? prs_io_uint8(s, &byte1) : False;
574     if (byte1 & 0x80)
575     {
576     res = res ? prs_io_uint8(s, &byte2) : False;
577     dt->length = ((byte1 & ~0x80) << 8) + byte2;
578     }
579     else dt->length = byte1;
580     }
581    
582 matty 3 return res;
583     }
584 matty 7

  ViewVC Help
Powered by ViewVC 1.1.26