diff --git a/rdp/rdp_iso.c b/rdp/rdp_iso.c new file mode 100644 index 00000000..ead91d40 --- /dev/null +++ b/rdp/rdp_iso.c @@ -0,0 +1,196 @@ +/* + 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. + + xrdp: A Remote Desktop Protocol server. + Copyright (C) Jay Sorg 2005 + + librdp iso layer + +*/ + +#include "rdp.h" + +/*****************************************************************************/ +struct rdp_iso* APP_CC +rdp_iso_create(struct rdp_mcs* owner) +{ + struct rdp_iso* self; + + self = (struct rdp_iso*)g_malloc(sizeof(struct rdp_iso), 1); + self->mcs_layer = owner; + self->tcp_layer = rdp_tcp_create(self); + return self; +} + +/*****************************************************************************/ +void APP_CC +rdp_iso_delete(struct rdp_iso* self) +{ + if (self == 0) + { + return; + } + rdp_tcp_delete(self->tcp_layer); + g_free(self); +} + +/*****************************************************************************/ +/* returns error */ +static int APP_CC +rdp_iso_recv_msg(struct rdp_iso* self, struct stream* s, int* code) +{ + int ver; + int len; + + *code = 0; + if (rdp_tcp_recv(self->tcp_layer, s, 4) != 0) + { + return 1; + } + in_uint8(s, ver); + if (ver != 3) + { + return 1; + } + in_uint8s(s, 1); + in_uint16_be(s, len); + if (rdp_tcp_recv(self->tcp_layer, s, len - 4) != 0) + { + return 1; + } + in_uint8s(s, 1); + in_uint8(s, *code); + if (*code == ISO_PDU_DT) + { + in_uint8s(s, 1); + } + else + { + in_uint8s(s, 5); + } + return 0; +} + +/*****************************************************************************/ +static int APP_CC +rdp_iso_send_msg(struct rdp_iso* self, struct stream* s, int code) +{ + if (rdp_tcp_init(self->tcp_layer, s) != 0) + { + return 1; + } + out_uint8(s, 3); + out_uint8(s, 0); + out_uint16_be(s, 11); /* length */ + out_uint8(s, 8); + out_uint8(s, code); + out_uint16_le(s, 0); + out_uint16_le(s, 0); + out_uint8(s, 0); + s_mark_end(s); + if (rdp_tcp_send(self->tcp_layer, s) != 0) + { + return 1; + } + return 0; +} + +/*****************************************************************************/ +/* returns error */ +int APP_CC +rdp_iso_recv(struct rdp_iso* self, struct stream* s) +{ + int code; + + if (rdp_iso_recv_msg(self, s, &code) != 0) + { + return 1; + } + if (code != ISO_PDU_DT) + { + return 1; + } + return 0; +} + +/*****************************************************************************/ +/* returns error */ +int APP_CC +rdp_iso_init(struct rdp_iso* self, struct stream* s) +{ + rdp_tcp_init(self->tcp_layer, s); + s_push_layer(s, iso_hdr, 7); + return 0; +} + +/*****************************************************************************/ +/* returns error */ +int APP_CC +rdp_iso_send(struct rdp_iso* self, struct stream* s) +{ + int len; + + s_pop_layer(s, iso_hdr); + len = s->end - s->p; + out_uint8(s, 3); + out_uint8(s, 0); + out_uint16_be(s, len); + out_uint8(s, 2); + out_uint8(s, ISO_PDU_DT); + out_uint8(s, 0x80); + if (rdp_tcp_send(self->tcp_layer, s) != 0) + { + return 1; + } + return 0; +} + +/*****************************************************************************/ +/* returns error */ +int APP_CC +rdp_iso_connect(struct rdp_iso* self, char* ip, char* port) +{ + int code; + struct stream* s; + + make_stream(s); + init_stream(s, 8192); + if (rdp_tcp_connect(self->tcp_layer, ip, port) != 0) + { + free_stream(s); + return 1; + } + if (rdp_iso_send_msg(self, s, ISO_PDU_CR) != 0) + { + free_stream(s); + rdp_tcp_disconnect(self->tcp_layer); + return 1; + } + init_stream(s, 8192); + if (rdp_iso_recv_msg(self, s, &code) != 0) + { + free_stream(s); + rdp_tcp_disconnect(self->tcp_layer); + return 1; + } + if (code != ISO_PDU_CC) + { + free_stream(s); + rdp_tcp_disconnect(self->tcp_layer); + return 1; + } + free_stream(s); + return 0; +}