--- sourceforge.net/trunk/rdesktop/iso.c 2001/01/06 03:12:10 24 +++ sourceforge.net/trunk/rdesktop/iso.c 2004/07/05 19:09:07 733 @@ -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,46 +42,81 @@ 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, uint8 * rdpver) { STREAM s; uint16 length; uint8 version; - s = tcp_recv(4); + s = tcp_recv(NULL, 4); if (s == NULL) - return False; - + return NULL; in_uint8(s, version); - if (version != 3) + if (rdpver != NULL) + *rdpver = version; + if (version == 3) { - ERROR("TPKT v%d\n", version); - return False; + in_uint8s(s, 1); /* pad */ + in_uint16_be(s, length); } - - in_uint8s(s, 1); /* pad */ - in_uint16_be(s, length); - - s = tcp_recv(length - 4); + else + { + in_uint8(s, length); + if (length & 0x80) + { + length &= ~0x80; + next_be(s, length); + } + } + s = tcp_recv(s, length - 4); if (s == NULL) - return False; - + return NULL; + if (version != 3) + return s; in_uint8s(s, 1); /* hdrlen */ in_uint8(s, *code); - if (*code == ISO_PDU_DT) { in_uint8s(s, 1); /* eot */ return s; } - in_uint8s(s, 5); /* dst_ref, src_ref, class */ return s; } /* Initialise ISO transport data packet */ -STREAM iso_init(int length) +STREAM +iso_init(int length) { STREAM s; @@ -91,7 +127,8 @@ } /* Send an ISO data PDU */ -void iso_send(STREAM s) +void +iso_send(STREAM s) { uint16 length; @@ -110,34 +147,43 @@ } /* Receive ISO transport data packet */ -STREAM iso_recv() +STREAM +iso_recv(uint8 * rdpver) { STREAM s; - uint8 code; + uint8 code = 0; - s = iso_recv_msg(&code); - if ((s == NULL) || (code != ISO_PDU_DT)) + s = iso_recv_msg(&code, rdpver); + if (s == NULL) + return NULL; + if (rdpver != NULL) + if (*rdpver != 3) + return s; + 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; + uint8 code = 0; if (!tcp_connect(server)) return False; - iso_send_msg(ISO_PDU_CR); + iso_send_connection_request(username); + + if (iso_recv_msg(&code, NULL) == 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 +192,8 @@ } /* Disconnect from the ISO layer */ -void iso_disconnect() +void +iso_disconnect(void) { iso_send_msg(ISO_PDU_DR); tcp_disconnect();