Example #1
0
BOOL gcc_read_server_network_data(wStream* s, rdpSettings* settings)
{
	int i;
	UINT16 MCSChannelId;
	UINT16 channelCount;
	UINT16 channelId;

	if(Stream_GetRemainingLength(s) < 4)
		return FALSE;
	Stream_Read_UINT16(s, MCSChannelId); /* MCSChannelId */
	Stream_Read_UINT16(s, channelCount); /* channelCount */

	if (channelCount != settings->ChannelCount)
	{
		fprintf(stderr, "requested %d channels, got %d instead\n",
				settings->ChannelCount, channelCount);
	}

	if(Stream_GetRemainingLength(s) < channelCount * 2)
		return FALSE;

	for (i = 0; i < channelCount; i++)
	{
		Stream_Read_UINT16(s, channelId); /* channelId */
		settings->ChannelDefArray[i].ChannelId = channelId;
	}

	if (channelCount % 2 == 1)
		return Stream_SafeSeek(s, 2); /* padding */

	return TRUE;
}
Example #2
0
int rdp_recv_enhanced_security_redirection_packet(rdpRdp* rdp, wStream* s)
{
	int status = 0;

	if (!Stream_SafeSeek(s, 2)) /* pad2Octets (2 bytes) */
		return -1;

	status = rdp_recv_server_redirection_pdu(rdp, s);

	if (status < 0)
		return status;

	if (!Stream_SafeSeek(s, 1)) /* pad2Octets (1 byte) */
		return -1;

	return status;
}
Example #3
0
BOOL ber_read_integer(wStream* s, UINT32* value)
{
	int length;

	if (!ber_read_universal_tag(s, BER_TAG_INTEGER, FALSE) ||
		!ber_read_length(s, &length) ||
		((int) Stream_GetRemainingLength(s)) < length)
		return FALSE;

	if (value == NULL)
	{
		// even if we don't care the integer value, check the announced size
		return Stream_SafeSeek(s, length);
	}

	if (length == 1)
	{
		Stream_Read_UINT8(s, *value);
	}
	else if (length == 2)
	{
		Stream_Read_UINT16_BE(s, *value);
	}
	else if (length == 3)
	{
		BYTE byte;
		Stream_Read_UINT8(s, byte);
		Stream_Read_UINT16_BE(s, *value);
		*value += (byte << 16);
	}
	else if (length == 4)
	{
		Stream_Read_UINT32_BE(s, *value);
	}
	else if (length == 8)
	{
		WLog_ERR(TAG,  "should implement reading an 8 bytes integer");
		return FALSE;
	}
	else
	{
		WLog_ERR(TAG,  "should implement reading an integer with length=%d", length);
		return FALSE;
	}

	return TRUE;
}
Example #4
0
int rdp_recv_enhanced_security_redirection_packet(rdpRdp* rdp, wStream* s)
{
	int status = 0;

	if (!Stream_SafeSeek(s, 2)) /* pad2Octets (2 bytes) */
		return -1;

	status = rdp_recv_server_redirection_pdu(rdp, s);

	if (status < 0)
		return status;

	if (Stream_GetRemainingLength(s) >= 1)
	{
		/* this field is optional, and its absence is not an error */
		Stream_Seek(s, 1); /* pad2Octets (1 byte) */
	}

	return status;
}
Example #5
0
BOOL gcc_read_server_network_data(wStream* s, rdpMcs* mcs)
{
	int i;
	UINT16 channelId;
	UINT16 MCSChannelId;
	UINT16 channelCount;
	UINT16 parsedChannelCount;

	if (Stream_GetRemainingLength(s) < 4)
		return FALSE;

	Stream_Read_UINT16(s, MCSChannelId); /* MCSChannelId */
	Stream_Read_UINT16(s, channelCount); /* channelCount */

	parsedChannelCount = channelCount;

	if (channelCount != mcs->channelCount)
	{
		WLog_ERR(TAG,  "requested %d channels, got %d instead",
				 mcs->channelCount, channelCount);

		/* we ensure that the response is not bigger than the request */

		if (channelCount > mcs->channelCount)
			parsedChannelCount = mcs->channelCount;
	}

	if (Stream_GetRemainingLength(s) < (size_t) channelCount * 2)
		return FALSE;

	for (i = 0; i < parsedChannelCount; i++)
	{
		Stream_Read_UINT16(s, channelId); /* channelId */
		mcs->channels[i].ChannelId = channelId;
	}

	if (channelCount % 2 == 1)
		return Stream_SafeSeek(s, 2); /* padding */

	return TRUE;
}
Example #6
0
BOOL tpdu_read_header(wStream* s, BYTE* code, BYTE* li)
{
	if (Stream_GetRemainingLength(s) < 3)
		return FALSE;

	Stream_Read_UINT8(s, *li); /* LI */
	Stream_Read_UINT8(s, *code); /* Code */

	if (*code == X224_TPDU_DATA)
	{
		/* EOT (1 byte) */
		Stream_Seek(s, 1);
	}
	else
	{
		/* DST-REF (2 bytes) */
		/* SRC-REF (2 bytes) */
		/* Class 0 (1 byte) */
		return Stream_SafeSeek(s, 5);
	}

	return TRUE;
}
Example #7
0
BOOL certificate_read_x509_certificate(rdpCertBlob* cert, rdpCertInfo* info)
{
	wStream* s;
	int length;
	BYTE padding;
	UINT32 version;
	int modulus_length;
	int exponent_length;
	int error = 0;

	if (!cert || !info)
		return FALSE;

	memset(info, 0, sizeof(rdpCertInfo));
	s = Stream_New(cert->data, cert->length);

	if (!s)
		return FALSE;

	info->Modulus = 0;

	if (!ber_read_sequence_tag(s, &length)) /* Certificate (SEQUENCE) */
		goto error1;

	error++;

	if (!ber_read_sequence_tag(s, &length)) /* TBSCertificate (SEQUENCE) */
		goto error1;

	error++;

	if (!ber_read_contextual_tag(s, 0, &length, TRUE))	/* Explicit Contextual Tag [0] */
		goto error1;

	error++;

	if (!ber_read_integer(s, &version)) /* version (INTEGER) */
		goto error1;

	error++;
	version++;

	/* serialNumber */
	if (!ber_read_integer(s, NULL)) /* CertificateSerialNumber (INTEGER) */
		goto error1;

	error++;

	/* signature */
	if (!ber_read_sequence_tag(s, &length) ||
	    !Stream_SafeSeek(s, length)) /* AlgorithmIdentifier (SEQUENCE) */
		goto error1;

	error++;

	/* issuer */
	if (!ber_read_sequence_tag(s, &length) || !Stream_SafeSeek(s, length)) /* Name (SEQUENCE) */
		goto error1;

	error++;

	/* validity */
	if (!ber_read_sequence_tag(s, &length) || !Stream_SafeSeek(s, length)) /* Validity (SEQUENCE) */
		goto error1;

	error++;

	/* subject */
	if (!ber_read_sequence_tag(s, &length) || !Stream_SafeSeek(s, length)) /* Name (SEQUENCE) */
		goto error1;

	error++;

	/* subjectPublicKeyInfo */
	if (!ber_read_sequence_tag(s, &length)) /* SubjectPublicKeyInfo (SEQUENCE) */
		goto error1;

	error++;

	/* subjectPublicKeyInfo::AlgorithmIdentifier */
	if (!ber_read_sequence_tag(s, &length) ||
	    !Stream_SafeSeek(s, length)) /* AlgorithmIdentifier (SEQUENCE) */
		goto error1;

	error++;

	/* subjectPublicKeyInfo::subjectPublicKey */
	if (!ber_read_bit_string(s, &length, &padding)) /* BIT_STRING */
		goto error1;

	error++;

	/* RSAPublicKey (SEQUENCE) */
	if (!ber_read_sequence_tag(s, &length)) /* SEQUENCE */
		goto error1;

	error++;

	if (!ber_read_integer_length(s, &modulus_length)) /* modulus (INTEGER) */
		goto error1;

	error++;

	/* skip zero padding, if any */
	do
	{
		if (Stream_GetRemainingLength(s) < 1)
			goto error1;

		Stream_Peek_UINT8(s, padding);

		if (padding == 0)
		{
			if (!Stream_SafeSeek(s, 1))
				goto error1;

			modulus_length--;
		}
	}
	while (padding == 0);

	error++;

	if (((int) Stream_GetRemainingLength(s)) < modulus_length)
		goto error1;

	info->ModulusLength = modulus_length;
	info->Modulus = (BYTE*) malloc(info->ModulusLength);

	if (!info->Modulus)
		goto error1;

	Stream_Read(s, info->Modulus, info->ModulusLength);
	error++;

	if (!ber_read_integer_length(s, &exponent_length)) /* publicExponent (INTEGER) */
		goto error2;

	error++;

	if ((((int) Stream_GetRemainingLength(s)) < exponent_length) || (exponent_length > 4))
		goto error2;

	Stream_Read(s, &info->exponent[4 - exponent_length], exponent_length);
	crypto_reverse(info->Modulus, info->ModulusLength);
	crypto_reverse(info->exponent, 4);
	Stream_Free(s, FALSE);
	return TRUE;
error2:
	free(info->Modulus);
	info->Modulus = 0;
error1:
	WLog_ERR(TAG, "error reading when reading certificate: part=%s error=%d",
	         certificate_read_errors[error], error);
	Stream_Free(s, FALSE);
	return FALSE;
}
Example #8
0
BOOL rdp_recv_server_redirection_pdu(rdpRdp* rdp, wStream* s)
{
	UINT16 flags;
	UINT16 length;
	rdpRedirection* redirection = rdp->redirection;

	if (Stream_GetRemainingLength(s) < 12)
		return -1;

	Stream_Read_UINT16(s, flags); /* flags (2 bytes) */
	Stream_Read_UINT16(s, length); /* length (2 bytes) */
	Stream_Read_UINT32(s, redirection->sessionID); /* sessionID (4 bytes) */
	Stream_Read_UINT32(s, redirection->flags); /* redirFlags (4 bytes) */

	WLog_Print(redirection->log, WLOG_DEBUG, "flags: 0x%04X, redirFlags: 0x%04X length: %d, sessionID: 0x%08X",
			flags, redirection->flags, length, redirection->sessionID);

#ifdef WITH_DEBUG_REDIR
	rdp_print_redirection_flags(redirection->flags);
#endif

	if (redirection->flags & LB_TARGET_NET_ADDRESS)
	{
		if (!rdp_redirection_read_string(s, &(redirection->TargetNetAddress)))
			return -1;
	}

	if (redirection->flags & LB_LOAD_BALANCE_INFO)
	{
		if (Stream_GetRemainingLength(s) < 4)
			return -1;

		Stream_Read_UINT32(s, redirection->LoadBalanceInfoLength);

		if (Stream_GetRemainingLength(s) < redirection->LoadBalanceInfoLength)
			return -1;

		redirection->LoadBalanceInfo = (BYTE*) malloc(redirection->LoadBalanceInfoLength);
		Stream_Read(s, redirection->LoadBalanceInfo, redirection->LoadBalanceInfoLength);
#ifdef WITH_DEBUG_REDIR
		DEBUG_REDIR("loadBalanceInfo:");
		winpr_HexDump(redirection->LoadBalanceInfo, redirection->LoadBalanceInfoLength);
#endif
	}

	if (redirection->flags & LB_USERNAME)
	{
		if (!rdp_redirection_read_string(s, &(redirection->Username)))
			return -1;

		WLog_Print(redirection->log, WLOG_DEBUG, "Username: %s", redirection->Username);
	}

	if (redirection->flags & LB_DOMAIN)
	{
		if (!rdp_redirection_read_string(s, &(redirection->Domain)))
			return FALSE;

		WLog_Print(redirection->log, WLOG_DEBUG, "Domain: %s", redirection->Domain);
	}

	if (redirection->flags & LB_PASSWORD)
	{
		/* Note: length (hopefully) includes double zero termination */
		if (Stream_GetRemainingLength(s) < 4)
			return -1;

		Stream_Read_UINT32(s, redirection->PasswordLength);
		redirection->Password = (BYTE*) malloc(redirection->PasswordLength);
		Stream_Read(s, redirection->Password, redirection->PasswordLength);

#ifdef WITH_DEBUG_REDIR
		DEBUG_REDIR("PasswordCookie:");
		winpr_HexDump(redirection->Password, redirection->PasswordLength);
#endif
	}

	if (redirection->flags & LB_TARGET_FQDN)
	{
		if (!rdp_redirection_read_string(s, &(redirection->TargetFQDN)))
			return -1;

		WLog_Print(redirection->log, WLOG_DEBUG, "TargetFQDN: %s", redirection->TargetFQDN);
	}

	if (redirection->flags & LB_TARGET_NETBIOS_NAME)
	{
		if (!rdp_redirection_read_string(s, &(redirection->TargetNetBiosName)))
			return -1;

		WLog_Print(redirection->log, WLOG_DEBUG, "TargetNetBiosName: %s", redirection->TargetNetBiosName);
	}

	if (redirection->flags & LB_CLIENT_TSV_URL)
	{
		if (Stream_GetRemainingLength(s) < 4)
			return -1;

		Stream_Read_UINT32(s, redirection->TsvUrlLength);

		if (Stream_GetRemainingLength(s) < redirection->TsvUrlLength)
			return -1;

		redirection->TsvUrl = (BYTE*) malloc(redirection->TsvUrlLength);
		Stream_Read(s, redirection->TsvUrl, redirection->TsvUrlLength);

#ifdef WITH_DEBUG_REDIR
		DEBUG_REDIR("TsvUrl:");
		winpr_HexDump(redirection->TsvUrl, redirection->TsvUrlLength);
#endif
	}

	if (redirection->flags & LB_TARGET_NET_ADDRESSES)
	{
		int i;
		UINT32 count;
		UINT32 targetNetAddressesLength;

		if (Stream_GetRemainingLength(s) < 8)
			return -1;

		Stream_Read_UINT32(s, targetNetAddressesLength);

		Stream_Read_UINT32(s, redirection->TargetNetAddressesCount);
		count = redirection->TargetNetAddressesCount;

		redirection->TargetNetAddresses = (char**) malloc(count * sizeof(char*));
		ZeroMemory(redirection->TargetNetAddresses, count * sizeof(char*));

		WLog_Print(redirection->log, WLOG_DEBUG, "TargetNetAddressesCount: %d", redirection->TargetNetAddressesCount);

		for (i = 0; i < (int) count; i++)
		{
			if (!rdp_redirection_read_string(s, &(redirection->TargetNetAddresses[i])))
				return FALSE;

			WLog_Print(redirection->log, WLOG_DEBUG, "TargetNetAddresses[%d]: %s", i, redirection->TargetNetAddresses[i]);
		}
	}

	if (!Stream_SafeSeek(s, 8)) /* pad (8 bytes) */
		return -1;

	if (redirection->flags & LB_NOREDIRECT)
		return 0;

	return 1;
}
Example #9
0
static BOOL rdpsnd_server_recv_formats(RdpsndServerContext* context, wStream* s)
{
	int i, num_known_format = 0;
	UINT32 flags, vol, pitch;
	UINT16 udpPort, version;
	BYTE lastblock;

	if (Stream_GetRemainingLength(s) < 20)
		return FALSE;

	Stream_Read_UINT32(s, flags); /* dwFlags */
	Stream_Read_UINT32(s, vol); /* dwVolume */
	Stream_Read_UINT32(s, pitch); /* dwPitch */
	Stream_Read_UINT16(s, udpPort); /* wDGramPort */
	Stream_Read_UINT16(s, context->num_client_formats); /* wNumberOfFormats */
	Stream_Read_UINT8(s, lastblock); /* cLastBlockConfirmed */
	Stream_Read_UINT16(s, version); /* wVersion */
	Stream_Seek_UINT8(s); /* bPad */

	/* this check is only a guess as cbSize can influence the size of a format record */
	if (Stream_GetRemainingLength(s) < context->num_client_formats * 18)
		return FALSE;

	if (!context->num_client_formats)
	{
		fprintf(stderr, "%s: client doesn't support any format!\n", __FUNCTION__);
		return FALSE;
	}

	context->client_formats = (AUDIO_FORMAT *)calloc(context->num_client_formats, sizeof(AUDIO_FORMAT));
	if (!context->client_formats)
		return FALSE;

	for (i = 0; i < context->num_client_formats; i++)
	{
		if (Stream_GetRemainingLength(s) < 18)
			goto out_free;

		Stream_Read_UINT16(s, context->client_formats[i].wFormatTag);
		Stream_Read_UINT16(s, context->client_formats[i].nChannels);
		Stream_Read_UINT32(s, context->client_formats[i].nSamplesPerSec);
		Stream_Read_UINT32(s, context->client_formats[i].nAvgBytesPerSec);
		Stream_Read_UINT16(s, context->client_formats[i].nBlockAlign);
		Stream_Read_UINT16(s, context->client_formats[i].wBitsPerSample);
		Stream_Read_UINT16(s, context->client_formats[i].cbSize);

		if (context->client_formats[i].cbSize > 0)
		{
			if (!Stream_SafeSeek(s, context->client_formats[i].cbSize))
				goto out_free;
		}

		if (context->client_formats[i].wFormatTag != 0)
		{
			//lets call this a known format
			//TODO: actually look through our own list of known formats
			num_known_format++;
		}
	}

	if (!context->num_client_formats)
	{
		fprintf(stderr, "%s: client doesn't support any known format!\n", __FUNCTION__);
		goto out_free;
	}

	return TRUE;

out_free:
	free(context->client_formats);
	return FALSE;
}
Example #10
0
RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, BYTE* data, UINT32 length)
{
	int pos;
	wStream* s;
	UINT32 blockLen;
	UINT32 blockType;
	RFX_MESSAGE* message;

	message = (RFX_MESSAGE*) malloc(sizeof(RFX_MESSAGE));
	ZeroMemory(message, sizeof(RFX_MESSAGE));

	s = Stream_New(data, length);

	while (Stream_GetRemainingLength(s) > 6)
	{
		/* RFX_BLOCKT */
		Stream_Read_UINT16(s, blockType); /* blockType (2 bytes) */
		Stream_Read_UINT32(s, blockLen); /* blockLen (4 bytes) */

		DEBUG_RFX("blockType 0x%X blockLen %d", blockType, blockLen);

		if (blockLen == 0)
		{
			DEBUG_WARN("zero blockLen");
			break;
		}

		if (Stream_GetRemainingLength(s) < blockLen - 6)
		{
			DEBUG_WARN("rfx_process_message: packet too small for blocklen=%d", blockLen);
			break;
		}


		pos = Stream_GetPosition(s) - 6 + blockLen;

		if (blockType >= WBT_CONTEXT && blockType <= WBT_EXTENSION)
		{
			/* RFX_CODEC_CHANNELT */
			/* codecId (1 byte) must be set to 0x01 */
			/* channelId (1 byte) must be set to 0x00 */
			if (!Stream_SafeSeek(s, 2))
			{
				DEBUG_WARN("rfx_process_message: unable to skip RFX_CODEC_CHANNELT");
				break;
			}
		}

		switch (blockType)
		{
			case WBT_SYNC:
				rfx_process_message_sync(context, s);
				break;

			case WBT_CODEC_VERSIONS:
				rfx_process_message_codec_versions(context, s);
				break;

			case WBT_CHANNELS:
				rfx_process_message_channels(context, s);
				break;

			case WBT_CONTEXT:
				rfx_process_message_context(context, s);
				break;

			case WBT_FRAME_BEGIN:
				rfx_process_message_frame_begin(context, message, s);
				break;

			case WBT_FRAME_END:
				rfx_process_message_frame_end(context, message, s);
				break;

			case WBT_REGION:
				rfx_process_message_region(context, message, s);
				break;

			case WBT_EXTENSION:
				rfx_process_message_tileset(context, message, s);
				break;

			default:
				DEBUG_WARN("unknown blockType 0x%X", blockType);
				break;
		}

		Stream_SetPosition(s, pos);
	}

	Stream_Free(s, FALSE);

	return message;
}
Example #11
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT rdpsnd_server_recv_formats(RdpsndServerContext* context, wStream* s)
{
	int i, num_known_format = 0;
	UINT32 flags, vol, pitch;
	UINT16 udpPort;
	BYTE lastblock;
	UINT error = CHANNEL_RC_OK;

	if (Stream_GetRemainingLength(s) < 20)
	{
		WLog_ERR(TAG, "not enought data in stream!");
		return ERROR_INVALID_DATA;
	}

	Stream_Read_UINT32(s, flags); /* dwFlags */
	Stream_Read_UINT32(s, vol); /* dwVolume */
	Stream_Read_UINT32(s, pitch); /* dwPitch */
	Stream_Read_UINT16(s, udpPort); /* wDGramPort */
	Stream_Read_UINT16(s, context->num_client_formats); /* wNumberOfFormats */
	Stream_Read_UINT8(s, lastblock); /* cLastBlockConfirmed */
	Stream_Read_UINT16(s, context->clientVersion); /* wVersion */
	Stream_Seek_UINT8(s); /* bPad */

	/* this check is only a guess as cbSize can influence the size of a format record */
	if (Stream_GetRemainingLength(s) < context->num_client_formats * 18)
	{
		WLog_ERR(TAG, "not enought data in stream!");
		return ERROR_INVALID_DATA;
	}

	if (!context->num_client_formats)
	{
		WLog_ERR(TAG,  "client doesn't support any format!");
		return ERROR_INTERNAL_ERROR;
	}

	context->client_formats = (AUDIO_FORMAT *)calloc(context->num_client_formats, sizeof(AUDIO_FORMAT));
	if (!context->client_formats)
	{
		WLog_ERR(TAG,  "calloc failed!");
		return CHANNEL_RC_NO_MEMORY;
	}

	for (i = 0; i < context->num_client_formats; i++)
	{
		if (Stream_GetRemainingLength(s) < 18)
		{
			WLog_ERR(TAG, "not enought data in stream!");
			error = ERROR_INVALID_DATA;
			goto out_free;
		}


		Stream_Read_UINT16(s, context->client_formats[i].wFormatTag);
		Stream_Read_UINT16(s, context->client_formats[i].nChannels);
		Stream_Read_UINT32(s, context->client_formats[i].nSamplesPerSec);
		Stream_Read_UINT32(s, context->client_formats[i].nAvgBytesPerSec);
		Stream_Read_UINT16(s, context->client_formats[i].nBlockAlign);
		Stream_Read_UINT16(s, context->client_formats[i].wBitsPerSample);
		Stream_Read_UINT16(s, context->client_formats[i].cbSize);

		if (context->client_formats[i].cbSize > 0)
		{
			if (!Stream_SafeSeek(s, context->client_formats[i].cbSize))
			{
				WLog_ERR(TAG, "Stream_SafeSeek failed!");
				error = ERROR_INTERNAL_ERROR;
				goto out_free;
			}

		}

		if (context->client_formats[i].wFormatTag != 0)
		{
			//lets call this a known format
			//TODO: actually look through our own list of known formats
			num_known_format++;
		}
	}

	if (!context->num_client_formats)
	{
		WLog_ERR(TAG,  "client doesn't support any known format!");
		goto out_free;
	}

	return CHANNEL_RC_OK;

out_free:
	free(context->client_formats);
	return error;
}