Ejemplo n.º 1
0
int ber_write_integer(STREAM* s, uint32 value)
{
	ber_write_universal_tag(s, BER_TAG_INTEGER, false);

	if (value <= 0xFF)
	{
		ber_write_length(s, 1);
		stream_write_uint8(s, value);
		return 2;
	}
	else if (value <= 0xFFFF)
	{
		ber_write_length(s, 2);
		stream_write_uint16_be(s, value);
		return 3;
	}
	else if (value <= 0xFFFFFFFF)
	{
		ber_write_length(s, 4);
		stream_write_uint32_be(s, value);
		return 5;
	}

	return 0;
}
Ejemplo n.º 2
0
void rdp_write_header(rdpRdp* rdp, STREAM* s, uint16 length, uint16 channel_id)
{
    int body_length;
    enum DomainMCSPDU MCSPDU;

    MCSPDU = (rdp->settings->server_mode) ? DomainMCSPDU_SendDataIndication : DomainMCSPDU_SendDataRequest;

    if ((rdp->sec_flags & SEC_ENCRYPT) && (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS))
    {
        int pad;

        body_length = length - RDP_PACKET_HEADER_MAX_LENGTH - 16;
        pad = 8 - (body_length % 8);
        if (pad != 8)
            length += pad;
    }

    mcs_write_domain_mcspdu_header(s, MCSPDU, length, 0);
    per_write_integer16(s, rdp->mcs->user_id, MCS_BASE_CHANNEL_ID); /* initiator */
    per_write_integer16(s, channel_id, 0); /* channelId */
    stream_write_uint8(s, 0x70); /* dataPriority + segmentation */
    /*
     * We always encode length in two bytes, eventhough we could use
     * only one byte if length <= 0x7F. It is just easier that way,
     * because we can leave room for fixed-length header, store all
     * the data first and then store the header.
     */
    length = (length - RDP_PACKET_HEADER_MAX_LENGTH) | 0x8000;
    stream_write_uint16_be(s, length); /* userData (OCTET_STRING) */
}
Ejemplo n.º 3
0
void rdp_write_header(rdpRdp* rdp, STREAM* s, uint16 length, uint16 channel_id)
{
	enum DomainMCSPDU MCSPDU;
	int body_length;

	MCSPDU = (rdp->settings->server_mode) ? DomainMCSPDU_SendDataIndication : DomainMCSPDU_SendDataRequest;

	if (rdp->sec_flags & SEC_ENCRYPT && rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS)
	{
		int pad;

		body_length = length - RDP_PACKET_HEADER_LENGTH - 16;
		pad = 8 - (body_length % 8);
		if (pad != 8)
			length += pad;
	}

	mcs_write_domain_mcspdu_header(s, MCSPDU, length, 0);
	per_write_integer16(s, rdp->mcs->user_id, MCS_BASE_CHANNEL_ID); /* initiator */
	per_write_integer16(s, channel_id, 0); /* channelId */
	stream_write_uint8(s, 0x70); /* dataPriority + segmentation */

	length = (length - RDP_PACKET_HEADER_LENGTH) | 0x8000;
	stream_write_uint16_be(s, length); /* userData (OCTET_STRING) */
}
Ejemplo n.º 4
0
void rdp_write_header(rdpRdp* rdp, STREAM* s, int length)
{
	mcs_write_domain_mcspdu_header(s, DomainMCSPDU_SendDataRequest, length);
	per_write_integer16(s, rdp->mcs->user_id, MCS_BASE_CHANNEL_ID); /* initiator */
	per_write_integer16(s, MCS_GLOBAL_CHANNEL_ID, 0); /* channelId */
	stream_write_uint8(s, 0x70); /* dataPriority + segmentation */

	length = (length - RDP_PACKET_HEADER_LENGTH) | 0x8000;
	stream_write_uint16_be(s, length); /* userData (OCTET_STRING) */
}
Ejemplo n.º 5
0
int ber_write_length(STREAM* s, int length)
{
	if (length > 0x7F)
	{
		stream_write_uint8(s, 0x82);
		stream_write_uint16_be(s, length);
		return 3;
	}
	else
	{
		stream_write_uint8(s, length);
		return 1;
	}
}
Ejemplo n.º 6
0
int ber_write_integer(STREAM* s, uint32 value)
{
	ber_write_universal_tag(s, BER_TAG_INTEGER, false);

	if (value <= 0xFF)
	{
		ber_write_length(s, 1);
		stream_write_uint8(s, value);
		return 2;
	}
	else if (value < 0xFF80)
	{
		ber_write_length(s, 2);
		stream_write_uint16_be(s, value);
		return 3;
	}
	else if (value < 0xFF8000)
	{
		ber_write_length(s, 3);
		stream_write_uint8(s, (value >> 16));
		stream_write_uint16_be(s, (value & 0xFFFF));
		return 4;
	}
Ejemplo n.º 7
0
Archivo: der.c Proyecto: Cyclic/FreeRDP
int der_write_length(STREAM* s, int length)
{
	if (length > 0x7F && length <= 0xFF)
	{
		stream_write_uint8(s, 0x81);
		stream_write_uint8(s, length);
		return 2;
	}
	else if (length > 0xFF)
	{
		stream_write_uint8(s, 0x82);
		stream_write_uint16_be(s, length);
		return 3;
	}
	else
	{
		stream_write_uint8(s, length);
		return 1;
	}
}
Ejemplo n.º 8
0
/* receives a list of server supported formats and returns a list
   of client supported formats */
static void rdpsnd_process_message_formats(rdpsndPlugin* rdpsnd, STREAM* data_in)
{
	uint16 wNumberOfFormats;
	uint16 nFormat;
	uint16 wVersion;
	STREAM* data_out;
	rdpsndFormat* out_formats;
	uint16 n_out_formats;
	rdpsndFormat* format;
	uint8* format_mark;
	uint8* data_mark;
	int pos;

	rdpsnd_free_supported_formats(rdpsnd);

	stream_seek_uint32(data_in); /* dwFlags */
	stream_seek_uint32(data_in); /* dwVolume */
	stream_seek_uint32(data_in); /* dwPitch */
	stream_seek_uint16(data_in); /* wDGramPort */
	stream_read_uint16(data_in, wNumberOfFormats);
	stream_read_uint8(data_in, rdpsnd->cBlockNo); /* cLastBlockConfirmed */
	stream_read_uint16(data_in, wVersion);
	stream_seek_uint8(data_in); /* bPad */

	DEBUG_SVC("wNumberOfFormats %d wVersion %d", wNumberOfFormats, wVersion);
	if (wNumberOfFormats < 1)
	{
		DEBUG_WARN("wNumberOfFormats is 0");
		return;
	}

	out_formats = (rdpsndFormat*)xzalloc(wNumberOfFormats * sizeof(rdpsndFormat));
	n_out_formats = 0;

	data_out = stream_new(24);
	stream_write_uint8(data_out, SNDC_FORMATS); /* msgType */
	stream_write_uint8(data_out, 0); /* bPad */
	stream_seek_uint16(data_out); /* BodySize */
	stream_write_uint32(data_out, TSSNDCAPS_ALIVE | TSSNDCAPS_VOLUME); /* dwFlags */
	stream_write_uint32(data_out, 0xFFFFFFFF); /* dwVolume */
	stream_write_uint32(data_out, 0); /* dwPitch */
	stream_write_uint16_be(data_out, 0); /* wDGramPort */
	stream_seek_uint16(data_out); /* wNumberOfFormats */
	stream_write_uint8(data_out, 0); /* cLastBlockConfirmed */
	stream_write_uint16(data_out, 6); /* wVersion */
	stream_write_uint8(data_out, 0); /* bPad */

	for (nFormat = 0; nFormat < wNumberOfFormats; nFormat++)
	{
		stream_get_mark(data_in, format_mark);
		format = &out_formats[n_out_formats];
		stream_read_uint16(data_in, format->wFormatTag);
		stream_read_uint16(data_in, format->nChannels);
		stream_read_uint32(data_in, format->nSamplesPerSec);
		stream_seek_uint32(data_in); /* nAvgBytesPerSec */
		stream_read_uint16(data_in, format->nBlockAlign);
		stream_read_uint16(data_in, format->wBitsPerSample);
		stream_read_uint16(data_in, format->cbSize);
		stream_get_mark(data_in, data_mark);
		stream_seek(data_in, format->cbSize);
		format->data = NULL;

		DEBUG_SVC("wFormatTag=%d nChannels=%d nSamplesPerSec=%d nBlockAlign=%d wBitsPerSample=%d",
			format->wFormatTag, format->nChannels, format->nSamplesPerSec,
			format->nBlockAlign, format->wBitsPerSample);

		if (rdpsnd->fixed_format > 0 && rdpsnd->fixed_format != format->wFormatTag)
			continue;
		if (rdpsnd->fixed_channel > 0 && rdpsnd->fixed_channel != format->nChannels)
			continue;
		if (rdpsnd->fixed_rate > 0 && rdpsnd->fixed_rate != format->nSamplesPerSec)
			continue;
		if (rdpsnd->device && rdpsnd->device->FormatSupported(rdpsnd->device, format))
		{
			DEBUG_SVC("format supported.");

			stream_check_size(data_out, 18 + format->cbSize);
			stream_write(data_out, format_mark, 18 + format->cbSize);
			if (format->cbSize > 0)
			{
				format->data = xmalloc(format->cbSize);
				memcpy(format->data, data_mark, format->cbSize);
			}
			n_out_formats++;
		}
	}

	rdpsnd->n_supported_formats = n_out_formats;
	if (n_out_formats > 0)
	{
		rdpsnd->supported_formats = out_formats;
	}
	else
	{
		xfree(out_formats);
		DEBUG_WARN("no formats supported");
	}

	pos = stream_get_pos(data_out);
	stream_set_pos(data_out, 2);
	stream_write_uint16(data_out, pos - 4);
	stream_set_pos(data_out, 18);
	stream_write_uint16(data_out, n_out_formats);
	stream_set_pos(data_out, pos);

	svc_plugin_send((rdpSvcPlugin*)rdpsnd, data_out);

	if (wVersion >= 6)
	{
		data_out = stream_new(8);
		stream_write_uint8(data_out, SNDC_QUALITYMODE); /* msgType */
		stream_write_uint8(data_out, 0); /* bPad */
		stream_write_uint16(data_out, 4); /* BodySize */
		stream_write_uint16(data_out, HIGH_QUALITY); /* wQualityMode */
		stream_write_uint16(data_out, 0); /* Reserved */

		svc_plugin_send((rdpSvcPlugin*)rdpsnd, data_out);
	}
}
Ejemplo n.º 9
0
static boolean rdp_establish_keys(rdpRdp* rdp)
{
	uint8 client_random[32];
	uint8 crypt_client_random[256 + 8];
	uint32 key_len;
	uint8* mod;
	uint8* exp;
	uint32 length;
	STREAM* s;

	if (rdp->settings->encryption == False)
	{
		/* no RDP encryption */
		return True;
	}

	/* encrypt client random */
	memset(crypt_client_random, 0, sizeof(crypt_client_random));
	memset(client_random, 0x5e, 32);
	crypto_nonce(client_random, 32);
	key_len = rdp->settings->server_cert->cert_info.modulus.length;
	mod = rdp->settings->server_cert->cert_info.modulus.data;
	exp = rdp->settings->server_cert->cert_info.exponent;
	crypto_rsa_encrypt(client_random, 32, key_len, mod, exp, crypt_client_random);

	/* send crypt client random to server */
	length = 7 + 8 + 4 + 4 + key_len + 8;
	s = transport_send_stream_init(rdp->mcs->transport, length);
	tpkt_write_header(s, length);
	tpdu_write_header(s, 2, 0xf0);
	per_write_choice(s, DomainMCSPDU_SendDataRequest << 2);
	per_write_integer16(s, rdp->mcs->user_id, MCS_BASE_CHANNEL_ID);
	per_write_integer16(s, MCS_GLOBAL_CHANNEL_ID, 0);
	stream_write_uint8(s, 0x70);
	length = (4 + 4 + key_len + 8) | 0x8000;
	stream_write_uint16_be(s, length);
	stream_write_uint32(s, 1); /* SEC_CLIENT_RANDOM */
	length = key_len + 8;
	stream_write_uint32(s, length);
	memcpy(s->p, crypt_client_random, length);
	stream_seek(s, length);
	if (transport_write(rdp->mcs->transport, s) < 0)
	{
		return False;
	}

	/* now calculate encrypt / decrypt and update keys */
	if (!security_establish_keys(client_random, rdp))
	{
		return False;
	}

	rdp->do_crypt = True;

	if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS)
	{
		uint8 fips_ivec[8] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
		rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec);
		rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->fips_decrypt_key, fips_ivec);

		rdp->fips_hmac = crypto_hmac_new();
		return True;
	}

	rdp->rc4_decrypt_key = crypto_rc4_init(rdp->decrypt_key, rdp->rc4_key_len);
	rdp->rc4_encrypt_key = crypto_rc4_init(rdp->encrypt_key, rdp->rc4_key_len);

	return True;
}