예제 #1
0
파일: license.c 프로젝트: BUGgs/FreeRDP
wStream* license_send_stream_init(rdpLicense* license)
{
	wStream* s;
	BOOL do_crypt = license->rdp->do_crypt;

	license->rdp->sec_flags = SEC_LICENSE_PKT;

	/**
	 * Encryption of licensing packets is optional even if the rdp security
	 * layer is used. If the peer has not indicated that it is capable of
	 * processing encrypted licensing packets (rdp->do_crypt_license) we turn
	 * off encryption (via rdp->do_crypt) before initializing the rdp stream
	 * and reenable it afterwards.
	 */

	if (do_crypt)
	{
		license->rdp->sec_flags |= SEC_LICENSE_ENCRYPT_CS;
		license->rdp->do_crypt = license->rdp->do_crypt_license;
	}

	s = transport_send_stream_init(license->rdp->transport, 4096);
	if (!s)
		return NULL;
	rdp_init_stream(license->rdp, s);

	license->rdp->do_crypt = do_crypt;
	license->PacketHeaderLength = Stream_GetPosition(s);
	Stream_Seek(s, LICENSE_PREAMBLE_LENGTH);
	return s;
}
예제 #2
0
파일: rdp.c 프로젝트: mwu406/FreeRDP-1.0
STREAM* rdp_send_stream_init(rdpRdp* rdp)
{
	STREAM* s;
	s = transport_send_stream_init(rdp->transport, 2048);
	stream_seek(s, RDP_PACKET_HEADER_LENGTH);
	return s;
}
예제 #3
0
파일: rdp.c 프로젝트: JozLes77/FreeRDP
wStream* rdp_data_pdu_init(rdpRdp* rdp)
{
    wStream* s;
    s = transport_send_stream_init(rdp->transport, 2048);
    rdp_init_stream_data_pdu(rdp, s);
    return s;
}
예제 #4
0
파일: license.c 프로젝트: Cyclic/FreeRDP
STREAM* license_send_stream_init(rdpLicense* license)
{
	STREAM* s;
	s = transport_send_stream_init(license->rdp->transport, 4096);
	stream_seek(s, LICENSE_PACKET_HEADER_MAX_LENGTH);
	return s;
}
예제 #5
0
파일: rdp.c 프로젝트: JozLes77/FreeRDP
wStream* rdp_message_channel_pdu_init(rdpRdp* rdp)
{
    wStream* s;
    s = transport_send_stream_init(rdp->transport, 2048);
    Stream_Seek(s, RDP_PACKET_HEADER_MAX_LENGTH);
    rdp_security_stream_init(rdp, s);
    return s;
}
예제 #6
0
STREAM* rdp_pdu_init(rdpRdp* rdp)
{
	STREAM* s;
	s = transport_send_stream_init(rdp->transport, 2048);
	stream_seek(s, RDP_PACKET_HEADER_MAX_LENGTH);
	rdp_security_stream_init(rdp, s);
	stream_seek(s, RDP_SHARE_CONTROL_HEADER_LENGTH);
	return s;
}
예제 #7
0
파일: rdp.c 프로젝트: bradh/FreeRDP-1.0
STREAM* rdp_data_pdu_init(rdpRdp* rdp)
{
	STREAM* s;
	s = transport_send_stream_init(rdp->transport, 2048);
	stream_seek(s, RDP_PACKET_HEADER_LENGTH);
	stream_seek(s, RDP_SHARE_CONTROL_HEADER_LENGTH);
	stream_seek(s, RDP_SHARE_DATA_HEADER_LENGTH);
	return s;
}
예제 #8
0
파일: nego.c 프로젝트: effort/FreeRDP
BOOL nego_send_negotiation_request(rdpNego* nego)
{
	STREAM* s;
	int length;
	BYTE *bm, *em;
	int cookie_length;

	s = transport_send_stream_init(nego->transport, 256);
	length = TPDU_CONNECTION_REQUEST_LENGTH;
	stream_get_mark(s, bm);
	stream_seek(s, length);

	if (nego->RoutingToken != NULL)
	{
		stream_write(s, nego->RoutingToken, nego->RoutingTokenLength);
		length += nego->RoutingTokenLength;
	}
	else if (nego->cookie != NULL)
	{
		cookie_length = strlen(nego->cookie);

		if (cookie_length > (int) nego->cookie_max_length)
			cookie_length = nego->cookie_max_length;

		stream_write(s, "Cookie: mstshash=", 17);
		stream_write(s, (BYTE*) nego->cookie, cookie_length);
		stream_write_BYTE(s, 0x0D); /* CR */
		stream_write_BYTE(s, 0x0A); /* LF */
		length += cookie_length + 19;
	}

	DEBUG_NEGO("requested_protocols: %d", nego->requested_protocols);

	if (nego->requested_protocols > PROTOCOL_RDP)
	{
		/* RDP_NEG_DATA must be present for TLS and NLA */
		stream_write_BYTE(s, TYPE_RDP_NEG_REQ);
		stream_write_BYTE(s, 0); /* flags, must be set to zero */
		stream_write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */
		stream_write_UINT32(s, nego->requested_protocols); /* requestedProtocols */
		length += 8;
	}

	stream_get_mark(s, em);
	stream_set_mark(s, bm);
	tpkt_write_header(s, length);
	tpdu_write_connection_request(s, length - 5);
	stream_set_mark(s, em);

	if (transport_write(nego->transport, s) < 0)
		return FALSE;

	return TRUE;
}
예제 #9
0
파일: nego.c 프로젝트: cheetah0216/FreeRDP
boolean nego_send_negotiation_request(rdpNego* nego)
{
	STREAM* s;
	int length;
	uint8 *bm, *em;

	s = transport_send_stream_init(nego->transport, 256);
	length = TPDU_CONNECTION_REQUEST_LENGTH;
	stream_get_mark(s, bm);
	stream_seek(s, length);

	if (nego->routing_token != NULL)
	{
		stream_write(s, nego->routing_token->data, nego->routing_token->length);
		length += nego->routing_token->length;
	}
	else if (nego->cookie != NULL)
	{
		int cookie_length = strlen(nego->cookie);
		stream_write(s, "Cookie: mstshash=", 17);
		stream_write(s, (uint8*) nego->cookie, cookie_length);
		stream_write_uint8(s, 0x0D); /* CR */
		stream_write_uint8(s, 0x0A); /* LF */
		length += cookie_length + 19;
	}

	DEBUG_NEGO("requested_protocols: %d", nego->requested_protocols);

	if (nego->requested_protocols > PROTOCOL_RDP)
	{
		/* RDP_NEG_DATA must be present for TLS and NLA */
		stream_write_uint8(s, TYPE_RDP_NEG_REQ);
		stream_write_uint8(s, 0); /* flags, must be set to zero */
		stream_write_uint16(s, 8); /* RDP_NEG_DATA length (8) */
		stream_write_uint32(s, nego->requested_protocols); /* requestedProtocols */
		length += 8;
	}

	stream_get_mark(s, em);
	stream_set_mark(s, bm);
	tpkt_write_header(s, length);
	tpdu_write_connection_request(s, length - 5);
	stream_set_mark(s, em);

	if (transport_write(nego->transport, s) < 0)
		return false;

	return true;
}
예제 #10
0
파일: nego.c 프로젝트: rafcabezas/FreeRDP
boolean nego_send_preconnection_pdu(rdpNego* nego)
{
	STREAM* s;
	uint32 cbSize;
	UNICONV* uniconv;
	uint16 cchPCB_times2 = 0;
	char* wszPCB = NULL;

	if (!nego->send_preconnection_pdu)
		return true;

	DEBUG_NEGO("Sending preconnection PDU");

	if (!nego_tcp_connect(nego))
		return false;

	/* it's easier to always send the version 2 PDU, and it's just 2 bytes overhead */
	cbSize = PRECONNECTION_PDU_V2_MIN_SIZE;

	if (nego->preconnection_blob)
	{
		size_t size;
		uniconv = freerdp_uniconv_new();
		wszPCB = freerdp_uniconv_out(uniconv, nego->preconnection_blob, &size);
		cchPCB_times2 = (uint16) size;
		freerdp_uniconv_free(uniconv);
		cchPCB_times2 += 2; /* zero-termination */
		cbSize += cchPCB_times2;
	}

	s = transport_send_stream_init(nego->transport, cbSize);
	stream_write_uint32(s, cbSize); /* cbSize */
	stream_write_uint32(s, 0); /* Flags */
	stream_write_uint32(s, PRECONNECTION_PDU_V2); /* Version */
	stream_write_uint32(s, nego->preconnection_id); /* Id */
	stream_write_uint16(s, cchPCB_times2 / 2); /* cchPCB */

	if (wszPCB)
	{
		stream_write(s, wszPCB, cchPCB_times2); /* wszPCB */
		xfree(wszPCB);
	}

	if (transport_write(nego->transport, s) < 0)
		return false;

	return true;
}
예제 #11
0
파일: license.c 프로젝트: CTCAdmin/FreeRDP
wStream* license_send_stream_init(rdpLicense* license)
{
	wStream* s;

	license->rdp->sec_flags = SEC_LICENSE_PKT;
	if (license->rdp->do_crypt)
			license->rdp->sec_flags |= SEC_LICENSE_ENCRYPT_CS;

	s = transport_send_stream_init(license->rdp->transport, 4096);
	rdp_init_stream(license->rdp, s);

	license->PacketHeaderLength = Stream_GetPosition(s);
	Stream_Seek(s, LICENSE_PREAMBLE_LENGTH);

	return s;
}
예제 #12
0
파일: nego.c 프로젝트: effort/FreeRDP
BOOL nego_send_preconnection_pdu(rdpNego* nego)
{
	STREAM* s;
	UINT32 cbSize;
	UINT16 cchPCB = 0;
	WCHAR* wszPCB = NULL;

	if (!nego->send_preconnection_pdu)
		return TRUE;

	DEBUG_NEGO("Sending preconnection PDU");

	if (!nego_tcp_connect(nego))
		return FALSE;

	/* it's easier to always send the version 2 PDU, and it's just 2 bytes overhead */
	cbSize = PRECONNECTION_PDU_V2_MIN_SIZE;

	if (nego->preconnection_blob)
	{
		cchPCB = (UINT16) ConvertToUnicode(CP_UTF8, 0, nego->preconnection_blob, -1, &wszPCB, 0);
		cchPCB += 1; /* zero-termination */
		cbSize += cchPCB * 2;
	}

	s = transport_send_stream_init(nego->transport, cbSize);
	stream_write_UINT32(s, cbSize); /* cbSize */
	stream_write_UINT32(s, 0); /* Flags */
	stream_write_UINT32(s, PRECONNECTION_PDU_V2); /* Version */
	stream_write_UINT32(s, nego->preconnection_id); /* Id */
	stream_write_UINT16(s, cchPCB); /* cchPCB */

	if (wszPCB)
	{
		stream_write(s, wszPCB, cchPCB * 2); /* wszPCB */
		free(wszPCB);
	}

	if (transport_write(nego->transport, s) < 0)
		return FALSE;

	return TRUE;
}
예제 #13
0
파일: nego.c 프로젝트: ydal/FreeRDP
boolean nego_send_negotiation_response(rdpNego* nego)
{
    STREAM* s;
    int length;
    uint8 *bm, *em;

    s = transport_send_stream_init(nego->transport, 256);
    length = TPDU_CONNECTION_CONFIRM_LENGTH;
    stream_get_mark(s, bm);
    stream_seek(s, length);

    if (nego->selected_protocol > PROTOCOL_RDP)
    {
        /* RDP_NEG_DATA must be present for TLS and NLA */
        stream_write_uint8(s, TYPE_RDP_NEG_RSP);
        stream_write_uint8(s, EXTENDED_CLIENT_DATA_SUPPORTED); /* flags */
        stream_write_uint16(s, 8); /* RDP_NEG_DATA length (8) */
        stream_write_uint32(s, nego->selected_protocol); /* selectedProtocol */
        length += 8;
    }

    stream_get_mark(s, em);
    stream_set_mark(s, bm);
    tpkt_write_header(s, length);
    tpdu_write_connection_confirm(s, length - 5);
    stream_set_mark(s, em);

    if (transport_write(nego->transport, s) < 0)
        return false;

    /* update settings with negotiated protocol security */
    nego->transport->settings->requested_protocols = nego->requested_protocols;
    nego->transport->settings->selected_protocol = nego->selected_protocol;

    return true;
}
예제 #14
0
파일: nego.c 프로젝트: rafcabezas/FreeRDP
boolean nego_send_negotiation_response(rdpNego* nego)
{
	STREAM* s;
	uint8* bm;
	uint8* em;
	int length;
	boolean status;
	rdpSettings* settings;

	status = true;
	settings = nego->transport->settings;

	s = transport_send_stream_init(nego->transport, 256);
	length = TPDU_CONNECTION_CONFIRM_LENGTH;
	stream_get_mark(s, bm);
	stream_seek(s, length);

	if (nego->selected_protocol > PROTOCOL_RDP)
	{
		/* RDP_NEG_DATA must be present for TLS and NLA */
		stream_write_uint8(s, TYPE_RDP_NEG_RSP);
		stream_write_uint8(s, EXTENDED_CLIENT_DATA_SUPPORTED); /* flags */
		stream_write_uint16(s, 8); /* RDP_NEG_DATA length (8) */
		stream_write_uint32(s, nego->selected_protocol); /* selectedProtocol */
		length += 8;
	}
	else if (!settings->rdp_security)
	{
		stream_write_uint8(s, TYPE_RDP_NEG_FAILURE);
		stream_write_uint8(s, 0); /* flags */
		stream_write_uint16(s, 8); /* RDP_NEG_DATA length (8) */
		/*
		 * TODO: Check for other possibilities,
		 *       like SSL_NOT_ALLOWED_BY_SERVER.
		 */
		printf("nego_send_negotiation_response: client supports only Standard RDP Security\n");
		stream_write_uint32(s, SSL_REQUIRED_BY_SERVER);
		length += 8;
		status = false;
	}

	stream_get_mark(s, em);
	stream_set_mark(s, bm);
	tpkt_write_header(s, length);
	tpdu_write_connection_confirm(s, length - 5);
	stream_set_mark(s, em);

	if (transport_write(nego->transport, s) < 0)
		return false;

	if (status)
	{
		/* update settings with negotiated protocol security */
		settings->requested_protocols = nego->requested_protocols;
		settings->selected_protocol = nego->selected_protocol;

		if (settings->selected_protocol == PROTOCOL_RDP)
		{
			settings->tls_security = false;
			settings->nla_security = false;
			settings->rdp_security = true;

			if (!settings->local)
			{
				settings->encryption = true;
				settings->encryption_method = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS;
				settings->encryption_level = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE;
			}

			if (settings->encryption && settings->server_key == NULL && settings->rdp_key_file == NULL)
				return false;
		}
		else if (settings->selected_protocol == PROTOCOL_TLS)
		{
			settings->tls_security = true;
			settings->nla_security = false;
			settings->rdp_security = false;
			settings->encryption = false;
			settings->encryption_method = ENCRYPTION_METHOD_NONE;
			settings->encryption_level = ENCRYPTION_LEVEL_NONE;
		}
		else if (settings->selected_protocol == PROTOCOL_NLA)
		{
			settings->tls_security = true;
			settings->nla_security = true;
			settings->rdp_security = false;
			settings->encryption = false;
			settings->encryption_method = ENCRYPTION_METHOD_NONE;
			settings->encryption_level = ENCRYPTION_LEVEL_NONE;
		}
	}

	return status;
}
예제 #15
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;
}
예제 #16
0
파일: nego.c 프로젝트: effort/FreeRDP
BOOL nego_send_negotiation_response(rdpNego* nego)
{
	STREAM* s;
	BYTE* bm;
	BYTE* em;
	int length;
	BOOL status;
	rdpSettings* settings;

	status = TRUE;
	settings = nego->transport->settings;

	s = transport_send_stream_init(nego->transport, 256);
	length = TPDU_CONNECTION_CONFIRM_LENGTH;
	stream_get_mark(s, bm);
	stream_seek(s, length);

	if (nego->selected_protocol > PROTOCOL_RDP)
	{
		/* RDP_NEG_DATA must be present for TLS and NLA */
		stream_write_BYTE(s, TYPE_RDP_NEG_RSP);
		stream_write_BYTE(s, EXTENDED_CLIENT_DATA_SUPPORTED); /* flags */
		stream_write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */
		stream_write_UINT32(s, nego->selected_protocol); /* selectedProtocol */
		length += 8;
	}
	else if (!settings->RdpSecurity)
	{
		stream_write_BYTE(s, TYPE_RDP_NEG_FAILURE);
		stream_write_BYTE(s, 0); /* flags */
		stream_write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */
		/*
		 * TODO: Check for other possibilities,
		 *       like SSL_NOT_ALLOWED_BY_SERVER.
		 */
		printf("nego_send_negotiation_response: client supports only Standard RDP Security\n");
		stream_write_UINT32(s, SSL_REQUIRED_BY_SERVER);
		length += 8;
		status = FALSE;
	}

	stream_get_mark(s, em);
	stream_set_mark(s, bm);
	tpkt_write_header(s, length);
	tpdu_write_connection_confirm(s, length - 5);
	stream_set_mark(s, em);

	if (transport_write(nego->transport, s) < 0)
		return FALSE;

	if (status)
	{
		/* update settings with negotiated protocol security */
		settings->RequestedProtocols = nego->requested_protocols;
		settings->SelectedProtocol = nego->selected_protocol;

		if (settings->SelectedProtocol == PROTOCOL_RDP)
		{
			settings->TlsSecurity = FALSE;
			settings->NlaSecurity = FALSE;
			settings->RdpSecurity = TRUE;

			if (!settings->LocalConnection)
			{
				settings->DisableEncryption = TRUE;
				settings->EncryptionMethods = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS;
				settings->EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE;
			}

			if (settings->DisableEncryption && settings->RdpServerRsaKey == NULL && settings->RdpKeyFile == NULL)
				return FALSE;
		}
		else if (settings->SelectedProtocol == PROTOCOL_TLS)
		{
			settings->TlsSecurity = TRUE;
			settings->NlaSecurity = FALSE;
			settings->RdpSecurity = FALSE;
			settings->DisableEncryption = FALSE;
			settings->EncryptionMethods = ENCRYPTION_METHOD_NONE;
			settings->EncryptionLevel = ENCRYPTION_LEVEL_NONE;
		}
		else if (settings->SelectedProtocol == PROTOCOL_NLA)
		{
			settings->TlsSecurity = TRUE;
			settings->NlaSecurity = TRUE;
			settings->RdpSecurity = FALSE;
			settings->DisableEncryption = FALSE;
			settings->EncryptionMethods = ENCRYPTION_METHOD_NONE;
			settings->EncryptionLevel = ENCRYPTION_LEVEL_NONE;
		}
	}

	return status;
}
예제 #17
0
static boolean rdp_client_establish_keys(rdpRdp* rdp)
{
	uint8 client_random[CLIENT_RANDOM_LENGTH];
	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));
	crypto_nonce(client_random, sizeof(client_random));
	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_public_encrypt(client_random, sizeof(client_random), key_len, mod, exp, crypt_client_random);

	/* send crypt client random to server */
	length = RDP_PACKET_HEADER_MAX_LENGTH + RDP_SECURITY_HEADER_LENGTH + 4 + key_len + 8;
	s = transport_send_stream_init(rdp->mcs->transport, length);
	rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID);
	rdp_write_security_header(s, SEC_EXCHANGE_PKT);
	length = key_len + 8;
	stream_write_uint32(s, length);
	stream_write(s, crypt_client_random, 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->salted_checksum)
		rdp->do_secure_checksum = 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;
}