diff options
Diffstat (limited to 'libxrdp/xrdp_iso.c')
| -rw-r--r-- | libxrdp/xrdp_iso.c | 232 |
1 files changed, 87 insertions, 145 deletions
diff --git a/libxrdp/xrdp_iso.c b/libxrdp/xrdp_iso.c index 1f546b0b..df00f52b 100644 --- a/libxrdp/xrdp_iso.c +++ b/libxrdp/xrdp_iso.c @@ -30,7 +30,7 @@ xrdp_iso_create(struct xrdp_mcs *owner, struct trans *trans) DEBUG((" in xrdp_iso_create")); self = (struct xrdp_iso *)g_malloc(sizeof(struct xrdp_iso), 1); self->mcs_layer = owner; - self->tcp_layer = xrdp_tcp_create(self, trans); + self->trans = trans; DEBUG((" out xrdp_iso_create")); return self; } @@ -44,7 +44,6 @@ xrdp_iso_delete(struct xrdp_iso *self) return; } - xrdp_tcp_delete(self->tcp_layer); g_free(self); } @@ -89,94 +88,30 @@ xrdp_iso_recv_rdpnegreq(struct xrdp_iso *self, struct stream *s) static int APP_CC xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code, int *len) { - int plen; // PacketLength + int ver; // TPKT Version + int plen; // TPKT PacketLength + int do_read; *code = 0; // X.224 Packet Type *len = 0; // X.224 Length Indicator - plen = xrdp_iso_recv_tpkt_header(self, s); + /* early in connection sequence, iso needs to do a force read */ + do_read = s != self->trans->in_s; - if (plen == 2) + if (do_read) { - DEBUG(("xrdp_iso_recv_msg: non-TPKT header detected, we try fastpath")); - return plen; - } - - if (plen == 1) { - return 1; - } - - // receive the left bytes - if (xrdp_tcp_recv(self->tcp_layer, s, plen - 4) != 0) - { - return 1; - } - - xrdp_iso_read_x224_header(s, code, len); - - return 0; -} -/*****************************************************************************/ -/* returns error */ -int APP_CC -xrdp_iso_recv(struct xrdp_iso *self, struct stream *s) -{ - int code; - int len; - int iso_msg; - - DEBUG((" in xrdp_iso_recv")); - - iso_msg = xrdp_iso_recv_msg(self, s, &code, &len); - - if (iso_msg == 2) // non-TPKT header - { - DEBUG((" out xrdp_iso_recv xrdp_iso_recv_msg return 2, non-TPKT header detected")); - return iso_msg; - } - - if (iso_msg == 1) // error - { - DEBUG((" out xrdp_iso_recv xrdp_iso_recv_msg return non zero")); - return 1; - } - - if (code != ISO_PDU_DT || len != 2) - { - DEBUG((" out xrdp_iso_recv code != ISO_PDU_DT or length != 2")); - return 1; - } - - DEBUG((" out xrdp_iso_recv")); - return 0; -} -/*****************************************************************************/ -/* returns packet length or error (1) */ -int APP_CC -xrdp_iso_recv_tpkt_header(struct xrdp_iso *self, struct stream *s) -{ - int plen; - int ver; - - if (xrdp_tcp_recv(self->tcp_layer, s, 1) != 0) - { - return 1; + init_stream(s, 4); + if (trans_force_read_s(self->trans, s, 4) != 0) + { + return 1; + } } - in_uint8_peek(s, ver); // Peek only so we can use it later in fastpath layer, if needed + in_uint8(s, ver); if (ver != 3) { - /* - * special error code that means we got non-TPKT header, - * so we gonna try fastpath input. - */ - return 2; - } - - if (xrdp_tcp_recv(self->tcp_layer, s, 3) != 0) - { - return 1; + return 2; // special code for fastpath } in_uint8s(s, 1); @@ -184,32 +119,25 @@ xrdp_iso_recv_tpkt_header(struct xrdp_iso *self, struct stream *s) if (plen < 4) { - return 1; // tpkt must be >= 4 bytes length + return 1; + } + + if (do_read) + { + init_stream(s, plen - 4); + if (trans_force_read_s(self->trans, s, plen - 4) != 0) + { + return 1; + } } - return plen; -} -/*****************************************************************************/ -void APP_CC -xrdp_iso_write_tpkt_header(struct stream *s, int len) -{ - /* TPKT HEADER - 4 bytes */ - out_uint8(s, 3); /* version */ - out_uint8(s, 0); /* RESERVED */ - out_uint16_be(s, len); /* length */ -} -/*****************************************************************************/ -/* returns error */ -int APP_CC -xrdp_iso_read_x224_header(struct stream *s, int *code, int *len) -{ if (!s_check_rem(s, 2)) { return 1; } - in_uint8(s, *len); /* length */ - in_uint8(s, *code); /* code */ + in_uint8(s, *len); + in_uint8(s, *code); if (*code == ISO_PDU_DT) { @@ -230,55 +158,63 @@ xrdp_iso_read_x224_header(struct stream *s, int *code, int *len) return 0; } + /*****************************************************************************/ -void APP_CC -xrdp_iso_write_x224_header(struct stream *s, int len, int code) +/* returns error */ +int APP_CC +xrdp_iso_recv(struct xrdp_iso *self, struct stream *s) { - /* ISO LAYER - X.224 - 7 bytes*/ - out_uint8(s, len); /* length */ - out_uint8(s, code); /* code */ + int code; + int len; + + DEBUG((" in xrdp_iso_recv")); + + if (xrdp_iso_recv_msg(self, s, &code, &len) != 0) + { + DEBUG((" out xrdp_iso_recv xrdp_iso_recv_msg return non zero")); + return 1; + } - if (code == ISO_PDU_DT) + if (code != ISO_PDU_DT || len != 2) { - out_uint8(s, 0x80); - } else { - out_uint16_be(s, 0); - out_uint16_be(s, 0x1234); - out_uint8(s, 0); + DEBUG((" out xrdp_iso_recv code != ISO_PDU_DT or length != 2")); + return 1; } + + DEBUG((" out xrdp_iso_recv")); + return 0; } + /*****************************************************************************/ static int APP_CC -xrdp_iso_send_rdpnegrsp(struct xrdp_iso *self, struct stream *s) +xrdp_iso_send_rdpnegrsp(struct xrdp_iso *self, struct stream *s, int code) { - if (xrdp_tcp_init(self->tcp_layer, s) != 0) - { - return 1; - } + init_stream(s, 8192 * 4); /* 32 KB */ - // Write TPKT Header + /* TPKT HEADER - 4 bytes */ + out_uint8(s, 3); /* version */ + out_uint8(s, 0); /* RESERVED */ if (self->selectedProtocol != -1) { - //rdp negotiation happens. - xrdp_iso_write_tpkt_header(s, 19); + out_uint16_be(s, 19); /* length */ //rdp negotiation happens. } else { - //rdp negotiation doesn't happen. - xrdp_iso_write_tpkt_header(s, 11); + out_uint16_be(s, 11); /* length */ //rdp negotiation doesn't happen. } - - // Write x224 header + /* ISO LAYER - X.224 - 7 bytes*/ if (self->selectedProtocol != -1) { - xrdp_iso_write_x224_header(s, 14, ISO_PDU_CC); + out_uint8(s, 14); /* length */ } else { - xrdp_iso_write_x224_header(s, 6, ISO_PDU_CC); + out_uint8(s, 6); /* length */ } - - /* RDP_NEG */ + out_uint8(s, code); /* SHOULD BE 0xD for CC */ + out_uint16_be(s, 0); + out_uint16_be(s, 0x1234); + out_uint8(s, 0); if (self->selectedProtocol != -1) { /* RDP_NEG_RSP - 8 bytes*/ @@ -290,7 +226,7 @@ xrdp_iso_send_rdpnegrsp(struct xrdp_iso *self, struct stream *s) s_mark_end(s); - if (xrdp_tcp_send(self->tcp_layer, s) != 0) + if (trans_force_write_s(self->trans, s) != 0) { return 1; } @@ -299,17 +235,20 @@ xrdp_iso_send_rdpnegrsp(struct xrdp_iso *self, struct stream *s) } /*****************************************************************************/ static int APP_CC -xrdp_iso_send_rdpnegfailure(struct xrdp_iso *self, struct stream *s, int failureCode) +xrdp_iso_send_rdpnegfailure(struct xrdp_iso *self, struct stream *s, int code, int failureCode) { - if (xrdp_tcp_init(self->tcp_layer, s) != 0) - { - return 1; - } - - xrdp_iso_write_tpkt_header(s, 19); - - xrdp_iso_write_x224_header(s, 14, ISO_PDU_CC); + init_stream(s, 8192 * 4); /* 32 KB */ + /* TPKT HEADER - 4 bytes */ + out_uint8(s, 3); /* version */ + out_uint8(s, 0); /* RESERVED */ + out_uint16_be(s, 19); /* length */ + /* ISO LAYER - X.224 - 7 bytes*/ + out_uint8(s, 14); /* length */ + out_uint8(s, code); /* SHOULD BE 0xD for CC */ + out_uint16_be(s, 0); + out_uint16_be(s, 0x1234); + out_uint8(s, 0); /* RDP_NEG_FAILURE - 8 bytes*/ out_uint8(s, RDP_NEG_FAILURE); out_uint8(s, 0); /* no flags available */ @@ -317,7 +256,7 @@ xrdp_iso_send_rdpnegfailure(struct xrdp_iso *self, struct stream *s, int failure out_uint32_le(s, failureCode); /* failure code */ s_mark_end(s); - if (xrdp_tcp_send(self->tcp_layer, s) != 0) + if (trans_force_write_s(self->trans, s) != 0) { return 1; } @@ -338,7 +277,8 @@ xrdp_iso_send_nego(struct xrdp_iso *self) if (self->requestedProtocol != PROTOCOL_RDP) { // Send RDP_NEG_FAILURE back to client - if (xrdp_iso_send_rdpnegfailure(self, s, SSL_NOT_ALLOWED_BY_SERVER) != 0) + if (xrdp_iso_send_rdpnegfailure(self, s, ISO_PDU_CC, + SSL_NOT_ALLOWED_BY_SERVER) != 0) { free_stream(s); return 1; @@ -348,7 +288,7 @@ xrdp_iso_send_nego(struct xrdp_iso *self) { self->selectedProtocol = PROTOCOL_RDP; // Send RDP_NEG_RSP back to client - if (xrdp_iso_send_rdpnegrsp(self, s) != 0) + if (xrdp_iso_send_rdpnegrsp(self, s, ISO_PDU_CC) != 0) { free_stream(s); return 1; @@ -384,7 +324,6 @@ xrdp_iso_incoming(struct xrdp_iso *self) if ((code != ISO_PDU_CR) || (len < 6)) { - DEBUG((" in xrdp_iso_recv_msg error: non iso_pdu_cr msg")); free_stream(s); return 1; } @@ -446,7 +385,7 @@ xrdp_iso_incoming(struct xrdp_iso *self) int APP_CC xrdp_iso_init(struct xrdp_iso *self, struct stream *s) { - xrdp_tcp_init(self->tcp_layer, s); + init_stream(s, 8192 * 4); /* 32 KB */ s_push_layer(s, iso_hdr, 7); return 0; } @@ -461,11 +400,14 @@ xrdp_iso_send(struct xrdp_iso *self, struct stream *s) DEBUG((" in xrdp_iso_send")); s_pop_layer(s, iso_hdr); len = (int)(s->end - s->p); - - xrdp_iso_write_tpkt_header(s, len); - xrdp_iso_write_x224_header(s, 2, ISO_PDU_DT); - - if (xrdp_tcp_send(self->tcp_layer, s) != 0) + out_uint8(s, 3); + out_uint8(s, 0); + out_uint16_be(s, len); + out_uint8(s, 2); + out_uint8(s, ISO_PDU_DT); + out_uint8(s, 0x80); + + if (trans_force_write_s(self->trans, s) != 0) { return 1; } |
