/[rdesktop]/sourceforge.net/tags/RDESKTOP-1-3-0/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

Diff of /sourceforge.net/tags/RDESKTOP-1-3-0/rdesktop/mcs.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

sourceforge.net/trunk/rdesktop/mcs.c revision 10 by matty, Tue Aug 15 10:23:24 2000 UTC sourceforge.net/tags/RDESKTOP-1-3-0/rdesktop/mcs.c revision 533, Wed Oct 29 14:14:47 2003 UTC
# Line 1  Line 1 
1  /*  /* -*- c-basic-offset: 8 -*-
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     Protocol services - Multipoint Communications Service     Protocol services - Multipoint Communications Service
4     Copyright (C) Matthew Chapman 1999-2000     Copyright (C) Matthew Chapman 1999-2002
5        
6     This program is free software; you can redistribute it and/or modify     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     it under the terms of the GNU General Public License as published by
# Line 20  Line 20 
20    
21  #include "rdesktop.h"  #include "rdesktop.h"
22    
23  uint16 mcs_userid;  uint16 g_mcs_userid;
24    extern VCHANNEL g_channels[];
25    extern unsigned int g_num_channels;
26    
27  /* Parse an ASN.1 BER header */  /* Parse an ASN.1 BER header */
28  static BOOL ber_parse_header(STREAM s, int tagval, int *length)  static BOOL
29    ber_parse_header(STREAM s, int tagval, int *length)
30  {  {
31          int tag, len;          int tag, len;
32    
# Line 33  static BOOL ber_parse_header(STREAM s, i Line 36  static BOOL ber_parse_header(STREAM s, i
36          }          }
37          else          else
38          {          {
39                  in_uint8(s, tag)          in_uint8(s, tag)}
         }  
40    
41          if (tag != tagval)          if (tag != tagval)
42          {          {
43                  ERROR("expected tag %d, got %d\n", tagval, tag);                  error("expected tag %d, got %d\n", tagval, tag);
44                  return False;                  return False;
45          }          }
46    
# Line 51  static BOOL ber_parse_header(STREAM s, i Line 53  static BOOL ber_parse_header(STREAM s, i
53                  while (len--)                  while (len--)
54                          next_be(s, *length);                          next_be(s, *length);
55          }          }
56          else *length = len;          else
57                    *length = len;
58    
59          return s_check(s);          return s_check(s);
60  }  }
61    
62  /* Output an ASN.1 BER header */  /* Output an ASN.1 BER header */
63  static void ber_out_header(STREAM s, int tagval, int length)  static void
64    ber_out_header(STREAM s, int tagval, int length)
65  {  {
66          if (tagval > 0xff)          if (tagval > 0xff)
67          {          {
# Line 73  static void ber_out_header(STREAM s, int Line 77  static void ber_out_header(STREAM s, int
77                  out_uint8(s, 0x82);                  out_uint8(s, 0x82);
78                  out_uint16_be(s, length);                  out_uint16_be(s, length);
79          }          }
80          else out_uint8(s, length);          else
81                    out_uint8(s, length);
82  }  }
83    
84  /* Output an ASN.1 BER integer */  /* Output an ASN.1 BER integer */
85  static void ber_out_integer(STREAM s, int value)  static void
86    ber_out_integer(STREAM s, int value)
87  {  {
88          ber_out_header(s, BER_TAG_INTEGER, 2);          ber_out_header(s, BER_TAG_INTEGER, 2);
89          out_uint16_be(s, value);          out_uint16_be(s, value);
90  }  }
91    
92  /* Output a DOMAIN_PARAMS structure (ASN.1 BER) */  /* Output a DOMAIN_PARAMS structure (ASN.1 BER) */
93  static void mcs_out_domain_params(STREAM s, int max_channels, int max_users,  static void
94                             int max_tokens, int max_pdusize)  mcs_out_domain_params(STREAM s, int max_channels, int max_users, int max_tokens, int max_pdusize)
95  {  {
96          ber_out_header(s, MCS_TAG_DOMAIN_PARAMS, 32);          ber_out_header(s, MCS_TAG_DOMAIN_PARAMS, 32);
97          ber_out_integer(s, max_channels);          ber_out_integer(s, max_channels);
98          ber_out_integer(s, max_users);          ber_out_integer(s, max_users);
99          ber_out_integer(s, max_tokens);          ber_out_integer(s, max_tokens);
100          ber_out_integer(s, 1); /* num_priorities */          ber_out_integer(s, 1);  /* num_priorities */
101          ber_out_integer(s, 0); /* min_throughput */          ber_out_integer(s, 0);  /* min_throughput */
102          ber_out_integer(s, 1); /* max_height */          ber_out_integer(s, 1);  /* max_height */
103          ber_out_integer(s, max_pdusize);          ber_out_integer(s, max_pdusize);
104          ber_out_integer(s, 2); /* ver_protocol */          ber_out_integer(s, 2);  /* ver_protocol */
105  }  }
106    
107  /* Parse a DOMAIN_PARAMS structure (ASN.1 BER) */  /* Parse a DOMAIN_PARAMS structure (ASN.1 BER) */
108  static BOOL mcs_parse_domain_params(STREAM s)  static BOOL
109    mcs_parse_domain_params(STREAM s)
110  {  {
111          int length;          int length;
112    
# Line 110  static BOOL mcs_parse_domain_params(STRE Line 117  static BOOL mcs_parse_domain_params(STRE
117  }  }
118    
119  /* Send an MCS_CONNECT_INITIAL message (ASN.1 BER) */  /* Send an MCS_CONNECT_INITIAL message (ASN.1 BER) */
120  static void mcs_send_connect_initial(STREAM mcs_data)  static void
121    mcs_send_connect_initial(STREAM mcs_data)
122  {  {
123          int datalen = mcs_data->end - mcs_data->data;          int datalen = mcs_data->end - mcs_data->data;
124          int length = 7 + 3*34 + 4 + datalen;          int length = 9 + 3 * 34 + 4 + datalen;
125          STREAM s;          STREAM s;
126    
127          s = iso_init(length + 5);          s = iso_init(length + 5);
128    
129          ber_out_header(s, MCS_CONNECT_INITIAL, length);          ber_out_header(s, MCS_CONNECT_INITIAL, length);
130          ber_out_header(s, BER_TAG_OCTET_STRING, 0); /* calling domain */          ber_out_header(s, BER_TAG_OCTET_STRING, 1);     /* calling domain */
131          ber_out_header(s, BER_TAG_OCTET_STRING, 0); /* called domain */          out_uint8(s, 1);
132            ber_out_header(s, BER_TAG_OCTET_STRING, 1);     /* called domain */
133            out_uint8(s, 1);
134    
135          ber_out_header(s, BER_TAG_BOOLEAN, 1);          ber_out_header(s, BER_TAG_BOOLEAN, 1);
136          out_uint8(s, 0xff); /* upward flag */          out_uint8(s, 0xff);     /* upward flag */
137    
138          mcs_out_domain_params(s, 2, 2, 0, 0xffff); /* target params */          mcs_out_domain_params(s, 34, 2, 0, 0xffff);     /* target params */
139          mcs_out_domain_params(s, 1, 1, 1, 0x420); /* min params */          mcs_out_domain_params(s, 1, 1, 1, 0x420);       /* min params */
140          mcs_out_domain_params(s, 0xffff, 0xfc17, 0xffff, 0xffff); /* max params */          mcs_out_domain_params(s, 0xffff, 0xfc17, 0xffff, 0xffff);       /* max params */
141    
142          ber_out_header(s, BER_TAG_OCTET_STRING, datalen);          ber_out_header(s, BER_TAG_OCTET_STRING, datalen);
143          out_uint8p(s, mcs_data->data, datalen);          out_uint8p(s, mcs_data->data, datalen);
# Line 137  static void mcs_send_connect_initial(STR Line 147  static void mcs_send_connect_initial(STR
147  }  }
148    
149  /* Expect a MCS_CONNECT_RESPONSE message (ASN.1 BER) */  /* Expect a MCS_CONNECT_RESPONSE message (ASN.1 BER) */
150  static BOOL mcs_recv_connect_response(STREAM mcs_data)  static BOOL
151    mcs_recv_connect_response(STREAM mcs_data)
152  {  {
153          uint8 result;          uint8 result;
154          int length;          int length;
# Line 153  static BOOL mcs_recv_connect_response(ST Line 164  static BOOL mcs_recv_connect_response(ST
164          in_uint8(s, result);          in_uint8(s, result);
165          if (result != 0)          if (result != 0)
166          {          {
167                  ERROR("MCS connect: %d\n", result);                  error("MCS connect: %d\n", result);
168                  return False;                  return False;
169          }          }
170    
171          ber_parse_header(s, BER_TAG_INTEGER, &length);          ber_parse_header(s, BER_TAG_INTEGER, &length);
172          in_uint8s(s, length); /* connect id */          in_uint8s(s, length);   /* connect id */
173          mcs_parse_domain_params(s);          mcs_parse_domain_params(s);
174    
175          ber_parse_header(s, BER_TAG_OCTET_STRING, &length);          ber_parse_header(s, BER_TAG_OCTET_STRING, &length);
         if (length > mcs_data->size)  
         {  
                 WARN("MCS data length %d\n", length);  
                 length = mcs_data->size;  
         }  
   
         in_uint8a(s, mcs_data->data, length);  
         mcs_data->p = mcs_data->data;  
         mcs_data->end = mcs_data->data + length;  
176    
177            sec_process_mcs_data(s);
178            /*
179               if (length > mcs_data->size)
180               {
181               error("MCS data length %d, expected %d\n", length,
182               mcs_data->size);
183               length = mcs_data->size;
184               }
185    
186               in_uint8a(s, mcs_data->data, length);
187               mcs_data->p = mcs_data->data;
188               mcs_data->end = mcs_data->data + length;
189             */
190          return s_check_end(s);          return s_check_end(s);
191  }  }
192    
193  /* Send an EDrq message (ASN.1 PER) */  /* Send an EDrq message (ASN.1 PER) */
194  static void mcs_send_edrq()  static void
195    mcs_send_edrq(void)
196  {  {
197          STREAM s;          STREAM s;
198    
199          s = iso_init(5);          s = iso_init(5);
200    
201          out_uint8(s, (MCS_EDRQ << 2));          out_uint8(s, (MCS_EDRQ << 2));
202          out_uint16_be(s, 1); /* height */          out_uint16_be(s, 1);    /* height */
203          out_uint16_be(s, 1); /* interval */          out_uint16_be(s, 1);    /* interval */
204    
205          s_mark_end(s);          s_mark_end(s);
206          iso_send(s);          iso_send(s);
207  }  }
208    
209  /* Send an AUrq message (ASN.1 PER) */  /* Send an AUrq message (ASN.1 PER) */
210  static void mcs_send_aurq()  static void
211    mcs_send_aurq(void)
212  {  {
213          STREAM s;          STREAM s;
214    
# Line 204  static void mcs_send_aurq() Line 221  static void mcs_send_aurq()
221  }  }
222    
223  /* Expect a AUcf message (ASN.1 PER) */  /* Expect a AUcf message (ASN.1 PER) */
224  static BOOL mcs_recv_aucf(uint16 *mcs_userid)  static BOOL
225    mcs_recv_aucf(uint16 * mcs_userid)
226  {  {
227          uint8 opcode, result;          uint8 opcode, result;
228          STREAM s;          STREAM s;
# Line 216  static BOOL mcs_recv_aucf(uint16 *mcs_us Line 234  static BOOL mcs_recv_aucf(uint16 *mcs_us
234          in_uint8(s, opcode);          in_uint8(s, opcode);
235          if ((opcode >> 2) != MCS_AUCF)          if ((opcode >> 2) != MCS_AUCF)
236          {          {
237                  ERROR("expected AUcf, got %d\n", opcode);                  error("expected AUcf, got %d\n", opcode);
238                  return False;                  return False;
239          }          }
240    
241          in_uint8(s, result);          in_uint8(s, result);
242          if (result != 0)          if (result != 0)
243          {          {
244                  ERROR("AUrq: %d\n", result);                  error("AUrq: %d\n", result);
245                  return False;                  return False;
246          }          }
247    
# Line 234  static BOOL mcs_recv_aucf(uint16 *mcs_us Line 252  static BOOL mcs_recv_aucf(uint16 *mcs_us
252  }  }
253    
254  /* Send a CJrq message (ASN.1 PER) */  /* Send a CJrq message (ASN.1 PER) */
255  static void mcs_send_cjrq(uint16 chanid)  static void
256    mcs_send_cjrq(uint16 chanid)
257  {  {
258          STREAM s;          STREAM s;
259    
260            DEBUG_RDP5(("Sending CJRQ for channel #%d\n", chanid));
261    
262          s = iso_init(5);          s = iso_init(5);
263    
264          out_uint8(s, (MCS_CJRQ << 2));          out_uint8(s, (MCS_CJRQ << 2));
265          out_uint16_be(s, mcs_userid);          out_uint16_be(s, g_mcs_userid);
266          out_uint16_be(s, chanid);          out_uint16_be(s, chanid);
267    
268          s_mark_end(s);          s_mark_end(s);
# Line 249  static void mcs_send_cjrq(uint16 chanid) Line 270  static void mcs_send_cjrq(uint16 chanid)
270  }  }
271    
272  /* Expect a CJcf message (ASN.1 PER) */  /* Expect a CJcf message (ASN.1 PER) */
273  static BOOL mcs_recv_cjcf()  static BOOL
274    mcs_recv_cjcf(void)
275  {  {
276          uint8 opcode, result;          uint8 opcode, result;
277          STREAM s;          STREAM s;
# Line 261  static BOOL mcs_recv_cjcf() Line 283  static BOOL mcs_recv_cjcf()
283          in_uint8(s, opcode);          in_uint8(s, opcode);
284          if ((opcode >> 2) != MCS_CJCF)          if ((opcode >> 2) != MCS_CJCF)
285          {          {
286                  ERROR("expected CJcf, got %d\n", opcode);                  error("expected CJcf, got %d\n", opcode);
287                  return False;                  return False;
288          }          }
289    
290          in_uint8(s, result);          in_uint8(s, result);
291          if (result != 0)          if (result != 0)
292          {          {
293                  ERROR("CJrq: %d\n", result);                  error("CJrq: %d\n", result);
294                  return False;                  return False;
295          }          }
296    
297          in_uint8s(s, 4); /* mcs_userid, req_chanid */          in_uint8s(s, 4);        /* mcs_userid, req_chanid */
298          if (opcode & 2)          if (opcode & 2)
299                  in_uint8s(s, 2); /* join_chanid */                  in_uint8s(s, 2);        /* join_chanid */
300    
301          return s_check_end(s);          return s_check_end(s);
302  }  }
303    
304  /* Initialise an MCS transport data packet */  /* Initialise an MCS transport data packet */
305  STREAM mcs_init(int length)  STREAM
306    mcs_init(int length)
307  {  {
308          STREAM s;          STREAM s;
309    
# Line 290  STREAM mcs_init(int length) Line 313  STREAM mcs_init(int length)
313          return s;          return s;
314  }  }
315    
316  /* Send an MCS transport data packet */  /* Send an MCS transport data packet to a specific channel */
317  void mcs_send(STREAM s)  void
318    mcs_send_to_channel(STREAM s, uint16 channel)
319  {  {
320          uint16 length;          uint16 length;
321    
# Line 300  void mcs_send(STREAM s) Line 324  void mcs_send(STREAM s)
324          length |= 0x8000;          length |= 0x8000;
325    
326          out_uint8(s, (MCS_SDRQ << 2));          out_uint8(s, (MCS_SDRQ << 2));
327          out_uint16_be(s, mcs_userid);          out_uint16_be(s, g_mcs_userid);
328          out_uint16_be(s, MCS_GLOBAL_CHANNEL);          out_uint16_be(s, channel);
329          out_uint8(s, 0x70); /* flags */          out_uint8(s, 0x70);     /* flags */
330          out_uint16_be(s, length);          out_uint16_be(s, length);
331    
332          iso_send(s);          iso_send(s);
333  }  }
334    
335    /* Send an MCS transport data packet to the global channel */
336    void
337    mcs_send(STREAM s)
338    {
339            mcs_send_to_channel(s, MCS_GLOBAL_CHANNEL);
340    }
341    
342  /* Receive an MCS transport data packet */  /* Receive an MCS transport data packet */
343  STREAM mcs_recv()  STREAM
344    mcs_recv(uint16 * channel)
345  {  {
346          uint8 opcode, appid, length;          uint8 opcode, appid, length;
347          STREAM s;          STREAM s;
# Line 324  STREAM mcs_recv() Line 356  STREAM mcs_recv()
356          {          {
357                  if (appid != MCS_DPUM)                  if (appid != MCS_DPUM)
358                  {                  {
359                          ERROR("expected data, got %d\n", opcode);                          error("expected data, got %d\n", opcode);
360                  }                  }
361                  return NULL;                  return NULL;
362          }          }
363    
364          in_uint8s(s, 5); /* userid, chanid, flags */          in_uint8s(s, 2);        /* userid */
365            in_uint16_be(s, *channel);
366            in_uint8s(s, 1);        /* flags */
367          in_uint8(s, length);          in_uint8(s, length);
368          if (length & 0x80)          if (length & 0x80)
369                  in_uint8s(s, 1); /* second byte of length */                  in_uint8s(s, 1);        /* second byte of length */
370    
371          return s;          return s;
372  }  }
373    
374  /* Establish a connection up to the MCS layer */  /* Establish a connection up to the MCS layer */
375  BOOL mcs_connect(char *server, STREAM mcs_data)  BOOL
376    mcs_connect(char *server, STREAM mcs_data, char *username)
377  {  {
378          if (!iso_connect(server))          unsigned int i;
379    
380            if (!iso_connect(server, username))
381                  return False;                  return False;
382    
383          mcs_send_connect_initial(mcs_data);          mcs_send_connect_initial(mcs_data);
# Line 350  BOOL mcs_connect(char *server, STREAM mc Line 387  BOOL mcs_connect(char *server, STREAM mc
387          mcs_send_edrq();          mcs_send_edrq();
388    
389          mcs_send_aurq();          mcs_send_aurq();
390          if (!mcs_recv_aucf(&mcs_userid))          if (!mcs_recv_aucf(&g_mcs_userid))
391                  goto error;                  goto error;
392    
393          mcs_send_cjrq(mcs_userid + 1001);          mcs_send_cjrq(g_mcs_userid + MCS_USERCHANNEL_BASE);
394    
395          if (!mcs_recv_cjcf())          if (!mcs_recv_cjcf())
396                  goto error;                  goto error;
397    
# Line 361  BOOL mcs_connect(char *server, STREAM mc Line 399  BOOL mcs_connect(char *server, STREAM mc
399          if (!mcs_recv_cjcf())          if (!mcs_recv_cjcf())
400                  goto error;                  goto error;
401    
402            for (i = 0; i < g_num_channels; i++)
403            {
404                    mcs_send_cjrq(g_channels[i].mcs_id);
405                    if (!mcs_recv_cjcf())
406                            goto error;
407            }
408          return True;          return True;
409    
410   error:        error:
411          iso_disconnect();          iso_disconnect();
412          return False;          return False;
413  }  }
414    
415  /* Disconnect from the MCS layer */  /* Disconnect from the MCS layer */
416  void mcs_disconnect()  void
417    mcs_disconnect(void)
418  {  {
419          iso_disconnect();          iso_disconnect();
420  }  }

Legend:
Removed from v.10  
changed lines
  Added in v.533

  ViewVC Help
Powered by ViewVC 1.1.26