From 209720fe1ae1733d905a3107f31e9d20c53ae062 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Thu, 5 Apr 2012 15:40:46 -0700 Subject: [PATCH] libxrdp: user freerdp mppc compressor --- configure.ac | 2 ++ libxrdp/Makefile.am | 28 +++++++++++++--- libxrdp/libxrdp.h | 1 + libxrdp/xrdp_rdp.c | 81 +++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 101 insertions(+), 11 deletions(-) diff --git a/configure.ac b/configure.ac index 5330143e..4ddd409f 100644 --- a/configure.ac +++ b/configure.ac @@ -28,6 +28,8 @@ AC_ARG_ENABLE(freerdp1, AS_HELP_STRING([--enable-freerdp1], [freerdp1=true], [freerdp1=false]) AM_CONDITIONAL(XRDP_FREERDP1, [test x$freerdp1 = xtrue]) +AM_CONDITIONAL(GOT_PREFIX, test "x${prefix}" != "xNONE"]) + # checking for openssl AC_CHECK_HEADER([openssl/rc4.h], [], [AC_MSG_ERROR([please install libssl-dev or openssl-devel])], diff --git a/libxrdp/Makefile.am b/libxrdp/Makefile.am index 9b85f7f7..057c1fda 100644 --- a/libxrdp/Makefile.am +++ b/libxrdp/Makefile.am @@ -1,9 +1,24 @@ EXTRA_DIST = libxrdp.h libxrdpinc.h +EXTRA_DEFINES = +EXTRA_INCLUDES = +EXTRA_LIBS = +EXTRA_FLAGS = + if XRDP_DEBUG -EXTRA_DEFINES = -DXRDP_DEBUG +EXTRA_DEFINES += -DXRDP_DEBUG else -EXTRA_DEFINES = -DXRDP_NODEBUG +EXTRA_DEFINES += -DXRDP_NODEBUG +endif + +if XRDP_FREERDP1 +EXTRA_DEFINES += -DXRDP_FREERDP1 +EXTRA_LIBS += -lfreerdp-codec +endif + +if GOT_PREFIX +EXTRA_INCLUDES += -I$(prefix)/include +EXTRA_FLAGS += -L$(prefix)/lib -Wl,-rpath -Wl,$(prefix)/lib endif AM_CFLAGS = \ @@ -14,7 +29,8 @@ AM_CFLAGS = \ $(EXTRA_DEFINES) INCLUDES = \ - -I$(top_srcdir)/common + -I$(top_srcdir)/common \ + $(EXTRA_INCLUDES) lib_LTLIBRARIES = \ libxrdp.la @@ -30,5 +46,9 @@ libxrdp_la_SOURCES = \ xrdp_tcp.c \ xrdp_bitmap_compress.c +libxrdp_la_LDFLAGS = \ + $(EXTRA_FLAGS) + libxrdp_la_LIBADD = \ - $(top_srcdir)/common/libcommon.la + $(top_srcdir)/common/libcommon.la \ + $(EXTRA_LIBS) diff --git a/libxrdp/libxrdp.h b/libxrdp/libxrdp.h index 0877d35e..6f622808 100644 --- a/libxrdp/libxrdp.h +++ b/libxrdp/libxrdp.h @@ -117,6 +117,7 @@ struct xrdp_rdp int share_id; int mcs_channel; struct xrdp_client_info client_info; + void* mppc_enc; }; /* state */ diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c index 78d0762c..c64f0a61 100644 --- a/libxrdp/xrdp_rdp.c +++ b/libxrdp/xrdp_rdp.c @@ -22,6 +22,10 @@ #include "libxrdp.h" +#if defined(XRDP_FREERDP1) +#include +#endif + /* some compilers need unsigned char to avoid warnings */ static tui8 g_unknown1[172] = { 0xff, 0x02, 0xb6, 0x00, 0x28, 0x00, 0x00, 0x00, @@ -150,6 +154,9 @@ xrdp_rdp_create(struct xrdp_session* session, struct trans* trans) self->client_info.cache3_entries = 262; self->client_info.cache3_size = 4096; g_write_ip_address(trans->sck, self->client_info.client_ip); /* load client ip info */ +#if defined(XRDP_FREERDP1) + self->mppc_enc = mppc_enc_new(PROTO_RDP_50); +#endif DEBUG(("out xrdp_rdp_create")); return self; } @@ -163,6 +170,9 @@ xrdp_rdp_delete(struct xrdp_rdp* self) return; } xrdp_sec_delete(self->sec_layer); +#if defined(XRDP_FREERDP1) + mppc_enc_free((struct rdp_mppc_enc*)(self->mppc_enc)); +#endif g_free(self); } @@ -278,21 +288,78 @@ int APP_CC xrdp_rdp_send_data(struct xrdp_rdp* self, struct stream* s, int data_pdu_type) { - int len = 0; + int len; + int ctype; + int clen; + int dlen; + int pdulen; + int pdutype; + int tocomplen; + int iso_offset; + int mcs_offset; + int sec_offset; + int rdp_offset; + struct stream ls; + struct rdp_mppc_enc* mppc_enc; DEBUG(("in xrdp_rdp_send_data")); s_pop_layer(s, rdp_hdr); - len = s->end - s->p; - out_uint16_le(s, len); - out_uint16_le(s, 0x10 | RDP_PDU_DATA); + len = (int)(s->end - s->p); + pdutype = 0x10 | RDP_PDU_DATA; + pdulen = len; + dlen = len; + ctype = 0; + clen = len; + tocomplen = pdulen - 18; + if (self->client_info.rdp_compression && self->session->up_and_running) + { + mppc_enc = (struct rdp_mppc_enc*)(self->mppc_enc); + if (compress_rdp(mppc_enc, s->p + 18, tocomplen)) + { + DEBUG(("mppc_encode ok flags 0x%x bytes_in_opb %d historyOffset %d " + "tocomplen %d", mppc_enc->flags, mppc_enc->bytes_in_opb, + mppc_enc->historyOffset, tocomplen)); + if (mppc_enc->flags & RDP_MPPC_COMPRESSED) + { + clen = mppc_enc->bytes_in_opb + 18; + pdulen = clen; + ctype = mppc_enc->flags; + iso_offset = (int)(s->iso_hdr - s->data); + mcs_offset = (int)(s->mcs_hdr - s->data); + sec_offset = (int)(s->sec_hdr - s->data); + rdp_offset = (int)(s->rdp_hdr - s->data); + + /* outputBuffer has 64 bytes preceding it */ + ls.data = mppc_enc->outputBuffer - (rdp_offset + 18); + ls.p = ls.data + rdp_offset; + ls.end = ls.p + clen; + ls.size = clen; + ls.iso_hdr = ls.data + iso_offset; + ls.mcs_hdr = ls.data + mcs_offset; + ls.sec_hdr = ls.data + sec_offset; + ls.rdp_hdr = ls.data + rdp_offset; + ls.channel_hdr = 0; + ls.next_packet = 0; + s = &ls; + } + } + else + { + g_writeln("mppc_encode not ok"); + } + } + + out_uint16_le(s, pdulen); + out_uint16_le(s, pdutype); out_uint16_le(s, self->mcs_channel); out_uint32_le(s, self->share_id); out_uint8(s, 0); out_uint8(s, 1); - out_uint16_le(s, len - 14); + out_uint16_le(s, dlen); out_uint8(s, data_pdu_type); - out_uint8(s, 0); - out_uint16_le(s, 0); + out_uint8(s, ctype); + out_uint16_le(s, clen); + if (xrdp_sec_send(self->sec_layer, s, MCS_GLOBAL_CHANNEL) != 0) { DEBUG(("out xrdp_rdp_send_data error"));