ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

mcs.c
Go to the documentation of this file.
00001 /* -*- c-basic-offset: 8 -*-
00002    rdesktop: A Remote Desktop Protocol client.
00003    Protocol services - Multipoint Communications Service
00004    Copyright (C) Matthew Chapman 1999-2005
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010 
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015 
00016    You should have received a copy of the GNU General Public License along
00017    with this program; if not, write to the Free Software Foundation, Inc.,
00018    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00019 */
00020 
00021 #include <precomp.h>
00022 
00023 uint16 g_mcs_userid;
00024 extern VCHANNEL g_channels[];
00025 extern unsigned int g_num_channels;
00026 
00027 /* Parse an ASN.1 BER header */
00028 static BOOL
00029 ber_parse_header(STREAM s, int tagval, int *length)
00030 {
00031     int tag, len;
00032 
00033     if (tagval > 0xff)
00034     {
00035         in_uint16_be(s, tag);
00036     }
00037     else
00038     {
00039     in_uint8(s, tag)}
00040 
00041     if (tag != tagval)
00042     {
00043         error("expected tag %d, got %d\n", tagval, tag);
00044         return False;
00045     }
00046 
00047     in_uint8(s, len);
00048 
00049     if (len & 0x80)
00050     {
00051         len &= ~0x80;
00052         *length = 0;
00053         while (len--)
00054             next_be(s, *length);
00055     }
00056     else
00057         *length = len;
00058 
00059     return s_check(s);
00060 }
00061 
00062 /* Output an ASN.1 BER header */
00063 static void
00064 ber_out_header(STREAM s, int tagval, int length)
00065 {
00066     if (tagval > 0xff)
00067     {
00068         out_uint16_be(s, tagval);
00069     }
00070     else
00071     {
00072         out_uint8(s, tagval);
00073     }
00074 
00075     if (length >= 0x80)
00076     {
00077         out_uint8(s, 0x82);
00078         out_uint16_be(s, length);
00079     }
00080     else
00081         out_uint8(s, length);
00082 }
00083 
00084 /* Output an ASN.1 BER integer */
00085 static void
00086 ber_out_integer(STREAM s, int value)
00087 {
00088     ber_out_header(s, BER_TAG_INTEGER, 2);
00089     out_uint16_be(s, value);
00090 }
00091 
00092 /* Output a DOMAIN_PARAMS structure (ASN.1 BER) */
00093 static void
00094 mcs_out_domain_params(STREAM s, int max_channels, int max_users, int max_tokens, int max_pdusize)
00095 {
00096     ber_out_header(s, MCS_TAG_DOMAIN_PARAMS, 32);
00097     ber_out_integer(s, max_channels);
00098     ber_out_integer(s, max_users);
00099     ber_out_integer(s, max_tokens);
00100     ber_out_integer(s, 1);  /* num_priorities */
00101     ber_out_integer(s, 0);  /* min_throughput */
00102     ber_out_integer(s, 1);  /* max_height */
00103     ber_out_integer(s, max_pdusize);
00104     ber_out_integer(s, 2);  /* ver_protocol */
00105 }
00106 
00107 /* Parse a DOMAIN_PARAMS structure (ASN.1 BER) */
00108 static BOOL
00109 mcs_parse_domain_params(STREAM s)
00110 {
00111     int length;
00112 
00113     ber_parse_header(s, MCS_TAG_DOMAIN_PARAMS, &length);
00114     in_uint8s(s, length);
00115 
00116     return s_check(s);
00117 }
00118 
00119 /* Send an MCS_CONNECT_INITIAL message (ASN.1 BER) */
00120 static void
00121 mcs_send_connect_initial(STREAM mcs_data)
00122 {
00123     int datalen = mcs_data->end - mcs_data->data;
00124     int length = 9 + 3 * 34 + 4 + datalen;
00125     STREAM s;
00126 
00127     s = iso_init(length + 5);
00128 
00129     ber_out_header(s, MCS_CONNECT_INITIAL, length);
00130     ber_out_header(s, BER_TAG_OCTET_STRING, 1); /* calling domain */
00131     out_uint8(s, 1);
00132     ber_out_header(s, BER_TAG_OCTET_STRING, 1); /* called domain */
00133     out_uint8(s, 1);
00134 
00135     ber_out_header(s, BER_TAG_BOOLEAN, 1);
00136     out_uint8(s, 0xff); /* upward flag */
00137 
00138     mcs_out_domain_params(s, 34, 2, 0, 0xffff); /* target params */
00139     mcs_out_domain_params(s, 1, 1, 1, 0x420);   /* min params */
00140     mcs_out_domain_params(s, 0xffff, 0xfc17, 0xffff, 0xffff);   /* max params */
00141 
00142     ber_out_header(s, BER_TAG_OCTET_STRING, datalen);
00143     out_uint8p(s, mcs_data->data, datalen);
00144 
00145     s_mark_end(s);
00146     iso_send(s);
00147 }
00148 
00149 /* Expect a MCS_CONNECT_RESPONSE message (ASN.1 BER) */
00150 static BOOL
00151 mcs_recv_connect_response(STREAM mcs_data)
00152 {
00153     uint8 result;
00154     int length;
00155     STREAM s;
00156 
00157     s = iso_recv(NULL);
00158     if (s == NULL)
00159         return False;
00160 
00161     ber_parse_header(s, MCS_CONNECT_RESPONSE, &length);
00162 
00163     ber_parse_header(s, BER_TAG_RESULT, &length);
00164     in_uint8(s, result);
00165     if (result != 0)
00166     {
00167         error("MCS connect: %d\n", result);
00168         return False;
00169     }
00170 
00171     ber_parse_header(s, BER_TAG_INTEGER, &length);
00172     in_uint8s(s, length);   /* connect id */
00173     mcs_parse_domain_params(s);
00174 
00175     ber_parse_header(s, BER_TAG_OCTET_STRING, &length);
00176 
00177     sec_process_mcs_data(s);
00178     /*
00179        if (length > mcs_data->size)
00180        {
00181        error("MCS data length %d, expected %d\n", length,
00182        mcs_data->size);
00183        length = mcs_data->size;
00184        }
00185 
00186        in_uint8a(s, mcs_data->data, length);
00187        mcs_data->p = mcs_data->data;
00188        mcs_data->end = mcs_data->data + length;
00189      */
00190     return s_check_end(s);
00191 }
00192 
00193 /* Send an EDrq message (ASN.1 PER) */
00194 static void
00195 mcs_send_edrq(void)
00196 {
00197     STREAM s;
00198 
00199     s = iso_init(5);
00200 
00201     out_uint8(s, (MCS_EDRQ << 2));
00202     out_uint16_be(s, 1);    /* height */
00203     out_uint16_be(s, 1);    /* interval */
00204 
00205     s_mark_end(s);
00206     iso_send(s);
00207 }
00208 
00209 /* Send an AUrq message (ASN.1 PER) */
00210 static void
00211 mcs_send_aurq(void)
00212 {
00213     STREAM s;
00214 
00215     s = iso_init(1);
00216 
00217     out_uint8(s, (MCS_AURQ << 2));
00218 
00219     s_mark_end(s);
00220     iso_send(s);
00221 }
00222 
00223 /* Expect a AUcf message (ASN.1 PER) */
00224 static BOOL
00225 mcs_recv_aucf(uint16 * mcs_userid)
00226 {
00227     uint8 opcode, result;
00228     STREAM s;
00229 
00230     s = iso_recv(NULL);
00231     if (s == NULL)
00232         return False;
00233 
00234     in_uint8(s, opcode);
00235     if ((opcode >> 2) != MCS_AUCF)
00236     {
00237         error("expected AUcf, got %d\n", opcode);
00238         return False;
00239     }
00240 
00241     in_uint8(s, result);
00242     if (result != 0)
00243     {
00244         error("AUrq: %d\n", result);
00245         return False;
00246     }
00247 
00248     if (opcode & 2)
00249         in_uint16_be(s, *mcs_userid);
00250 
00251     return s_check_end(s);
00252 }
00253 
00254 /* Send a CJrq message (ASN.1 PER) */
00255 static void
00256 mcs_send_cjrq(uint16 chanid)
00257 {
00258     STREAM s;
00259 
00260     DEBUG_RDP5(("Sending CJRQ for channel #%d\n", chanid));
00261 
00262     s = iso_init(5);
00263 
00264     out_uint8(s, (MCS_CJRQ << 2));
00265     out_uint16_be(s, g_mcs_userid);
00266     out_uint16_be(s, chanid);
00267 
00268     s_mark_end(s);
00269     iso_send(s);
00270 }
00271 
00272 /* Expect a CJcf message (ASN.1 PER) */
00273 static BOOL
00274 mcs_recv_cjcf(void)
00275 {
00276     uint8 opcode, result;
00277     STREAM s;
00278 
00279     s = iso_recv(NULL);
00280     if (s == NULL)
00281         return False;
00282 
00283     in_uint8(s, opcode);
00284     if ((opcode >> 2) != MCS_CJCF)
00285     {
00286         error("expected CJcf, got %d\n", opcode);
00287         return False;
00288     }
00289 
00290     in_uint8(s, result);
00291     if (result != 0)
00292     {
00293         error("CJrq: %d\n", result);
00294         return False;
00295     }
00296 
00297     in_uint8s(s, 4);    /* mcs_userid, req_chanid */
00298     if (opcode & 2)
00299         in_uint8s(s, 2);    /* join_chanid */
00300 
00301     return s_check_end(s);
00302 }
00303 
00304 /* Initialise an MCS transport data packet */
00305 STREAM
00306 mcs_init(int length)
00307 {
00308     STREAM s;
00309 
00310     s = iso_init(length + 8);
00311     s_push_layer(s, mcs_hdr, 8);
00312 
00313     return s;
00314 }
00315 
00316 /* Send an MCS transport data packet to a specific channel */
00317 void
00318 mcs_send_to_channel(STREAM s, uint16 channel)
00319 {
00320     uint16 length;
00321 
00322     s_pop_layer(s, mcs_hdr);
00323     length = s->end - s->p - 8;
00324     length |= 0x8000;
00325 
00326     out_uint8(s, (MCS_SDRQ << 2));
00327     out_uint16_be(s, g_mcs_userid);
00328     out_uint16_be(s, channel);
00329     out_uint8(s, 0x70); /* flags */
00330     out_uint16_be(s, length);
00331 
00332     iso_send(s);
00333 }
00334 
00335 /* Send an MCS transport data packet to the global channel */
00336 void
00337 mcs_send(STREAM s)
00338 {
00339     mcs_send_to_channel(s, MCS_GLOBAL_CHANNEL);
00340 }
00341 
00342 /* Receive an MCS transport data packet */
00343 STREAM
00344 mcs_recv(uint16 * channel, uint8 * rdpver)
00345 {
00346     uint8 opcode, appid, length;
00347     STREAM s;
00348 
00349     s = iso_recv(rdpver);
00350     if (s == NULL)
00351         return NULL;
00352     if (rdpver != NULL)
00353         if (*rdpver != 3)
00354             return s;
00355     in_uint8(s, opcode);
00356     appid = opcode >> 2;
00357     if (appid != MCS_SDIN)
00358     {
00359         if (appid != MCS_DPUM)
00360         {
00361             error("expected data, got %d\n", opcode);
00362         }
00363         return NULL;
00364     }
00365     in_uint8s(s, 2);    /* userid */
00366     in_uint16_be(s, *channel);
00367     in_uint8s(s, 1);    /* flags */
00368     in_uint8(s, length);
00369     if (length & 0x80)
00370         in_uint8s(s, 1);    /* second byte of length */
00371     return s;
00372 }
00373 
00374 /* Establish a connection up to the MCS layer */
00375 BOOL
00376 mcs_connect(char *server, STREAM mcs_data, char *username)
00377 {
00378     unsigned int i;
00379 
00380     if (!iso_connect(server, username))
00381         return False;
00382 
00383     mcs_send_connect_initial(mcs_data);
00384     if (!mcs_recv_connect_response(mcs_data))
00385         goto error;
00386 
00387     mcs_send_edrq();
00388 
00389     mcs_send_aurq();
00390     if (!mcs_recv_aucf(&g_mcs_userid))
00391         goto error;
00392 
00393     mcs_send_cjrq((uint16) (g_mcs_userid + MCS_USERCHANNEL_BASE));
00394 
00395     if (!mcs_recv_cjcf())
00396         goto error;
00397 
00398     mcs_send_cjrq(MCS_GLOBAL_CHANNEL);
00399     if (!mcs_recv_cjcf())
00400         goto error;
00401 
00402     for (i = 0; i < g_num_channels; i++)
00403     {
00404         mcs_send_cjrq(g_channels[i].mcs_id);
00405         if (!mcs_recv_cjcf())
00406             goto error;
00407     }
00408     return True;
00409 
00410       error:
00411     iso_disconnect();
00412     return False;
00413 }
00414 
00415 /* Establish a connection up to the MCS layer */
00416 BOOL
00417 mcs_reconnect(char *server, STREAM mcs_data)
00418 {
00419     unsigned int i;
00420 
00421     if (!iso_reconnect(server))
00422         return False;
00423 
00424     mcs_send_connect_initial(mcs_data);
00425     if (!mcs_recv_connect_response(mcs_data))
00426         goto error;
00427 
00428     mcs_send_edrq();
00429 
00430     mcs_send_aurq();
00431     if (!mcs_recv_aucf(&g_mcs_userid))
00432         goto error;
00433 
00434     mcs_send_cjrq((uint16) (g_mcs_userid + MCS_USERCHANNEL_BASE));
00435 
00436     if (!mcs_recv_cjcf())
00437         goto error;
00438 
00439     mcs_send_cjrq(MCS_GLOBAL_CHANNEL);
00440     if (!mcs_recv_cjcf())
00441         goto error;
00442 
00443     for (i = 0; i < g_num_channels; i++)
00444     {
00445         mcs_send_cjrq(g_channels[i].mcs_id);
00446         if (!mcs_recv_cjcf())
00447             goto error;
00448     }
00449     return True;
00450 
00451       error:
00452     iso_disconnect();
00453     return False;
00454 }
00455 
00456 /* Disconnect from the MCS layer */
00457 void
00458 mcs_disconnect(void)
00459 {
00460     iso_disconnect();
00461 }
00462 
00463 /* reset the state of the mcs layer */
00464 void
00465 mcs_reset_state(void)
00466 {
00467     g_mcs_userid = 0;
00468     iso_reset_state();
00469 }

Generated on Sat May 26 2012 04:16:05 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.