X-Git-Url: https://git.sesse.net/?p=rdpsrv;a=blobdiff_plain;f=rdp.c;h=538e053ae821ea14f089036fd2c40c32aaf4dc02;hp=11ed6f914d859cfb29c68a716a985375bee64683;hb=55a546ab6b5970438e6cca1a962ec4e7dd669d11;hpb=63fa9a9043d4a58ee7994e669bcc566f09bc9e9b diff --git a/rdp.c b/rdp.c index 11ed6f9..538e053 100644 --- a/rdp.c +++ b/rdp.c @@ -72,7 +72,7 @@ rdp_recv(uint8 * type) #if WITH_DEBUG DEBUG(("RDP packet #%d, (type %x, length %u)\n", ++g_packetno, *type, length)); - hexdump(g_next_packet, length); + //hexdump(g_next_packet, length); #endif /* */ g_next_packet += length; @@ -80,7 +80,7 @@ rdp_recv(uint8 * type) } /* Initialise an RDP data packet */ -static STREAM +STREAM rdp_init_data(int maxlen) { STREAM s; @@ -92,7 +92,7 @@ rdp_init_data(int maxlen) } /* Send an RDP data packet */ -static void +void rdp_send_data(STREAM s, uint8 data_pdu_type) { uint16 length; @@ -132,6 +132,159 @@ rdp_out_unistr(STREAM s, char *string, int len) s->p += len; } +/* Input a string in Unicode (uuuuuuugly, use iconv later) */ +void +rdp_in_unistr(STREAM s, char *string, int len) +{ + int i = 0, j = 0; + len += 2; + + while (i < len) + { + string[j++] = s->p[i]; + i += 2; + } + + s->p += len; +} + +void rdp_send_bitmap_update(unsigned x, unsigned y, unsigned width, unsigned height, unsigned char *data) +{ + STREAM s; + + int length = 10*2 + width*height*3 + 5; + + s = rdp5_init(length, 0); + + out_uint8(s, 1); // process bitmap update + out_uint16_le(s, 10*2 + width*height*3 + 2); // RDP5 chunk length + out_uint16_le(s, 10*2 + width*height*3); // part length + + out_uint16_le(s, 1); // one update + out_uint16_le(s, x); // left, top, right, bottom + out_uint16_le(s, y); + out_uint16_le(s, x+width); + out_uint16_le(s, y+height); + out_uint16_le(s, width); // width, height + out_uint16_le(s, height); + out_uint16_le(s, 24); // bpp + out_uint16_le(s, 0); // no compression + out_uint16_le(s, width*height*3); // bufsize + + out_uint8p(s, data, width*height*3); + + s_mark_end(s); + rdp5_send(s, 0); +} + +#define EXPECT16(value) { in_uint16_le(s, unknown); if (unknown != (value)) printf("Unknown value on code line %u; expected 0x%x, got 0x%x\n", __LINE__, (value), unknown); } +#define EXPECT32(value) { in_uint32_le(s, unknown); if (unknown != (value)) printf("Unknown value on code line %u; expected 0x%x, got 0x%x\n", __LINE__, (value), unknown); } + +void +rdp_get_logon_info(STREAM s) +{ + uint32 flags, unknown; + uint16 tzone_major, tzone_minor; + int len_domain, len_user, len_password, len_program, len_directory, len_ip, len_dll; + char domain[256], user[256], password[256], program[256], directory[256], ip[256], dll[256], tz1[256], tz2[256]; // FIXME + + in_uint32_le(s, unknown); + in_uint32_le(s, flags); + + printf("logon flags: %x\n", flags); + + if (flags & RDP_LOGON_BLOB) { + printf("RDP5-style logon packet\n"); + + in_uint16_le(s, len_domain); + in_uint16_le(s, len_user); + + if (flags & RDP_LOGON_AUTO) { + in_uint16_le(s, len_password); + } else { + strcpy(password, ""); + } + if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO)) { + // is this too some kind of length? + EXPECT16(0); + } + in_uint16_le(s, len_program); + in_uint16_le(s, len_directory); + + rdp_in_unistr(s, domain, len_domain); + rdp_in_unistr(s, user, len_user); + + if (flags & RDP_LOGON_AUTO) + rdp_in_unistr(s, password, len_password); + + if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO)) + EXPECT16(0); + + rdp_in_unistr(s, program, len_program); + rdp_in_unistr(s, directory, len_directory); + + EXPECT16(2); + + in_uint16_le(s, len_ip); + rdp_in_unistr(s, ip, len_ip - 2); + + in_uint16_le(s, len_dll); + rdp_in_unistr(s, dll, len_dll - 2); + + in_uint16_le(s, tzone_major); + in_uint16_le(s, tzone_minor); + + // time zone names? + rdp_in_unistr(s, tz1, 62); + EXPECT32(0x0a0000); + EXPECT32(0x050000); + EXPECT32(3); + EXPECT32(0); + EXPECT32(0); + + rdp_in_unistr(s, tz2, 62); + EXPECT32(0x030000); + EXPECT32(0x050000); + EXPECT32(2); + EXPECT32(0); + EXPECT32(0xffffffc4); + EXPECT32(0xfffffffe); + EXPECT32(0x0f); + EXPECT32(0); + + printf("domain='%s'\n", domain); + printf("user='%s'\n", user); + printf("password='%s'\n", password); + printf("program='%s'\n", program); + printf("directory='%s'\n", directory); + printf("ip='%s'\n", ip); + printf("dll='%s'\n", dll); + printf("timezone=%d:%02d\n", tzone_major, tzone_minor); + printf("tz1='%64s'\n", tz1); + printf("tz2='%64s'\n", tz2); + } else { + in_uint16_le(s, len_domain); + in_uint16_le(s, len_user); + in_uint16_le(s, len_password); + in_uint16_le(s, len_program); + in_uint16_le(s, len_directory); + rdp_in_unistr(s, domain, len_domain); + rdp_in_unistr(s, user, len_user); + rdp_in_unistr(s, password, len_password); + rdp_in_unistr(s, program, len_program); + rdp_in_unistr(s, directory, len_directory); + + printf("domain='%s'\n", domain); + printf("user='%s'\n", user); + printf("password='%s'\n", password); + printf("program='%s'\n", program); + printf("directory='%s'\n", directory); + } + + if (!s_check_end(s)) { + printf("Unknown data at end of logon packet!\n"); + } +} /* Send a control PDU */ static void @@ -164,25 +317,15 @@ rdp_send_synchronise(void) rdp_send_data(s, RDP_DATA_PDU_SYNCHRONISE); } -/* Send a single input event */ +/* Receive a single input event */ void -rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, uint16 param2) +rdp_recv_input(STREAM s, uint32 *time, uint16 *message_type, uint16 *device_flags, uint16 *param1, uint16 *param2) { - STREAM s; - - s = rdp_init_data(16); - - out_uint16_le(s, 1); /* number of events */ - out_uint16(s, 0); /* pad */ - - out_uint32_le(s, time); - out_uint16_le(s, message_type); - out_uint16_le(s, device_flags); - out_uint16_le(s, param1); - out_uint16_le(s, param2); - - s_mark_end(s); - rdp_send_data(s, RDP_DATA_PDU_INPUT); + in_uint32_le(s, *time); + in_uint16_le(s, *message_type); + in_uint16_le(s, *device_flags); + in_uint16_le(s, *param1); + in_uint16_le(s, *param2); } /* Disconnect from the RDP layer */