summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/xrdp_constants.h18
-rw-r--r--libxrdp/Makefile.am3
-rw-r--r--libxrdp/libxrdp.h20
-rw-r--r--libxrdp/xrdp_fastpath.c62
-rw-r--r--libxrdp/xrdp_iso.c10
-rw-r--r--libxrdp/xrdp_rdp.c11
-rw-r--r--libxrdp/xrdp_sec.c29
7 files changed, 129 insertions, 24 deletions
diff --git a/common/xrdp_constants.h b/common/xrdp_constants.h
index ed74fd01..0dc327df 100644
--- a/common/xrdp_constants.h
+++ b/common/xrdp_constants.h
@@ -560,6 +560,24 @@
#define RDP_CAPSET_LPOINTER 0x27
#define RDP_CAPLEN_LPOINTER 0x06
+/* fastpath input */
+#define FASTPATH_INPUT_SECURE_CHECKSUM 0x1
+#define FASTPATH_INPUT_ENCRYPTED 0x2
+
+#define FASTPATH_INPUT_ACTION_FASTPATH 0x0
+#define FASTPATH_INPUT_ACTION_X224 0x3
+
+#define FASTPATH_INPUT_EVENT_SCANCODE 0x0
+#define FASTPATH_INPUT_EVENT_MOUSE 0x1
+#define FASTPATH_INPUT_EVENT_MOUSEX 0x2
+#define FASTPATH_INPUT_EVENT_SYNC 0x3
+#define FASTPATH_INPUT_EVENT_UNICODE 0x4
+
+#define FASTPATH_INPUT_KBDFLAGS_RELEASE 0x01
+#define FASTPATH_INPUT_KBDFLAGS_EXTENDED 0x02
+
+
+/* fastpath output */
#define FASTPATH_OUTPUT_ACTION_FASTPATH 0x0
#define FASTPATH_OUTPUT_ACTION_X224 0x3
diff --git a/libxrdp/Makefile.am b/libxrdp/Makefile.am
index 6564da36..3fdc963d 100644
--- a/libxrdp/Makefile.am
+++ b/libxrdp/Makefile.am
@@ -59,7 +59,8 @@ libxrdp_la_SOURCES = \
xrdp_bitmap_compress.c \
xrdp_jpeg_compress.c \
xrdp_orders_rail.c \
- xrdp_mppc_enc.c
+ xrdp_mppc_enc.c \
+ xrdp_fastpath.c
libxrdp_la_LDFLAGS = \
$(EXTRA_FLAGS)
diff --git a/libxrdp/libxrdp.h b/libxrdp/libxrdp.h
index a9150111..b15cc989 100644
--- a/libxrdp/libxrdp.h
+++ b/libxrdp/libxrdp.h
@@ -42,6 +42,8 @@ struct xrdp_tcp
{
struct trans* trans;
struct xrdp_iso* iso_layer; /* owner */
+ struct xrdp_fastpath* fastpath_layer; /* owner */
+
};
/* iso */
@@ -73,11 +75,21 @@ struct xrdp_mcs
struct list* channel_list;
};
+/* fastpath */
+struct xrdp_fastpath
+{
+ struct xrdp_sec* sec_layer; /* owner */
+ struct xrdp_tcp* tcp_layer;
+ int numEvents;
+ int secFlags;
+};
+
/* sec */
struct xrdp_sec
{
struct xrdp_rdp* rdp_layer; /* owner */
struct xrdp_mcs* mcs_layer;
+ struct xrdp_fastpath* fastpath_layer;
struct xrdp_channel* chan_layer;
char server_random[32];
char client_random[64];
@@ -494,4 +506,12 @@ int APP_CC
xrdp_channel_process(struct xrdp_channel* self, struct stream* s,
int chanid);
+/* xrdp_fastpath.c */
+struct xrdp_fastpath *APP_CC
+xrdp_fastpath_create(struct xrdp_sec *owner, struct trans *trans);
+void APP_CC
+xrdp_fastpath_delete(struct xrdp_fastpath *self);
+int APP_CC
+xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s);
+
#endif
diff --git a/libxrdp/xrdp_fastpath.c b/libxrdp/xrdp_fastpath.c
index 96d84972..c8b4927d 100644
--- a/libxrdp/xrdp_fastpath.c
+++ b/libxrdp/xrdp_fastpath.c
@@ -21,16 +21,15 @@
/*****************************************************************************/
struct xrdp_fastpath *APP_CC
-xrdp_fastpath_create(struct xrdp_session *session)
+xrdp_fastpath_create(struct xrdp_sec *owner, struct trans *trans)
{
struct xrdp_fastpath *self;
+ DEBUG((" in xrdp_fastpath_create"));
self = (struct xrdp_fastpath *)g_malloc(sizeof(struct xrdp_fastpath), 1);
- self->tcp_layer =
- ((struct xrdp_rdp *)session->rdp)->sec_layer->
- mcs_layer->iso_layer->tcp_layer;
- make_stream(self->out_s);
- init_stream(self->out_s, FASTPATH_MAX_PACKET_SIZE);
+ self->sec_layer = owner;
+ self->tcp_layer = owner->mcs_layer->iso_layer->tcp_layer;
+ DEBUG((" out xrdp_fastpath_create"));
return self;
}
@@ -42,8 +41,6 @@ xrdp_fastpath_delete(struct xrdp_fastpath *self)
{
return;
}
-
- free_stream(self->out_s);
g_free(self);
}
@@ -54,7 +51,52 @@ xrdp_fastpath_reset(struct xrdp_fastpath *self)
{
return 0;
}
+/*****************************************************************************/
+int APP_CC
+xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s)
+{
+ int fp_hdr;
+ int len;
+ int byte;
+ DEBUG((" in xrdp_fastpath_recv"));
+
+ /* read the first fastpath byte
+ * (we already received it via iso layer */
+ in_uint8(s, fp_hdr); /* fpInputHeader (1 byte) */
+
+ self->numEvents = (fp_hdr & 0x3C) >> 2;
+ self->secFlags = (fp_hdr & 0xC0) >> 6;
+
+ // receive fastpath packet length
+ if (xrdp_tcp_recv(self->tcp_layer, s, 1) != 0)
+ {
+ return 1;
+ }
+
+ in_uint8(s, byte); /* length 1 */
+
+ if (byte & 0x80)
+ {
+ byte &= ~(0x80);
+ len = (byte << 8);
+ in_uint8(s, byte); /* length 2 */
+ len += byte;
+ }
+ else
+ {
+ len = byte;
+ }
+ // receive the left bytes
+ if (xrdp_tcp_recv(self->tcp_layer, s, len) != 0)
+ {
+ return 1;
+ }
+ DEBUG((" out xrdp_fastpath_recv"));
+
+ return 0;
+}
+/*****************************************************************************/
int APP_CC
xrdp_fastpath_init(struct xrdp_fastpath *self)
{
@@ -76,7 +118,7 @@ xrdp_fastpath_send_update_pdu(struct xrdp_fastpath *self, tui8 updateCode,
int i32;
compression = 0;
- s_send = self->out_s;
+// s_send = self->out_s;
maxLen = FASTPATH_MAX_PACKET_SIZE - 6; /* 6 bytes for header */
payloadLeft = (s->end - s->data);
@@ -112,7 +154,7 @@ xrdp_fastpath_send_update_pdu(struct xrdp_fastpath *self, tui8 updateCode,
((compression & 0x03) << 6);
out_uint8(s_send, i32);
out_uint16_le(s_send, len);
- s_copy(s_send, s, len);
+// s_copy(s_send, s, len);
s_mark_end(s_send);
if (xrdp_tcp_send(self->tcp_layer, s_send) != 0)
diff --git a/libxrdp/xrdp_iso.c b/libxrdp/xrdp_iso.c
index 82a76e5f..f29cbf23 100644
--- a/libxrdp/xrdp_iso.c
+++ b/libxrdp/xrdp_iso.c
@@ -158,15 +158,13 @@ xrdp_iso_recv_tpkt_header(struct xrdp_iso *self, struct stream *s)
int plen;
int ver;
- DEBUG((" in xrdp_iso_recv_tpkt_header"));
-
if (xrdp_tcp_recv(self->tcp_layer, s, 1) != 0)
{
return 1;
}
- in_uint8_peek(s, ver);
- g_writeln(" tpkt version: %x", ver);
+ in_uint8_peek(s, ver); // Peek only so we can use it later in fastpath layer, if needed
+ g_writeln(" tpkt version: %x", ver); // TODO: delete it
if (ver != 3)
{
@@ -190,8 +188,6 @@ xrdp_iso_recv_tpkt_header(struct xrdp_iso *self, struct stream *s)
return 1; // tpkt must be >= 4 bytes length
}
- DEBUG((" out xrdp_iso_recv_tpkt_header"));
-
return plen;
}
/*****************************************************************************/
@@ -208,7 +204,6 @@ xrdp_iso_write_tpkt_header(struct stream *s, int len)
int APP_CC
xrdp_iso_read_x224_header(struct stream *s, int *code, int *len)
{
- DEBUG((" in xrdp_iso_read_x224_header"));
if (!s_check_rem(s, 2))
{
return 1;
@@ -233,7 +228,6 @@ xrdp_iso_read_x224_header(struct stream *s, int *code, int *len)
}
in_uint8s(s, 5);
}
- DEBUG((" out xrdp_iso_read_x224_header"));
return 0;
}
diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c
index 923b0358..f98a5dce 100644
--- a/libxrdp/xrdp_rdp.c
+++ b/libxrdp/xrdp_rdp.c
@@ -348,10 +348,13 @@ xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code)
int APP_CC
xrdp_rdp_recv_fastpath(struct xrdp_rdp *self, struct stream *s, int *code)
{
- g_writeln("Booyah!");
- int msg;
- in_uint8(s, msg);
- g_writeln("msg= %x", msg);
+ int i;
+ DEBUG(("in xrdp_rdp_recv_fastpath"));
+// for (i = 0 ; i < self->sec_layer->fastpath_layer->numEvents ; i++) {
+//
+// }
+ g_hexdump(s->data, 7);
+ DEBUG(("out xrdp_rdp_recv_fastpath"));
return 1;
}
/*****************************************************************************/
diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c
index 40fedb85..44eb5812 100644
--- a/libxrdp/xrdp_sec.c
+++ b/libxrdp/xrdp_sec.c
@@ -185,6 +185,7 @@ xrdp_sec_create(struct xrdp_rdp *owner, struct trans *trans, int crypt_level,
self->encrypt_rc4_info = ssl_rc4_info_create();
self->mcs_layer = xrdp_mcs_create(self, trans, &self->client_mcs_data,
&self->server_mcs_data);
+ self->fastpath_layer = xrdp_fastpath_create(self, trans);
self->chan_layer = xrdp_channel_create(self, self->mcs_layer);
DEBUG((" out xrdp_sec_create"));
return self;
@@ -202,6 +203,7 @@ xrdp_sec_delete(struct xrdp_sec *self)
xrdp_channel_delete(self->chan_layer);
xrdp_mcs_delete(self->mcs_layer);
+ xrdp_fastpath_delete(self->fastpath_layer);
ssl_rc4_info_delete(self->decrypt_rc4_info); /* TODO clear all data */
ssl_rc4_info_delete(self->encrypt_rc4_info); /* TODO clear all data */
g_free(self->client_mcs_data.data);
@@ -732,7 +734,32 @@ xrdp_sec_establish_keys(struct xrdp_sec *self)
ssl_rc4_set_key(self->decrypt_rc4_info, self->decrypt_key, self->rc4_key_len);
ssl_rc4_set_key(self->encrypt_rc4_info, self->encrypt_key, self->rc4_key_len);
}
+/*****************************************************************************/
+/* returns error */
+int APP_CC
+xrdp_sec_recv_fastpath(struct xrdp_sec *self, struct stream *s)
+{
+ if (xrdp_fastpath_recv(self->fastpath_layer, s) != 0) {
+ return 1;
+ }
+
+ in_uint8s(s, 8); /* dataSignature, skip for now */
+
+ if (self->fastpath_layer->secFlags & FASTPATH_INPUT_ENCRYPTED) {
+ xrdp_sec_decrypt(self, s->p, (int)(s->end - s->p));
+ }
+
+ if (self->fastpath_layer->numEvents == 0) {
+ /**
+ * If numberEvents is not provided in fpInputHeader, it will be provided
+ * as one additional byte here.
+ */
+ in_uint8(s, self->fastpath_layer->numEvents); /* numEvents (optional) */
+ }
+
+ return 0;
+}
/*****************************************************************************/
/* returns error */
int APP_CC
@@ -749,7 +776,7 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan)
if (mcs_msg == 2)
{
DEBUG((" out xrdp_sec_recv : non-TPKT msg detected, we try fastpath"));
-// xrdp_sec_recv_fastpath(self->mcs_layer->iso_layer, s);
+ xrdp_sec_recv_fastpath(self, s);
return mcs_msg;
}