summaryrefslogtreecommitdiffstats
path: root/libxrdp/xrdp_iso.c
diff options
context:
space:
mode:
Diffstat (limited to 'libxrdp/xrdp_iso.c')
-rw-r--r--libxrdp/xrdp_iso.c232
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;
}