Example #1
0
BOOL rdp_read_extended_info_packet(wStream* s, rdpSettings* settings)
{
	UINT16 clientAddressFamily;
	UINT16 cbClientAddress;
	UINT16 cbClientDir;
	UINT16 cbAutoReconnectLen;

	if (Stream_GetRemainingLength(s) < 4)
		return FALSE;
	Stream_Read_UINT16(s, clientAddressFamily); /* clientAddressFamily */
	Stream_Read_UINT16(s, cbClientAddress); /* cbClientAddress */

	settings->IPv6Enabled = (clientAddressFamily == ADDRESS_FAMILY_INET6 ? TRUE : FALSE);

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

	ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), cbClientAddress / 2, &settings->ClientAddress, 0, NULL, NULL);
	Stream_Seek(s, cbClientAddress);

	if (Stream_GetRemainingLength(s) < 2)
		return FALSE;
	Stream_Read_UINT16(s, cbClientDir); /* cbClientDir */

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

	if (settings->ClientDir)
		free(settings->ClientDir);

	ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), cbClientDir / 2, &settings->ClientDir, 0, NULL, NULL);
	Stream_Seek(s, cbClientDir);

	if (!rdp_read_client_time_zone(s, settings))
		return FALSE;

	if (Stream_GetRemainingLength(s) < 10)
		return FALSE;
	Stream_Seek_UINT32(s); /* clientSessionId, should be set to 0 */
	Stream_Read_UINT32(s, settings->PerformanceFlags); /* performanceFlags */

	Stream_Read_UINT16(s, cbAutoReconnectLen); /* cbAutoReconnectLen */

	if (cbAutoReconnectLen > 0)
		return rdp_read_client_auto_reconnect_cookie(s, settings); /* autoReconnectCookie */

	/* reserved1 (2 bytes) */
	/* reserved2 (2 bytes) */

	return TRUE;
}
Example #2
0
boolean rdp_read_extended_info_packet(STREAM* s, rdpSettings* settings)
{
	uint16 clientAddressFamily;
	uint16 cbClientAddress;
	uint16 cbClientDir;
	uint16 cbAutoReconnectLen;

	stream_read_uint16(s, clientAddressFamily); /* clientAddressFamily */
	stream_read_uint16(s, cbClientAddress); /* cbClientAddress */

	settings->ipv6 = (clientAddressFamily == ADDRESS_FAMILY_INET6 ? true : false);
	if (stream_get_left(s) < cbClientAddress)
		return false;
	settings->ip_address = freerdp_uniconv_in(settings->uniconv, stream_get_tail(s), cbClientAddress);
	stream_seek(s, cbClientAddress);

	stream_read_uint16(s, cbClientDir); /* cbClientDir */
	if (stream_get_left(s) < cbClientDir)
		return false;
	if (settings->client_dir)
		xfree(settings->client_dir);
	settings->client_dir = freerdp_uniconv_in(settings->uniconv, stream_get_tail(s), cbClientDir);
	stream_seek(s, cbClientDir);

	if (!rdp_read_client_time_zone(s, settings))
		return false;

	stream_seek_uint32(s); /* clientSessionId, should be set to 0 */
	stream_read_uint32(s, settings->performance_flags); /* performanceFlags */

	stream_read_uint16(s, cbAutoReconnectLen); /* cbAutoReconnectLen */

	if (cbAutoReconnectLen > 0)
		return rdp_read_client_auto_reconnect_cookie(s, settings); /* autoReconnectCookie */

	/* reserved1 (2 bytes) */
	/* reserved2 (2 bytes) */

	return true;
}
Example #3
0
BOOL rdp_read_extended_info_packet(rdpRdp* rdp, wStream* s)
{
	UINT16 clientAddressFamily;
	UINT16 cbClientAddress;
	UINT16 cbClientDir;
	UINT16 cbAutoReconnectLen;
	rdpSettings* settings = rdp->settings;
	WCHAR* wstr;

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

	Stream_Read_UINT16(s, clientAddressFamily); /* clientAddressFamily (2 bytes) */
	Stream_Read_UINT16(s, cbClientAddress); /* cbClientAddress (2 bytes) */

	/* cbClientAddress is the size in bytes of the character data in the clientAddress field.
	 * This size includes the length of the mandatory null terminator.
	 * The maximum allowed value is 80 bytes
	 * Note: Although according to [MS-RDPBCGR 2.2.1.11.1.1.1] the null terminator
	 * is mandatory, connections via Microsoft's TS Gateway set cbClientAddress to 0.
	 */

	if ((cbClientAddress % 2) || cbClientAddress > 80)
	{
		WLog_ERR(TAG, "protocol error: invalid cbClientAddress value: %u", cbClientAddress);
		return FALSE;
	}

	settings->IPv6Enabled = (clientAddressFamily == ADDRESS_FAMILY_INET6 ? TRUE : FALSE);

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

	if (settings->ClientAddress)
	{
		free(settings->ClientAddress);
		settings->ClientAddress = NULL;
	}

	if (cbClientAddress)
	{
		wstr = (WCHAR*) Stream_Pointer(s);
		if (wstr[cbClientAddress / 2 - 1])
		{
			WLog_ERR(TAG, "protocol error: clientAddress must be null terminated");
			return FALSE;
		}
		if (ConvertFromUnicode(CP_UTF8, 0, wstr, -1, &settings->ClientAddress, 0, NULL, NULL) < 1)
		{
			WLog_ERR(TAG, "failed to convert client address");
			return FALSE;
		}
		Stream_Seek(s, cbClientAddress);
		WLog_DBG(TAG, "rdp client address: [%s]", settings->ClientAddress);
	}

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

	Stream_Read_UINT16(s, cbClientDir); /* cbClientDir (2 bytes) */

	/* cbClientDir is the size in bytes of the character data in the clientDir field.
	 * This size includes the length of the mandatory null terminator.
	 * The maximum allowed value is 512 bytes.
	 * Note: Although according to [MS-RDPBCGR 2.2.1.11.1.1.1] the null terminator
	 * is mandatory the Microsoft Android client (starting with version 8.1.31.44)
	 * sets cbClientDir to 0.
	 */

	if ((cbClientDir % 2) || cbClientDir > 512)
	{
		WLog_ERR(TAG, "protocol error: invalid cbClientDir value: %u", cbClientDir);
		return FALSE;
	}

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

	if (settings->ClientDir)
	{
		free(settings->ClientDir);
		settings->ClientDir = NULL;
	}

	if (cbClientDir)
	{
		wstr = (WCHAR*) Stream_Pointer(s);
		if (wstr[cbClientDir / 2 - 1])
		{
			WLog_ERR(TAG, "protocol error: clientDir must be null terminated");
			return FALSE;
		}
		if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), -1, &settings->ClientDir, 0, NULL, NULL) < 1)
		{
			WLog_ERR(TAG, "failed to convert client directory");
			return FALSE;
		}
		Stream_Seek(s, cbClientDir);
		WLog_DBG(TAG, "rdp client dir: [%s]", settings->ClientDir);
	}

	/**
	 * down below all fields are optional but if one field is not present,
	 * then all of the subsequent fields also MUST NOT be present.
	 */

	/* optional: clientTimeZone (172 bytes) */
	if (Stream_GetRemainingLength(s) == 0)
		return TRUE;
	if (!rdp_read_client_time_zone(s, settings))
		return FALSE;

	/* optional: clientSessionId (4 bytes), should be set to 0 */
	if (Stream_GetRemainingLength(s) == 0)
		return TRUE;
	if (Stream_GetRemainingLength(s) < 4)
		return FALSE;
	Stream_Seek_UINT32(s);

	/* optional: performanceFlags (4 bytes) */
	if (Stream_GetRemainingLength(s) == 0)
		return TRUE;
	if (Stream_GetRemainingLength(s) < 4)
		return FALSE;
	Stream_Read_UINT32(s, settings->PerformanceFlags);
	freerdp_performance_flags_split(settings);

	/* optional: cbAutoReconnectLen (2 bytes) */
	if (Stream_GetRemainingLength(s) == 0)
		return TRUE;
	if (Stream_GetRemainingLength(s) < 2)
		return FALSE;
	Stream_Read_UINT16(s, cbAutoReconnectLen);

	/* optional: autoReconnectCookie (28 bytes) */
	/* must be present if cbAutoReconnectLen is > 0 */
	if (cbAutoReconnectLen > 0)
		return rdp_read_client_auto_reconnect_cookie(rdp, s);

	/* TODO */

	/* reserved1 (2 bytes) */
	/* reserved2 (2 bytes) */
	/* cbDynamicDSTTimeZoneKeyName (2 bytes) */
	/* dynamicDSTTimeZoneKeyName (variable) */
	/* dynamicDaylightTimeDisabled (2 bytes) */

	return TRUE;
}
Example #4
0
BOOL rdp_read_extended_info_packet(rdpRdp* rdp, wStream* s)
{
	UINT16 clientAddressFamily;
	UINT16 cbClientAddress;
	UINT16 cbClientDir;
	UINT16 cbAutoReconnectLen;
	rdpSettings* settings = rdp->settings;
	WCHAR* wstr;

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

	Stream_Read_UINT16(s, clientAddressFamily); /* clientAddressFamily (2 bytes) */
	Stream_Read_UINT16(s, cbClientAddress); /* cbClientAddress (2 bytes) */

	/* cbClientAddress is the size in bytes of the character data in the clientAddress field.
	 * This size includes the length of the mandatory null terminator.
	 * The maximum allowed value is 80 bytes
	 */

	if ((cbClientAddress % 2) || cbClientAddress < 2 || cbClientAddress > 80)
	{
		WLog_ERR(TAG, "protocol error: invalid cbClientAddress value: %u", cbClientAddress);
		return FALSE;
	}

	settings->IPv6Enabled = (clientAddressFamily == ADDRESS_FAMILY_INET6 ? TRUE : FALSE);

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

	if (settings->ClientAddress)
	{
		free(settings->ClientAddress);
		settings->ClientAddress = NULL;
	}

	wstr = (WCHAR*) Stream_Pointer(s);
	if (wstr[cbClientAddress / 2 - 1])
	{
		WLog_ERR(TAG, "protocol error: clientAddress must be null terminated");
		return FALSE;
	}
	if (ConvertFromUnicode(CP_UTF8, 0, wstr, -1, &settings->ClientAddress, 0, NULL, NULL) < 1)
	{
		WLog_ERR(TAG, "failed to convert client address");
		return FALSE;
	}
	Stream_Seek(s, cbClientAddress);

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

	Stream_Read_UINT16(s, cbClientDir); /* cbClientDir (2 bytes) */

	/* cbClientDir is the size in bytes of the character data in the clientDir field.
	 * This size includes the length of the mandatory null terminator.
	 * The maximum allowed value is 512 bytes
	 */

	if ((cbClientDir % 2) || cbClientDir < 2 || cbClientDir > 512)
	{
		WLog_ERR(TAG, "protocol error: invalid cbClientDir value: %u", cbClientDir);
		return FALSE;
	}

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

	if (settings->ClientDir)
	{
		free(settings->ClientDir);
		settings->ClientDir = NULL;
	}

	wstr = (WCHAR*) Stream_Pointer(s);
	if (wstr[cbClientDir / 2 - 1])
	{
		WLog_ERR(TAG, "protocol error: clientDir must be null terminated");
		return FALSE;
	}
	if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), -1, &settings->ClientDir, 0, NULL, NULL) < 1)
	{
		WLog_ERR(TAG, "failed to convert client directory");
		return FALSE;
	}
	Stream_Seek(s, cbClientDir);

	if (!rdp_read_client_time_zone(s, settings))
		return FALSE;

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

	Stream_Seek_UINT32(s); /* clientSessionId (4 bytes), should be set to 0 */
	Stream_Read_UINT32(s, settings->PerformanceFlags); /* performanceFlags (4 bytes) */
	freerdp_performance_flags_split(settings);

	Stream_Read_UINT16(s, cbAutoReconnectLen); /* cbAutoReconnectLen (2 bytes) */

	if (cbAutoReconnectLen > 0)
		return rdp_read_client_auto_reconnect_cookie(rdp, s); /* autoReconnectCookie */

	/* reserved1 (2 bytes) */
	/* reserved2 (2 bytes) */

	return TRUE;
}