boolean rdp_read_header(rdpRdp* rdp, STREAM* s, uint16* length, uint16* channel_id) { uint16 initiator; enum DomainMCSPDU MCSPDU; MCSPDU = (rdp->settings->server_mode) ? DomainMCSPDU_SendDataRequest : DomainMCSPDU_SendDataIndication; mcs_read_domain_mcspdu_header(s, &MCSPDU, length); if (*length - 8 > stream_get_left(s)) return false; if (MCSPDU == DomainMCSPDU_DisconnectProviderUltimatum) { uint8 reason; (void) per_read_enumerated(s, &reason, 0); rdp->disconnect = true; return true; } per_read_integer16(s, &initiator, MCS_BASE_CHANNEL_ID); /* initiator (UserId) */ per_read_integer16(s, channel_id, 0); /* channelId */ stream_seek(s, 1); /* dataPriority + Segmentation (0x70) */ per_read_length(s, length); /* userData (OCTET_STRING) */ if (*length > stream_get_left(s)) return false; return true; }
tbool rdp_read_header(rdpRdp* rdp, STREAM* s, uint16* length, uint16* channel_id) { uint8 reason; uint16 initiator; enum DomainMCSPDU MCSPDU; MCSPDU = (rdp->settings->server_mode) ? DomainMCSPDU_SendDataRequest : DomainMCSPDU_SendDataIndication; if (!mcs_read_domain_mcspdu_header(s, &MCSPDU, length)) { LLOGLN(0, ("rdp_read_header: mcs_read_domain_mcspdu_header failed")); return false; } if (*length - 8 > stream_get_left(s)) { LLOGLN(0, ("rdp_read_header: parse error")); return false; } if (MCSPDU == DomainMCSPDU_DisconnectProviderUltimatum) { if (!per_read_enumerated(s, &reason, 0)) { LLOGLN(0, ("rdp_read_header: per_read_enumerated failed")); return false; } rdp->disconnect = true; *channel_id = MCS_GLOBAL_CHANNEL_ID; return true; } if (stream_get_left(s) < 5) { LLOGLN(0, ("rdp_read_header: parse error")); return false; } per_read_integer16(s, &initiator, MCS_BASE_CHANNEL_ID); /* initiator (UserId) */ per_read_integer16(s, channel_id, 0); /* channelId */ stream_seek(s, 1); /* dataPriority + Segmentation (0x70) */ if (!per_read_length(s, length)) /* userData (OCTET_STRING) */ { LLOGLN(0, ("rdp_read_header: per_read_length failed")); return false; } if (*length > stream_get_left(s)) { return false; LLOGLN(0, ("rdp_read_header: parse error")); } return true; }
boolean rdp_read_header(rdpRdp* rdp, STREAM* s, uint16* length, uint16* channel_id) { uint16 initiator; enum DomainMCSPDU MCSPDU; MCSPDU = (rdp->settings->server_mode) ? DomainMCSPDU_SendDataRequest : DomainMCSPDU_SendDataIndication; mcs_read_domain_mcspdu_header(s, &MCSPDU, length); per_read_integer16(s, &initiator, MCS_BASE_CHANNEL_ID); /* initiator (UserId) */ per_read_integer16(s, channel_id, 0); /* channelId */ stream_seek(s, 1); /* dataPriority + Segmentation (0x70) */ per_read_length(s, length); /* userData (OCTET_STRING) */ if (*length > stream_get_left(s)) return False; return True; }
BOOL rdp_read_header(rdpRdp* rdp, wStream* s, UINT16* length, UINT16* channel_id) { UINT16 initiator; enum DomainMCSPDU MCSPDU; MCSPDU = (rdp->settings->ServerMode) ? DomainMCSPDU_SendDataRequest : DomainMCSPDU_SendDataIndication; if (!mcs_read_domain_mcspdu_header(s, &MCSPDU, length)) { if (MCSPDU != DomainMCSPDU_DisconnectProviderUltimatum) return FALSE; } if (*length - 8 > Stream_GetRemainingLength(s)) return FALSE; if (MCSPDU == DomainMCSPDU_DisconnectProviderUltimatum) { BYTE reason; (void) per_read_enumerated(s, &reason, 0); DEBUG_RDP("DisconnectProviderUltimatum from server, reason code 0x%02x\n", reason); rdp->disconnect = TRUE; return TRUE; } if (Stream_GetRemainingLength(s) < 5) return FALSE; per_read_integer16(s, &initiator, MCS_BASE_CHANNEL_ID); /* initiator (UserId) */ per_read_integer16(s, channel_id, 0); /* channelId */ Stream_Seek(s, 1); /* dataPriority + Segmentation (0x70) */ if (!per_read_length(s, length)) /* userData (OCTET_STRING) */ return FALSE; if (*length > Stream_GetRemainingLength(s)) return FALSE; return TRUE; }
void rdp_recv(rdpRdp* rdp) { STREAM* s; int length; uint16 pduType; uint16 pduLength; uint16 initiator; uint16 channelId; uint16 sec_flags; enum DomainMCSPDU MCSPDU; s = transport_recv_stream_init(rdp->transport, 4096); transport_read(rdp->transport, s); MCSPDU = DomainMCSPDU_SendDataIndication; mcs_read_domain_mcspdu_header(s, &MCSPDU, &length); per_read_integer16(s, &initiator, MCS_BASE_CHANNEL_ID); /* initiator (UserId) */ per_read_integer16(s, &channelId, 0); /* channelId */ stream_seek(s, 1); /* dataPriority + Segmentation (0x70) */ per_read_length(s, &pduLength); /* userData (OCTET_STRING) */ if (rdp->connected != True) { rdp_read_security_header(s, &sec_flags); if (sec_flags & SEC_PKT_MASK) { switch (sec_flags & SEC_PKT_MASK) { case SEC_LICENSE_PKT: license_recv(rdp->license, s); break; case SEC_REDIRECTION_PKT: rdp_read_redirection_packet(rdp, s); break; default: printf("incorrect security flags: 0x%04X\n", sec_flags); break; } } } else { rdp_read_share_control_header(s, &pduLength, &pduType, &rdp->settings->pdu_source); switch (pduType) { case PDU_TYPE_DATA: rdp_read_data_pdu(rdp, s); break; case PDU_TYPE_DEMAND_ACTIVE: rdp_recv_demand_active(rdp, s, rdp->settings); break; case PDU_TYPE_DEACTIVATE_ALL: rdp_read_deactivate_all(s, rdp->settings); break; case PDU_TYPE_SERVER_REDIRECTION: rdp_read_enhanced_security_redirection_packet(rdp, s); break; default: printf("incorrect PDU type: 0x%04X\n", pduType); break; } } }
BOOL rdp_read_header(rdpRdp* rdp, wStream* s, UINT16* length, UINT16* channelId) { BYTE byte; UINT16 initiator; enum DomainMCSPDU MCSPDU; MCSPDU = (rdp->settings->ServerMode) ? DomainMCSPDU_SendDataRequest : DomainMCSPDU_SendDataIndication; if (!mcs_read_domain_mcspdu_header(s, &MCSPDU, length)) { if (MCSPDU != DomainMCSPDU_DisconnectProviderUltimatum) return FALSE; } if ((size_t) (*length - 8) > Stream_GetRemainingLength(s)) return FALSE; if (MCSPDU == DomainMCSPDU_DisconnectProviderUltimatum) { int reason = 0; TerminateEventArgs e; rdpContext* context; if (!mcs_recv_disconnect_provider_ultimatum(rdp->mcs, s, &reason)) return FALSE; if (rdp->instance == NULL) { rdp->disconnect = TRUE; return FALSE; } context = rdp->instance->context; if (rdp->errorInfo == ERRINFO_SUCCESS) { /** * Some servers like Windows Server 2008 R2 do not send the error info pdu * when the user logs off like they should. Map DisconnectProviderUltimatum * to a ERRINFO_LOGOFF_BY_USER when the errinfo code is ERRINFO_SUCCESS. */ if (reason == MCS_Reason_provider_initiated) rdp_set_error_info(rdp, ERRINFO_RPC_INITIATED_DISCONNECT); else if (reason == MCS_Reason_user_requested) rdp_set_error_info(rdp, ERRINFO_LOGOFF_BY_USER); else rdp_set_error_info(rdp, ERRINFO_RPC_INITIATED_DISCONNECT); } DEBUG_WARN( "DisconnectProviderUltimatum: reason: %d\n", reason); rdp->disconnect = TRUE; EventArgsInit(&e, "freerdp"); e.code = 0; PubSub_OnTerminate(context->pubSub, context, &e); return TRUE; } if (Stream_GetRemainingLength(s) < 5) return FALSE; per_read_integer16(s, &initiator, MCS_BASE_CHANNEL_ID); /* initiator (UserId) */ per_read_integer16(s, channelId, 0); /* channelId */ Stream_Read_UINT8(s, byte); /* dataPriority + Segmentation (0x70) */ if (!per_read_length(s, length)) /* userData (OCTET_STRING) */ return FALSE; if (*length > Stream_GetRemainingLength(s)) return FALSE; return TRUE; }