/[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

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

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

revision 24 by matty, Sat Jan 6 03:12:10 2001 UTC revision 1365 by jsorg71, Thu Jan 4 05:39:39 2007 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-2007
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
8     the Free Software Foundation; either version 2 of the License, or     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.     (at your option) any later version.
10      
11     This program is distributed in the hope that it will be useful,     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.     GNU General Public License for more details.
15      
16     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
# 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 37  static BOOL ber_parse_header(STREAM s, i Line 40  static BOOL ber_parse_header(STREAM s, i
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 57  static BOOL ber_parse_header(STREAM s, i Line 60  static BOOL ber_parse_header(STREAM s, i
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 78  static void ber_out_header(STREAM s, int Line 82  static void ber_out_header(STREAM s, int
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);
# Line 100  static void mcs_out_domain_params(STREAM Line 105  static void mcs_out_domain_params(STREAM
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 111  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    
# Line 138  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;
155          STREAM s;          STREAM s;
156    
157          s = iso_recv();          s = iso_recv(NULL);
158          if (s == NULL)          if (s == NULL)
159                  return False;                  return False;
160    
# Line 154  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    
# Line 163  static BOOL mcs_recv_connect_response(ST Line 173  static BOOL mcs_recv_connect_response(ST
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    
# Line 192  static void mcs_send_edrq() Line 207  static void mcs_send_edrq()
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 205  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;
229    
230          s = iso_recv();          s = iso_recv(NULL);
231          if (s == NULL)          if (s == NULL)
232                  return False;                  return False;
233    
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 235  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 250  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;
278    
279          s = iso_recv();          s = iso_recv(NULL);
280          if (s == NULL)          if (s == NULL)
281                  return False;                  return False;
282    
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    
# Line 281  static BOOL mcs_recv_cjcf() Line 302  static BOOL mcs_recv_cjcf()
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 291  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 301  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, uint8 * rdpver)
345  {  {
346          uint8 opcode, appid, length;          uint8 opcode, appid, length;
347          STREAM s;          STREAM s;
348    
349          s = iso_recv();          s = iso_recv(rdpver);
350          if (s == NULL)          if (s == NULL)
351                  return NULL;                  return NULL;
352            if (rdpver != NULL)
353                    if (*rdpver != 3)
354                            return s;
355          in_uint8(s, opcode);          in_uint8(s, opcode);
356          appid = opcode >> 2;          appid = opcode >> 2;
357          if (appid != MCS_SDIN)          if (appid != MCS_SDIN)
358          {          {
359                  if (appid != MCS_DPUM)                  if (appid != MCS_DPUM)
360                  {                  {
361                          ERROR("expected data, got %d\n", opcode);                          error("expected data, got %d\n", opcode);
362                  }                  }
363                  return NULL;                  return NULL;
364          }          }
365            in_uint8s(s, 2);        /* userid */
366          in_uint8s(s, 5);        /* userid, chanid, flags */          in_uint16_be(s, *channel);
367            in_uint8s(s, 1);        /* flags */
368          in_uint8(s, length);          in_uint8(s, length);
369          if (length & 0x80)          if (length & 0x80)
370                  in_uint8s(s, 1);        /* second byte of length */                  in_uint8s(s, 1);        /* second byte of length */
   
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 351  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 362  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;
409    
410          error:
411            iso_disconnect();
412            return False;
413    }
414    
415    /* Establish a connection up to the MCS layer */
416    BOOL
417    mcs_reconnect(char *server, STREAM mcs_data)
418    {
419            unsigned int i;
420    
421            if (!iso_reconnect(server))
422                    return False;
423    
424            mcs_send_connect_initial(mcs_data);
425            if (!mcs_recv_connect_response(mcs_data))
426                    goto error;
427    
428            mcs_send_edrq();
429    
430            mcs_send_aurq();
431            if (!mcs_recv_aucf(&g_mcs_userid))
432                    goto error;
433    
434            mcs_send_cjrq(g_mcs_userid + MCS_USERCHANNEL_BASE);
435    
436            if (!mcs_recv_cjcf())
437                    goto error;
438    
439            mcs_send_cjrq(MCS_GLOBAL_CHANNEL);
440            if (!mcs_recv_cjcf())
441                    goto error;
442    
443            for (i = 0; i < g_num_channels; i++)
444            {
445                    mcs_send_cjrq(g_channels[i].mcs_id);
446                    if (!mcs_recv_cjcf())
447                            goto error;
448            }
449          return True;          return True;
450    
451        error:        error:
# Line 370  BOOL mcs_connect(char *server, STREAM mc Line 454  BOOL mcs_connect(char *server, STREAM mc
454  }  }
455    
456  /* Disconnect from the MCS layer */  /* Disconnect from the MCS layer */
457  void mcs_disconnect()  void
458    mcs_disconnect(void)
459  {  {
460          iso_disconnect();          iso_disconnect();
461  }  }
462    
463    /* reset the state of the mcs layer */
464    void
465    mcs_reset_state(void)
466    {
467            g_mcs_userid = 0;
468            iso_reset_state();
469    }

Legend:
Removed from v.24  
changed lines
  Added in v.1365

  ViewVC Help
Powered by ViewVC 1.1.26