<commit_before>/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Remote Desktop Gateway (RDG)
*
* Copyright 2015 <NAME> <<EMAIL>>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <assert.h>

#include <winpr/crt.h>
#include <winpr/synch.h>
#include <winpr/print.h>
#include <winpr/stream.h>
#include <winpr/winsock.h>

#include <freerdp/log.h>
#include <freerdp/error.h>
#include <freerdp/utils/ringbuffer.h>

#include "rdg.h"
#include "../proxy.h"
#include "../rdp.h"
#include "../../crypto/opensslcompat.h"

#define TAG FREERDP_TAG("core.gateway.rdg")

#pragma pack(push, 1)

typedef struct rdg_packet_header
{
	UINT16 type;
	UINT16 reserved;
	UINT32 packetLength;
} RdgPacketHeader;

#pragma pack(pop)

static BOOL rdg_write_packet(rdpRdg* rdg, wStream* sPacket)
{
	int status;
	wStream* sChunk;
	char chunkSize[11];
	sprintf_s(chunkSize, sizeof(chunkSize), "%"PRIXz"\r\n", Stream_Length(sPacket));
	sChunk = Stream_New(NULL, strlen(chunkSize) + Stream_Length(sPacket) + 2);

	if (!sChunk)
		return FALSE;

	Stream_Write(sChunk, chunkSize, strlen(chunkSize));
	Stream_Write(sChunk, Stream_Buffer(sPacket), Stream_Length(sPacket));
	Stream_Write(sChunk, "\r\n", 2);
	Stream_SealLength(sChunk);
	status = tls_write_all(rdg->tlsIn, Stream_Buffer(sChunk), Stream_Length(sChunk));
	Stream_Free(sChunk, TRUE);

	if (status < 0)
		return FALSE;

	return TRUE;
}

static wStream* rdg_receive_packet(rdpRdg* rdg)
{
	int status;
	wStream* s;
	RdgPacketHeader* packet;
	UINT32 readCount = 0;
	s = Stream_New(NULL, 1024);

	if (!s)
		return NULL;

	packet = (RdgPacketHeader*) Stream_Buffer(s);

	while (readCount < sizeof(RdgPacketHeader))
	{
		status = BIO_read(rdg->tlsOut->bio, Stream_Pointer(s), sizeof(RdgPacketHeader) - readCount);

		if (status < 0)
		{
			continue;
		}

		readCount += status;
		Stream_Seek(s, readCount);
	}

	if (Stream_Capacity(s) < packet->packetLength)
	{
		if (!Stream_EnsureCapacity(s, packet->packetLength))
		{
			Stream_Free(s, TRUE);
			return NULL;
		}

		packet = (RdgPacketHeader*) Stream_Buffer(s);
	}

	while (readCount < packet->packetLength)
	{
		status = BIO_read(rdg->tlsOut->bio, Stream_Pointer(s), packet->packetLength - readCount);

		if (status < 0)
		{
			continue;
		}

		readCount += status;
		Stream_Seek(s, readCount);
	}

	Stream_SealLength(s);
	return s;
}

static BOOL rdg_send_handshake(rdpRdg* rdg)
{
	wStream* s;
	BOOL status;
	s = Stream_New(NULL, 14);

	if (!s)
		return FALSE;

	Stream_Write_UINT16(s, PKT_TYPE_HANDSHAKE_REQUEST); /* Type (2 bytes) */
	Stream_Write_UINT16(s, 0); /* Reserved (2 bytes) */
	Stream_Write_UINT32(s, 14); /* PacketLength (4 bytes) */
	Stream_Write_UINT8(s, 1); /* VersionMajor (1 byte) */
	Stream_Write_UINT8(s, 0); /* VersionMinor (1 byte) */
	Stream_Write_UINT16(s, 0); /* ClientVersion (2 bytes), must be 0 */
	Stream_Write_UINT16(s, rdg->extAuth); /* ExtendedAuthentication (2 bytes) */
	Stream_SealLength(s);
	status = rdg_write_packet(rdg, s);
	Stream_Free(s, TRUE);

	if (status)
	{
		rdg->state = RDG_CLIENT_STATE_HANDSHAKE;<commit_msg>Moved some repeated "read all" code into function.<commit_after>/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Remote Desktop Gateway (RDG)
*
* Copyright 2015 <NAME> <<EMAIL>>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <assert.h>

#include <winpr/crt.h>
#include <winpr/synch.h>
#include <winpr/print.h>
#include <winpr/stream.h>
#include <winpr/winsock.h>

#include <freerdp/log.h>
#include <freerdp/error.h>
#include <freerdp/utils/ringbuffer.h>

#include "rdg.h"
#include "../proxy.h"
#include "../rdp.h"
#include "../../crypto/opensslcompat.h"

#define TAG FREERDP_TAG("core.gateway.rdg")

#pragma pack(push, 1)

typedef struct rdg_packet_header
{
	UINT16 type;
	UINT16 reserved;
	UINT32 packetLength;
} RdgPacketHeader;

#pragma pack(pop)

static BOOL rdg_write_packet(rdpRdg* rdg, wStream* sPacket)
{
	int status;
	wStream* sChunk;
	char chunkSize[11];
	sprintf_s(chunkSize, sizeof(chunkSize), "%"PRIXz"\r\n", Stream_Length(sPacket));
	sChunk = Stream_New(NULL, strlen(chunkSize) + Stream_Length(sPacket) + 2);

	if (!sChunk)
		return FALSE;

	Stream_Write(sChunk, chunkSize, strlen(chunkSize));
	Stream_Write(sChunk, Stream_Buffer(sPacket), Stream_Length(sPacket));
	Stream_Write(sChunk, "\r\n", 2);
	Stream_SealLength(sChunk);
	status = tls_write_all(rdg->tlsIn, Stream_Buffer(sChunk), Stream_Length(sChunk));
	Stream_Free(sChunk, TRUE);

	if (status < 0)
		return FALSE;

	return TRUE;
}

static BOOL rdg_read_all(rdpTls* tls, BYTE* buffer, int size)
{
	int status;
	int readCount = 0;

	while (readCount < size)
	{
		status = BIO_read(tls->bio, buffer, size - readCount);

		if (status <= 0)
		{
			if (!BIO_should_retry(tls->bio))
				return FALSE;

			continue;
		}

		readCount += status;
	}
	return TRUE;
}

static wStream* rdg_receive_packet(rdpRdg* rdg)
{
	wStream* s;
	size_t packetLength;

	s = Stream_New(NULL, 1024);

	if (!s)
		return NULL;

	if (!rdg_read_all(rdg->tlsOut, Stream_Buffer(s), sizeof(RdgPacketHeader)))
	{
		Stream_Free(s, TRUE);
		return NULL;
	}

	packetLength = ((RdgPacketHeader*)Stream_Buffer(s))->packetLength;

	if (!Stream_EnsureCapacity(s, packetLength))
	{
		Stream_Free(s, TRUE);
		return NULL;
	}

	if (!rdg_read_all(rdg->tlsOut, Stream_Buffer(s) + sizeof(RdgPacketHeader),
			packetLength - sizeof(RdgPacketHeader)))
	{
		Stream_Free(s, TRUE);
		return NULL;
	}

	Stream_SetLength(s, packetLength);

	return s;
}

static BOOL rdg_send_handshake(rdpRdg* rdg)
{
	wStream* s;
	BOOL status;
	s = Stream_New(NULL, 14);

	if (!s)
		return FALSE;

	Stream_Write_UINT16(s, PKT_TYPE_HANDSHAKE_REQUEST); /* Type (2 bytes) */
	Stream_Write_UINT16(s, 0); /* Reserved (2 bytes) */
	Stream_Write_UINT32(s, 14); /* PacketLength (4 bytes) */
	Stream_Write_UINT8(s, 1); /* VersionMajor (1 byte) */
	Stream_Write_UINT8(s, 0); /* VersionMinor (1 byte) */
	Stream_Write_UINT16(s, 0); /* ClientVersion (2 bytes), must be 0 */
	Stream_Write_UINT16(s, rdg->extAuth); /* ExtendedAuthentication (2 bytes) */
	Stream_SealLength(s);
	status = rdg_write_packet(rdg, s);
	Stream_Free(s, TRUE);

	if (status)
	{
		rdg->state = RDG_CLIENT_STATE_HANDSHAKE;
{'fraction_non_alphanumeric': 0.1366836946016844, 'fraction_numerical': 0.015325141515946432, 'mean_word_length': 4.823151125401929, 'pattern_counts': {'":': 0, '<': 36, '<?xml version=': 0, '>': 46, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6861466', 'n_tokens_mistral': 2874, 'n_tokens_neox': 2654, 'n_words': 662}