Esempio n. 1
0
boolean nego_read_request(rdpNego* nego, STREAM* s)
{
	uint8 li;
	uint8 c;
	uint8 type;

	tpkt_read_header(s);
	li = tpdu_read_connection_request(s);

	if (li != stream_get_left(s) + 6)
	{
		printf("Incorrect TPDU length indicator.\n");
		return false;
	}

	if (stream_get_left(s) > 8)
	{
		/* Optional routingToken or cookie, ending with CR+LF */
		while (stream_get_left(s) > 0)
		{
			stream_read_uint8(s, c);

			if (c != '\x0D')
				continue;

			stream_peek_uint8(s, c);

			if (c != '\x0A')
				continue;

			stream_seek_uint8(s);
			break;
		}
	}

	if (stream_get_left(s) >= 8)
	{
		/* rdpNegData (optional) */

		stream_read_uint8(s, type); /* Type */

		if (type != TYPE_RDP_NEG_REQ)
		{
			printf("Incorrect negotiation request type %d\n", type);
			return false;
		}

		nego_process_negotiation_request(nego, s);
	}

	return true;
}
Esempio n. 2
0
uint16
tpkt_read_header(STREAM* s)
{
	uint8 version;
	uint16 length;

	stream_peek_uint8(s, version);

	if (version == 3)
	{
		stream_seek(s, 2);
		stream_read_uint16_be(s, length);
	}
	else
	{
		/* not a TPKT header */
		length = 0;
	}

	return length;
}
Esempio n. 3
0
void certificate_read_x509_certificate(rdpCertBlob* cert, rdpCertInfo* info)
{
	STREAM* s;
	int length;
	uint8 padding;
	uint32 version;
	int modulus_length;
	int exponent_length;

	s = stream_new(0);
	s->p = s->data = cert->data;

	ber_read_sequence_tag(s, &length); /* Certificate (SEQUENCE) */

	ber_read_sequence_tag(s, &length); /* TBSCertificate (SEQUENCE) */

	/* Explicit Contextual Tag [0] */
	ber_read_contextual_tag(s, 0, &length, true);
	ber_read_integer(s, &version); /* version (INTEGER) */
	version++;

	/* serialNumber */
	ber_read_integer(s, NULL); /* CertificateSerialNumber (INTEGER) */

	/* signature */
	ber_read_sequence_tag(s, &length); /* AlgorithmIdentifier (SEQUENCE) */
	stream_seek(s, length);

	/* issuer */
	ber_read_sequence_tag(s, &length); /* Name (SEQUENCE) */
	stream_seek(s, length);

	/* validity */
	ber_read_sequence_tag(s, &length); /* Validity (SEQUENCE) */
	stream_seek(s, length);

	/* subject */
	ber_read_sequence_tag(s, &length); /* Name (SEQUENCE) */
	stream_seek(s, length);

	/* subjectPublicKeyInfo */
	ber_read_sequence_tag(s, &length); /* SubjectPublicKeyInfo (SEQUENCE) */

	/* subjectPublicKeyInfo::AlgorithmIdentifier */
	ber_read_sequence_tag(s, &length); /* AlgorithmIdentifier (SEQUENCE) */
	stream_seek(s, length);

	/* subjectPublicKeyInfo::subjectPublicKey */
	ber_read_bit_string(s, &length, &padding); /* BIT_STRING */

	/* RSAPublicKey (SEQUENCE) */
	ber_read_sequence_tag(s, &length); /* SEQUENCE */

	ber_read_integer_length(s, &modulus_length); /* modulus (INTEGER) */

	/* skip zero padding, if any */
	do
	{
		stream_peek_uint8(s, padding);

		if (padding == 0)
		{
			stream_seek(s, 1);
			modulus_length--;
		}
	}
	while (padding == 0);

	freerdp_blob_alloc(&info->modulus, modulus_length);
	stream_read(s, info->modulus.data, modulus_length);

	ber_read_integer_length(s, &exponent_length); /* publicExponent (INTEGER) */
	stream_read(s, &info->exponent[4 - exponent_length], exponent_length);
	crypto_reverse(info->modulus.data, modulus_length);
	crypto_reverse(info->exponent, 4);
}
Esempio n. 4
0
static void rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, boolean user_loggedon)
{
	STREAM* data_out;
	DEVICE* device;
	LIST_ITEM* item;
	uint32 count;
	uint8 c;
	int data_len;
	int i;
	int count_pos;
	int pos;

	data_out = stream_new(256);

	stream_write_uint16(data_out, RDPDR_CTYP_CORE);
	stream_write_uint16(data_out, PAKID_CORE_DEVICELIST_ANNOUNCE);

	count_pos = stream_get_pos(data_out);
	count = 0;
	stream_seek_uint32(data_out); /* deviceCount */

	for (item = rdpdr->devman->devices->head; item; item = item->next)
	{
		device = (DEVICE*)item->data;

		/**
		 * 1. versionMinor 0x0005 doesn't send PAKID_CORE_USER_LOGGEDON
		 *    so all devices should be sent regardless of user_loggedon
		 * 2. smartcard devices should be always sent
		 * 3. other devices are sent only after user_loggedon
		 */
		if (rdpdr->versionMinor == 0x0005 ||
			device->type == RDPDR_DTYP_SMARTCARD ||
			user_loggedon)
		{
			data_len = (device->data == NULL ? 0 : stream_get_length(device->data));
			stream_check_size(data_out, 20 + data_len);

			stream_write_uint32(data_out, device->type); /* deviceType */
			stream_write_uint32(data_out, device->id); /* deviceID */
			strncpy((char*)stream_get_tail(data_out), device->name, 8);

			for (i = 0; i < 8; i++)
			{
				stream_peek_uint8(data_out, c);
				if (c > 0x7F)
					stream_write_uint8(data_out, '_');
				else
					stream_seek_uint8(data_out);
			}

			stream_write_uint32(data_out, data_len);
			if (data_len > 0)
				stream_write(data_out, stream_get_data(device->data), data_len);

			count++;
			printf("registered device #%d: %s (type=%d id=%d)\n",
				count, device->name, device->type, device->id);
		}
	}

	pos = stream_get_pos(data_out);
	stream_set_pos(data_out, count_pos);
	stream_write_uint32(data_out, count);
	stream_set_pos(data_out, pos);
	stream_seal(data_out);

	svc_plugin_send((rdpSvcPlugin*)rdpdr, data_out);
}
Esempio n. 5
0
int transport_check_fds(rdpTransport* transport)
{
	int pos;
	int status;
	uint8 header;
	uint16 length;
	STREAM* received;

	status = transport_read_nonblocking(transport);
	if (status <= 0)
		return status;

	while ((pos = stream_get_pos(transport->recv_buffer)) > 0)
	{
		/* Ensure the TPKT or Fast Path header is available. */
		if (pos <= 4)
			return 0;

		stream_set_pos(transport->recv_buffer, 0);
		stream_peek_uint8(transport->recv_buffer, header);
		if (header == 0x03) /* TPKT */
			length = tpkt_read_header(transport->recv_buffer);
		else /* Fast Path */
			length = fastpath_read_header(transport->recv_buffer, NULL);

		if (length == 0)
		{
			printf("transport_check_fds: protocol error, not a TPKT header (%d).\n", header);
			return -1;
		}

		if (pos < length)
		{
			stream_set_pos(transport->recv_buffer, pos);
			return 0; /* Packet is not yet completely received. */
		}

		/*
		 * A complete packet has been received. In case there are trailing data
		 * for the next packet, we copy it to the new receive buffer.
		 */
		received = transport->recv_buffer;
		transport->recv_buffer = stream_new(BUFFER_SIZE);

		if (pos > length)
		{
			stream_set_pos(received, length);
			stream_check_size(transport->recv_buffer, pos - length);
			stream_copy(transport->recv_buffer, received, pos - length);
		}

		stream_set_pos(received, length);
		stream_seal(received);
		stream_set_pos(received, 0);
		status = transport->recv_callback(transport, received, transport->recv_extra);
		stream_free(received);

		if (status < 0)
			return status;
	}

	return 0;
}