diff options
| -rw-r--r-- | common/xrdp_constants.h | 18 | ||||
| -rw-r--r-- | libxrdp/Makefile.am | 3 | ||||
| -rw-r--r-- | libxrdp/libxrdp.h | 20 | ||||
| -rw-r--r-- | libxrdp/xrdp_fastpath.c | 62 | ||||
| -rw-r--r-- | libxrdp/xrdp_iso.c | 10 | ||||
| -rw-r--r-- | libxrdp/xrdp_rdp.c | 11 | ||||
| -rw-r--r-- | libxrdp/xrdp_sec.c | 29 |
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; } |
