diff --git a/mppc.c b/mppc.c index e5525ce..64a978e 100644 --- a/mppc.c +++ b/mppc.c @@ -3,7 +3,7 @@ #include "rdesktop.h" -/* mppc-like??? decompression */ +/* mppc decompression */ /* http://www.faqs.org/rfcs/rfc2118.html */ /* TODO: research the below statements */ @@ -18,11 +18,15 @@ /* already paying royalties */ /* through the CAL licenses? */ -/* the dictionary is empty when init. like */ -/* LZ78, which is not patented */ +/* as the rfc states the algorithm seems to */ +/* be LZ77 with a sliding buffer */ +/* that is empty at init. */ + +/* as of my limited knowledge these patents */ +/* has expired. */ -RDPCOMP mppc_dict; +RDPCOMP g_mppc_dict; int mppc_expand(uint8 * data, uint32 clen, uint8 ctype, uint32 * roff, uint32 * rlen) @@ -33,7 +37,7 @@ mppc_expand(uint8 * data, uint32 clen, uint8 ctype, uint32 * roff, uint32 * rlen int match_len; int old_offset, match_bits; - signed char *dict = &(mppc_dict.hist); + signed char *dict = &(g_mppc_dict.hist); if ((ctype & RDP_MPPC_COMPRESSED) == 0) { @@ -44,19 +48,19 @@ mppc_expand(uint8 * data, uint32 clen, uint8 ctype, uint32 * roff, uint32 * rlen if ((ctype & RDP_MPPC_RESET) != 0) { - mppc_dict.roff = 0; + g_mppc_dict.roff = 0; } if ((ctype & RDP_MPPC_FLUSH) != 0) { memset(dict, 0, RDP_MPPC_DICT_SIZE); - mppc_dict.roff = 0; + g_mppc_dict.roff = 0; } *roff = 0; *rlen = 0; - walker = mppc_dict.roff; + walker = g_mppc_dict.roff; next_offset = walker; old_offset = next_offset; @@ -267,7 +271,7 @@ mppc_expand(uint8 * data, uint32 clen, uint8 ctype, uint32 * roff, uint32 * rlen while (1); /* store history offset */ - mppc_dict.roff = next_offset; + g_mppc_dict.roff = next_offset; *roff = old_offset; *rlen = next_offset - old_offset; diff --git a/rdp.c b/rdp.c index 0805995..c236702 100644 --- a/rdp.c +++ b/rdp.c @@ -38,7 +38,7 @@ extern BOOL g_bitmap_cache; uint8 *g_next_packet; uint32 g_rdp_shareid; -extern RDPCOMP mppc_dict; +extern RDPCOMP g_mppc_dict; #if WITH_DEBUG static uint32 g_packetno; @@ -176,16 +176,16 @@ rdp_send_logon_info(uint32 flags, char *domain, char *user, time_t t = time(NULL); time_t tzone; +#if 0 + /* enable rdp compression */ + /* some problems still exist with rdp5 */ + flags |= RDP_COMPRESSION; +#endif + if (!g_use_rdp5 || 1 == g_server_rdp_version) { DEBUG_RDP5(("Sending RDP4-style Logon packet\n")); -#if 0 - /* enable rdp compression */ - /* decompression also works with rdp5 */ - /* but there are some unknown opcodes */ - flags |= RDP_COMPRESSION; -#endif s = sec_init(sec_flags, 18 + len_domain + len_user + len_password + len_program + len_directory + 10); @@ -962,8 +962,7 @@ process_data_pdu(STREAM s, uint32 * ext_disc_reason) uint32 roff, rlen; - struct stream *ns = &(mppc_dict.ns); - uint8 *dict = (mppc_dict.hist); + struct stream *ns = &(g_mppc_dict.ns); in_uint8s(s, 6); /* shareid, pad, streamid */ in_uint16(s, len); @@ -978,18 +977,14 @@ process_data_pdu(STREAM s, uint32 * ext_disc_reason) if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1) error("error while decompressing packet\n"); - len -= 18; - - /* this should never happen */ - if (len != rlen) - error("decompression error len != rlen\n"); + //len -= 18; /* allocate memory and copy the uncompressed data into the temporary stream */ - ns->data = xrealloc(ns->data, len); + ns->data = xrealloc(ns->data, rlen); - memcpy((ns->data), (unsigned char *) (mppc_dict.hist + roff), len); + memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen); - ns->size = len; + ns->size = rlen; ns->end = (ns->data + ns->size); ns->p = ns->data; ns->rdp_hdr = ns->p; diff --git a/rdp5.c b/rdp5.c index b07d051..7269065 100644 --- a/rdp5.c +++ b/rdp5.c @@ -23,13 +23,19 @@ extern uint8 *g_next_packet; +extern RDPCOMP g_mppc_dict; + void rdp5_process(STREAM s, BOOL encryption) { uint16 length, count, x, y; - uint8 type; + uint8 type, ctype; uint8 *next; + uint32 roff, rlen; + struct stream *ns = &(g_mppc_dict.ns); + struct stream *ts; + if (encryption) { in_uint8s(s, 8); /* signature */ @@ -44,9 +50,40 @@ rdp5_process(STREAM s, BOOL encryption) while (s->p < s->end) { in_uint8(s, type); - in_uint16_le(s, length); + if (type & RDP_COMPRESSION) + { + in_uint8(s, ctype); + in_uint16_le(s, length); + type ^= RDP_COMPRESSION; + } + else + { + ctype = 0; + in_uint16_le(s, length); + } g_next_packet = next = s->p + length; + if (ctype & RDP_MPPC_COMPRESSED) + { + + if (mppc_expand(s->p, length, ctype, &roff, &rlen) == -1) + error("error while decompressing packet\n"); + + /* allocate memory and copy the uncompressed data into the temporary stream */ + ns->data = xrealloc(ns->data, rlen); + + memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen); + + ns->size = rlen; + ns->end = (ns->data + ns->size); + ns->p = ns->data; + ns->rdp_hdr = ns->p; + + ts = ns; + } + else + ts = s; + switch (type) { /* Thanks to Jeroen Meijer