mcs.c revision 4b9d6701570cb98fd36e209314239d104ec584d3
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Protocol services - Multipoint Communications Service
Copyright (C) Matthew Chapman 1999-2007
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* Oracle GPL Disclaimer: For the avoidance of doubt, except that if any license choice
* other than GPL or LGPL is available it will apply instead, Oracle elects to use only
* the General Public License version 2 (GPLv2) at this time for any software where
* a choice of GPL license versions is made available with the language indicating
* that GPLv2 or any later version may be used, or where a choice of which version
* of the GPL is applied is otherwise unspecified.
*/
#include "rdesktop.h"
extern VCHANNEL g_channels[];
extern unsigned int g_num_channels;
/* Parse an ASN.1 BER header */
static RD_BOOL
{
if (tagval > 0xff)
{
in_uint16_be(s, tag);
}
else
{
}
{
return False;
}
if (len & 0x80)
{
len &= ~0x80;
*length = 0;
while (len--)
}
else
return s_check(s);
}
/* Output an ASN.1 BER header */
static void
{
if (tagval > 0xff)
{
out_uint16_be(s, tagval);
}
else
{
}
if (length >= 0x80)
{
out_uint8(s, 0x82);
out_uint16_be(s, length);
}
else
}
/* Output an ASN.1 BER integer */
static void
{
out_uint16_be(s, value);
}
/* Output a DOMAIN_PARAMS structure (ASN.1 BER) */
static void
{
ber_out_integer(s, max_users);
ber_out_integer(s, 0); /* min_throughput */
}
/* Parse a DOMAIN_PARAMS structure (ASN.1 BER) */
static RD_BOOL
{
int length;
return s_check(s);
}
/* Send an MCS_CONNECT_INITIAL message (ASN.1 BER) */
static void
{
STREAM s;
out_uint8(s, 1);
out_uint8(s, 1);
s_mark_end(s);
iso_send(s);
}
/* Expect a MCS_CONNECT_RESPONSE message (ASN.1 BER) */
static RD_BOOL
{
int length;
STREAM s;
if (s == NULL)
return False;
if (result != 0)
{
return False;
}
/*
if (length > mcs_data->size)
{
error("MCS data length %d, expected %d\n", length,
mcs_data->size);
length = mcs_data->size;
}
in_uint8a(s, mcs_data->data, length);
mcs_data->p = mcs_data->data;
mcs_data->end = mcs_data->data + length;
*/
return s_check_end(s);
}
/* Send an EDrq message (ASN.1 PER) */
static void
mcs_send_edrq(void)
{
STREAM s;
s = iso_init(5);
s_mark_end(s);
iso_send(s);
}
/* Send an AUrq message (ASN.1 PER) */
static void
mcs_send_aurq(void)
{
STREAM s;
s = iso_init(1);
s_mark_end(s);
iso_send(s);
}
/* Expect a AUcf message (ASN.1 PER) */
static RD_BOOL
{
STREAM s;
if (s == NULL)
return False;
{
return False;
}
if (result != 0)
{
return False;
}
if (opcode & 2)
in_uint16_be(s, *mcs_userid);
return s_check_end(s);
}
/* Send a CJrq message (ASN.1 PER) */
static void
{
STREAM s;
s = iso_init(5);
out_uint16_be(s, chanid);
s_mark_end(s);
iso_send(s);
}
/* Expect a CJcf message (ASN.1 PER) */
static RD_BOOL
mcs_recv_cjcf(void)
{
STREAM s;
if (s == NULL)
return False;
{
return False;
}
if (result != 0)
{
return False;
}
if (opcode & 2)
return s_check_end(s);
}
/* Initialise an MCS transport data packet */
{
STREAM s;
return s;
}
/* Send an MCS transport data packet to a specific channel */
void
{
s_pop_layer(s, mcs_hdr);
length |= 0x8000;
out_uint16_be(s, channel);
out_uint16_be(s, length);
iso_send(s);
}
/* Send an MCS transport data packet to the global channel */
void
{
}
/* Receive an MCS transport data packet */
{
STREAM s;
if (s == NULL)
return NULL;
if (*rdpver != 3)
return s;
{
{
}
return NULL;
}
in_uint16_be(s, *channel);
if (length & 0x80)
return s;
}
/* Establish a connection up to the MCS layer */
{
unsigned int i;
return False;
goto error;
if (!mcs_recv_aucf(&g_mcs_userid))
goto error;
if (!mcs_recv_cjcf())
goto error;
if (!mcs_recv_cjcf())
goto error;
for (i = 0; i < g_num_channels; i++)
{
if (!mcs_recv_cjcf())
goto error;
}
return True;
return False;
}
/* Establish a connection up to the MCS layer */
{
unsigned int i;
if (!iso_reconnect(server))
return False;
goto error;
if (!mcs_recv_aucf(&g_mcs_userid))
goto error;
if (!mcs_recv_cjcf())
goto error;
if (!mcs_recv_cjcf())
goto error;
for (i = 0; i < g_num_channels; i++)
{
if (!mcs_recv_cjcf())
goto error;
}
return True;
return False;
}
/* Disconnect from the MCS layer */
void
mcs_disconnect(void)
{
}
/* reset the state of the mcs layer */
void
mcs_reset_state(void)
{
g_mcs_userid = 0;
}