diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c index dc7a9869..9d584244 100644 --- a/libxrdp/libxrdp.c +++ b/libxrdp/libxrdp.c @@ -152,7 +152,7 @@ libxrdp_process_data(struct xrdp_session *session, struct stream *s) } break; case 2: /* FASTPATH_INPUT_EVENT */ - if (xrdp_rdp_process_fastpath_data_input(rdp, s) != 0) + if (xrdp_fastpath_process_input_event(rdp->sec_layer->fastpath_layer, s) != 0) { DEBUG(("libxrdp_process_data returned non zero")); cont = 0; diff --git a/libxrdp/libxrdp.h b/libxrdp/libxrdp.h index 2843089b..4e7218d6 100644 --- a/libxrdp/libxrdp.h +++ b/libxrdp/libxrdp.h @@ -72,6 +72,7 @@ struct xrdp_fastpath { struct xrdp_sec* sec_layer; /* owner */ struct trans* trans; + struct xrdp_session* session; int numEvents; int secFlags; }; @@ -386,8 +387,6 @@ xrdp_rdp_process_confirm_active(struct xrdp_rdp* self, struct stream* s); int APP_CC xrdp_rdp_process_data(struct xrdp_rdp* self, struct stream* s); int APP_CC -xrdp_rdp_process_fastpath_data_input(struct xrdp_rdp *self, struct stream *s); -int APP_CC xrdp_rdp_disconnect(struct xrdp_rdp* self); int APP_CC xrdp_rdp_send_deactive(struct xrdp_rdp* self); @@ -551,5 +550,6 @@ void APP_CC xrdp_fastpath_delete(struct xrdp_fastpath *self); int APP_CC xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s); - +int APP_CC +xrdp_fastpath_process_input_event(struct xrdp_fastpath *self, struct stream *s); #endif diff --git a/libxrdp/xrdp_fastpath.c b/libxrdp/xrdp_fastpath.c index 843fdc1b..572b5a98 100644 --- a/libxrdp/xrdp_fastpath.c +++ b/libxrdp/xrdp_fastpath.c @@ -29,6 +29,7 @@ xrdp_fastpath_create(struct xrdp_sec *owner, struct trans *trans) self = (struct xrdp_fastpath *)g_malloc(sizeof(struct xrdp_fastpath), 1); self->sec_layer = owner; self->trans = trans; + self->session = owner->rdp_layer->session; DEBUG((" out xrdp_fastpath_create")); return self; } @@ -243,3 +244,183 @@ xrdp_fastpath_process_data(struct xrdp_fastpath *self, struct stream *s, in_uint16_le(s, size); return xrdp_fastpath_process_update(self, updateCode, size, s); } + +/*****************************************************************************/ +/* FASTPATH_INPUT_EVENT_SCANCODE */ +int APP_CC +xrdp_fastpath_process_EVENT_SCANCODE(struct xrdp_fastpath *self, int eventFlags, struct stream *s) +{ + int flags; + int code; + flags = 0; + + in_uint8(s, code); /* keyCode (1 byte) */ + //g_writeln("scan code detected: %d", code); + + if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_RELEASE)) + flags |= KBD_FLAG_UP; + else + flags |= KBD_FLAG_DOWN; + + if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_EXTENDED)) + flags |= KBD_FLAG_EXT; + + if (self->session->callback != 0) + { + /* msg_type can be + RDP_INPUT_SYNCHRONIZE - 0 + RDP_INPUT_SCANCODE - 4 + RDP_INPUT_MOUSE - 0x8001 + RDP_INPUT_MOUSEX - 0x8002 */ + /* call to xrdp_wm.c : callback */ + self->session->callback(self->session->id, RDP_INPUT_SCANCODE, code, 0, + flags, 0); + } + return 0; +} +/*****************************************************************************/ +/* FASTPATH_INPUT_EVENT_MOUSE */ +int APP_CC +xrdp_fastpath_process_EVENT_MOUSE(struct xrdp_fastpath *self, int eventFlags, struct stream *s) +{ + int pointerFlags; + int xPos; + int yPos; + + in_uint16_le(s, pointerFlags); /* pointerFlags (2 bytes) */ + in_uint16_le(s, xPos); /* xPos (2 bytes) */ + in_uint16_le(s, yPos); /* yPos (2 bytes) */ + + if (self->session->callback != 0) + { + /* msg_type can be + RDP_INPUT_SYNCHRONIZE - 0 + RDP_INPUT_SCANCODE - 4 + RDP_INPUT_MOUSE - 0x8001 + RDP_INPUT_MOUSEX - 0x8002 */ + /* call to xrdp_wm.c : callback */ + self->session->callback(self->session->id, RDP_INPUT_MOUSE, xPos, yPos, + pointerFlags, 0); + } + return 0; +} +/*****************************************************************************/ +/* FASTPATH_INPUT_EVENT_MOUSEX */ +int APP_CC +xrdp_fastpath_process_EVENT_MOUSEX(struct xrdp_fastpath *self, int eventFlags, struct stream *s) +{ + int pointerFlags; + int xPos; + int yPos; + + in_uint16_le(s, pointerFlags); /* pointerFlags (2 bytes) */ + in_uint16_le(s, xPos); /* xPos (2 bytes) */ + in_uint16_le(s, yPos); /* yPos (2 bytes) */ + + if (self->session->callback != 0) + { + /* msg_type can be + RDP_INPUT_SYNCHRONIZE - 0 + RDP_INPUT_SCANCODE - 4 + RDP_INPUT_MOUSE - 0x8001 + RDP_INPUT_MOUSEX - 0x8002 */ + /* call to xrdp_wm.c : callback */ + self->session->callback(self->session->id, RDP_INPUT_MOUSEX, xPos, yPos, + pointerFlags, 0); + } + return 0; +} +/*****************************************************************************/ +/* FASTPATH_INPUT_EVENT_SYNC */ +int APP_CC +xrdp_fastpath_process_EVENT_SYNC(struct xrdp_fastpath *self, int eventCode, int eventFlags, struct stream *s) +{ + /* + * The eventCode bitfield (3 bits in size) MUST be set to FASTPATH_INPUT_EVENT_SYNC (3). + * The eventFlags bitfield (5 bits in size) contains flags indicating the "on" + * status of the keyboard toggle keys. + */ + if (self->session->callback != 0) + { + /* msg_type can be + RDP_INPUT_SYNCHRONIZE - 0 + RDP_INPUT_SCANCODE - 4 + RDP_INPUT_MOUSE - 0x8001 + RDP_INPUT_MOUSEX - 0x8002 */ + /* call to xrdp_wm.c : callback */ + self->session->callback(self->session->id, RDP_INPUT_SYNCHRONIZE, eventCode, 0, + eventFlags, 0); + } + return 0; +} +/*****************************************************************************/ +/* FASTPATH_INPUT_EVENT_UNICODE */ +int APP_CC +xrdp_fastpath_process_EVENT_UNICODE(struct xrdp_fastpath *self, int eventFlags, struct stream *s) +{ + in_uint8s(s, 2); + return 0; +} +/*****************************************************************************/ +/* FASTPATH_INPUT_EVENT */ +int APP_CC +xrdp_fastpath_process_input_event(struct xrdp_fastpath *self, struct stream *s) +{ + int i; + int eventHeader; + int eventCode; + int eventFlags; + + // process fastpath input events + for (i = 0 ; i < self->numEvents ; i++) { + in_uint8(s, eventHeader); + + eventFlags = (eventHeader & 0x1F); + eventCode = (eventHeader >> 5); + +// g_writeln("eventCode= %d, eventFlags= %d, numEvents= %d", +// eventCode, eventFlags, self->sec_layer->fastpath_layer->numEvents); + + switch (eventCode) + { + case FASTPATH_INPUT_EVENT_SCANCODE: + if (xrdp_fastpath_process_EVENT_SCANCODE(self, eventFlags, s) != 0) + { + return 1; + } + break; + + case FASTPATH_INPUT_EVENT_MOUSE: + if (xrdp_fastpath_process_EVENT_MOUSE(self, eventFlags, s) != 0) + { + return 1; + } + break; + case FASTPATH_INPUT_EVENT_MOUSEX: + if (xrdp_fastpath_process_EVENT_MOUSEX(self, eventFlags, s) != 0) + { + return 1; + } + break; + case FASTPATH_INPUT_EVENT_SYNC: + if (xrdp_fastpath_process_EVENT_SYNC(self, eventCode, eventFlags, s) != 0) + { + return 1; + } + break; + case FASTPATH_INPUT_EVENT_UNICODE: + if (xrdp_fastpath_process_EVENT_UNICODE(self, eventFlags, s) != 0) + { + return 1; + } + + break; + default: + g_writeln("xrdp_rdp_process_fastpath_data_input: unknown eventCode %d", eventCode); + break; + } + + } + + return 0; +} diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c index d909abd9..787b6e6c 100644 --- a/libxrdp/xrdp_rdp.c +++ b/libxrdp/xrdp_rdp.c @@ -289,7 +289,6 @@ xrdp_rdp_init_data(struct xrdp_rdp *self, struct stream *s) s_push_layer(s, rdp_hdr, 18); return 0; } - /*****************************************************************************/ /* returns error */ int APP_CC @@ -305,7 +304,6 @@ xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code) DEBUG(("in xrdp_rdp_recv")); if (s->next_packet == 0 || s->next_packet >= s->end) { - /* check for fastpath first */ if ((header[0] != 0x3) && (header[0] != 0x3c)) { @@ -313,7 +311,7 @@ xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code) { return 1; } - *code = 2; // special code for fastpath + *code = 2; // special code for fastpath input DEBUG(("out (fastpath) xrdp_rdp_recv")); return 0; } @@ -1676,128 +1674,7 @@ xrdp_rdp_send_disconnect_reason(struct xrdp_rdp *self, int reason) return 0; } #endif -/*****************************************************************************/ -/* FASTPATH_INPUT_EVENT */ -int APP_CC -xrdp_rdp_process_fastpath_data_input(struct xrdp_rdp *self, struct stream *s) -{ - int i; - int eventHeader; - int eventCode; - int eventFlags; - int code; - int flags; - int param2; - int time; - int pointerFlags; - int xPos; - int yPos; - - // process fastpath input events - for (i = 0 ; i < self->sec_layer->fastpath_layer->numEvents ; i++) { - in_uint8(s, eventHeader); - - eventFlags = (eventHeader & 0x1F); - eventCode = (eventHeader >> 5); - -// g_writeln("eventCode= %d, eventFlags= %d, numEvents= %d", -// eventCode, eventFlags, self->sec_layer->fastpath_layer->numEvents); - - switch (eventCode) - { - case FASTPATH_INPUT_EVENT_SCANCODE: - in_uint8(s, code); /* keyCode (1 byte) */ - //g_writeln("scan code detected: %d", code); - flags = 0; - if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_RELEASE)) - flags |= KBD_FLAG_UP; - else - flags |= KBD_FLAG_DOWN; - - if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_EXTENDED)) - flags |= KBD_FLAG_EXT; - - if (self->session->callback != 0) - { - /* msg_type can be - RDP_INPUT_SYNCHRONIZE - 0 - RDP_INPUT_SCANCODE - 4 - RDP_INPUT_MOUSE - 0x8001 - RDP_INPUT_MOUSEX - 0x8002 */ - /* call to xrdp_wm.c : callback */ - self->session->callback(self->session->id, RDP_INPUT_SCANCODE, code, 0, - flags, 0); - } - break; - - case FASTPATH_INPUT_EVENT_MOUSE: - in_uint16_le(s, pointerFlags); /* pointerFlags (2 bytes) */ - in_uint16_le(s, xPos); /* xPos (2 bytes) */ - in_uint16_le(s, yPos); /* yPos (2 bytes) */ - - if (self->session->callback != 0) - { - /* msg_type can be - RDP_INPUT_SYNCHRONIZE - 0 - RDP_INPUT_SCANCODE - 4 - RDP_INPUT_MOUSE - 0x8001 - RDP_INPUT_MOUSEX - 0x8002 */ - /* call to xrdp_wm.c : callback */ - self->session->callback(self->session->id, RDP_INPUT_MOUSE, xPos, yPos, - pointerFlags, 0); - } - break; - - case FASTPATH_INPUT_EVENT_MOUSEX: - in_uint16_le(s, pointerFlags); /* pointerFlags (2 bytes) */ - in_uint16_le(s, xPos); /* xPos (2 bytes) */ - in_uint16_le(s, yPos); /* yPos (2 bytes) */ - - if (self->session->callback != 0) - { - /* msg_type can be - RDP_INPUT_SYNCHRONIZE - 0 - RDP_INPUT_SCANCODE - 4 - RDP_INPUT_MOUSE - 0x8001 - RDP_INPUT_MOUSEX - 0x8002 */ - /* call to xrdp_wm.c : callback */ - self->session->callback(self->session->id, RDP_INPUT_MOUSEX, xPos, yPos, - pointerFlags, 0); - } - break; - - case FASTPATH_INPUT_EVENT_SYNC: - /* - * The eventCode bitfield (3 bits in size) MUST be set to FASTPATH_INPUT_EVENT_SYNC (3). - * The eventFlags bitfield (5 bits in size) contains flags indicating the "on" - * status of the keyboard toggle keys. - */ - if (self->session->callback != 0) - { - /* msg_type can be - RDP_INPUT_SYNCHRONIZE - 0 - RDP_INPUT_SCANCODE - 4 - RDP_INPUT_MOUSE - 0x8001 - RDP_INPUT_MOUSEX - 0x8002 */ - /* call to xrdp_wm.c : callback */ - self->session->callback(self->session->id, RDP_INPUT_SYNCHRONIZE, eventCode, 0, - eventFlags, 0); - } - break; - - case FASTPATH_INPUT_EVENT_UNICODE: - in_uint8s(s, 2); - break; - - default: - g_writeln("xrdp_rdp_process_fastpath_data_input: unknown eventCode %d", eventCode); - break; - } - - } - return 0; -} /*****************************************************************************/ /* RDP_PDU_DATA */ int APP_CC @@ -1854,7 +1731,6 @@ xrdp_rdp_process_data(struct xrdp_rdp *self, struct stream *s) return 0; } - /*****************************************************************************/ int APP_CC xrdp_rdp_disconnect(struct xrdp_rdp *self) diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c index 6b8dbbc4..76df3cae 100644 --- a/libxrdp/xrdp_sec.c +++ b/libxrdp/xrdp_sec.c @@ -949,9 +949,15 @@ xrdp_sec_recv_fastpath(struct xrdp_sec *self, struct stream *s) return 1; } - in_uint8s(s, 8); /* dataSignature, skip for now */ + if (self->crypt_level == CRYPT_LEVEL_FIPS) + { + in_uint8s(s, 4); /* fipsInformation (4 bytes) */ + } + + in_uint8s(s, 8); /* dataSignature (8 bytes), skip for now */ - if (self->fastpath_layer->secFlags & FASTPATH_INPUT_ENCRYPTED) { + if (self->fastpath_layer->secFlags & FASTPATH_INPUT_ENCRYPTED) + { xrdp_sec_decrypt(self, s->p, (int)(s->end - s->p)); } @@ -960,7 +966,7 @@ xrdp_sec_recv_fastpath(struct xrdp_sec *self, struct stream *s) * 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) */ + in_uint8(s, self->fastpath_layer->numEvents); /* numEvents (1 byte) (optional) */ } return 0;