diff options
Diffstat (limited to 'libxrdp')
-rw-r--r-- | libxrdp/libxrdp.c | 130 | ||||
-rw-r--r-- | libxrdp/libxrdpinc.h | 4 | ||||
-rw-r--r-- | libxrdp/xrdp_fastpath.c | 2 | ||||
-rw-r--r-- | libxrdp/xrdp_iso.c | 36 | ||||
-rw-r--r-- | libxrdp/xrdp_mcs.c | 84 | ||||
-rw-r--r-- | libxrdp/xrdp_rdp.c | 5 | ||||
-rw-r--r-- | libxrdp/xrdp_sec.c | 1 |
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; } |