--- sourceforge.net/trunk/rdesktop/iso.c 2001/01/06 03:12:10 24 +++ sourceforge.net/trunk/rdesktop/iso.c 2003/08/11 11:08:19 439 @@ -1,7 +1,7 @@ -/* +/* -*- c-basic-offset: 8 -*- rdesktop: A Remote Desktop Protocol client. Protocol services - ISO layer - Copyright (C) Matthew Chapman 1999-2000 + Copyright (C) Matthew Chapman 1999-2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,7 +21,8 @@ #include "rdesktop.h" /* Send a self-contained ISO PDU */ -static void iso_send_msg(uint8 code) +static void +iso_send_msg(uint8 code) { STREAM s; @@ -41,30 +42,78 @@ tcp_send(s); } +static void +iso_send_connection_request(char *username) +{ + STREAM s; + int length = 30 + strlen(username); + + s = tcp_init(length); + + out_uint8(s, 3); /* version */ + out_uint8(s, 0); /* reserved */ + out_uint16_be(s, length); /* length */ + + out_uint8(s, length - 5); /* hdrlen */ + out_uint8(s, ISO_PDU_CR); + out_uint16(s, 0); /* dst_ref */ + out_uint16(s, 0); /* src_ref */ + out_uint8(s, 0); /* class */ + + out_uint8p(s, "Cookie: mstshash=", strlen("Cookie: mstshash=")); + out_uint8p(s, username, strlen(username)); + + out_uint8(s, 0x0d); /* Unknown */ + out_uint8(s, 0x0a); /* Unknown */ + + s_mark_end(s); + tcp_send(s); +} + /* Receive a message on the ISO layer, return code */ -static STREAM iso_recv_msg(uint8 *code) +static STREAM +iso_recv_msg(uint8 * code) { STREAM s; uint16 length; uint8 version; - s = tcp_recv(4); + next_packet: + s = tcp_recv(NULL, 4); if (s == NULL) - return False; + return NULL; in_uint8(s, version); - if (version != 3) + switch (version & 3) { - ERROR("TPKT v%d\n", version); - return False; + case 0: + in_uint8(s, length); + if (length & 0x80) + { + length &= ~0x80; + next_be(s, length); + } + break; + + case 3: + in_uint8s(s, 1); /* pad */ + in_uint16_be(s, length); + break; + + default: + error("TPKT v%d\n", version); + return NULL; } - in_uint8s(s, 1); /* pad */ - in_uint16_be(s, length); - - s = tcp_recv(length - 4); + s = tcp_recv(s, length - 4); if (s == NULL) - return False; + return NULL; + + if ((version & 3) == 0) + { + rdp5_process(s, version & 0x80); + goto next_packet; + } in_uint8s(s, 1); /* hdrlen */ in_uint8(s, *code); @@ -80,7 +129,8 @@ } /* Initialise ISO transport data packet */ -STREAM iso_init(int length) +STREAM +iso_init(int length) { STREAM s; @@ -91,7 +141,8 @@ } /* Send an ISO data PDU */ -void iso_send(STREAM s) +void +iso_send(STREAM s) { uint16 length; @@ -110,34 +161,42 @@ } /* Receive ISO transport data packet */ -STREAM iso_recv() +STREAM +iso_recv(void) { STREAM s; uint8 code; s = iso_recv_msg(&code); - if ((s == NULL) || (code != ISO_PDU_DT)) + if (s == NULL) + return NULL; + + if (code != ISO_PDU_DT) { - ERROR("expected DT, got %d\n", code); - return False; + error("expected DT, got 0x%x\n", code); + return NULL; } return s; } /* Establish a connection up to the ISO layer */ -BOOL iso_connect(char *server) +BOOL +iso_connect(char *server, char *username) { uint8 code; if (!tcp_connect(server)) return False; - iso_send_msg(ISO_PDU_CR); + iso_send_connection_request(username); + + if (iso_recv_msg(&code) == NULL) + return False; - if ((iso_recv_msg(&code) == NULL) || (code != ISO_PDU_CC)) + if (code != ISO_PDU_CC) { - ERROR("expected CC, got %d\n", code); + error("expected CC, got 0x%x\n", code); tcp_disconnect(); return False; } @@ -146,7 +205,8 @@ } /* Disconnect from the ISO layer */ -void iso_disconnect() +void +iso_disconnect(void) { iso_send_msg(ISO_PDU_DR); tcp_disconnect();