summaryrefslogtreecommitdiffstats
path: root/libxrdp
diff options
context:
space:
mode:
Diffstat (limited to 'libxrdp')
-rw-r--r--libxrdp/libxrdp.c130
-rw-r--r--libxrdp/libxrdpinc.h4
-rw-r--r--libxrdp/xrdp_fastpath.c2
-rw-r--r--libxrdp/xrdp_iso.c36
-rw-r--r--libxrdp/xrdp_mcs.c84
-rw-r--r--libxrdp/xrdp_rdp.c5
-rw-r--r--libxrdp/xrdp_sec.c1
7 files changed, 167 insertions, 95 deletions
diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c
index 9d584244..ea1e7f25 100644
--- a/libxrdp/libxrdp.c
+++ b/libxrdp/libxrdp.c
@@ -62,7 +62,101 @@ libxrdp_disconnect(struct xrdp_session *session)
int EXPORT_CC
libxrdp_process_incomming(struct xrdp_session *session)
{
- return xrdp_rdp_incoming((struct xrdp_rdp *)session->rdp);
+ int rv;
+
+ rv = xrdp_rdp_incoming((struct xrdp_rdp *)(session->rdp));
+ return rv;
+}
+
+/*****************************************************************************/
+int EXPORT_CC
+libxrdp_get_pdu_bytes(const char *aheader)
+{
+ int rv;
+ const tui8 *header;
+
+ rv = -1;
+ header = (const tui8 *) aheader;
+
+ if (header[0] == 0x03)
+ {
+ /* TPKT */
+ rv = (header[2] << 8) | header[3];
+ }
+ else if (header[0] == 0x30)
+ {
+ /* TSRequest (NLA) */
+ if (header[1] & 0x80)
+ {
+ if ((header[1] & ~(0x80)) == 1)
+ {
+ rv = header[2];
+ rv += 3;
+ }
+ else if ((header[1] & ~(0x80)) == 2)
+ {
+ rv = (header[2] << 8) | header[3];
+ rv += 4;
+ }
+ else
+ {
+ g_writeln("libxrdp_get_pdu_bytes: error TSRequest!");
+ return -1;
+ }
+ }
+ else
+ {
+ rv = header[1];
+ rv += 2;
+ }
+ }
+ else
+ {
+ /* Fast-Path */
+ if (header[1] & 0x80)
+ {
+ rv = ((header[1] & 0x7F) << 8) | header[2];
+ }
+ else
+ {
+ rv = header[1];
+ }
+ }
+ return rv;
+}
+
+/******************************************************************************/
+/* only used durring connection */
+struct stream * APP_CC
+libxrdp_force_read(struct trans* trans)
+{
+ int bytes;
+ struct stream *s;
+
+ s = trans->in_s;
+ init_stream(s, 32 * 1024);
+ if (trans_force_read(trans, 4) != 0)
+ {
+ g_writeln("libxrdp_force_read: error");
+ return 0;
+ }
+ bytes = libxrdp_get_pdu_bytes(s->data);
+ if (bytes < 1)
+ {
+ g_writeln("libxrdp_force_read: error");
+ return 0;
+ }
+ if (bytes > 32 * 1024)
+ {
+ g_writeln("libxrdp_force_read: error");
+ return 0;
+ }
+ if (trans_force_read(trans, bytes - 4) != 0)
+ {
+ g_writeln("libxrdp_force_read: error");
+ return 0;
+ }
+ return s;
}
/******************************************************************************/
@@ -74,9 +168,15 @@ libxrdp_process_data(struct xrdp_session *session, struct stream *s)
int code;
int term;
int dead_lock_counter;
+ int do_read;
struct xrdp_rdp *rdp;
- struct stream *ls;
+ do_read = s == 0;
+ if (do_read && session->up_and_running)
+ {
+ g_writeln("libxrdp_process_data: error logic");
+ return 1;
+ }
if (session->in_process_data != 0)
{
g_writeln("libxrdp_process_data: error reentry");
@@ -84,14 +184,6 @@ libxrdp_process_data(struct xrdp_session *session, struct stream *s)
}
session->in_process_data++;
- ls = 0;
- if (s == 0)
- {
- make_stream(ls);
- init_stream(ls, 8192 * 4);
- s = ls;
- }
-
term = 0;
cont = 1;
rv = 0;
@@ -106,13 +198,26 @@ libxrdp_process_data(struct xrdp_session *session, struct stream *s)
if (session->is_term())
{
term = 1;
+ break;
}
}
code = 0;
+ if (do_read)
+ {
+ s = libxrdp_force_read(session->trans);
+ if (s == 0)
+ {
+ g_writeln("libxrdp_process_data: libxrdp_force_read failed");
+ rv = 1;
+ break;
+ }
+ }
+
if (xrdp_rdp_recv(rdp, s, &code) != 0)
{
+ g_writeln("libxrdp_process_data: xrdp_rdp_recv failed");
rv = 1;
break;
}
@@ -181,11 +286,6 @@ libxrdp_process_data(struct xrdp_session *session, struct stream *s)
}
}
- if (s == ls)
- {
- free_stream(s);
- }
-
session->in_process_data--;
return rv;
diff --git a/libxrdp/libxrdpinc.h b/libxrdp/libxrdpinc.h
index d322eafa..58ba5093 100644
--- a/libxrdp/libxrdpinc.h
+++ b/libxrdp/libxrdpinc.h
@@ -82,6 +82,10 @@ int DEFAULT_CC
libxrdp_disconnect(struct xrdp_session* session);
int DEFAULT_CC
libxrdp_process_incomming(struct xrdp_session* session);
+int EXPORT_CC
+libxrdp_get_pdu_bytes(const char *aheader);
+struct stream * APP_CC
+libxrdp_force_read(struct trans* trans);
int DEFAULT_CC
libxrdp_process_data(struct xrdp_session* session, struct stream *s);
int DEFAULT_CC
diff --git a/libxrdp/xrdp_fastpath.c b/libxrdp/xrdp_fastpath.c
index 572b5a98..5f7ccc97 100644
--- a/libxrdp/xrdp_fastpath.c
+++ b/libxrdp/xrdp_fastpath.c
@@ -63,7 +63,7 @@ xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s)
DEBUG((" in xrdp_fastpath_recv"));
in_uint8(s, fp_hdr); /* fpInputHeader (1 byte) */
- g_writeln("xrdp_fastpath_recv: header= 0x%8.8x", fp_hdr);
+ //g_writeln("xrdp_fastpath_recv: header= 0x%8.8x", fp_hdr);
self->numEvents = (fp_hdr & 0x3C) >> 2;
self->secFlags = (fp_hdr & 0xC0) >> 6;
diff --git a/libxrdp/xrdp_iso.c b/libxrdp/xrdp_iso.c
index 31c279b5..0ea07c18 100644
--- a/libxrdp/xrdp_iso.c
+++ b/libxrdp/xrdp_iso.c
@@ -90,27 +90,21 @@ xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code, int *len)
{
int ver; // TPKT Version
int plen; // TPKT PacketLength
- int do_read;
*code = 0; // X.224 Packet Type
*len = 0; // X.224 Length Indicator
- /* early in connection sequence, iso needs to do a force read */
- do_read = s != self->trans->in_s;
-
- if (do_read)
+ if (s != self->trans->in_s)
{
- init_stream(s, 4);
- if (trans_force_read_s(self->trans, s, 4) != 0)
- {
- return 1;
- }
+ g_writeln("xrdp_iso_recv_msg error logic");
}
in_uint8(s, ver);
if (ver != 3)
{
+ g_writeln("xrdp_iso_recv_msg: bad ver");
+ g_hexdump(s->data, 4);
return 1;
}
@@ -122,15 +116,6 @@ xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code, int *len)
return 1;
}
- if (do_read)
- {
- init_stream(s, plen - 4);
- if (trans_force_read_s(self->trans, s, plen - 4) != 0)
- {
- return 1;
- }
- }
-
if (!s_check_rem(s, 2))
{
return 1;
@@ -311,20 +296,22 @@ xrdp_iso_incoming(struct xrdp_iso *self)
char *pend;
struct stream *s;
- make_stream(s);
- init_stream(s, 8192);
DEBUG((" in xrdp_iso_incoming"));
+ s = libxrdp_force_read(self->trans);
+ if (s == 0)
+ {
+ return 1;
+ }
+
if (xrdp_iso_recv_msg(self, s, &code, &len) != 0)
{
DEBUG((" in xrdp_iso_recv_msg error!!"));
- free_stream(s);
return 1;
}
if ((code != ISO_PDU_CR) || (len < 6))
{
- free_stream(s);
return 1;
}
@@ -343,7 +330,6 @@ xrdp_iso_incoming(struct xrdp_iso *self)
case RDP_NEG_REQ: /* rdpNegReq 1 */
if (xrdp_iso_recv_rdpnegreq(self, s) != 0)
{
- free_stream(s);
return 1;
}
break;
@@ -371,12 +357,10 @@ xrdp_iso_incoming(struct xrdp_iso *self)
if (xrdp_iso_send_nego(self) != 0)
{
- free_stream(s);
return 1;
}
DEBUG((" out xrdp_iso_incoming"));
- free_stream(s);
return 0;
}
diff --git a/libxrdp/xrdp_mcs.c b/libxrdp/xrdp_mcs.c
index 08055191..a9e8d7b5 100644
--- a/libxrdp/xrdp_mcs.c
+++ b/libxrdp/xrdp_mcs.c
@@ -129,6 +129,7 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan)
if (xrdp_iso_recv(self->iso_layer, s) != 0)
{
DEBUG((" out xrdp_mcs_recv, xrdp_iso_recv return non zero"));
+ g_writeln("xrdp_mcs_recv: xrdp_iso_recv failed");
return 1;
}
@@ -150,12 +151,7 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan)
/* this is channels getting added from the client */
if (appid == MCS_CJRQ)
{
- if (s == self->iso_layer->trans->in_s)
- {
- /* this should not happen */
- g_writeln("xrdp_mcs_recv: error, MCS_CJRQ at wrong time");
- return 1;
- }
+
if (!s_check_rem(s, 4))
{
return 1;
@@ -170,6 +166,14 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan)
{
log_message(LOG_LEVEL_ERROR,"Non handled error from xrdp_mcs_send_cjcf") ;
}
+
+ s = libxrdp_force_read(self->iso_layer->trans);
+ if (s == 0)
+ {
+ g_writeln("xrdp_mcs_recv: libxrdp_force_read failed");
+ return 1;
+ }
+
continue;
}
@@ -321,30 +325,29 @@ xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self)
int len;
struct stream *s;
- make_stream(s);
- init_stream(s, 16 * 1024);
+ s = libxrdp_force_read(self->iso_layer->trans);
+ if (s == 0)
+ {
+ return 1;
+ }
if (xrdp_iso_recv(self->iso_layer, s) != 0)
{
- free_stream(s);
return 1;
}
if (xrdp_mcs_ber_parse_header(self, s, MCS_CONNECT_INITIAL, &len) != 0)
{
- free_stream(s);
return 1;
}
if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_OCTET_STRING, &len) != 0)
{
- free_stream(s);
return 1;
}
if ((len < 0) || !s_check_rem(s, len))
{
- free_stream(s);
return 1;
}
@@ -352,13 +355,11 @@ xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self)
if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_OCTET_STRING, &len) != 0)
{
- free_stream(s);
return 1;
}
if ((len < 0) || !s_check_rem(s, len))
{
- free_stream(s);
return 1;
}
@@ -366,13 +367,11 @@ xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self)
if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_BOOLEAN, &len) != 0)
{
- free_stream(s);
return 1;
}
if ((len < 0) || !s_check_rem(s, len))
{
- free_stream(s);
return 1;
}
@@ -380,38 +379,32 @@ xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self)
if (xrdp_mcs_parse_domain_params(self, s) != 0)
{
- free_stream(s);
return 1;
}
if (xrdp_mcs_parse_domain_params(self, s) != 0)
{
- free_stream(s);
return 1;
}
if (xrdp_mcs_parse_domain_params(self, s) != 0)
{
- free_stream(s);
return 1;
}
if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_OCTET_STRING, &len) != 0)
{
- free_stream(s);
return 1;
}
/* mcs data can not be zero length */
if ((len <= 0) || (len > 16 * 1024))
{
- free_stream(s);
return 1;
}
if (!s_check_rem(s, len))
{
- free_stream(s);
return 1;
}
@@ -423,12 +416,10 @@ xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self)
if (s_check_end(s))
{
- free_stream(s);
return 0;
}
else
{
- free_stream(s);
return 1;
}
}
@@ -442,18 +433,20 @@ xrdp_mcs_recv_edrq(struct xrdp_mcs *self)
struct stream *s;
DEBUG((" in xrdp_mcs_recv_edrq"));
- make_stream(s);
- init_stream(s, 8192);
+
+ s = libxrdp_force_read(self->iso_layer->trans);
+ if (s == 0)
+ {
+ return 1;
+ }
if (xrdp_iso_recv(self->iso_layer, s) != 0)
{
- free_stream(s);
return 1;
}
-
+
if (!s_check_rem(s, 1))
{
- free_stream(s);
return 1;
}
@@ -461,13 +454,11 @@ xrdp_mcs_recv_edrq(struct xrdp_mcs *self)
if ((opcode >> 2) != MCS_EDRQ)
{
- free_stream(s);
return 1;
}
if (!s_check_rem(s, 4))
{
- free_stream(s);
return 1;
}
@@ -478,7 +469,6 @@ xrdp_mcs_recv_edrq(struct xrdp_mcs *self)
{
if (!s_check_rem(s, 2))
{
- free_stream(s);
return 1;
}
in_uint16_be(s, self->userid);
@@ -486,11 +476,9 @@ xrdp_mcs_recv_edrq(struct xrdp_mcs *self)
if (!(s_check_end(s)))
{
- free_stream(s);
return 1;
}
- free_stream(s);
DEBUG((" out xrdp_mcs_recv_edrq"));
return 0;
}
@@ -504,18 +492,20 @@ xrdp_mcs_recv_aurq(struct xrdp_mcs *self)
struct stream *s;
DEBUG((" in xrdp_mcs_recv_aurq"));
- make_stream(s);
- init_stream(s, 8192);
+
+ s = libxrdp_force_read(self->iso_layer->trans);
+ if (s == 0)
+ {
+ return 1;
+ }
if (xrdp_iso_recv(self->iso_layer, s) != 0)
{
- free_stream(s);
return 1;
}
if (!s_check_rem(s, 1))
{
- free_stream(s);
return 1;
}
@@ -523,7 +513,6 @@ xrdp_mcs_recv_aurq(struct xrdp_mcs *self)
if ((opcode >> 2) != MCS_AURQ)
{
- free_stream(s);
return 1;
}
@@ -531,7 +520,6 @@ xrdp_mcs_recv_aurq(struct xrdp_mcs *self)
{
if (!s_check_rem(s, 2))
{
- free_stream(s);
return 1;
}
in_uint16_be(s, self->userid);
@@ -539,11 +527,9 @@ xrdp_mcs_recv_aurq(struct xrdp_mcs *self)
if (!(s_check_end(s)))
{
- free_stream(s);
return 1;
}
- free_stream(s);
DEBUG((" out xrdp_mcs_recv_aurq"));
return 0;
}
@@ -591,18 +577,19 @@ xrdp_mcs_recv_cjrq(struct xrdp_mcs *self)
int opcode;
struct stream *s;
- make_stream(s);
- init_stream(s, 8192);
+ s = libxrdp_force_read(self->iso_layer->trans);
+ if (s == 0)
+ {
+ return 1;
+ }
if (xrdp_iso_recv(self->iso_layer, s) != 0)
{
- free_stream(s);
return 1;
}
if (!s_check_rem(s, 1))
{
- free_stream(s);
return 1;
}
@@ -610,13 +597,11 @@ xrdp_mcs_recv_cjrq(struct xrdp_mcs *self)
if ((opcode >> 2) != MCS_CJRQ)
{
- free_stream(s);
return 1;
}
if (!s_check_rem(s, 4))
{
- free_stream(s);
return 1;
}
@@ -626,7 +611,6 @@ xrdp_mcs_recv_cjrq(struct xrdp_mcs *self)
{
if (!s_check_rem(s, 2))
{
- free_stream(s);
return 1;
}
in_uint8s(s, 2);
@@ -634,11 +618,9 @@ xrdp_mcs_recv_cjrq(struct xrdp_mcs *self)
if (!(s_check_end(s)))
{
- free_stream(s);
return 1;
}
- free_stream(s);
return 0;
}
diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c
index 787b6e6c..729a2f29 100644
--- a/libxrdp/xrdp_rdp.c
+++ b/libxrdp/xrdp_rdp.c
@@ -299,17 +299,17 @@ xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code)
int pdu_code = 0;
int chan = 0;
const tui8 *header;
- header = (const tui8 *) (self->session->trans->in_s->p);
DEBUG(("in xrdp_rdp_recv"));
if (s->next_packet == 0 || s->next_packet >= s->end)
{
/* check for fastpath first */
+ header = (const tui8 *) (self->session->trans->in_s->p);
if ((header[0] != 0x3) && (header[0] != 0x3c))
{
if (xrdp_sec_recv_fastpath(self->sec_layer, s) != 0)
{
- return 1;
+ return 1;
}
*code = 2; // special code for fastpath input
DEBUG(("out (fastpath) xrdp_rdp_recv"));
@@ -331,6 +331,7 @@ xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code)
if (error != 0)
{
DEBUG(("out xrdp_rdp_recv error"));
+ g_writeln("xrdp_rdp_recv: xrdp_sec_recv failed");
return 1;
}
diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c
index d0f84273..c99f9188 100644
--- a/libxrdp/xrdp_sec.c
+++ b/libxrdp/xrdp_sec.c
@@ -996,6 +996,7 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan)
if (xrdp_mcs_recv(self->mcs_layer, s, chan) != 0)
{
DEBUG((" out xrdp_sec_recv : error"));
+ g_writeln("xrdp_sec_recv: xrdp_mcs_recv failed");
return 1;
}