boolean rdp_recv_client_info(rdpRdp* rdp, STREAM* s) { uint16 length; uint16 channelId; uint16 securityFlags; if (!rdp_read_header(rdp, s, &length, &channelId)) return false; rdp_read_security_header(s, &securityFlags); if ((securityFlags & SEC_INFO_PKT) == 0) return false; if (rdp->settings->encryption) { if (securityFlags & SEC_REDIRECTION_PKT) { printf("Error: SEC_REDIRECTION_PKT unsupported\n"); return false; } if (securityFlags & SEC_ENCRYPT) { if (!rdp_decrypt(rdp, s, length - 4, securityFlags)) { printf("rdp_decrypt failed\n"); return false; } } } return rdp_read_info_packet(s, rdp->settings); }
BOOL rdp_client_connect_auto_detect(rdpRdp* rdp, wStream* s) { BYTE* mark; UINT16 length; UINT16 channelId; /* If the MCS message channel has been joined... */ if (rdp->mcs->messageChannelId != 0) { /* Process any MCS message channel PDUs. */ Stream_GetPointer(s, mark); if (rdp_read_header(rdp, s, &length, &channelId)) { if (channelId == rdp->mcs->messageChannelId) { UINT16 securityFlags; if (!rdp_read_security_header(s, &securityFlags)) return FALSE; if (rdp_recv_message_channel_pdu(rdp, s, securityFlags) == 0) return TRUE; } } Stream_SetPointer(s, mark); } return FALSE; }
int rdp_recv_message_channel_pdu(rdpRdp* rdp, wStream* s) { UINT16 securityFlags; if (!rdp_read_security_header(s, &securityFlags)) return -1; if (securityFlags & SEC_AUTODETECT_REQ) { /* Server Auto-Detect Request PDU */ return rdp_recv_autodetect_packet(rdp, s); } if (securityFlags & SEC_HEARTBEAT) { /* Heartbeat PDU */ return rdp_recv_heartbeat_packet(rdp, s); } if (securityFlags & SEC_TRANSPORT_REQ) { /* Initiate Multitransport Request PDU */ return rdp_recv_multitransport_packet(rdp, s); } return -1; }
BOOL rdp_recv_client_info(rdpRdp* rdp, wStream* s) { UINT16 length; UINT16 channelId; UINT16 securityFlags; if (!rdp_read_header(rdp, s, &length, &channelId)) return FALSE; if (!rdp_read_security_header(s, &securityFlags)) return FALSE; if ((securityFlags & SEC_INFO_PKT) == 0) return FALSE; if (rdp->settings->DisableEncryption) { if (securityFlags & SEC_REDIRECTION_PKT) { fprintf(stderr, "Error: SEC_REDIRECTION_PKT unsupported\n"); return FALSE; } if (securityFlags & SEC_ENCRYPT) { if (!rdp_decrypt(rdp, s, length - 4, securityFlags)) { fprintf(stderr, "rdp_decrypt failed\n"); return FALSE; } } } return rdp_read_info_packet(s, rdp->settings); }
static int peer_recv_tpkt_pdu(freerdp_peer* client, wStream* s) { rdpRdp* rdp; UINT16 length; UINT16 pduType; UINT16 pduLength; UINT16 pduSource; UINT16 channelId; UINT16 securityFlags; rdp = client->context->rdp; if (!rdp_read_header(rdp, s, &length, &channelId)) { fprintf(stderr, "Incorrect RDP header.\n"); return -1; } if (rdp->settings->DisableEncryption) { if (!rdp_read_security_header(s, &securityFlags)) return -1; if (securityFlags & SEC_ENCRYPT) { if (!rdp_decrypt(rdp, s, length - 4, securityFlags)) { fprintf(stderr, "rdp_decrypt failed\n"); return -1; } } } if (channelId != MCS_GLOBAL_CHANNEL_ID) { if(!freerdp_channel_peer_process(client, s, channelId)) return -1; } else { if (!rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource)) return -1; client->settings->PduSource = pduSource; switch (pduType) { case PDU_TYPE_DATA: if (!peer_recv_data_pdu(client, s)) return -1; break; default: fprintf(stderr, "Client sent pduType %d\n", pduType); return -1; } } return 0; }
boolean rdp_recv_client_info(rdpRdp* rdp, STREAM* s) { uint16 length; uint16 channelId; uint16 sec_flags; if (!rdp_read_header(rdp, s, &length, &channelId)) return False; rdp_read_security_header(s, &sec_flags); if ((sec_flags & SEC_INFO_PKT) == 0) return False; return rdp_read_info_packet(s, rdp->settings); }
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_server_establish_keys(rdpRdp* rdp, wStream* s) { BYTE client_random[64]; /* Should be only 32 after successful decryption, but on failure might take up to 64 bytes. */ BYTE crypt_client_random[256 + 8]; UINT32 rand_len, key_len; UINT16 channel_id, length, sec_flags; BYTE* mod; BYTE* priv_exp; if (!rdp->settings->DisableEncryption) { /* No RDP Security. */ return TRUE; } if (!rdp_read_header(rdp, s, &length, &channel_id)) { fprintf(stderr, "rdp_server_establish_keys: invalid RDP header\n"); return FALSE; } if (!rdp_read_security_header(s, &sec_flags)) return FALSE; if ((sec_flags & SEC_EXCHANGE_PKT) == 0) { fprintf(stderr, "rdp_server_establish_keys: missing SEC_EXCHANGE_PKT in security header\n"); return FALSE; } if (Stream_GetRemainingLength(s) < 4) return FALSE; Stream_Read_UINT32(s, rand_len); if (Stream_GetRemainingLength(s) < rand_len + 8) /* include 8 bytes of padding */ return FALSE; key_len = rdp->settings->RdpServerRsaKey->ModulusLength; if (rand_len != key_len + 8) { fprintf(stderr, "rdp_server_establish_keys: invalid encrypted client random length\n"); return FALSE; } ZeroMemory(crypt_client_random, sizeof(crypt_client_random)); Stream_Read(s, crypt_client_random, rand_len); /* 8 zero bytes of padding */ Stream_Seek(s, 8); mod = rdp->settings->RdpServerRsaKey->Modulus; priv_exp = rdp->settings->RdpServerRsaKey->PrivateExponent; crypto_rsa_private_decrypt(crypt_client_random, rand_len - 8, key_len, mod, priv_exp, client_random); /* now calculate encrypt / decrypt and update keys */ if (!security_establish_keys(client_random, rdp)) { return FALSE; } rdp->do_crypt = TRUE; if (rdp->settings->SaltedChecksum) rdp->do_secure_checksum = TRUE; if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS) { rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec); rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->fips_decrypt_key, fips_ivec); rdp->fips_hmac = crypto_hmac_new(); return TRUE; } rdp->rc4_decrypt_key = crypto_rc4_init(rdp->decrypt_key, rdp->rc4_key_len); rdp->rc4_encrypt_key = crypto_rc4_init(rdp->encrypt_key, rdp->rc4_key_len); return TRUE; }
boolean license_recv(rdpLicense* license, STREAM* s) { uint16 length; uint16 channelId; uint16 sec_flags; uint8 flags; uint8 bMsgType; uint16 wMsgSize; if (!rdp_read_header(license->rdp, s, &length, &channelId)) { printf("Incorrect RDP header.\n"); return false; } rdp_read_security_header(s, &sec_flags); if (!(sec_flags & SEC_LICENSE_PKT)) { stream_rewind(s, RDP_SECURITY_HEADER_LENGTH); if (rdp_recv_out_of_sequence_pdu(license->rdp, s) != true) { printf("Unexpected license packet.\n"); return false; } return true; } license_read_preamble(s, &bMsgType, &flags, &wMsgSize); /* preamble (4 bytes) */ DEBUG_LICENSE("Receiving %s Packet", LICENSE_MESSAGE_STRINGS[bMsgType & 0x1F]); switch (bMsgType) { case LICENSE_REQUEST: license_read_license_request_packet(license, s); license_send_new_license_request_packet(license); break; case PLATFORM_CHALLENGE: license_read_platform_challenge_packet(license, s); license_send_platform_challenge_response_packet(license); break; case NEW_LICENSE: license_read_new_license_packet(license, s); break; case UPGRADE_LICENSE: license_read_upgrade_license_packet(license, s); break; case ERROR_ALERT: license_read_error_alert_packet(license, s); break; default: printf("invalid bMsgType:%d\n", bMsgType); return false; } return true; }
static boolean rdp_server_establish_keys(rdpRdp* rdp, STREAM* s) { uint8 client_random[64]; /* Should be only 32 after successfull decryption, but on failure might take up to 64 bytes. */ uint8 crypt_client_random[256 + 8]; uint32 rand_len, key_len; uint16 channel_id, length, sec_flags; uint8* mod; uint8* priv_exp; if (rdp->settings->encryption == false) { /* No RDP Security. */ return true; } if (!rdp_read_header(rdp, s, &length, &channel_id)) { printf("rdp_server_establish_keys: invalid RDP header\n"); return false; } rdp_read_security_header(s, &sec_flags); if ((sec_flags & SEC_EXCHANGE_PKT) == 0) { printf("rdp_server_establish_keys: missing SEC_EXCHANGE_PKT in security header\n"); return false; } stream_read_uint32(s, rand_len); key_len = rdp->settings->server_key->modulus.length; if (rand_len != key_len + 8) { printf("rdp_server_establish_keys: invalid encrypted client random length\n"); return false; } memset(crypt_client_random, 0, sizeof(crypt_client_random)); stream_read(s, crypt_client_random, rand_len); /* 8 zero bytes of padding */ stream_seek(s, 8); mod = rdp->settings->server_key->modulus.data; priv_exp = rdp->settings->server_key->private_exponent.data; crypto_rsa_private_decrypt(crypt_client_random, rand_len - 8, key_len, mod, priv_exp, client_random); /* now calculate encrypt / decrypt and update keys */ if (!security_establish_keys(client_random, rdp)) { return false; } rdp->do_crypt = true; if (rdp->settings->salted_checksum) rdp->do_secure_checksum = true; if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS) { uint8 fips_ivec[8] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF }; rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec); rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->fips_decrypt_key, fips_ivec); rdp->fips_hmac = crypto_hmac_new(); return true; } rdp->rc4_decrypt_key = crypto_rc4_init(rdp->decrypt_key, rdp->rc4_key_len); rdp->rc4_encrypt_key = crypto_rc4_init(rdp->encrypt_key, rdp->rc4_key_len); return true; }
BOOL rdp_server_establish_keys(rdpRdp* rdp, wStream* s) { BYTE* client_random = NULL; BYTE* crypt_client_random = NULL; UINT32 rand_len, key_len; UINT16 channel_id, length, sec_flags; BYTE* mod; BYTE* priv_exp; BOOL ret = FALSE; if (!rdp->settings->DisableEncryption) { /* No RDP Security. */ return TRUE; } if (!rdp_read_header(rdp, s, &length, &channel_id)) { WLog_ERR(TAG, "invalid RDP header"); return FALSE; } if (!rdp_read_security_header(s, &sec_flags)) { WLog_ERR(TAG, "invalid security header"); return FALSE; } if ((sec_flags & SEC_EXCHANGE_PKT) == 0) { WLog_ERR(TAG, "missing SEC_EXCHANGE_PKT in security header"); return FALSE; } rdp->do_crypt_license = (sec_flags & SEC_LICENSE_ENCRYPT_SC) != 0 ? TRUE : FALSE; if (Stream_GetRemainingLength(s) < 4) return FALSE; Stream_Read_UINT32(s, rand_len); /* rand_len already includes 8 bytes of padding */ if (Stream_GetRemainingLength(s) < rand_len) return FALSE; key_len = rdp->settings->RdpServerRsaKey->ModulusLength; client_random = malloc(key_len); if (!client_random) return FALSE; if (rand_len != key_len + 8) { WLog_ERR(TAG, "invalid encrypted client random length"); goto end2; } crypt_client_random = calloc(1, rand_len); if (!crypt_client_random) goto end2; Stream_Read(s, crypt_client_random, rand_len); mod = rdp->settings->RdpServerRsaKey->Modulus; priv_exp = rdp->settings->RdpServerRsaKey->PrivateExponent; crypto_rsa_private_decrypt(crypt_client_random, rand_len - 8, key_len, mod, priv_exp, client_random); /* now calculate encrypt / decrypt and update keys */ if (!security_establish_keys(client_random, rdp)) { goto end; } rdp->do_crypt = TRUE; if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS) { rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec); if (!rdp->fips_encrypt) { WLog_ERR(TAG, "unable to allocate des3 encrypt key"); goto end; } rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->fips_decrypt_key, fips_ivec); if (!rdp->fips_decrypt) { WLog_ERR(TAG, "unable to allocate des3 decrypt key"); goto end; } rdp->fips_hmac = crypto_hmac_new(); if (!rdp->fips_hmac) { WLog_ERR(TAG, "unable to allocate fips hmac"); goto end; } ret = TRUE; goto end; } rdp->rc4_decrypt_key = crypto_rc4_init(rdp->decrypt_key, rdp->rc4_key_len); if (!rdp->rc4_decrypt_key) { WLog_ERR(TAG, "unable to allocate rc4 decrypt key"); goto end; } rdp->rc4_encrypt_key = crypto_rc4_init(rdp->encrypt_key, rdp->rc4_key_len); if (!rdp->rc4_encrypt_key) { WLog_ERR(TAG, "unable to allocate rc4 encrypt key"); goto end; } ret = TRUE; end: if (crypt_client_random) free(crypt_client_random); end2: if (client_random) free(client_random); return ret; }
int license_recv(rdpLicense* license, wStream* s) { BYTE flags; BYTE bMsgType; UINT16 wMsgSize; UINT16 length; UINT16 channelId; UINT16 securityFlags; if (!rdp_read_header(license->rdp, s, &length, &channelId)) { WLog_ERR(TAG, "Incorrect RDP header."); return -1; } if (!rdp_read_security_header(s, &securityFlags)) return -1; if (securityFlags & SEC_ENCRYPT) { if (!rdp_decrypt(license->rdp, s, length - 4, securityFlags)) { WLog_ERR(TAG, "rdp_decrypt failed"); return -1; } } if (!(securityFlags & SEC_LICENSE_PKT)) { int status; if (!(securityFlags & SEC_ENCRYPT)) Stream_Rewind(s, RDP_SECURITY_HEADER_LENGTH); status = rdp_recv_out_of_sequence_pdu(license->rdp, s); if (status < 0) { WLog_ERR(TAG, "unexpected license packet."); return status; } return 0; } if (!license_read_preamble(s, &bMsgType, &flags, &wMsgSize)) /* preamble (4 bytes) */ return -1; DEBUG_LICENSE("Receiving %s Packet", LICENSE_MESSAGE_STRINGS[bMsgType & 0x1F]); switch (bMsgType) { case LICENSE_REQUEST: if (!license_read_license_request_packet(license, s)) return -1; if (!license_send_new_license_request_packet(license)) return -1; break; case PLATFORM_CHALLENGE: if (!license_read_platform_challenge_packet(license, s)) return -1; if (!license_send_platform_challenge_response_packet(license)) return -1; break; case NEW_LICENSE: license_read_new_license_packet(license, s); break; case UPGRADE_LICENSE: license_read_upgrade_license_packet(license, s); break; case ERROR_ALERT: if (!license_read_error_alert_packet(license, s)) return -1; break; default: WLog_ERR(TAG, "invalid bMsgType:%d", bMsgType); return FALSE; } return 0; }
static int rdp_recv_tpkt_pdu(rdpRdp* rdp, STREAM* s) { UINT16 length; UINT16 pduType; UINT16 pduLength; UINT16 pduSource; UINT16 channelId; UINT16 securityFlags; BYTE* nextp; if (!rdp_read_header(rdp, s, &length, &channelId)) { printf("Incorrect RDP header.\n"); return -1; } if (rdp->settings->DisableEncryption) { if (!rdp_read_security_header(s, &securityFlags)) return -1; if (securityFlags & (SEC_ENCRYPT | SEC_REDIRECTION_PKT)) { if (!rdp_decrypt(rdp, s, length - 4, securityFlags)) { printf("rdp_decrypt failed\n"); return -1; } } if (securityFlags & SEC_REDIRECTION_PKT) { /* * [MS-RDPBCGR] 2.2.13.2.1 * - no share control header, nor the 2 byte pad */ s->p -= 2; rdp_recv_enhanced_security_redirection_packet(rdp, s); return -1; } } if (channelId != MCS_GLOBAL_CHANNEL_ID) { if (!freerdp_channel_process(rdp->instance, s, channelId)) return -1; } else { while (stream_get_left(s) > 3) { stream_get_mark(s, nextp); if (!rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource)) return -1; nextp += pduLength; rdp->settings->PduSource = pduSource; switch (pduType) { case PDU_TYPE_DATA: if (rdp_recv_data_pdu(rdp, s) < 0) { printf("rdp_recv_data_pdu failed\n"); return -1; } break; case PDU_TYPE_DEACTIVATE_ALL: if (!rdp_recv_deactivate_all(rdp, s)) return -1; break; case PDU_TYPE_SERVER_REDIRECTION: if (!rdp_recv_enhanced_security_redirection_packet(rdp, s)) return -1; break; default: printf("incorrect PDU type: 0x%04X\n", pduType); break; } stream_set_mark(s, nextp); } } return 0; }
static tbool rdp_recv_tpkt_pdu(rdpRdp* rdp, STREAM* s) { uint16 length; uint16 pduType; uint16 pduLength; uint16 pduSource; uint16 channelId; uint16 securityFlags; uint8* nextp; LLOGLN(10, ("rdp_recv_tpkt_pdu:")); if (!rdp_read_header(rdp, s, &length, &channelId)) { LLOGLN(0, ("Incorrect RDP header.")); return false; } LLOGLN(10, ("rdp_recv_tpkt_pdu: length %d", length)); if (rdp->disconnect) { LLOGLN(0, ("rdp_recv_tpkt_pdu: disconnect")); return false; } if (rdp->settings->encryption) { rdp_read_security_header(s, &securityFlags); LLOGLN(10, ("rdp_recv_tpkt_pdu: securityFlags 0x%8.8x", securityFlags)); if (securityFlags & (SEC_ENCRYPT | SEC_REDIRECTION_PKT)) { if (!rdp_decrypt(rdp, s, length - 4, securityFlags)) { LLOGLN(0, ("rdp_decrypt failed")); return false; } } if (securityFlags & SEC_REDIRECTION_PKT) { LLOGLN(0, ("rdp_recv_tpkt_pdu: got SEC_REDIRECTION_PKT securityFlags 0x%8.8x", securityFlags)); /* * [MS-RDPBCGR] 2.2.13.2.1 * - no share control header, nor the 2 byte pad */ s->p -= 2; rdp_recv_enhanced_security_redirection_packet(rdp, s); return true; } } if (channelId != MCS_GLOBAL_CHANNEL_ID) { freerdp_channel_process(rdp->instance, s, channelId); } else { while (stream_get_left(s) > 3) { stream_get_mark(s, nextp); rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource); nextp += pduLength; rdp->settings->pdu_source = pduSource; switch (pduType) { case PDU_TYPE_DATA: if (!rdp_recv_data_pdu(rdp, s)) { LLOGLN(0, ("rdp_recv_data_pdu failed")); return false; } break; case PDU_TYPE_DEACTIVATE_ALL: if (!rdp_recv_deactivate_all(rdp, s)) return false; break; case PDU_TYPE_SERVER_REDIRECTION: rdp_recv_enhanced_security_redirection_packet(rdp, s); break; default: LLOGLN(0, ("incorrect PDU type: 0x%04X", pduType)); break; } stream_set_mark(s, nextp); } } return true; }
static boolean rdp_recv_tpkt_pdu(rdpRdp* rdp, STREAM* s) { uint16 length; uint16 pduType; uint16 pduLength; uint16 pduSource; uint16 channelId; uint16 securityFlags; if (!rdp_read_header(rdp, s, &length, &channelId)) { printf("Incorrect RDP header.\n"); return false; } if (rdp->settings->encryption) { rdp_read_security_header(s, &securityFlags); if (securityFlags & (SEC_ENCRYPT|SEC_REDIRECTION_PKT)) { if (!rdp_decrypt(rdp, s, length - 4, securityFlags)) { printf("rdp_decrypt failed\n"); return false; } } if (securityFlags & SEC_REDIRECTION_PKT) { /* * [MS-RDPBCGR] 2.2.13.2.1 * - no share control header, nor the 2 byte pad */ s->p -= 2; rdp_recv_enhanced_security_redirection_packet(rdp, s); return true; } } if (channelId != MCS_GLOBAL_CHANNEL_ID) { freerdp_channel_process(rdp->instance, s, channelId); } else { rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource); rdp->settings->pdu_source = pduSource; switch (pduType) { case PDU_TYPE_DATA: rdp_recv_data_pdu(rdp, s); break; case PDU_TYPE_DEACTIVATE_ALL: if (!rdp_recv_deactivate_all(rdp, s)) return false; break; case PDU_TYPE_SERVER_REDIRECTION: rdp_recv_enhanced_security_redirection_packet(rdp, s); break; default: printf("incorrect PDU type: 0x%04X\n", pduType); break; } } return true; }
static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s) { UINT16 length; UINT16 pduType; UINT16 pduLength; UINT16 pduSource; UINT16 channelId = 0; UINT16 securityFlags; int nextPosition; if (!rdp_read_header(rdp, s, &length, &channelId)) { DEBUG_WARN( "Incorrect RDP header.\n"); return -1; } if (rdp->settings->DisableEncryption) { if (!rdp_read_security_header(s, &securityFlags)) return -1; if (securityFlags & (SEC_ENCRYPT | SEC_REDIRECTION_PKT)) { if (!rdp_decrypt(rdp, s, length - 4, securityFlags)) { DEBUG_WARN( "rdp_decrypt failed\n"); return -1; } } if (securityFlags & SEC_REDIRECTION_PKT) { /* * [MS-RDPBCGR] 2.2.13.2.1 * - no share control header, nor the 2 byte pad */ Stream_Rewind(s, 2); return rdp_recv_enhanced_security_redirection_packet(rdp, s); } } if (channelId == MCS_GLOBAL_CHANNEL_ID) { while (Stream_GetRemainingLength(s) > 3) { nextPosition = Stream_GetPosition(s); if (!rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource)) return -1; nextPosition += pduLength; rdp->settings->PduSource = pduSource; switch (pduType) { case PDU_TYPE_DATA: if (rdp_recv_data_pdu(rdp, s) < 0) { DEBUG_WARN( "rdp_recv_data_pdu failed\n"); return -1; } break; case PDU_TYPE_DEACTIVATE_ALL: if (!rdp_recv_deactivate_all(rdp, s)) return -1; break; case PDU_TYPE_SERVER_REDIRECTION: return rdp_recv_enhanced_security_redirection_packet(rdp, s); break; default: DEBUG_WARN( "incorrect PDU type: 0x%04X\n", pduType); break; } Stream_SetPosition(s, nextPosition); } } else if (rdp->mcs->messageChannelId && channelId == rdp->mcs->messageChannelId) { return rdp_recv_message_channel_pdu(rdp, s); } else { if (!freerdp_channel_process(rdp->instance, s, channelId)) return -1; } return 0; }
static int peer_recv_tpkt_pdu(freerdp_peer* client, wStream* s) { rdpRdp* rdp; UINT16 length; UINT16 pduType; UINT16 pduLength; UINT16 pduSource; UINT16 channelId; UINT16 securityFlags = 0; rdp = client->context->rdp; if (!rdp_read_header(rdp, s, &length, &channelId)) { WLog_ERR(TAG, "Incorrect RDP header."); return -1; } if (freerdp_shall_disconnect(rdp->instance)) return 0; if (rdp->settings->UseRdpSecurityLayer) { if (!rdp_read_security_header(s, &securityFlags)) return -1; if (securityFlags & SEC_ENCRYPT) { if (!rdp_decrypt(rdp, s, length - 4, securityFlags)) { WLog_ERR(TAG, "rdp_decrypt failed"); return -1; } } } if (channelId == MCS_GLOBAL_CHANNEL_ID) { if (!rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource)) return -1; client->settings->PduSource = pduSource; switch (pduType) { case PDU_TYPE_DATA: if (!peer_recv_data_pdu(client, s)) return -1; break; case PDU_TYPE_CONFIRM_ACTIVE: if (!rdp_server_accept_confirm_active(rdp, s)) return -1; break; case PDU_TYPE_FLOW_RESPONSE: case PDU_TYPE_FLOW_STOP: case PDU_TYPE_FLOW_TEST: break; default: WLog_ERR(TAG, "Client sent pduType %"PRIu16"", pduType); return -1; } } else if (rdp->mcs->messageChannelId && channelId == rdp->mcs->messageChannelId) { if (!rdp->settings->UseRdpSecurityLayer) if (!rdp_read_security_header(s, &securityFlags)) return -1; return rdp_recv_message_channel_pdu(rdp, s, securityFlags); } else { if (!freerdp_channel_peer_process(client, s, channelId)) return -1; } return 0; }
BOOL rdp_server_establish_keys(rdpRdp* rdp, wStream* s) { BYTE* client_random = NULL; BYTE* crypt_client_random = NULL; UINT32 rand_len, key_len; UINT16 channel_id, length, sec_flags; BYTE* mod; BYTE* priv_exp; BOOL ret = FALSE; if (!rdp->settings->UseRdpSecurityLayer) { /* No RDP Security. */ return TRUE; } if (!rdp_read_header(rdp, s, &length, &channel_id)) { WLog_ERR(TAG, "invalid RDP header"); return FALSE; } if (!rdp_read_security_header(s, &sec_flags, NULL)) { WLog_ERR(TAG, "invalid security header"); return FALSE; } if ((sec_flags & SEC_EXCHANGE_PKT) == 0) { WLog_ERR(TAG, "missing SEC_EXCHANGE_PKT in security header"); return FALSE; } rdp->do_crypt_license = (sec_flags & SEC_LICENSE_ENCRYPT_SC) != 0 ? TRUE : FALSE; if (Stream_GetRemainingLength(s) < 4) return FALSE; Stream_Read_UINT32(s, rand_len); /* rand_len already includes 8 bytes of padding */ if (Stream_GetRemainingLength(s) < rand_len) return FALSE; key_len = rdp->settings->RdpServerRsaKey->ModulusLength; client_random = malloc(key_len); if (!client_random) return FALSE; if (rand_len != key_len + 8) { WLog_ERR(TAG, "invalid encrypted client random length"); free(client_random); goto end; } crypt_client_random = calloc(1, rand_len); if (!crypt_client_random) { free(client_random); goto end; } Stream_Read(s, crypt_client_random, rand_len); mod = rdp->settings->RdpServerRsaKey->Modulus; priv_exp = rdp->settings->RdpServerRsaKey->PrivateExponent; if (crypto_rsa_private_decrypt(crypt_client_random, rand_len - 8, key_len, mod, priv_exp, client_random) <= 0) { free(client_random); goto end; } rdp->settings->ClientRandom = client_random; rdp->settings->ClientRandomLength = 32; /* now calculate encrypt / decrypt and update keys */ if (!security_establish_keys(client_random, rdp)) goto end; rdp->do_crypt = TRUE; if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS) { rdp->fips_encrypt = winpr_Cipher_New(WINPR_CIPHER_DES_EDE3_CBC, WINPR_ENCRYPT, rdp->fips_encrypt_key, fips_ivec); if (!rdp->fips_encrypt) { WLog_ERR(TAG, "unable to allocate des3 encrypt key"); goto end; } rdp->fips_decrypt = winpr_Cipher_New(WINPR_CIPHER_DES_EDE3_CBC, WINPR_DECRYPT, rdp->fips_decrypt_key, fips_ivec); if (!rdp->fips_decrypt) { WLog_ERR(TAG, "unable to allocate des3 decrypt key"); goto end; } ret = TRUE; goto end; } rdp->rc4_decrypt_key = winpr_RC4_New(rdp->decrypt_key, rdp->rc4_key_len); rdp->rc4_encrypt_key = winpr_RC4_New(rdp->encrypt_key, rdp->rc4_key_len); if (!rdp->rc4_decrypt_key || !rdp->rc4_encrypt_key) goto end; ret = TRUE; end: free(crypt_client_random); if (!ret) { winpr_Cipher_Free(rdp->fips_encrypt); winpr_Cipher_Free(rdp->fips_decrypt); winpr_RC4_Free(rdp->rc4_encrypt_key); winpr_RC4_Free(rdp->rc4_decrypt_key); rdp->fips_encrypt = NULL; rdp->fips_decrypt = NULL; rdp->rc4_encrypt_key = NULL; rdp->rc4_decrypt_key = NULL; } return ret; }