@paramself @param(in/out)s:thestreamtoreadfrom.Uponreturnthestreamis? @param(out)code:thepducodefromthepacket returnserror
*/ int
xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code)
{ int error = 0; int len = 0; int pdu_code = 0; int chan = 0; const tui8 *header;
if (s->next_packet == 0 || s->next_packet >= s->end)
{ /* check for fastpath first */
header = (const tui8 *) (s->p); if (header[0] != 0x3)
{ if (xrdp_sec_recv_fastpath(self->sec_layer, s) != 0)
{
LOG(LOG_LEVEL_ERROR, "xrdp_rdp_recv: xrdp_sec_recv_fastpath failed"); return1;
} /* next_packet gets set in xrdp_sec_recv_fastpath */
*code = 2; // special code for fastpath input
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp_recv: out code 2 (fastpath)"); return0;
}
/* not fastpath, do tpkt */
chan = 0;
error = xrdp_sec_recv(self->sec_layer, s, &chan);
if (error == -1) /* special code for send demand active */
{
s->next_packet = 0;
*code = -1;
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp_recv: out code -1 (send demand active)"); return0;
}
if (!s_check_rem_and_log(s, 6, "Parsing [MS-RDPBCGR] TS_SHARECONTROLHEADER"))
{
s->next_packet = 0;
*code = 0;
LOG(LOG_LEVEL_ERROR, "xrdp_rdp_recv: out code 0 bad RDP packet"); return1;
}
in_uint16_le(s, len); /* totalLength */
in_uint16_le(s, pdu_code); /* pduType */
in_uint8s(s, 2); /* pduSource */ // Length must be at least the size of TS_SHARECONTROLHEADER, and // cannot fall beyond the end of the PDU if (len < 6 || !s_check_rem(s, len - 6))
{
LOG(LOG_LEVEL_ERROR, "bad TS_SHARECONTROLHEADER length 0x%04X", len); return1;
}
*code = pdu_code & 0xf;
s->next_packet += len;
LOG_DEVEL(LOG_LEVEL_TRACE, "Received header [MS-RDPBCGR] TS_SHARECONTROLHEADER " "totalLength %d, pduType.type %s (%d), pduType.PDUVersion %d, " "pduSource (ignored)", len, PDUTYPE_TO_STR(*code), *code,
((pdu_code & 0xfff0) >> 4)); return0;
}
/*****************************************************************************/ /* Send a [MS-RDPBCGR] Control PDU with for the given pduType with the headers
added */ int
xrdp_rdp_send(struct xrdp_rdp *self, struct stream *s, int pdu_type)
{ int len = 0;
/*****************************************************************************/ /* Send a [MS-RDPBCGR] Data PDU for the given pduType2 from *thespecifiedsourcewiththeheaders
added and data compressed */ int
xrdp_rdp_send_data_from_channel(struct xrdp_rdp *self, struct stream *s, int data_pdu_type, int channel_id, int compress)
{ int len; int ctype; int clen; int dlen; int pdulen; int pdutype; int tocomplen; int iso_offset; int mcs_offset; int sec_offset; int rdp_offset; struct stream ls; struct xrdp_mppc_enc *mppc_enc;
/*****************************************************************************/ /* Send a [MS-RDPBCGR] Data PDU on the MCS channel for the given pduType2
* with the headers added and data compressed */ int
xrdp_rdp_send_data(struct xrdp_rdp *self, struct stream *s, int data_pdu_type)
{ return xrdp_rdp_send_data_from_channel(self, s, data_pdu_type,
self->mcs_channel, 1);
}
/*****************************************************************************/ /* returns the fastpath rdp byte count */ int
xrdp_rdp_get_fastpath_bytes(struct xrdp_rdp *self)
{ if (self->client_info.rdp_compression)
{ return4;
} return3;
}
/*****************************************************************************/ /* returns error */ /* 2.2.9.1.2.1 Fast-Path Update (TS_FP_UPDATE)
* http://msdn.microsoft.com/en-us/library/cc240622.aspx */ int
xrdp_rdp_send_fastpath(struct xrdp_rdp *self, struct stream *s, int data_pdu_type)
{ int updateHeader; int updateCode; int fragmentation; int compression; int comp_type; int comp_len; int no_comp_len; int send_len; int cont; int header_bytes; int sec_bytes; int to_comp_len; int sec_offset; int rdp_offset; struct stream frag_s; struct stream comp_s; struct stream send_s; struct xrdp_mppc_enc *mppc_enc; char comp_type_str[7];
comp_type_str[0] = '\0';
/*****************************************************************************/ /* Send a [MS-RDPBCGR] TS_UPDATE_SYNC or TS_FP_UPDATE_SYNCHRONIZE message
depending on if the client supports the fast path capability or not */ int
xrdp_rdp_send_data_update_sync(struct xrdp_rdp *self)
{ struct stream *s = (struct stream *)NULL;
/* log TLS version and cipher of TLS connections */ if (iso->selectedProtocol > PROTOCOL_RDP)
{
LOG(LOG_LEVEL_INFO, "TLS connection established from %s %s with cipher %s",
self->client_info.client_description,
iso->trans->ssl_protocol,
iso->trans->cipher_name);
} /* log non-TLS connections */ else
{ int crypt_level = self->sec_layer->crypt_level; constchar *security_level =
(crypt_level == CRYPT_LEVEL_NONE) ? "none" :
(crypt_level == CRYPT_LEVEL_LOW) ? "low" :
(crypt_level == CRYPT_LEVEL_CLIENT_COMPATIBLE) ? "medium" :
(crypt_level == CRYPT_LEVEL_HIGH) ? "high" :
(crypt_level == CRYPT_LEVEL_FIPS) ? "fips" : /* default */ "unknown";
LOG(LOG_LEVEL_INFO, "Non-TLS connection established from %s with security level : %s",
self->client_info.client_description, security_level);
}
return0;
}
/*****************************************************************************/ /* Process a [MS-RDPBCGR] TS_POINTER_PDU message */ staticint
xrdp_rdp_process_data_pointer(struct xrdp_rdp *self, struct stream *s)
{
LOG_DEVEL(LOG_LEVEL_WARNING, "Protocol error ignored: a [MS-RDPBCGR] " "TS_SHAREDATAHEADER PDUTYPE2_POINTER was received by the server " "but this type of PDU is only suppose to be sent by the server " "to the client."); return0;
}
/*****************************************************************************/ /* Process a [MS-RDPBCGR] TS_INPUT_PDU_DATA message */ staticint
xrdp_rdp_process_data_input(struct xrdp_rdp *self, struct stream *s)
{ int num_events; int index; int msg_type; int device_flags; int param1; int param2; int time;
/*****************************************************************************/ /* 2.2.11.2.1 Refresh Rect PDU Data (TS_REFRESH_RECT_PDU) */ staticint
xrdp_rdp_process_screen_update(struct xrdp_rdp *self, struct stream *s)
{ int index; int num_rects; int left; int top; int right; int bottom; int cx; int cy;
/*****************************************************************************/ /* Process a [MS-RDPBCGR] TS_FONT_LIST_PDU message */ staticint
xrdp_rdp_process_data_font(struct xrdp_rdp *self, struct stream *s)
{ int seq;
if (!s_check_rem_and_log(s, 6, "Parsing [MS-RDPBCGR] TS_FONT_LIST_PDU"))
{ return1;
}
in_uint8s(s, 2); /* NumberFonts: 0x0, SHOULD be set to 0 */
in_uint8s(s, 2); /* TotalNumberFonts: 0x0, SHOULD be set to 0 */
in_uint16_le(s, seq); /* ListFlags */
LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_FONT_LIST_PDU " "numberFonts (ignored), totalNumFonts (ignored), listFlags 0x%4.4x",
seq);
/* 419 client sends Seq 1, then 2 */ /* 2600 clients sends only Seq 3 */ /* listFlags SHOULD be set to 0x0003, which is the logical OR'd value of
FONTLIST_FIRST (0x0001) and FONTLIST_LAST (0x0002) */ if (seq == 2 || seq == 3) /* after second font message, we are up and */
{ /* running */
LOG_DEVEL(LOG_LEVEL_DEBUG, "Client sent FONTLIST_LAST, replying with server fontmap");
xrdp_rdp_send_fontmap(self);
/* This is also the end of an Deactivation-reactivation
* sequence [MS-RDPBCGR] 1.3.1.3 */
xrdp_rdp_suppress_output(self, 0, XSO_REASON_DEACTIVATE_REACTIVATE, 0, 0,
self->client_info.display_sizes.session_width,
self->client_info.display_sizes.session_height);
if (self->session->callback != 0)
{ /* call to xrdp_wm.c : callback */
self->session->callback(self->session->id, 0x555a, 0, 0, 0, 0);
}
} else
{
LOG_DEVEL(LOG_LEVEL_DEBUG, "Received [MS-RDPBCGR] TS_FONT_LIST_PDU " "without FONTLIST_LAST in the listFlags field. Ignoring message.");
}
/*****************************************************************************/ /* Process a [MS-RDPBCGR] TS_SUPPRESS_OUTPUT_PDU message */ staticint
xrdp_rdp_process_suppress(struct xrdp_rdp *self, struct stream *s)
{ int rv = 1; int allowDisplayUpdates; int left; int top; int right; int bottom;
/*****************************************************************************/ /* Process a [MS-RDPBCGR] TS_SHAREDATAHEADER message based on it's pduType2 */ int
xrdp_rdp_process_data(struct xrdp_rdp *self, struct stream *s)
{ int uncompressedLength; int pduType2; int compressedType; int compressedLength;
if (compressedType != 0)
{ /* don't support compression */ /* PACKET_COMPR_TYPE_8K = 0x00 */
LOG(LOG_LEVEL_ERROR, "Only RDP 4.0 bulk compression " "(PACKET_COMPR_TYPE_8K) is supported by XRDP"); return1;
} if (compressedLength > uncompressedLength)
{
LOG(LOG_LEVEL_ERROR, "The compressed length %d is larger than " "the uncompressed length %d, failing the processing of this " "PDU", compressedLength, uncompressedLength); return1;
}
switch (pduType2)
{ case RDP_DATA_PDU_POINTER: /* 27(0x1b) */
xrdp_rdp_process_data_pointer(self, s); break; case RDP_DATA_PDU_INPUT: /* 28(0x1c) */
xrdp_rdp_process_data_input(self, s); break; case RDP_DATA_PDU_CONTROL: /* 20(0x14) */
xrdp_rdp_process_data_control(self, s); break; case RDP_DATA_PDU_SYNCHRONISE: /* 31(0x1f) */
xrdp_rdp_process_data_sync(self); break; case PDUTYPE2_REFRESH_RECT:
xrdp_rdp_process_screen_update(self, s); break; case PDUTYPE2_SUPPRESS_OUTPUT: /* 35(0x23) */
xrdp_rdp_process_suppress(self, s); break; case PDUTYPE2_SHUTDOWN_REQUEST: /* 36(0x24) ?? disconnect query? */ /* when this message comes, send a 37 back so the client */ /* is sure the connection is alive and it can ask if user */ /* really wants to disconnect */
LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_SHUTDOWN_REQ_PDU");
xrdp_rdp_send_disconnect_query_response(self); /* send a 37 back */ break; case RDP_DATA_PDU_FONT2: /* 39(0x27) */
xrdp_rdp_process_data_font(self, s); break; case56: /* PDUTYPE2_FRAME_ACKNOWLEDGE 0x38 */
xrdp_rdp_process_frame_ack(self, s); break; default:
LOG(LOG_LEVEL_WARNING, "Received unknown [MS-RDPBCGR] TS_SHAREDATAHEADER pduType2 %d (ignoring)",
pduType2); break;
} return0;
} /*****************************************************************************/ int
xrdp_rdp_disconnect(struct xrdp_rdp *self)
{ return xrdp_sec_disconnect(self->sec_layer);
}
/*****************************************************************************/ int
xrdp_rdp_send_deactivate(struct xrdp_rdp *self)
{ // See [MS-RDPBCGR] 2.2.3.1.1 constchar source_descriptor[] = { '\0' }; struct stream *s;
/*****************************************************************************/ /** Send a [MS-RDPBCGR] TS_SAVE_SESSION_INFO_PDU_DATA message. * *@paramself *@paramdatathedatatosendtotheclientinthe *TS_SAVE_SESSION_INFO_PDU_DATAmessage.Thefirst4bytesofthedata *bufferMUSTbytheinfoTypevalueasspecifiedinMS-RDPBCGR2.2.10.1.1 *@paramdata_bytesthelengthofthedatabuffer *@returnserrorcode
*/ int
xrdp_rdp_send_session_info(struct xrdp_rdp *self, constchar *data, int data_bytes)
{ struct stream *s;
if (data == NULL)
{
LOG(LOG_LEVEL_ERROR, "data must not be null"); return1;
} if (data_bytes < 4)
{
LOG(LOG_LEVEL_ERROR, "data_bytes must greater than or equal to 4"); return1;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.