void gcc_write_server_core_data(STREAM* s, rdpSettings *settings) { gcc_write_user_data_header(s, SC_CORE, 12); stream_write_uint32(s, settings->rdp_version == 4 ? RDP_VERSION_4 : RDP_VERSION_5_PLUS); stream_write_uint32(s, settings->requested_protocols); /* clientRequestedProtocols */ }
void gcc_write_client_monitor_data(STREAM* s, rdpSettings *settings) { int i; uint16 length; uint32 left, top, right, bottom, flags; if (settings->num_monitors > 1) { length = (20 * settings->num_monitors) + 12; gcc_write_user_data_header(s, CS_MONITOR, length); stream_write_uint32(s, 0); /* flags */ stream_write_uint32(s, settings->num_monitors); /* monitorCount */ for (i = 0; i < settings->num_monitors; i++) { left = settings->monitors[i].x; top = settings->monitors[i].y; right = settings->monitors[i].x + settings->monitors[i].width - 1; bottom = settings->monitors[i].y + settings->monitors[i].height - 1; flags = settings->monitors[i].is_primary ? MONITOR_PRIMARY : 0; stream_write_uint32(s, left); /* left */ stream_write_uint32(s, top); /* top */ stream_write_uint32(s, right); /* right */ stream_write_uint32(s, bottom); /* bottom */ stream_write_uint32(s, flags); /* flags */ } } }
void gcc_write_server_core_data(wStream* s, rdpSettings* settings) { gcc_write_user_data_header(s, SC_CORE, 12); Stream_Write_UINT32(s, settings->RdpVersion == 4 ? RDP_VERSION_4 : RDP_VERSION_5_PLUS); Stream_Write_UINT32(s, settings->RequestedProtocols); /* clientRequestedProtocols */ }
void gcc_write_client_monitor_data(wStream* s, rdpMcs* mcs) { int i; UINT16 length; UINT32 left, top, right, bottom, flags; rdpSettings* settings = mcs->settings; if (settings->MonitorCount > 1) { length = (20 * settings->MonitorCount) + 12; gcc_write_user_data_header(s, CS_MONITOR, length); Stream_Write_UINT32(s, 0); /* flags */ Stream_Write_UINT32(s, settings->MonitorCount); /* monitorCount */ for (i = 0; i < settings->MonitorCount; i++) { left = settings->MonitorDefArray[i].x; top = settings->MonitorDefArray[i].y; right = settings->MonitorDefArray[i].x + settings->MonitorDefArray[i].width - 1; bottom = settings->MonitorDefArray[i].y + settings->MonitorDefArray[i].height - 1; flags = settings->MonitorDefArray[i].is_primary ? MONITOR_PRIMARY : 0; Stream_Write_UINT32(s, left); /* left */ Stream_Write_UINT32(s, top); /* top */ Stream_Write_UINT32(s, right); /* right */ Stream_Write_UINT32(s, bottom); /* bottom */ Stream_Write_UINT32(s, flags); /* flags */ } } }
void gcc_write_server_multitransport_channel_data(wStream* s, rdpMcs* mcs) { UINT32 flags = 0; gcc_write_user_data_header(s, SC_MULTITRANSPORT, 8); Stream_Write_UINT32(s, flags); /* flags (4 bytes) */ }
void gcc_write_server_message_channel_data(wStream* s, rdpMcs* mcs) { UINT16 mcsChannelId = 0; gcc_write_user_data_header(s, SC_MCS_MSGCHANNEL, 6); Stream_Write_UINT16(s, mcsChannelId); /* mcsChannelId (2 bytes) */ }
void gcc_write_server_core_data(wStream* s, rdpMcs* mcs) { rdpSettings* settings = mcs->settings; gcc_write_user_data_header(s, SC_CORE, 16); Stream_Write_UINT32(s, settings->RdpVersion == 4 ? RDP_VERSION_4 : RDP_VERSION_5_PLUS); Stream_Write_UINT32(s, settings->RequestedProtocols); /* clientRequestedProtocols */ Stream_Write_UINT32(s, settings->EarlyCapabilityFlags); /* earlyCapabilityFlags */ }
void gcc_write_client_multitransport_channel_data(wStream* s, rdpMcs* mcs) { rdpSettings* settings = mcs->settings; if (settings->MultitransportFlags != 0) { gcc_write_user_data_header(s, CS_MULTITRANSPORT, 8); Stream_Write_UINT32(s, settings->MultitransportFlags); /* flags */ } }
void gcc_write_server_security_data(STREAM* s, rdpSettings *settings) { gcc_write_user_data_header(s, SC_SECURITY, 12); stream_write_uint32(s, ENCRYPTION_METHOD_NONE); /* encryptionMethod */ stream_write_uint32(s, ENCRYPTION_LEVEL_NONE); /* encryptionLevel */ #if 0 stream_write_uint32(s, 0); /* serverRandomLen */ stream_write_uint32(s, 0); /* serverCertLen */ #endif }
void gcc_write_client_message_channel_data(wStream* s, rdpMcs* mcs) { rdpSettings* settings = mcs->settings; if (settings->NetworkAutoDetect || settings->SupportHeartbeatPdu || settings->SupportMultitransport) { gcc_write_user_data_header(s, CS_MCS_MSGCHANNEL, 8); Stream_Write_UINT32(s, 0); /* flags */ } }
void gcc_write_client_cluster_data(wStream* s, rdpSettings* settings) { UINT32 flags; gcc_write_user_data_header(s, CS_CLUSTER, 12); flags = REDIRECTION_SUPPORTED | (REDIRECTION_VERSION4 << 2); if (settings->ConsoleSession || settings->RedirectedSessionId) flags |= REDIRECTED_SESSIONID_FIELD_VALID; Stream_Write_UINT32(s, flags); /* flags */ Stream_Write_UINT32(s, settings->RedirectedSessionId); /* redirectedSessionID */ }
void gcc_write_client_cluster_data(STREAM* s, rdpSettings *settings) { uint32 flags; gcc_write_user_data_header(s, CS_CLUSTER, 12); flags = REDIRECTION_SUPPORTED | (REDIRECTION_VERSION4 << 2); if (settings->console_session || settings->redirected_session_id) flags |= REDIRECTED_SESSIONID_FIELD_VALID; stream_write_uint32(s, flags); /* flags */ stream_write_uint32(s, settings->redirected_session_id); /* redirectedSessionID */ }
void gcc_write_client_security_data(STREAM* s, rdpSettings *settings) { gcc_write_user_data_header(s, CS_SECURITY, 12); if (settings->encryption > 0) { stream_write_uint32(s, settings->encryption_methods); /* encryptionMethods */ stream_write_uint32(s, 0); /* extEncryptionMethods */ } else { /* French locale, disable encryption */ stream_write_uint32(s, 0); /* encryptionMethods */ stream_write_uint32(s, settings->encryption_methods); /* extEncryptionMethods */ } }
void gcc_write_client_security_data(wStream* s, rdpSettings* settings) { gcc_write_user_data_header(s, CS_SECURITY, 12); if (settings->DisableEncryption) { Stream_Write_UINT32(s, settings->EncryptionMethods); /* encryptionMethods */ Stream_Write_UINT32(s, 0); /* extEncryptionMethods */ } else { /* French locale, disable encryption */ Stream_Write_UINT32(s, 0); /* encryptionMethods */ Stream_Write_UINT32(s, settings->EncryptionMethods); /* extEncryptionMethods */ } }
void gcc_write_server_network_data(wStream* s, rdpSettings* settings) { int i; gcc_write_user_data_header(s, SC_NET, 8 + settings->ChannelCount * 2 + (settings->ChannelCount % 2 == 1 ? 2 : 0)); Stream_Write_UINT16(s, MCS_GLOBAL_CHANNEL_ID); /* MCSChannelId */ Stream_Write_UINT16(s, settings->ChannelCount); /* channelCount */ for (i = 0; i < settings->ChannelCount; i++) { Stream_Write_UINT16(s, settings->ChannelDefArray[i].ChannelId); } if (settings->ChannelCount % 2 == 1) Stream_Write_UINT16(s, 0); }
void gcc_write_server_network_data(STREAM* s, rdpSettings *settings) { int i; gcc_write_user_data_header(s, SC_NET, 8 + settings->num_channels * 2 + (settings->num_channels % 2 == 1 ? 2 : 0)); stream_write_uint16(s, MCS_GLOBAL_CHANNEL_ID); /* MCSChannelId */ stream_write_uint16(s, settings->num_channels); /* channelCount */ for (i = 0; i < settings->num_channels; i++) { stream_write_uint16(s, settings->channels[i].channel_id); } if (settings->num_channels % 2 == 1) stream_write_uint16(s, 0); }
void gcc_write_server_core_data(wStream* s, rdpMcs* mcs) { UINT32 version; UINT32 earlyCapabilityFlags = 0; rdpSettings* settings = mcs->settings; gcc_write_user_data_header(s, SC_CORE, 16); version = settings->RdpVersion == 4 ? RDP_VERSION_4 : RDP_VERSION_5_PLUS; if (settings->SupportDynamicTimeZone) earlyCapabilityFlags |= RNS_UD_SC_DYNAMIC_DST_SUPPORTED; Stream_Write_UINT32(s, version); /* version (4 bytes) */ Stream_Write_UINT32(s, settings->RequestedProtocols); /* clientRequestedProtocols (4 bytes) */ Stream_Write_UINT32(s, earlyCapabilityFlags); /* earlyCapabilityFlags (4 bytes) */ }
void gcc_write_server_network_data(wStream* s, rdpMcs* mcs) { UINT32 i; gcc_write_user_data_header(s, SC_NET, 8 + mcs->channelCount * 2 + (mcs->channelCount % 2 == 1 ? 2 : 0)); Stream_Write_UINT16(s, MCS_GLOBAL_CHANNEL_ID); /* MCSChannelId */ Stream_Write_UINT16(s, mcs->channelCount); /* channelCount */ for (i = 0; i < mcs->channelCount; i++) { Stream_Write_UINT16(s, mcs->channels[i].ChannelId); } if (mcs->channelCount % 2 == 1) Stream_Write_UINT16(s, 0); }
void gcc_write_client_network_data(wStream* s, rdpSettings* settings) { int i; UINT16 length; if (settings->ChannelCount > 0) { length = settings->ChannelCount * 12 + 8; gcc_write_user_data_header(s, CS_NET, length); Stream_Write_UINT32(s, settings->ChannelCount); /* channelCount */ /* channelDefArray */ for (i = 0; i < settings->ChannelCount; i++) { /* CHANNEL_DEF */ Stream_Write(s, settings->ChannelDefArray[i].Name, 8); /* name (8 bytes) */ Stream_Write_UINT32(s, settings->ChannelDefArray[i].options); /* options (4 bytes) */ } } }
void gcc_write_client_network_data(STREAM* s, rdpSettings *settings) { int i; uint16 length; if (settings->num_channels > 0) { length = settings->num_channels * 12 + 8; gcc_write_user_data_header(s, CS_NET, length); stream_write_uint32(s, settings->num_channels); /* channelCount */ /* channelDefArray */ for (i = 0; i < settings->num_channels; i++) { /* CHANNEL_DEF */ stream_write(s, settings->channels[i].name, 8); /* name (8 bytes) */ stream_write_uint32(s, settings->channels[i].options); /* options (4 bytes) */ } } }
void gcc_write_client_network_data(wStream* s, rdpMcs* mcs) { UINT32 i; UINT16 length; if (mcs->channelCount > 0) { length = mcs->channelCount * 12 + 8; gcc_write_user_data_header(s, CS_NET, length); Stream_Write_UINT32(s, mcs->channelCount); /* channelCount */ /* channelDefArray */ for (i = 0; i < mcs->channelCount; i++) { /* CHANNEL_DEF */ Stream_Write(s, mcs->channels[i].Name, 8); /* name (8 bytes) */ Stream_Write_UINT32(s, mcs->channels[i].options); /* options (4 bytes) */ } } }
void gcc_write_server_security_data(STREAM* s, rdpSettings* settings) { CryptoMd5 md5; uint8* sigData; int expLen, keyLen, sigDataLen; uint8 encryptedSignature[TSSK_KEY_LENGTH]; uint8 signature[sizeof(initial_signature)]; uint32 headerLen, serverRandomLen, serverCertLen, wPublicKeyBlobLen; if (!settings->encryption) { settings->encryption_method = ENCRYPTION_METHOD_NONE; settings->encryption_level = ENCRYPTION_LEVEL_NONE; } else if ((settings->encryption_method & ENCRYPTION_METHOD_FIPS) != 0) { settings->encryption_method = ENCRYPTION_METHOD_FIPS; } else if ((settings->encryption_method & ENCRYPTION_METHOD_128BIT) != 0) { settings->encryption_method = ENCRYPTION_METHOD_128BIT; } else if ((settings->encryption_method & ENCRYPTION_METHOD_40BIT) != 0) { settings->encryption_method = ENCRYPTION_METHOD_40BIT; } if (settings->encryption_method != ENCRYPTION_METHOD_NONE) settings->encryption_level = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE; headerLen = 12; keyLen = 0; wPublicKeyBlobLen = 0; serverRandomLen = 0; serverCertLen = 0; if (settings->encryption_method != ENCRYPTION_METHOD_NONE || settings->encryption_level != ENCRYPTION_LEVEL_NONE) { serverRandomLen = 32; keyLen = settings->server_key->modulus.length; expLen = sizeof(settings->server_key->exponent); wPublicKeyBlobLen = 4; /* magic (RSA1) */ wPublicKeyBlobLen += 4; /* keylen */ wPublicKeyBlobLen += 4; /* bitlen */ wPublicKeyBlobLen += 4; /* datalen */ wPublicKeyBlobLen += expLen; wPublicKeyBlobLen += keyLen; wPublicKeyBlobLen += 8; /* 8 bytes of zero padding */ serverCertLen = 4; /* dwVersion */ serverCertLen += 4; /* dwSigAlgId */ serverCertLen += 4; /* dwKeyAlgId */ serverCertLen += 2; /* wPublicKeyBlobType */ serverCertLen += 2; /* wPublicKeyBlobLen */ serverCertLen += wPublicKeyBlobLen; serverCertLen += 2; /* wSignatureBlobType */ serverCertLen += 2; /* wSignatureBlobLen */ serverCertLen += sizeof(encryptedSignature); /* SignatureBlob */ serverCertLen += 8; /* 8 bytes of zero padding */ headerLen += sizeof(serverRandomLen); headerLen += sizeof(serverCertLen); headerLen += serverRandomLen; headerLen += serverCertLen; } gcc_write_user_data_header(s, SC_SECURITY, headerLen); stream_write_uint32(s, settings->encryption_method); /* encryptionMethod */ stream_write_uint32(s, settings->encryption_level); /* encryptionLevel */ if (settings->encryption_method == ENCRYPTION_METHOD_NONE && settings->encryption_level == ENCRYPTION_LEVEL_NONE) { return; } stream_write_uint32(s, serverRandomLen); /* serverRandomLen */ stream_write_uint32(s, serverCertLen); /* serverCertLen */ freerdp_blob_alloc(settings->server_random, serverRandomLen); crypto_nonce(settings->server_random->data, serverRandomLen); stream_write(s, settings->server_random->data, serverRandomLen); sigData = stream_get_tail(s); stream_write_uint32(s, CERT_CHAIN_VERSION_1); /* dwVersion (4 bytes) */ stream_write_uint32(s, SIGNATURE_ALG_RSA); /* dwSigAlgId */ stream_write_uint32(s, KEY_EXCHANGE_ALG_RSA); /* dwKeyAlgId */ stream_write_uint16(s, BB_RSA_KEY_BLOB); /* wPublicKeyBlobType */ stream_write_uint16(s, wPublicKeyBlobLen); /* wPublicKeyBlobLen */ stream_write(s, "RSA1", 4); /* magic */ stream_write_uint32(s, keyLen + 8); /* keylen */ stream_write_uint32(s, keyLen * 8); /* bitlen */ stream_write_uint32(s, keyLen - 1); /* datalen */ stream_write(s, settings->server_key->exponent, expLen); stream_write(s, settings->server_key->modulus.data, keyLen); stream_write_zero(s, 8); sigDataLen = stream_get_tail(s) - sigData; stream_write_uint16(s, BB_RSA_SIGNATURE_BLOB); /* wSignatureBlobType */ stream_write_uint16(s, keyLen + 8); /* wSignatureBlobLen */ memcpy(signature, initial_signature, sizeof(initial_signature)); md5 = crypto_md5_init(); crypto_md5_update(md5, sigData, sigDataLen); crypto_md5_final(md5, signature); crypto_rsa_private_encrypt(signature, sizeof(signature), TSSK_KEY_LENGTH, tssk_modulus, tssk_privateExponent, encryptedSignature); stream_write(s, encryptedSignature, sizeof(encryptedSignature)); stream_write_zero(s, 8); }
void gcc_write_client_core_data(wStream* s, rdpMcs* mcs) { UINT32 version; WCHAR* clientName = NULL; int clientNameLength; BYTE connectionType; UINT16 highColorDepth; UINT16 supportedColorDepths; UINT16 earlyCapabilityFlags; WCHAR* clientDigProductId = NULL; int clientDigProductIdLength; rdpSettings* settings = mcs->settings; gcc_write_user_data_header(s, CS_CORE, 216); version = settings->RdpVersion >= 5 ? RDP_VERSION_5_PLUS : RDP_VERSION_4; clientNameLength = ConvertToUnicode(CP_UTF8, 0, settings->ClientHostname, -1, &clientName, 0); clientDigProductIdLength = ConvertToUnicode(CP_UTF8, 0, settings->ClientProductId, -1, &clientDigProductId, 0); Stream_Write_UINT32(s, version); /* Version */ Stream_Write_UINT16(s, settings->DesktopWidth); /* DesktopWidth */ Stream_Write_UINT16(s, settings->DesktopHeight); /* DesktopHeight */ Stream_Write_UINT16(s, RNS_UD_COLOR_8BPP); /* ColorDepth, ignored because of postBeta2ColorDepth */ Stream_Write_UINT16(s, RNS_UD_SAS_DEL); /* SASSequence (Secure Access Sequence) */ Stream_Write_UINT32(s, settings->KeyboardLayout); /* KeyboardLayout */ Stream_Write_UINT32(s, settings->ClientBuild); /* ClientBuild */ /* clientName (32 bytes, null-terminated unicode, truncated to 15 characters) */ if (clientNameLength >= 16) { clientNameLength = 16; clientName[clientNameLength - 1] = 0; } Stream_Write(s, clientName, (clientNameLength * 2)); Stream_Zero(s, 32 - (clientNameLength * 2)); free(clientName); Stream_Write_UINT32(s, settings->KeyboardType); /* KeyboardType */ Stream_Write_UINT32(s, settings->KeyboardSubType); /* KeyboardSubType */ Stream_Write_UINT32(s, settings->KeyboardFunctionKey); /* KeyboardFunctionKey */ Stream_Zero(s, 64); /* imeFileName */ Stream_Write_UINT16(s, RNS_UD_COLOR_8BPP); /* postBeta2ColorDepth */ Stream_Write_UINT16(s, 1); /* clientProductID */ Stream_Write_UINT32(s, 0); /* serialNumber (should be initialized to 0) */ highColorDepth = MIN(settings->ColorDepth, 24); supportedColorDepths = RNS_UD_24BPP_SUPPORT | RNS_UD_16BPP_SUPPORT | RNS_UD_15BPP_SUPPORT; earlyCapabilityFlags = RNS_UD_CS_SUPPORT_ERRINFO_PDU; if (settings->NetworkAutoDetect) settings->ConnectionType = CONNECTION_TYPE_AUTODETECT; if (settings->RemoteFxCodec && !settings->NetworkAutoDetect) settings->ConnectionType = CONNECTION_TYPE_LAN; connectionType = settings->ConnectionType; if (connectionType) earlyCapabilityFlags |= RNS_UD_CS_VALID_CONNECTION_TYPE; if (settings->ColorDepth == 32) { supportedColorDepths |= RNS_UD_32BPP_SUPPORT; earlyCapabilityFlags |= RNS_UD_CS_WANT_32BPP_SESSION; } if (settings->NetworkAutoDetect) earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_NETWORK_AUTODETECT; if (settings->SupportHeartbeatPdu) earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_HEARTBEAT_PDU; if (settings->SupportGraphicsPipeline) earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL; if (settings->SupportDynamicTimeZone) earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE; Stream_Write_UINT16(s, highColorDepth); /* highColorDepth */ Stream_Write_UINT16(s, supportedColorDepths); /* supportedColorDepths */ Stream_Write_UINT16(s, earlyCapabilityFlags); /* earlyCapabilityFlags */ /* clientDigProductId (64 bytes, null-terminated unicode, truncated to 31 characters) */ if (clientDigProductIdLength >= 32) { clientDigProductIdLength = 32; clientDigProductId[clientDigProductIdLength - 1] = 0; } Stream_Write(s, clientDigProductId, (clientDigProductIdLength * 2) ); Stream_Zero(s, 64 - (clientDigProductIdLength * 2) ); free(clientDigProductId); Stream_Write_UINT8(s, connectionType); /* connectionType */ Stream_Write_UINT8(s, 0); /* pad1octet */ Stream_Write_UINT32(s, settings->SelectedProtocol); /* serverSelectedProtocol */ }
void gcc_write_client_core_data(STREAM* s, rdpSettings* settings) { UINT32 version; WCHAR* clientName; int clientNameLength; BYTE connectionType; UINT16 highColorDepth; UINT16 supportedColorDepths; UINT16 earlyCapabilityFlags; WCHAR* clientDigProductId; int clientDigProductIdLength; gcc_write_user_data_header(s, CS_CORE, 216); version = settings->RdpVersion >= 5 ? RDP_VERSION_5_PLUS : RDP_VERSION_4; clientNameLength = ConvertToUnicode(CP_UTF8, 0, settings->ClientHostname, -1, &clientName, 0); clientDigProductIdLength = ConvertToUnicode(CP_UTF8, 0, settings->ClientProductId, -1, &clientDigProductId, 0); stream_write_UINT32(s, version); /* Version */ stream_write_UINT16(s, settings->DesktopWidth); /* DesktopWidth */ stream_write_UINT16(s, settings->DesktopHeight); /* DesktopHeight */ stream_write_UINT16(s, RNS_UD_COLOR_8BPP); /* ColorDepth, ignored because of postBeta2ColorDepth */ stream_write_UINT16(s, RNS_UD_SAS_DEL); /* SASSequence (Secure Access Sequence) */ stream_write_UINT32(s, settings->KeyboardLayout); /* KeyboardLayout */ stream_write_UINT32(s, settings->ClientBuild); /* ClientBuild */ /* clientName (32 bytes, null-terminated unicode, truncated to 15 characters) */ if (clientNameLength >= 16) { clientNameLength = 16; clientName[clientNameLength-1] = 0; } stream_write(s, clientName, (clientNameLength * 2)); stream_write_zero(s, 32 - (clientNameLength * 2)); free(clientName); stream_write_UINT32(s, settings->KeyboardType); /* KeyboardType */ stream_write_UINT32(s, settings->KeyboardSubType); /* KeyboardSubType */ stream_write_UINT32(s, settings->KeyboardFunctionKey); /* KeyboardFunctionKey */ stream_write_zero(s, 64); /* imeFileName */ stream_write_UINT16(s, RNS_UD_COLOR_8BPP); /* postBeta2ColorDepth */ stream_write_UINT16(s, 1); /* clientProductID */ stream_write_UINT32(s, 0); /* serialNumber (should be initialized to 0) */ highColorDepth = MIN(settings->ColorDepth, 24); supportedColorDepths = RNS_UD_24BPP_SUPPORT | RNS_UD_16BPP_SUPPORT | RNS_UD_15BPP_SUPPORT; connectionType = settings->ConnectionType; earlyCapabilityFlags = RNS_UD_CS_SUPPORT_ERRINFO_PDU; if (settings->RemoteFxCodec) connectionType = CONNECTION_TYPE_LAN; if (connectionType != 0) earlyCapabilityFlags |= RNS_UD_CS_VALID_CONNECTION_TYPE; if (settings->ColorDepth == 32) { supportedColorDepths |= RNS_UD_32BPP_SUPPORT; earlyCapabilityFlags |= RNS_UD_CS_WANT_32BPP_SESSION; } stream_write_UINT16(s, highColorDepth); /* highColorDepth */ stream_write_UINT16(s, supportedColorDepths); /* supportedColorDepths */ stream_write_UINT16(s, earlyCapabilityFlags); /* earlyCapabilityFlags */ /* clientDigProductId (64 bytes, null-terminated unicode, truncated to 31 characters) */ if (clientDigProductIdLength >= 32) { clientDigProductIdLength = 32; clientDigProductId[clientDigProductIdLength-1] = 0; } stream_write(s, clientDigProductId, (clientDigProductIdLength * 2) ); stream_write_zero(s, 64 - (clientDigProductIdLength * 2) ); free(clientDigProductId); stream_write_BYTE(s, connectionType); /* connectionType */ stream_write_BYTE(s, 0); /* pad1octet */ stream_write_UINT32(s, settings->SelectedProtocol); /* serverSelectedProtocol */ }
void gcc_write_client_core_data(STREAM* s, rdpSettings *settings) { uint32 version; uint8* clientName; size_t clientNameLength; uint8 connectionType; uint16 highColorDepth; uint16 supportedColorDepths; uint16 earlyCapabilityFlags; uint8* clientDigProductId; size_t clientDigProductIdLength; gcc_write_user_data_header(s, CS_CORE, 216); version = settings->rdp_version >= 5 ? RDP_VERSION_5_PLUS : RDP_VERSION_4; clientName = freerdp_uniconv_out(settings->uniconv, settings->client_hostname, &clientNameLength); clientDigProductId = freerdp_uniconv_out(settings->uniconv, settings->client_product_id, &clientDigProductIdLength); stream_write_uint32(s, version); /* version */ stream_write_uint16(s, settings->width); /* desktopWidth */ stream_write_uint16(s, settings->height); /* desktopHeight */ stream_write_uint16(s, RNS_UD_COLOR_8BPP); /* colorDepth, ignored because of postBeta2ColorDepth */ stream_write_uint16(s, RNS_UD_SAS_DEL); /* SASSequence (Secure Access Sequence) */ stream_write_uint32(s, settings->kbd_layout); /* keyboardLayout */ stream_write_uint32(s, settings->client_build); /* clientBuild */ /* clientName (32 bytes, null-terminated unicode, truncated to 15 characters) */ if (clientNameLength > 30) { clientNameLength = 30; clientName[clientNameLength] = 0; clientName[clientNameLength + 1] = 0; } stream_write(s, clientName, clientNameLength + 2); stream_write_zero(s, 32 - clientNameLength - 2); xfree(clientName); stream_write_uint32(s, settings->kbd_type); /* keyboardType */ stream_write_uint32(s, settings->kbd_subtype); /* keyboardSubType */ stream_write_uint32(s, settings->kbd_fn_keys); /* keyboardFunctionKey */ stream_write_zero(s, 64); /* imeFileName */ stream_write_uint16(s, RNS_UD_COLOR_8BPP); /* postBeta2ColorDepth */ stream_write_uint16(s, 1); /* clientProductID */ stream_write_uint32(s, 0); /* serialNumber (should be initialized to 0) */ highColorDepth = MIN(settings->color_depth, 24); supportedColorDepths = RNS_UD_32BPP_SUPPORT | RNS_UD_24BPP_SUPPORT | RNS_UD_16BPP_SUPPORT | RNS_UD_15BPP_SUPPORT; connectionType = 0; earlyCapabilityFlags = RNS_UD_CS_SUPPORT_ERRINFO_PDU; if (settings->performance_flags == PERF_FLAG_NONE) { earlyCapabilityFlags |= RNS_UD_CS_VALID_CONNECTION_TYPE; connectionType = CONNECTION_TYPE_LAN; } if (settings->color_depth == 32) { supportedColorDepths |= RNS_UD_32BPP_SUPPORT; earlyCapabilityFlags |= RNS_UD_CS_WANT_32BPP_SESSION; } stream_write_uint16(s, highColorDepth); /* highColorDepth */ stream_write_uint16(s, supportedColorDepths); /* supportedColorDepths */ stream_write_uint16(s, earlyCapabilityFlags); /* earlyCapabilityFlags */ /* clientDigProductId (64 bytes, null-terminated unicode, truncated to 30 characters) */ if (clientDigProductIdLength > 62) { clientDigProductIdLength = 62; clientDigProductId[clientDigProductIdLength] = 0; clientDigProductId[clientDigProductIdLength + 1] = 0; } stream_write(s, clientDigProductId, clientDigProductIdLength + 2); stream_write_zero(s, 64 - clientDigProductIdLength - 2); xfree(clientDigProductId); stream_write_uint8(s, connectionType); /* connectionType */ stream_write_uint8(s, 0); /* pad1octet */ stream_write_uint32(s, settings->selected_protocol); /* serverSelectedProtocol */ }
void gcc_write_server_security_data(wStream* s, rdpMcs* mcs) { CryptoMd5 md5; BYTE* sigData; int expLen, keyLen, sigDataLen; BYTE encryptedSignature[TSSK_KEY_LENGTH]; BYTE signature[sizeof(initial_signature)]; UINT32 headerLen, serverRandomLen, serverCertLen, wPublicKeyBlobLen; rdpSettings* settings = mcs->settings; /** * Re: settings->EncryptionLevel: * This is configured/set by the server implementation and serves the same * purpose as the "Encryption Level" setting in the RDP-Tcp configuration * dialog of Microsoft's Remote Desktop Session Host Configuration. * Re: settings->EncryptionMethods: * at this point this setting contains the client's supported encryption * methods we've received in gcc_read_client_security_data() */ if (!settings->UseRdpSecurityLayer) { /* TLS/NLA is used: disable rdp style encryption */ settings->EncryptionLevel = ENCRYPTION_LEVEL_NONE; } /* verify server encryption level value */ switch (settings->EncryptionLevel) { case ENCRYPTION_LEVEL_NONE: WLog_INFO(TAG, "Active rdp encryption level: NONE"); break; case ENCRYPTION_LEVEL_FIPS: WLog_INFO(TAG, "Active rdp encryption level: FIPS Compliant"); break; case ENCRYPTION_LEVEL_HIGH: WLog_INFO(TAG, "Active rdp encryption level: HIGH"); break; case ENCRYPTION_LEVEL_LOW: WLog_INFO(TAG, "Active rdp encryption level: LOW"); break; case ENCRYPTION_LEVEL_CLIENT_COMPATIBLE: WLog_INFO(TAG, "Active rdp encryption level: CLIENT-COMPATIBLE"); break; default: WLog_ERR(TAG, "Invalid server encryption level 0x%08X", settings->EncryptionLevel); WLog_ERR(TAG, "Switching to encryption level CLIENT-COMPATIBLE"); settings->EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE; } /* choose rdp encryption method based on server level and client methods */ switch (settings->EncryptionLevel) { case ENCRYPTION_LEVEL_NONE: /* The only valid method is NONE in this case */ settings->EncryptionMethods = ENCRYPTION_METHOD_NONE; break; case ENCRYPTION_LEVEL_FIPS: /* The only valid method is FIPS in this case */ if (!(settings->EncryptionMethods & ENCRYPTION_METHOD_FIPS)) { WLog_WARN(TAG, "client does not support FIPS as required by server configuration"); } settings->EncryptionMethods = ENCRYPTION_METHOD_FIPS; break; case ENCRYPTION_LEVEL_HIGH: /* Maximum key strength supported by the server must be used (128 bit)*/ if (!(settings->EncryptionMethods & ENCRYPTION_METHOD_128BIT)) { WLog_WARN(TAG, "client does not support 128 bit encryption method as required by server configuration"); } settings->EncryptionMethods = ENCRYPTION_METHOD_128BIT; break; case ENCRYPTION_LEVEL_LOW: case ENCRYPTION_LEVEL_CLIENT_COMPATIBLE: /* Maximum key strength supported by the client must be used */ if (settings->EncryptionMethods & ENCRYPTION_METHOD_128BIT) settings->EncryptionMethods = ENCRYPTION_METHOD_128BIT; else if (settings->EncryptionMethods & ENCRYPTION_METHOD_56BIT) settings->EncryptionMethods = ENCRYPTION_METHOD_56BIT; else if (settings->EncryptionMethods & ENCRYPTION_METHOD_40BIT) settings->EncryptionMethods = ENCRYPTION_METHOD_40BIT; else if (settings->EncryptionMethods & ENCRYPTION_METHOD_FIPS) settings->EncryptionMethods = ENCRYPTION_METHOD_FIPS; else { WLog_WARN(TAG, "client has not announced any supported encryption methods"); settings->EncryptionMethods = ENCRYPTION_METHOD_128BIT; } break; default: WLog_ERR(TAG, "internal error: unknown encryption level"); } /* log selected encryption method */ switch (settings->EncryptionMethods) { case ENCRYPTION_METHOD_NONE: WLog_INFO(TAG, "Selected rdp encryption method: NONE"); break; case ENCRYPTION_METHOD_40BIT: WLog_INFO(TAG, "Selected rdp encryption method: 40BIT"); break; case ENCRYPTION_METHOD_56BIT: WLog_INFO(TAG, "Selected rdp encryption method: 56BIT"); break; case ENCRYPTION_METHOD_128BIT: WLog_INFO(TAG, "Selected rdp encryption method: 128BIT"); break; case ENCRYPTION_METHOD_FIPS: WLog_INFO(TAG, "Selected rdp encryption method: FIPS"); break; default: WLog_ERR(TAG, "internal error: unknown encryption method"); } headerLen = 12; keyLen = 0; wPublicKeyBlobLen = 0; serverRandomLen = 0; serverCertLen = 0; if (settings->EncryptionMethods != ENCRYPTION_METHOD_NONE) { serverRandomLen = 32; keyLen = settings->RdpServerRsaKey->ModulusLength; expLen = sizeof(settings->RdpServerRsaKey->exponent); wPublicKeyBlobLen = 4; /* magic (RSA1) */ wPublicKeyBlobLen += 4; /* keylen */ wPublicKeyBlobLen += 4; /* bitlen */ wPublicKeyBlobLen += 4; /* datalen */ wPublicKeyBlobLen += expLen; wPublicKeyBlobLen += keyLen; wPublicKeyBlobLen += 8; /* 8 bytes of zero padding */ serverCertLen = 4; /* dwVersion */ serverCertLen += 4; /* dwSigAlgId */ serverCertLen += 4; /* dwKeyAlgId */ serverCertLen += 2; /* wPublicKeyBlobType */ serverCertLen += 2; /* wPublicKeyBlobLen */ serverCertLen += wPublicKeyBlobLen; serverCertLen += 2; /* wSignatureBlobType */ serverCertLen += 2; /* wSignatureBlobLen */ serverCertLen += sizeof(encryptedSignature); /* SignatureBlob */ serverCertLen += 8; /* 8 bytes of zero padding */ headerLen += sizeof(serverRandomLen); headerLen += sizeof(serverCertLen); headerLen += serverRandomLen; headerLen += serverCertLen; } gcc_write_user_data_header(s, SC_SECURITY, headerLen); Stream_Write_UINT32(s, settings->EncryptionMethods); /* encryptionMethod */ Stream_Write_UINT32(s, settings->EncryptionLevel); /* encryptionLevel */ if (settings->EncryptionMethods == ENCRYPTION_METHOD_NONE) { return; } Stream_Write_UINT32(s, serverRandomLen); /* serverRandomLen */ Stream_Write_UINT32(s, serverCertLen); /* serverCertLen */ settings->ServerRandomLength = serverRandomLen; settings->ServerRandom = (BYTE*) malloc(serverRandomLen); crypto_nonce(settings->ServerRandom, serverRandomLen); Stream_Write(s, settings->ServerRandom, serverRandomLen); sigData = Stream_Pointer(s); Stream_Write_UINT32(s, CERT_CHAIN_VERSION_1); /* dwVersion (4 bytes) */ Stream_Write_UINT32(s, SIGNATURE_ALG_RSA); /* dwSigAlgId */ Stream_Write_UINT32(s, KEY_EXCHANGE_ALG_RSA); /* dwKeyAlgId */ Stream_Write_UINT16(s, BB_RSA_KEY_BLOB); /* wPublicKeyBlobType */ Stream_Write_UINT16(s, wPublicKeyBlobLen); /* wPublicKeyBlobLen */ Stream_Write(s, "RSA1", 4); /* magic */ Stream_Write_UINT32(s, keyLen + 8); /* keylen */ Stream_Write_UINT32(s, keyLen * 8); /* bitlen */ Stream_Write_UINT32(s, keyLen - 1); /* datalen */ Stream_Write(s, settings->RdpServerRsaKey->exponent, expLen); Stream_Write(s, settings->RdpServerRsaKey->Modulus, keyLen); Stream_Zero(s, 8); sigDataLen = Stream_Pointer(s) - sigData; Stream_Write_UINT16(s, BB_RSA_SIGNATURE_BLOB); /* wSignatureBlobType */ Stream_Write_UINT16(s, sizeof(encryptedSignature) + 8); /* wSignatureBlobLen */ memcpy(signature, initial_signature, sizeof(initial_signature)); md5 = crypto_md5_init(); if (!md5) { WLog_ERR(TAG, "unable to allocate a md5"); return; } crypto_md5_update(md5, sigData, sigDataLen); crypto_md5_final(md5, signature); crypto_rsa_private_encrypt(signature, sizeof(signature), TSSK_KEY_LENGTH, tssk_modulus, tssk_privateExponent, encryptedSignature); Stream_Write(s, encryptedSignature, sizeof(encryptedSignature)); Stream_Zero(s, 8); }
void gcc_write_server_security_data(wStream* s, rdpMcs* mcs) { CryptoMd5 md5; BYTE* sigData; int expLen, keyLen, sigDataLen; BYTE encryptedSignature[TSSK_KEY_LENGTH]; BYTE signature[sizeof(initial_signature)]; UINT32 headerLen, serverRandomLen, serverCertLen, wPublicKeyBlobLen; rdpSettings* settings = mcs->settings; if (!settings->DisableEncryption) { settings->EncryptionMethods = ENCRYPTION_METHOD_NONE; settings->EncryptionLevel = ENCRYPTION_LEVEL_NONE; } else if ((settings->EncryptionMethods & ENCRYPTION_METHOD_FIPS) != 0) { settings->EncryptionMethods = ENCRYPTION_METHOD_FIPS; } else if ((settings->EncryptionMethods & ENCRYPTION_METHOD_128BIT) != 0) { settings->EncryptionMethods = ENCRYPTION_METHOD_128BIT; } else if ((settings->EncryptionMethods & ENCRYPTION_METHOD_40BIT) != 0) { settings->EncryptionMethods = ENCRYPTION_METHOD_40BIT; } if (settings->EncryptionMethods != ENCRYPTION_METHOD_NONE) settings->EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE; headerLen = 12; keyLen = 0; wPublicKeyBlobLen = 0; serverRandomLen = 0; serverCertLen = 0; if (settings->EncryptionMethods != ENCRYPTION_METHOD_NONE || settings->EncryptionLevel != ENCRYPTION_LEVEL_NONE) { serverRandomLen = 32; keyLen = settings->RdpServerRsaKey->ModulusLength; expLen = sizeof(settings->RdpServerRsaKey->exponent); wPublicKeyBlobLen = 4; /* magic (RSA1) */ wPublicKeyBlobLen += 4; /* keylen */ wPublicKeyBlobLen += 4; /* bitlen */ wPublicKeyBlobLen += 4; /* datalen */ wPublicKeyBlobLen += expLen; wPublicKeyBlobLen += keyLen; wPublicKeyBlobLen += 8; /* 8 bytes of zero padding */ serverCertLen = 4; /* dwVersion */ serverCertLen += 4; /* dwSigAlgId */ serverCertLen += 4; /* dwKeyAlgId */ serverCertLen += 2; /* wPublicKeyBlobType */ serverCertLen += 2; /* wPublicKeyBlobLen */ serverCertLen += wPublicKeyBlobLen; serverCertLen += 2; /* wSignatureBlobType */ serverCertLen += 2; /* wSignatureBlobLen */ serverCertLen += sizeof(encryptedSignature); /* SignatureBlob */ serverCertLen += 8; /* 8 bytes of zero padding */ headerLen += sizeof(serverRandomLen); headerLen += sizeof(serverCertLen); headerLen += serverRandomLen; headerLen += serverCertLen; } gcc_write_user_data_header(s, SC_SECURITY, headerLen); Stream_Write_UINT32(s, settings->EncryptionMethods); /* encryptionMethod */ Stream_Write_UINT32(s, settings->EncryptionLevel); /* encryptionLevel */ if (settings->EncryptionMethods == ENCRYPTION_METHOD_NONE && settings->EncryptionLevel == ENCRYPTION_LEVEL_NONE) { return; } Stream_Write_UINT32(s, serverRandomLen); /* serverRandomLen */ Stream_Write_UINT32(s, serverCertLen); /* serverCertLen */ settings->ServerRandomLength = serverRandomLen; settings->ServerRandom = (BYTE*) malloc(serverRandomLen); crypto_nonce(settings->ServerRandom, serverRandomLen); Stream_Write(s, settings->ServerRandom, serverRandomLen); sigData = Stream_Pointer(s); Stream_Write_UINT32(s, CERT_CHAIN_VERSION_1); /* dwVersion (4 bytes) */ Stream_Write_UINT32(s, SIGNATURE_ALG_RSA); /* dwSigAlgId */ Stream_Write_UINT32(s, KEY_EXCHANGE_ALG_RSA); /* dwKeyAlgId */ Stream_Write_UINT16(s, BB_RSA_KEY_BLOB); /* wPublicKeyBlobType */ Stream_Write_UINT16(s, wPublicKeyBlobLen); /* wPublicKeyBlobLen */ Stream_Write(s, "RSA1", 4); /* magic */ Stream_Write_UINT32(s, keyLen + 8); /* keylen */ Stream_Write_UINT32(s, keyLen * 8); /* bitlen */ Stream_Write_UINT32(s, keyLen - 1); /* datalen */ Stream_Write(s, settings->RdpServerRsaKey->exponent, expLen); Stream_Write(s, settings->RdpServerRsaKey->Modulus, keyLen); Stream_Zero(s, 8); sigDataLen = Stream_Pointer(s) - sigData; Stream_Write_UINT16(s, BB_RSA_SIGNATURE_BLOB); /* wSignatureBlobType */ Stream_Write_UINT16(s, keyLen + 8); /* wSignatureBlobLen */ memcpy(signature, initial_signature, sizeof(initial_signature)); md5 = crypto_md5_init(); crypto_md5_update(md5, sigData, sigDataLen); crypto_md5_final(md5, signature); crypto_rsa_private_encrypt(signature, sizeof(signature), TSSK_KEY_LENGTH, tssk_modulus, tssk_privateExponent, encryptedSignature); Stream_Write(s, encryptedSignature, sizeof(encryptedSignature)); Stream_Zero(s, 8); }