/* Parse an ASN.1 BER header */ RD_BOOL ber_parse_header(rdpMcs * mcs, STREAM s, int tagval, int *length) { int tag, len; if (tagval > 0xff) { in_uint16_be(s, tag); } else { in_uint8(s, tag); } if (tag != tagval) { ui_error(mcs->sec->rdp->inst, "expected tag %d, got %d\n", tagval, tag); return False; } in_uint8(s, len); if (len & 0x80) { len &= ~0x80; *length = 0; while (len--) next_be(s, *length); } else *length = len; return s_check(s); }
/* Receive a message on the ISO layer, return code */ static STREAM iso_recv_msg(uint8 * code, uint8 * rdpver) { STREAM s; uint16 length; uint8 version; s = tcp_recv(NULL, 4); if (s == NULL) return NULL; in_uint8(s, version); if (rdpver != NULL) *rdpver = version; if (version == 3) { in_uint8s(s, 1); /* pad */ in_uint16_be(s, length); } else { in_uint8(s, length); if (length & 0x80) { length &= ~0x80; next_be(s, length); } } if (length < 4) { error("Bad packet header\n"); return NULL; } s = tcp_recv(s, length - 4); if (s == NULL) return NULL; if (version != 3) return s; in_uint8s(s, 1); /* hdrlen */ in_uint8(s, *code); if (*code == ISO_PDU_DT) { in_uint8s(s, 1); /* eot */ return s; } in_uint8s(s, 5); /* dst_ref, src_ref, class */ return s; }
/* Receive a packet from tcp and return stream. * If no ptype then only TPKT header with X.224 is accepted. * If ptype then Fast-Path packets are accepted too. * Return NULL on error. */ STREAM tpkt_recv(rdpIso * iso, uint8 * pcode, isoRecvType * ptype) { STREAM s; int length; s = tcp_recv(iso->tcp, NULL, 4); if (s == NULL) return NULL; length = tpkt_input_header(s); if (length >= 0) { /* Valid TPKT header, payload is X.224 TPDU */ if (ptype != NULL) *ptype = ISO_RECV_X224; s = x224_recv(iso, s, length, pcode); return s; } else if (ptype != NULL) { /* Fast-Path header */ uint8 fpInputHeader; in_uint8(s, fpInputHeader); ASSERT((fpInputHeader & 3) == 0); /* assume actionCode FASTPATH_OUTPUT_ACTION_FASTPATH */ *ptype = (fpInputHeader & 0x80) ? ISO_RECV_FAST_PATH_ENCRYPTED : ISO_RECV_FAST_PATH; /* TODO: 0x40 FASTPATH_OUTPUT_SECURE_CHECKSUM indicates salted MAC */ in_uint8(s, length); if (length & 0x80) { length &= ~0x80; next_be(s, length); } s = tcp_recv(iso->tcp, s, length - 4); return s; } return NULL; /* Fast-Path not allowed */ }
/* Receive a message on the ISO layer, return code */ static STREAM iso_recv_msg(RDPCLIENT * This, uint8 * code, uint8 * rdpver) { STREAM s; uint16 length; uint8 version; s = tcp_recv(This, NULL, 4); if (s == NULL) return NULL; in_uint8(s, version); if (rdpver != NULL) *rdpver = version; if (version == 3) { in_uint8s(s, 1); /* pad */ in_uint16_be(s, length); } else { in_uint8(s, length); if (length & 0x80) { length &= ~0x80; next_be(s, length); } } s = tcp_recv(This, s, length - 4); if (s == NULL) return NULL; if (version != 3) return s; in_uint8s(s, 1); /* hdrlen */ in_uint8(s, *code); if (*code == ISO_PDU_DT) { in_uint8s(s, 1); /* eot */ return s; } in_uint8s(s, 5); /* dst_ref, src_ref, class */ return s; }