BOOL gcc_read_conference_create_response(wStream* s, rdpMcs* mcs) { UINT16 length; UINT32 tag; UINT16 nodeID; BYTE result; BYTE choice; BYTE number; /* ConnectData */ if (!per_read_choice(s, &choice) || !per_read_object_identifier(s, t124_02_98_oid)) return FALSE; /* ConnectData::connectPDU (OCTET_STRING) */ if (!per_read_length(s, &length)) return FALSE; /* ConnectGCCPDU */ if (!per_read_choice(s, &choice)) return FALSE; /* ConferenceCreateResponse::nodeID (UserID) */ if (!per_read_integer16(s, &nodeID, 1001)) return FALSE; /* ConferenceCreateResponse::tag (INTEGER) */ if (!per_read_integer(s, &tag)) return FALSE; /* ConferenceCreateResponse::result (ENUMERATED) */ if (!per_read_enumerated(s, &result, MCS_Result_enum_length)) return FALSE; /* number of UserData sets */ if (!per_read_number_of_sets(s, &number)) return FALSE; /* UserData::value present + select h221NonStandard (1) */ if (!per_read_choice(s, &choice)) return FALSE; /* h221NonStandard */ if (!per_read_octet_string(s, h221_sc_key, 4, 4)) /* h221NonStandard, server-to-client H.221 key, "McDn" */ return FALSE; /* userData (OCTET_STRING) */ if (!per_read_length(s, &length)) return FALSE; if (!gcc_read_server_data_blocks(s, mcs, length)) { WLog_ERR(TAG, "gcc_read_conference_create_response: gcc_read_server_data_blocks failed"); return FALSE; } return TRUE; }
boolean gcc_read_conference_create_request(STREAM* s, rdpSettings* settings) { uint16 length; uint8 choice; uint8 number; uint8 selection; /* ConnectData */ if (!per_read_choice(s, &choice)) return false; if (!per_read_object_identifier(s, t124_02_98_oid)) return false; /* ConnectData::connectPDU (OCTET_STRING) */ if (!per_read_length(s, &length)) return false; /* ConnectGCCPDU */ if (!per_read_choice(s, &choice)) return false; if (!per_read_selection(s, &selection)) return false; /* ConferenceCreateRequest::conferenceName */ if (!per_read_numeric_string(s, 1)) /* ConferenceName::numeric */ return false; if (!per_read_padding(s, 1)) /* padding */ return false; /* UserData (SET OF SEQUENCE) */ if (!per_read_number_of_sets(s, &number) || number != 1) /* one set of UserData */ return false; if (!per_read_choice(s, &choice) || choice != 0xC0) /* UserData::value present + select h221NonStandard (1) */ return false; /* h221NonStandard */ if (!per_read_octet_string(s, h221_cs_key, 4, 4)) /* h221NonStandard, client-to-server H.221 key, "Duca" */ return false; /* userData::value (OCTET_STRING) */ if (!per_read_length(s, &length)) return false; if (stream_get_left(s) < length) return false; if (!gcc_read_client_data_blocks(s, settings, length)) return false; return true; }
BOOL gcc_read_conference_create_request(wStream* s, rdpMcs* mcs) { UINT16 length; BYTE choice; BYTE number; BYTE selection; /* ConnectData */ if (!per_read_choice(s, &choice)) return FALSE; if (!per_read_object_identifier(s, t124_02_98_oid)) return FALSE; /* ConnectData::connectPDU (OCTET_STRING) */ if (!per_read_length(s, &length)) return FALSE; /* ConnectGCCPDU */ if (!per_read_choice(s, &choice)) return FALSE; if (!per_read_selection(s, &selection)) return FALSE; /* ConferenceCreateRequest::conferenceName */ if (!per_read_numeric_string(s, 1)) /* ConferenceName::numeric */ return FALSE; if (!per_read_padding(s, 1)) /* padding */ return FALSE; /* UserData (SET OF SEQUENCE) */ if (!per_read_number_of_sets(s, &number) || number != 1) /* one set of UserData */ return FALSE; if (!per_read_choice(s, &choice) || choice != 0xC0) /* UserData::value present + select h221NonStandard (1) */ return FALSE; /* h221NonStandard */ if (!per_read_octet_string(s, h221_cs_key, 4, 4)) /* h221NonStandard, client-to-server H.221 key, "Duca" */ return FALSE; /* userData::value (OCTET_STRING) */ if (!per_read_length(s, &length)) return FALSE; if (Stream_GetRemainingLength(s) < length) return FALSE; if (!gcc_read_client_data_blocks(s, mcs, length)) return FALSE; return TRUE; }
boolean gcc_read_conference_create_response(STREAM* s, rdpSettings* settings) { uint16 length; uint32 tag; uint16 nodeID; uint8 result; uint8 choice; uint8 number; /* ConnectData */ per_read_choice(s, &choice); per_read_object_identifier(s, t124_02_98_oid); /* ConnectData::connectPDU (OCTET_STRING) */ per_read_length(s, &length); /* ConnectGCCPDU */ per_read_choice(s, &choice); /* ConferenceCreateResponse::nodeID (UserID) */ per_read_integer16(s, &nodeID, 1001); /* ConferenceCreateResponse::tag (INTEGER) */ per_read_integer(s, &tag); /* ConferenceCreateResponse::result (ENUMERATED) */ per_read_enumerated(s, &result, MCS_Result_enum_length); /* number of UserData sets */ per_read_number_of_sets(s, &number); /* UserData::value present + select h221NonStandard (1) */ per_read_choice(s, &choice); /* h221NonStandard */ if (!per_read_octet_string(s, h221_sc_key, 4, 4)) /* h221NonStandard, server-to-client H.221 key, "McDn" */ return false; /* userData (OCTET_STRING) */ per_read_length(s, &length); if (!gcc_read_server_data_blocks(s, settings, length)) { printf("gcc_read_conference_create_response: gcc_read_server_data_blocks failed\n"); return false; } 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); 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; }