/[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 64 by astrand, Thu Jul 18 16:38:31 2002 UTC revision 1372 by jsorg71, Mon Jan 8 04:47:06 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-2001     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  static RD_BOOL
29  ber_parse_header(STREAM s, int tagval, int *length)  ber_parse_header(STREAM s, int tagval, int *length)
30  {  {
31          int tag, len;          int tag, len;
# Line 89  ber_out_integer(STREAM s, int value) Line 91  ber_out_integer(STREAM s, int value)
91    
92  /* Output a DOMAIN_PARAMS structure (ASN.1 BER) */  /* Output a DOMAIN_PARAMS structure (ASN.1 BER) */
93  static void  static void
94  mcs_out_domain_params(STREAM s, int max_channels, int max_users,  mcs_out_domain_params(STREAM s, int max_channels, int max_users, int max_tokens, int max_pdusize)
                       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 104  mcs_out_domain_params(STREAM s, int max_ Line 105  mcs_out_domain_params(STREAM s, int max_
105  }  }
106    
107  /* Parse a DOMAIN_PARAMS structure (ASN.1 BER) */  /* Parse a DOMAIN_PARAMS structure (ASN.1 BER) */
108  static BOOL  static RD_BOOL
109  mcs_parse_domain_params(STREAM s)  mcs_parse_domain_params(STREAM s)
110  {  {
111          int length;          int length;
# Line 120  static void Line 121  static void
121  mcs_send_connect_initial(STREAM mcs_data)  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 144  mcs_send_connect_initial(STREAM mcs_data Line 147  mcs_send_connect_initial(STREAM mcs_data
147  }  }
148    
149  /* Expect a MCS_CONNECT_RESPONSE message (ASN.1 BER) */  /* Expect a MCS_CONNECT_RESPONSE message (ASN.1 BER) */
150  static BOOL  static RD_BOOL
151  mcs_recv_connect_response(STREAM mcs_data)  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 170  mcs_recv_connect_response(STREAM mcs_dat Line 173  mcs_recv_connect_response(STREAM mcs_dat
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)  
         {  
                 error("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  static void
195  mcs_send_edrq()  mcs_send_edrq(void)
196  {  {
197          STREAM s;          STREAM s;
198    
# Line 201  mcs_send_edrq() Line 208  mcs_send_edrq()
208    
209  /* Send an AUrq message (ASN.1 PER) */  /* Send an AUrq message (ASN.1 PER) */
210  static void  static void
211  mcs_send_aurq()  mcs_send_aurq(void)
212  {  {
213          STREAM s;          STREAM s;
214    
# Line 214  mcs_send_aurq() Line 221  mcs_send_aurq()
221  }  }
222    
223  /* Expect a AUcf message (ASN.1 PER) */  /* Expect a AUcf message (ASN.1 PER) */
224  static BOOL  static RD_BOOL
225  mcs_recv_aucf(uint16 * mcs_userid)  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    
# Line 250  mcs_send_cjrq(uint16 chanid) Line 257  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 261  mcs_send_cjrq(uint16 chanid) Line 270  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  static RD_BOOL
274  mcs_recv_cjcf()  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    
# Line 304  mcs_init(int length) Line 313  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  void
318  mcs_send(STREAM s)  mcs_send_to_channel(STREAM s, uint16 channel)
319  {  {
320          uint16 length;          uint16 length;
321    
# Line 315  mcs_send(STREAM s) Line 324  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  STREAM
344  mcs_recv()  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)
# Line 344  mcs_recv() Line 362  mcs_recv()
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  RD_BOOL
376  mcs_connect(char *server, STREAM mcs_data)  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 367  mcs_connect(char *server, STREAM mcs_dat Line 387  mcs_connect(char *server, STREAM mcs_dat
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 378  mcs_connect(char *server, STREAM mcs_dat Line 399  mcs_connect(char *server, STREAM mcs_dat
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    RD_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 387  mcs_connect(char *server, STREAM mcs_dat Line 455  mcs_connect(char *server, STREAM mcs_dat
455    
456  /* Disconnect from the MCS layer */  /* Disconnect from the MCS layer */
457  void  void
458  mcs_disconnect()  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.64  
changed lines
  Added in v.1372

  ViewVC Help
Powered by ViewVC 1.1.26