From: Steinar H. Gunderson Date: Thu, 3 Feb 2005 22:35:45 +0000 (+0000) Subject: Pull in lots of protocol stuff from rdesktop. X-Git-Url: https://git.sesse.net/?p=rdpsrv;a=commitdiff_plain;h=46f3372353ccdd654ef45f0b73128c16fb057e58;ds=sidebyside Pull in lots of protocol stuff from rdesktop. --- diff --git a/Makefile b/Makefile index fb58bb3..c76e30b 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ all: rdpsrv -OBJS=rdpsrv.o +OBJS=rdpsrv.o iso.o tcp.o util.o rdpsrv: $(OBJS) - $(CXX) -o rdpsrv $(OBJS) + $(CC) -o rdpsrv $(OBJS) clean: $(RM) $(OBJS) rdpsrv diff --git a/iso.c b/iso.c new file mode 100644 index 0000000..26e967b --- /dev/null +++ b/iso.c @@ -0,0 +1,215 @@ +/* -*- c-basic-offset: 8 -*- + rdesktop: A Remote Desktop Protocol client. + Protocol services - ISO layer + 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 + 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. +*/ + +#include "rdesktop.h" + +/* Send a self-contained ISO PDU */ +static void +iso_send_msg(uint8 code) +{ + STREAM s; + + s = tcp_init(11); + + out_uint8(s, 3); /* version */ + out_uint8(s, 0); /* reserved */ + out_uint16_be(s, 11); /* length */ + + out_uint8(s, 6); /* hdrlen */ + out_uint8(s, code); + out_uint16(s, 0); /* dst_ref */ + out_uint16(s, 0); /* src_ref */ + out_uint8(s, 0); /* class */ + + s_mark_end(s); + 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) +{ + STREAM s; + uint16 length; + uint8 version; + + next_packet: + s = tcp_recv(NULL, 4); + if (s == NULL) + return NULL; + + in_uint8(s, version); + switch (version & 3) + { + 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; + } + + s = tcp_recv(s, length - 4); + if (s == NULL) + return NULL; + + if ((version & 3) == 0) + { + // FIXME :-) + // rdp5_process(s, version & 0x80); + printf("rdp5_process()\n"); + goto next_packet; + } + + 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 s; + + s = tcp_init(length + 7); + s_push_layer(s, iso_hdr, 7); + + return s; +} + +/* Send an ISO data PDU */ +void +iso_send(STREAM s) +{ + uint16 length; + + s_pop_layer(s, iso_hdr); + length = s->end - s->p; + + out_uint8(s, 3); /* version */ + out_uint8(s, 0); /* reserved */ + out_uint16_be(s, length); + + out_uint8(s, 2); /* hdrlen */ + out_uint8(s, ISO_PDU_DT); /* code */ + out_uint8(s, 0x80); /* eot */ + + tcp_send(s); +} + +/* Receive ISO transport data packet */ +STREAM +iso_recv(void) +{ + STREAM s; + uint8 code; + + s = iso_recv_msg(&code); + if (s == NULL) + return NULL; + + if (code != ISO_PDU_DT) + { + 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, char *username) +{ + uint8 code; + + if (!tcp_connect(server)) + return False; + + iso_send_connection_request(username); + + if (iso_recv_msg(&code) == NULL) + return False; + + if (code != ISO_PDU_CC) + { + error("expected CC, got 0x%x\n", code); + tcp_disconnect(); + return False; + } + + return True; +} + +/* Disconnect from the ISO layer */ +void +iso_disconnect(void) +{ + iso_send_msg(ISO_PDU_DR); + tcp_disconnect(); +} diff --git a/rdpsrv.cpp b/rdpsrv.c similarity index 77% rename from rdpsrv.cpp rename to rdpsrv.c index ea4892f..5b1603d 100644 --- a/rdpsrv.cpp +++ b/rdpsrv.c @@ -6,23 +6,24 @@ #include #include -static const int RDP_PORT = 3389; +const int tcp_port_rdp = 3389; int create_server_socket(); +int serve_client(int sock); int main() { int server_sock = create_server_socket(); for ( ;; ) { - sockaddr_in sin; + struct sockaddr_in sin; socklen_t len; - int sock = accept(server_sock, (sockaddr *)&sin, &len); + int sock = accept(server_sock, (struct sockaddr *)&sin, &len); if (sock == -1) { perror("accept()"); exit(1); } - printf("Got socket.\n"); + serve_client(sock); close(sock); } @@ -40,7 +41,7 @@ int create_server_socket() addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; - addr.sin_port = htons(RDP_PORT); + addr.sin_port = htons(tcp_port_rdp); do { err = bind(server_sock, (struct sockaddr *)&addr, sizeof(struct sockaddr)); @@ -63,3 +64,13 @@ int create_server_socket() return server_sock; } + +int serve_client(int sock) +{ + for ( ;; ) { + unsigned char buf[4096]; + + /* receive ISO packets */ + + } +}