summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenrik Andersson <hean01@cendio.com>2018-01-26 12:17:59 +0100
committerHenrik Andersson <hean01@cendio.com>2018-02-01 12:47:22 +0100
commitb5708cf775546056bf8c4acb7d1979a846140ff4 (patch)
treeffc15b37912f175149a2c6c30402459d0784cb2e
parent81c030a8879fdf6c4b62d773a246cc9d0118e80f (diff)
downloadrdesktop-b5708cf775546056bf8c4acb7d1979a846140ff4.zip
Refactoring of slow and fastpath handling
This changes clarifies a chunk of code related to receiving data and handle slow and fast path pdus.
-rw-r--r--constants.h4
-rw-r--r--iso.c40
-rw-r--r--mcs.c30
-rw-r--r--proto.h6
-rw-r--r--rdp.c15
-rw-r--r--secure.c27
6 files changed, 71 insertions, 51 deletions
diff --git a/constants.h b/constants.h
index 267522b..512a35e 100644
--- a/constants.h
+++ b/constants.h
@@ -2,6 +2,7 @@
rdesktop: A Remote Desktop Protocol client.
Miscellaneous protocol constants
Copyright (C) Matthew Chapman 1999-2008
+ Copyright 2017-2018 Henrik Andersson <hean01@cendio.se> for Cendio AB
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -36,9 +37,6 @@
#define FASTPATH_OUTPUT_SECURE_CHECKSUM 0x1
#define FASTPATH_OUTPUT_ENCRYPTED 0x2
-#define IS_FASTPATH(hdr) ((hdr & 0x03) == FASTPATH_OUTPUT_ACTION_FASTPATH)
-#define IS_SLOWPATH(hdr) ((hdr) == FASTPATH_OUTPUT_ACTION_X224)
-
/* [MS-RDPBCGR] 2.2.9.1.2.1 */
/* adjusted for position in updateHeader */
#define FASTPATH_UPDATETYPE_ORDERS 0x0
diff --git a/iso.c b/iso.c
index eac4274..278f32a 100644
--- a/iso.c
+++ b/iso.c
@@ -3,7 +3,7 @@
Protocol services - ISO layer
Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
Copyright 2005-2011 Peter Astrand <astrand@cendio.se> for Cendio AB
- Copyright 2012-2017 Henrik Andersson <hean01@cendio.se> for Cendio AB
+ Copyright 2012-2018 Henrik Andersson <hean01@cendio.se> for Cendio AB
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -98,7 +98,7 @@ iso_send_connection_request(char *username, uint32 neg_proto)
/* Receive a message on the ISO layer, return code */
static STREAM
-iso_recv_msg(uint8 * code, uint8 * rdpver)
+iso_recv_msg(uint8 * code, RD_BOOL *is_fastpath, uint8 *fastpath_hdr)
{
STREAM s;
uint16 length;
@@ -107,16 +107,23 @@ iso_recv_msg(uint8 * code, uint8 * rdpver)
s = tcp_recv(NULL, 4);
if (s == NULL)
return NULL;
- in_uint8(s, version);
- if (rdpver != NULL)
- *rdpver = version;
- if (IS_SLOWPATH(version))
+
+ in_uint8(s, version); /* T.123 version or Fastpath output header */
+
+ /* detect if this is a slow or fast path PDU */
+ *fastpath_hdr = 0x00;
+ *is_fastpath = False;
+ if (version == T123_HEADER_VERSION)
{
in_uint8s(s, 1); /* reserved */
in_uint16_be(s, length); /* length */
}
else
{
+ /* if version is not an expected T.123 version eg. 3, then this
+ stream is a fast path pdu */
+ *is_fastpath = True;
+ *fastpath_hdr = version;
in_uint8(s, length); /* length1 */
if (length & 0x80)
{
@@ -125,16 +132,20 @@ iso_recv_msg(uint8 * code, uint8 * rdpver)
next_be(s, length);
}
}
+
if (length < 4)
{
logger(Protocol, Error, "iso_recv_msg(), bad packet header, length < 4");
return NULL;
}
+
s = tcp_recv(s, length - 4);
if (s == NULL)
return NULL;
- if (IS_FASTPATH(version))
+
+ if (*is_fastpath == True)
return s;
+
in_uint8s(s, 1); /* hdrlen */
in_uint8(s, *code);
if (*code == ISO_PDU_DT)
@@ -180,17 +191,18 @@ iso_send(STREAM s)
/* Receive ISO transport data packet */
STREAM
-iso_recv(uint8 * rdpver)
+iso_recv(RD_BOOL *is_fastpath, uint8 *fastpath_hdr)
{
STREAM s;
uint8 code = 0;
- s = iso_recv_msg(&code, rdpver);
+ s = iso_recv_msg(&code, is_fastpath, fastpath_hdr);
if (s == NULL)
return NULL;
- if (rdpver != NULL)
- if (IS_FASTPATH(*rdpver))
- return s;
+
+ if (*is_fastpath == True)
+ return s;
+
if (code != ISO_PDU_DT)
{
logger(Protocol, Error, "iso_recv(), expected ISO_PDU_DT, got 0x%x", code);
@@ -208,6 +220,8 @@ iso_connect(char *server, char *username, char *domain, char *password,
STREAM s;
uint8 code;
uint32 neg_proto;
+ RD_BOOL is_fastpath;
+ uint8 fastpath_hdr;
g_negotiate_rdp_protocol = True;
@@ -236,7 +250,7 @@ iso_connect(char *server, char *username, char *domain, char *password,
iso_send_connection_request(username, neg_proto);
- s = iso_recv_msg(&code, NULL);
+ s = iso_recv_msg(&code, &is_fastpath, &fastpath_hdr);
if (s == NULL)
return False;
diff --git a/mcs.c b/mcs.c
index a68174c..f3a4c23 100644
--- a/mcs.c
+++ b/mcs.c
@@ -3,6 +3,7 @@
Protocol services - Multipoint Communications Service
Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
Copyright 2005-2011 Peter Astrand <astrand@cendio.se> for Cendio AB
+ Copyright 2018 Henrik Andersson <hean01@cendio.com> for Cendio AB
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -90,8 +91,12 @@ mcs_recv_connect_response(STREAM mcs_data)
uint8 result;
int length;
STREAM s;
+ RD_BOOL is_fastpath;
+ uint8 fastpath_hdr;
+
logger(Protocol, Debug, "%s()", __func__);
- s = iso_recv(NULL);
+ s = iso_recv(&is_fastpath, &fastpath_hdr);
+
if (s == NULL)
return False;
@@ -160,10 +165,14 @@ mcs_send_aurq(void)
static RD_BOOL
mcs_recv_aucf(uint16 * mcs_userid)
{
+ RD_BOOL is_fastpath;
+ uint8 fastpath_hdr;
uint8 opcode, result;
STREAM s;
+
logger(Protocol, Debug, "%s()", __func__);
- s = iso_recv(NULL);
+ s = iso_recv(&is_fastpath, &fastpath_hdr);
+
if (s == NULL)
return False;
@@ -209,10 +218,14 @@ mcs_send_cjrq(uint16 chanid)
static RD_BOOL
mcs_recv_cjcf(void)
{
+ RD_BOOL is_fastpath;
+ uint8 fastpath_hdr;
uint8 opcode, result;
STREAM s;
+
logger(Protocol, Debug, "%s()", __func__);
- s = iso_recv(NULL);
+ s = iso_recv(&is_fastpath, &fastpath_hdr);
+
if (s == NULL)
return False;
@@ -303,17 +316,18 @@ mcs_send(STREAM s)
/* Receive an MCS transport data packet */
STREAM
-mcs_recv(uint16 * channel, uint8 * rdpver)
+mcs_recv(uint16 * channel, RD_BOOL *is_fastpath, uint8 *fastpath_hdr)
{
uint8 opcode, appid, length;
STREAM s;
- s = iso_recv(rdpver);
+ s = iso_recv(is_fastpath, fastpath_hdr);
if (s == NULL)
return NULL;
- if (rdpver != NULL)
- if (*rdpver != 3)
- return s;
+
+ if (*is_fastpath == True)
+ return s;
+
in_uint8(s, opcode);
appid = opcode >> 2;
if (appid != MCS_SDIN)
diff --git a/proto.h b/proto.h
index a5aa2f5..7ce19b4 100644
--- a/proto.h
+++ b/proto.h
@@ -82,7 +82,7 @@ void ewmh_init(void);
/* iso.c */
STREAM iso_init(int length);
void iso_send(STREAM s);
-STREAM iso_recv(uint8 * rdpver);
+STREAM iso_recv(RD_BOOL *is_fastpath, uint8 *fastpath_hdr);
RD_BOOL iso_connect(char *server, char *username, char *domain, char *password, RD_BOOL reconnect,
uint32 * selected_protocol);
void iso_disconnect(void);
@@ -95,7 +95,7 @@ void licence_process(STREAM s);
STREAM mcs_init(int length);
void mcs_send_to_channel(STREAM s, uint16 channel);
void mcs_send(STREAM s);
-STREAM mcs_recv(uint16 * channel, uint8 * rdpver);
+STREAM mcs_recv(uint16 * channel, RD_BOOL *is_fastpath, uint8 *fastpath_hdr);
RD_BOOL mcs_connect_start(char *server, char *username, char *domain, char *password,
RD_BOOL reconnect, uint32 * selected_protocol);
RD_BOOL mcs_connect_finalize(STREAM s);
@@ -199,7 +199,7 @@ STREAM sec_init(uint32 flags, int maxlen);
void sec_send_to_channel(STREAM s, uint32 flags, uint16 channel);
void sec_send(STREAM s, uint32 flags);
void sec_process_mcs_data(STREAM s);
-STREAM sec_recv(uint8 * rdpver);
+STREAM sec_recv(RD_BOOL * is_fastpath);
RD_BOOL sec_connect(char *server, char *username, char *domain, char *password, RD_BOOL reconnect);
void sec_disconnect(void);
void sec_reset_state(void);
diff --git a/rdp.c b/rdp.c
index 749bf1b..95a37ad 100644
--- a/rdp.c
+++ b/rdp.c
@@ -3,7 +3,7 @@
Protocol services - RDP layer
Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
Copyright 2003-2011 Peter Astrand <astrand@cendio.se> for Cendio AB
- Copyright 2011-2017 Henrik Andersson <hean01@cendio.se> for Cendio AB
+ Copyright 2011-2018 Henrik Andersson <hean01@cendio.se> for Cendio AB
Copyright 2017 Karl Mikaelsson <derfian@cendio.se> for Cendio AB
This program is free software: you can redistribute it and/or modify
@@ -96,22 +96,17 @@ static void rdp_out_unistr(STREAM s, char *string, int len);
static STREAM
rdp_recv(uint8 * type)
{
+ RD_BOOL is_fastpath;
static STREAM rdp_s;
uint16 length, pdu_type;
- uint8 rdpver;
if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end) || (g_next_packet == NULL))
{
- rdp_s = sec_recv(&rdpver);
+ rdp_s = sec_recv(&is_fastpath);
if (rdp_s == NULL)
return NULL;
- if (rdpver == 0xff)
- {
- g_next_packet = rdp_s->end;
- *type = 0;
- return rdp_s;
- }
- else if (rdpver != 3)
+
+ if (is_fastpath == True)
{
/* process_ts_fp_updates moves g_next_packet */
process_ts_fp_updates(rdp_s);
diff --git a/secure.c b/secure.c
index c093bcc..b829a02 100644
--- a/secure.c
+++ b/secure.c
@@ -3,7 +3,7 @@
Protocol services - RDP encryption and licensing
Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
Copyright 2005-2011 Peter Astrand <astrand@cendio.se> for Cendio AB
- Copyright 2017 Henrik Andersson <hean01@cendio.se> for Cendio AB
+ Copyright 2017-2018 Henrik Andersson <hean01@cendio.se> for Cendio AB
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -842,26 +842,27 @@ sec_process_mcs_data(STREAM s)
/* Receive secure transport packet */
STREAM
-sec_recv(uint8 * rdpver)
+sec_recv(RD_BOOL *is_fastpath)
{
+ uint8 fastpath_hdr;
uint16 sec_flags;
uint16 channel;
STREAM s;
- while ((s = mcs_recv(&channel, rdpver)) != NULL)
+ while ((s = mcs_recv(&channel, is_fastpath, &fastpath_hdr)) != NULL)
{
- if (rdpver != NULL)
+ if (*is_fastpath == True)
{
- if (*rdpver != 3)
+ /* If fastpath packet is encrypted, read data
+ signature and decrypt */
+ if (fastpath_hdr & FASTPATH_OUTPUT_ENCRYPTED)
{
- if (*rdpver & 0x80)
- {
- in_uint8s(s, 8); /* signature */
- sec_decrypt(s->p, s->end - s->p);
- }
- return s;
+ in_uint8s(s, 8); /* signature */
+ sec_decrypt(s->p, s->end - s->p);
}
+ return s;
}
+
if (g_encryption || (!g_licence_issued && !g_licence_error_result))
{
/* TS_SECURITY_HEADER */
@@ -926,9 +927,7 @@ sec_recv(uint8 * rdpver)
if (channel != MCS_GLOBAL_CHANNEL)
{
channel_process(s, channel);
- if (rdpver != NULL)
- *rdpver = 0xff;
- return s;
+ continue;
}
return s;