Beispiel #1
0
void credssp_read_ts_credentials(rdpCredssp* credssp, PSecBuffer ts_credentials)
{
    wStream* s;
    int length;
    int ts_password_creds_length;

    s = stream_new(0);
    stream_attach(s, ts_credentials->pvBuffer, ts_credentials->cbBuffer);

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

    /* [0] credType (INTEGER) */
    ber_read_contextual_tag(s, 0, &length, TRUE);
    ber_read_integer(s, NULL);

    /* [1] credentials (OCTET STRING) */
    ber_read_contextual_tag(s, 1, &length, TRUE);
    ber_read_octet_string_tag(s, &ts_password_creds_length);

    credssp_read_ts_password_creds(credssp, s);

    stream_detach(s);
    stream_free(s);
}
Beispiel #2
0
int rts_recv_pdu(rdpRpc* rpc, RTS_PDU* rts_pdu)
{
	STREAM* s;
	int status;
	int length;
	BYTE header_buffer[20];
	rdpTls* tls_out = rpc->tls_out;

	/* read first 20 bytes to get RTS PDU Header */
	status = tls_read(tls_out, (BYTE*) &header_buffer, 20);

	if (status <= 0)
	{
		printf("rts_recv error\n");
		return status;
	}

	s = stream_new(0);
	stream_attach(s, header_buffer, 20);

	rts_pdu_header_read(s, &(rts_pdu->header));

	stream_detach(s);
	stream_free(s);

	length = rts_pdu->header.frag_length - 20;
	rts_pdu->content = (BYTE*) malloc(length);

	status = tls_read(tls_out, rts_pdu->content, length);

	if (status < 0)
	{
		printf("rts_recv error\n");
		return status;
	}

	if (rts_pdu->header.ptype != PTYPE_RTS)
	{
		printf("rts_recv error: unexpected ptype:%d\n", rts_pdu->header.ptype);
		return -1;
	}

#ifdef WITH_DEBUG_RTS
	printf("rts_recv(): length: %d\n", length);
	freerdp_hexdump(rts_pdu->content, length);
	printf("\n");
#endif

	rts_recv_pdu_commands(rpc, rts_pdu);

	return rts_pdu->header.frag_length;
}
Beispiel #3
0
static void xf_cliprdr_process_dib(clipboardContext* cb, uint8* data, int size)
{
	STREAM* s;
	uint16 bpp;
	uint32 offset;
	uint32 ncolors;

	/* size should be at least sizeof(BITMAPINFOHEADER) */
	if (size < 40)
	{
		DEBUG_X11("dib size %d too short", size);
		return;
	}

	s = stream_new(0);
	stream_attach(s, data, size);
	stream_seek(s, 14);
	stream_read_uint16(s, bpp);
	stream_read_uint32(s, ncolors);
	offset = 14 + 40 + (bpp <= 8 ? (ncolors == 0 ? (1 << bpp) : ncolors) * 4 : 0);
	stream_detach(s);
	stream_free(s);

	DEBUG_X11("offset=%d bpp=%d ncolors=%d",
		offset, bpp, ncolors);

	s = stream_new(14 + size);
	stream_write_uint8(s, 'B');
	stream_write_uint8(s, 'M');
	stream_write_uint32(s, 14 + size);
	stream_write_uint32(s, 0);
	stream_write_uint32(s, offset);
	stream_write(s, data, size);

	cb->data = stream_get_head(s);
	cb->data_length = stream_get_length(s);
	stream_detach(s);
	stream_free(s);
}
Beispiel #4
0
void credssp_encode_ts_credentials(rdpCredssp* credssp)
{
	STREAM* s;
	int length;

	s = stream_new(0);
	length = credssp_skip_ts_credentials(credssp);
	sspi_SecBufferAlloc(&credssp->ts_credentials, length);
	stream_attach(s, credssp->ts_credentials.pvBuffer, length);

	credssp_write_ts_credentials(credssp, s);
	stream_detach(s);
	stream_free(s);
}
Beispiel #5
0
static
int alsa_seqmidi_detach(alsa_midi_t *m)
{
	alsa_seqmidi_t *self = (alsa_seqmidi_t*) m;

	debug_log("midi: detach");

	if (!self->seq)
		return -EALREADY;

	alsa_seqmidi_stop(m);

	jack_ringbuffer_reset(self->port_add);
	free_ports(self, self->port_del);

	stream_detach(self, PORT_INPUT);
	stream_detach(self, PORT_OUTPUT);

	snd_seq_close(self->seq);
	self->seq = NULL;

	return 0;
}
Beispiel #6
0
void credssp_encode_ts_credentials(rdpCredssp* credssp)
{
	STREAM* s;
	int length;

	s = stream_new(0);
	length = credssp_skip_ts_credentials(credssp);
	freerdp_blob_alloc(&credssp->ts_credentials, length);
	stream_attach(s, credssp->ts_credentials.data, length);

	credssp_write_ts_credentials(credssp, s);
	stream_detach(s);
	stream_free(s);
}
Beispiel #7
0
int rpc_recv_bind_ack_pdu(rdpRpc* rpc)
{
    BYTE* p;
    STREAM* s;
    int status;
    BYTE* pdu;
    BYTE* auth_data;
    RPC_PDU_HEADER header;
    int pdu_length = 0x8FFF;

    pdu = malloc(pdu_length);

    if (pdu == NULL)
        return -1;

    status = rpc_out_read(rpc, pdu, pdu_length);

    if (status > 0)
    {
        s = stream_new(0);
        stream_attach(s, pdu, pdu_length);
        rpc_pdu_header_read(s, &header);
        stream_detach(s);
        stream_free(s);

        auth_data = malloc(header.auth_length);

        if (auth_data == NULL)
        {
            free(pdu);
            return -1;
        }

        p = (pdu + (header.frag_length - header.auth_length));
        memcpy(auth_data, p, header.auth_length);

        rpc->ntlm->inputBuffer.pvBuffer = auth_data;
        rpc->ntlm->inputBuffer.cbBuffer = header.auth_length;

        ntlm_authenticate(rpc->ntlm);
    }

    free(pdu);
    return status;
}
Beispiel #8
0
boolean WTSVirtualChannelWrite(
	/* __in */  void* hChannelHandle,
	/* __in */  uint8* Buffer,
	/* __in */  uint32 Length,
	/* __out */ uint32* pBytesWritten)
{
	rdpPeerChannel* channel = (rdpPeerChannel*) hChannelHandle;
	wts_data_item* item;
	STREAM* s;
	int cbLen;
	int cbChId;
	int first;
	uint32 written;

	if (channel == NULL)
		return false;

	if (channel->channel_type == RDP_PEER_CHANNEL_TYPE_SVC)
	{
		item = xnew(wts_data_item);
		item->buffer = xmalloc(Length);
		item->length = Length;
		memcpy(item->buffer, Buffer, Length);

		wts_queue_send_item(channel, item);
	}
	else if (channel->vcm->drdynvc_channel == NULL || channel->vcm->drdynvc_state != DRDYNVC_STATE_READY)
	{
		DEBUG_DVC("drdynvc not ready");
		return false;
	}
	else
	{
		s = stream_new(0);
		first = true;

		while (Length > 0)
		{
			item = xnew(wts_data_item);
			item->buffer = xmalloc(channel->client->settings->vc_chunk_size);
			stream_attach(s, item->buffer, channel->client->settings->vc_chunk_size);

			stream_seek_uint8(s);
			cbChId = wts_write_variable_uint(s, channel->channel_id);
			if (first && (Length > (uint32) stream_get_left(s)))
			{
				cbLen = wts_write_variable_uint(s, Length);
				item->buffer[0] = (DATA_FIRST_PDU << 4) | (cbLen << 2) | cbChId;
			}
			else
			{
				item->buffer[0] = (DATA_PDU << 4) | cbChId;
			}
			first = false;
			written = stream_get_left(s);
			if (written > Length)
				written = Length;
			stream_write(s, Buffer, written);
			item->length = stream_get_length(s);
			stream_detach(s);
			Length -= written;
			Buffer += written;

			wts_queue_send_item(channel->vcm->drdynvc_channel, item);
		}

		stream_free(s);
	}

	if (pBytesWritten != NULL)
		*pBytesWritten = Length;
	return true;
}
Beispiel #9
0
int rpc_out_read(rdpRpc* rpc, uint8* data, int length)
{
	STREAM* s;
	int status;
	uint8* pdu;
	int content_length;
	RPC_PDU_HEADER header;

	if (rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow < 0x00008FFF) /* Just a simple workaround */
		rts_send_flow_control_ack_pdu(rpc);  /* Send FlowControlAck every time AvailableWindow reaches the half */

	pdu = xmalloc(0xFFFF);
	if (pdu == NULL)
	{
		printf("rpc_out_read error: memory allocation failed") ;
		return -1 ;
	}

	status = tls_read(rpc->tls_out, pdu, 16); /* read first 16 bytes to get RPC PDU Header */

	if (status <= 0)
	{
		xfree(pdu);
		return status;
	}

	s = stream_new(0);
	stream_attach(s, pdu, 16);

	rpc_pdu_header_read(s, &header);

	stream_detach(s);
	stream_free(s);

	content_length = header.frag_length - 16;
	status = tls_read(rpc->tls_out, pdu + 16, content_length);

	if (status < 0)
	{
		xfree(pdu);
		return status;
	}

	if (header.ptype == PTYPE_RTS) /* RTS PDU */
	{
		printf("rpc_out_read error: Unexpected RTS PDU\n");
		xfree(pdu);
		return -1;
	}
	else
	{
		/* RTS PDUs are not subject to flow control */
		rpc->VirtualConnection->DefaultOutChannel->BytesReceived += header.frag_length;
		rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow -= header.frag_length;
	}

	if (length < header.frag_length)
	{
		printf("rpc_out_read error! receive buffer is not large enough\n");
		xfree(pdu);
		return -1;
	}

	memcpy(data, pdu, header.frag_length);

#ifdef WITH_DEBUG_RPC
	printf("rpc_out_read(): length: %d\n", header.frag_length);
	freerdp_hexdump(data, header.frag_length);
	printf("\n");
#endif

	xfree(pdu);
	return header.frag_length;
}
Beispiel #10
0
static int tsmf_on_data_received(IWTSVirtualChannelCallback* pChannelCallback,
	uint32 cbSize,
	uint8* pBuffer)
{
	int length;
	STREAM* input;
	STREAM* output;
	int error = -1;
	TSMF_IFMAN ifman;
	uint32 MessageId;
	uint32 FunctionId;
	uint32 InterfaceId;
	TSMF_CHANNEL_CALLBACK* callback = (TSMF_CHANNEL_CALLBACK*) pChannelCallback;

	/* 2.2.1 Shared Message Header (SHARED_MSG_HEADER) */
	if (cbSize < 12)
	{
		DEBUG_WARN("invalid size. cbSize=%d", cbSize);
		return 1;
	}
	input = stream_new(0);
	stream_attach(input, (uint8*) pBuffer, cbSize);
	output = stream_new(256);
	stream_seek(output, 8);

	stream_read_uint32(input, InterfaceId);
	stream_read_uint32(input, MessageId);
	stream_read_uint32(input, FunctionId);
	DEBUG_DVC("cbSize=%d InterfaceId=0x%X MessageId=0x%X FunctionId=0x%X",
		cbSize, InterfaceId, MessageId, FunctionId);

	memset(&ifman, 0, sizeof(TSMF_IFMAN));
	ifman.channel_callback = pChannelCallback;
	ifman.decoder_name = ((TSMF_PLUGIN*) callback->plugin)->decoder_name;
	ifman.audio_name = ((TSMF_PLUGIN*) callback->plugin)->audio_name;
	ifman.audio_device = ((TSMF_PLUGIN*) callback->plugin)->audio_device;
	memcpy(ifman.presentation_id, callback->presentation_id, 16);
	ifman.stream_id = callback->stream_id;
	ifman.message_id = MessageId;
	ifman.input = input;
	ifman.input_size = cbSize - 12;
	ifman.output = output;
	ifman.output_pending = false;
	ifman.output_interface_id = InterfaceId;

	switch (InterfaceId)
	{
		case TSMF_INTERFACE_CAPABILITIES | STREAM_ID_NONE:

			switch (FunctionId)
			{
				case RIM_EXCHANGE_CAPABILITY_REQUEST:
					error = tsmf_ifman_rim_exchange_capability_request(&ifman);
					break;

				default:
					break;
			}
			break;

		case TSMF_INTERFACE_DEFAULT | STREAM_ID_PROXY:

			switch (FunctionId)
			{
				case SET_CHANNEL_PARAMS:
					memcpy(callback->presentation_id, stream_get_tail(input), 16);
					stream_seek(input, 16);
					stream_read_uint32(input, callback->stream_id);
					DEBUG_DVC("SET_CHANNEL_PARAMS StreamId=%d", callback->stream_id);
					ifman.output_pending = true;
					error = 0;
					break;

				case EXCHANGE_CAPABILITIES_REQ:
					error = tsmf_ifman_exchange_capability_request(&ifman);
					break;

				case CHECK_FORMAT_SUPPORT_REQ:
					error = tsmf_ifman_check_format_support_request(&ifman);
					break;

				case ON_NEW_PRESENTATION:
					error = tsmf_ifman_on_new_presentation(&ifman);
					break;

				case ADD_STREAM:
					error = tsmf_ifman_add_stream(&ifman);
					break;

				case SET_TOPOLOGY_REQ:
					error = tsmf_ifman_set_topology_request(&ifman);
					break;

				case REMOVE_STREAM:
					error = tsmf_ifman_remove_stream(&ifman);
					break;

				case SHUTDOWN_PRESENTATION_REQ:
					error = tsmf_ifman_shutdown_presentation(&ifman);
					break;

				case ON_STREAM_VOLUME:
					error = tsmf_ifman_on_stream_volume(&ifman);
					break;

				case ON_CHANNEL_VOLUME:
					error = tsmf_ifman_on_channel_volume(&ifman);
					break;

				case SET_VIDEO_WINDOW:
					error = tsmf_ifman_set_video_window(&ifman);
					break;

				case UPDATE_GEOMETRY_INFO:
					error = tsmf_ifman_update_geometry_info(&ifman);
					break;

				case SET_ALLOCATOR:
					error = tsmf_ifman_set_allocator(&ifman);
					break;

				case NOTIFY_PREROLL:
					error = tsmf_ifman_notify_preroll(&ifman);
					break;

				case ON_SAMPLE:
					error = tsmf_ifman_on_sample(&ifman);
					break;

				case ON_FLUSH:
					error = tsmf_ifman_on_flush(&ifman);
					break;

				case ON_END_OF_STREAM:
					error = tsmf_ifman_on_end_of_stream(&ifman);
					break;

				case ON_PLAYBACK_STARTED:
					error = tsmf_ifman_on_playback_started(&ifman);
					break;

				case ON_PLAYBACK_PAUSED:
					error = tsmf_ifman_on_playback_paused(&ifman);
					break;

				case ON_PLAYBACK_RESTARTED:
					error = tsmf_ifman_on_playback_restarted(&ifman);
					break;

				case ON_PLAYBACK_STOPPED:
					error = tsmf_ifman_on_playback_stopped(&ifman);
					break;

				case ON_PLAYBACK_RATE_CHANGED:
					error = tsmf_ifman_on_playback_rate_changed(&ifman);
					break;

				default:
					break;
			}
			break;

		default:
			break;
	}

	stream_detach(input);
	stream_free(input);
	input = NULL;
	ifman.input = NULL;

	if (error == -1)
	{
		switch (FunctionId)
		{
			case RIMCALL_RELEASE:
				/* [MS-RDPEXPS] 2.2.2.2 Interface Release (IFACE_RELEASE)
				   This message does not require a reply. */
				error = 0;
				ifman.output_pending = 1;
				break;

			case RIMCALL_QUERYINTERFACE:
				/* [MS-RDPEXPS] 2.2.2.1.2 Query Interface Response (QI_RSP)
				   This message is not supported in this channel. */
				error = 0;
				break;
		}

		if (error == -1)
		{
			DEBUG_WARN("InterfaceId 0x%X FunctionId 0x%X not processed.",
				InterfaceId, FunctionId);
			/* When a request is not implemented we return empty response indicating error */
		}
		error = 0;
	}

	if (error == 0 && !ifman.output_pending)
	{
		/* Response packet does not have FunctionId */
		length = stream_get_length(output);
		stream_set_pos(output, 0);
		stream_write_uint32(output, ifman.output_interface_id);
		stream_write_uint32(output, MessageId);

		DEBUG_DVC("response size %d", length);
		error = callback->channel->Write(callback->channel, length, stream_get_head(output), NULL);
		if (error)
		{
			DEBUG_WARN("response error %d", error);
		}
	}

	stream_free(output);

	return error;
}
Beispiel #11
0
BOOL certificate_read_x509_certificate(rdpCertBlob* cert, rdpCertInfo* info)
{
	wStream* s;
	int length;
	BYTE padding;
	UINT32 version;
	int modulus_length;
	int exponent_length;
	int error = 0;

	s = stream_new(0);
	stream_attach(s, cert->data, cert->length);
	info->Modulus = 0;

	if(!ber_read_sequence_tag(s, &length)) /* Certificate (SEQUENCE) */
		goto error1;
	error++;

	if(!ber_read_sequence_tag(s, &length)) /* TBSCertificate (SEQUENCE) */
		goto error1;
	error++;

	if(!ber_read_contextual_tag(s, 0, &length, TRUE))	/* Explicit Contextual Tag [0] */
		goto error1;
	error++;
	if(!ber_read_integer(s, &version)) /* version (INTEGER) */
		goto error1;
	error++;
	version++;

	/* serialNumber */
	if(!ber_read_integer(s, NULL)) /* CertificateSerialNumber (INTEGER) */
		goto error1;
	error++;

	/* signature */
	if(!ber_read_sequence_tag(s, &length) || !stream_skip(s, length)) /* AlgorithmIdentifier (SEQUENCE) */
		goto error1;
	error++;

	/* issuer */
	if(!ber_read_sequence_tag(s, &length) || !stream_skip(s, length)) /* Name (SEQUENCE) */
		goto error1;
	error++;

	/* validity */
	if(!ber_read_sequence_tag(s, &length) || !stream_skip(s, length)) /* Validity (SEQUENCE) */
		goto error1;
	error++;

	/* subject */
	if(!ber_read_sequence_tag(s, &length) || !stream_skip(s, length)) /* Name (SEQUENCE) */
		goto error1;
	error++;

	/* subjectPublicKeyInfo */
	if(!ber_read_sequence_tag(s, &length)) /* SubjectPublicKeyInfo (SEQUENCE) */
		goto error1;
	error++;

	/* subjectPublicKeyInfo::AlgorithmIdentifier */
	if(!ber_read_sequence_tag(s, &length) || !stream_skip(s, length)) /* AlgorithmIdentifier (SEQUENCE) */
		goto error1;
	error++;

	/* subjectPublicKeyInfo::subjectPublicKey */
	if(!ber_read_bit_string(s, &length, &padding)) /* BIT_STRING */
		goto error1;
	error++;

	/* RSAPublicKey (SEQUENCE) */
	if(!ber_read_sequence_tag(s, &length)) /* SEQUENCE */
		goto error1;
	error++;

	if(!ber_read_integer_length(s, &modulus_length)) /* modulus (INTEGER) */
		goto error1;
	error++;

	/* skip zero padding, if any */
	do
	{
		if(stream_get_left(s) < 1)
			goto error1;
		stream_peek_BYTE(s, padding);

		if (padding == 0)
		{
			if(!stream_skip(s, 1))
				goto error1;
			modulus_length--;
		}
	}
	while (padding == 0);
	error++;

	if(stream_get_left(s) < modulus_length)
		goto error1;
	info->ModulusLength = modulus_length;
	info->Modulus = (BYTE*) malloc(info->ModulusLength);
	stream_read(s, info->Modulus, info->ModulusLength);
	error++;

	if(!ber_read_integer_length(s, &exponent_length)) /* publicExponent (INTEGER) */
		goto error2;
	error++;
	if(stream_get_left(s) < exponent_length || exponent_length > 4)
		goto error2;
	stream_read(s, &info->exponent[4 - exponent_length], exponent_length);
	crypto_reverse(info->Modulus, info->ModulusLength);
	crypto_reverse(info->exponent, 4);

	stream_detach(s);
	stream_free(s);
	return TRUE;

error2:
	free(info->Modulus);
	info->Modulus = 0;
error1:
	fprintf(stderr, "error reading when reading certificate: part=%s error=%d\n", certificate_read_errors[error], error);
	stream_detach(s);
	stream_free(s);
	return FALSE;
}
Beispiel #12
0
tbool rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s)
{
	uint8 type;
	uint16 length;
	uint32 share_id;
	uint8 compressed_type;
	uint16 compressed_len;
	uint32 roff;
	uint32 rlen;
	STREAM* comp_stream;

	rdp_read_share_data_header(s, &length, &type, &share_id, &compressed_type, &compressed_len);

	comp_stream = s;

	if (compressed_type & PACKET_COMPRESSED)
	{
		if (decompress_rdp(rdp, s->p, compressed_len - 18, compressed_type, &roff, &rlen))
		{
			comp_stream = stream_new(0);
			comp_stream->data = rdp->mppc->history_buf + roff;
			comp_stream->p = comp_stream->data;
			comp_stream->size = rlen;
		}
		else
		{
			printf("decompress_rdp() failed\n");
			return false;
		}
	}

#ifdef WITH_DEBUG_RDP
	if (type != DATA_PDU_TYPE_UPDATE)
		printf("recv %s Data PDU (0x%02X), length:%d\n", DATA_PDU_TYPE_STRINGS[type], type, length);
#endif

	switch (type)
	{
		case DATA_PDU_TYPE_UPDATE:
			update_recv(rdp->update, comp_stream);
			break;

		case DATA_PDU_TYPE_CONTROL:
			rdp_recv_server_control_pdu(rdp, comp_stream);
			break;

		case DATA_PDU_TYPE_POINTER:
			update_recv_pointer(rdp->update, comp_stream);
			break;

		case DATA_PDU_TYPE_INPUT:
			break;

		case DATA_PDU_TYPE_SYNCHRONIZE:
			rdp_recv_synchronize_pdu(rdp, comp_stream);
			break;

		case DATA_PDU_TYPE_REFRESH_RECT:
			break;

		case DATA_PDU_TYPE_PLAY_SOUND:
			update_recv_play_sound(rdp->update, comp_stream);
			break;

		case DATA_PDU_TYPE_SUPPRESS_OUTPUT:
			break;

		case DATA_PDU_TYPE_SHUTDOWN_REQUEST:
			break;

		case DATA_PDU_TYPE_SHUTDOWN_DENIED:
			break;

		case DATA_PDU_TYPE_SAVE_SESSION_INFO:
			rdp_recv_save_session_info(rdp, comp_stream);
			break;

		case DATA_PDU_TYPE_FONT_LIST:
			break;

		case DATA_PDU_TYPE_FONT_MAP:
			rdp_recv_font_map_pdu(rdp, comp_stream);
			break;

		case DATA_PDU_TYPE_SET_KEYBOARD_INDICATORS:
			break;

		case DATA_PDU_TYPE_BITMAP_CACHE_PERSISTENT_LIST:
			break;

		case DATA_PDU_TYPE_BITMAP_CACHE_ERROR:
			break;

		case DATA_PDU_TYPE_SET_KEYBOARD_IME_STATUS:
			break;

		case DATA_PDU_TYPE_OFFSCREEN_CACHE_ERROR:
			break;

		case DATA_PDU_TYPE_SET_ERROR_INFO:
			rdp_recv_set_error_info_data_pdu(rdp, comp_stream);
			break;

		case DATA_PDU_TYPE_DRAW_NINEGRID_ERROR:
			break;

		case DATA_PDU_TYPE_DRAW_GDIPLUS_ERROR:
			break;

		case DATA_PDU_TYPE_ARC_STATUS:
			break;

		case DATA_PDU_TYPE_STATUS_INFO:
			break;

		case DATA_PDU_TYPE_MONITOR_LAYOUT:
			break;

		default:
			break;
	}

	if (comp_stream != s)
	{
		stream_detach(comp_stream);
		stream_free(comp_stream);
	}

	return true;
}
Beispiel #13
0
RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, uint8* data, uint32 length)
{
	int pos;
	STREAM* s;
	uint32 blockLen;
	uint32 blockType;
	RFX_MESSAGE* message;

	s = stream_new(0);
	message = xnew(RFX_MESSAGE);
	stream_attach(s, data, length);

	while (stream_get_left(s) > 6)
	{
		/* RFX_BLOCKT */
		stream_read_uint16(s, blockType); /* blockType (2 bytes) */
		stream_read_uint32(s, blockLen); /* blockLen (4 bytes) */

		DEBUG_RFX("blockType 0x%X blockLen %d", blockType, blockLen);

		if (blockLen == 0)
		{
			DEBUG_WARN("zero blockLen");
			break;
		}

		pos = stream_get_pos(s) - 6 + blockLen;

		if (blockType >= WBT_CONTEXT && blockType <= WBT_EXTENSION)
		{
			/* RFX_CODEC_CHANNELT */
			/* codecId (1 byte) must be set to 0x01 */
			/* channelId (1 byte) must be set to 0x00 */
			stream_seek(s, 2);
		}

		switch (blockType)
		{
			case WBT_SYNC:
				rfx_process_message_sync(context, s);
				break;

			case WBT_CODEC_VERSIONS:
				rfx_process_message_codec_versions(context, s);
				break;

			case WBT_CHANNELS:
				rfx_process_message_channels(context, s);
				break;

			case WBT_CONTEXT:
				rfx_process_message_context(context, s);
				break;

			case WBT_FRAME_BEGIN:
				rfx_process_message_frame_begin(context, message, s);
				break;

			case WBT_FRAME_END:
				rfx_process_message_frame_end(context, message, s);
				break;

			case WBT_REGION:
				rfx_process_message_region(context, message, s);
				break;

			case WBT_EXTENSION:
				rfx_process_message_tileset(context, message, s);
				break;

			default:
				DEBUG_WARN("unknown blockType 0x%X", blockType);
				break;
		}

		stream_set_pos(s, pos);
	}

	stream_detach(s);
	stream_free(s);

	return message;
}
Beispiel #14
0
BOOL WTSVirtualChannelWrite(
	/* __in */  void* hChannelHandle,
	/* __in */  BYTE* Buffer,
	/* __in */  UINT32 Length,
	/* __out */ UINT32* pBytesWritten)
{
	rdpPeerChannel* channel = (rdpPeerChannel*) hChannelHandle;
	wts_data_item* item;
	wStream* s;
	int cbLen;
	int cbChId;
	int first;
	UINT32 written;

	if (channel == NULL)
		return FALSE;

	if (channel->channel_type == RDP_PEER_CHANNEL_TYPE_SVC)
	{
		item = (wts_data_item*) malloc(sizeof(wts_data_item));
		ZeroMemory(item, sizeof(wts_data_item));

		item->buffer = malloc(Length);
		item->length = Length;
		CopyMemory(item->buffer, Buffer, Length);

		wts_queue_send_item(channel, item);
	}
	else if (channel->vcm->drdynvc_channel == NULL || channel->vcm->drdynvc_state != DRDYNVC_STATE_READY)
	{
		DEBUG_DVC("drdynvc not ready");
		return FALSE;
	}
	else
	{
		s = stream_new(0);
		first = TRUE;

		while (Length > 0)
		{
			item = (wts_data_item*) malloc(sizeof(wts_data_item));
			ZeroMemory(item, sizeof(wts_data_item));

			item->buffer = malloc(channel->client->settings->VirtualChannelChunkSize);
			stream_attach(s, item->buffer, channel->client->settings->VirtualChannelChunkSize);

			stream_seek_BYTE(s);
			cbChId = wts_write_variable_uint(s, channel->channel_id);

			if (first && (Length > (UINT32) stream_get_left(s)))
			{
				cbLen = wts_write_variable_uint(s, Length);
				item->buffer[0] = (DATA_FIRST_PDU << 4) | (cbLen << 2) | cbChId;
			}
			else
			{
				item->buffer[0] = (DATA_PDU << 4) | cbChId;
			}

			first = FALSE;
			written = stream_get_left(s);

			if (written > Length)
				written = Length;

			stream_write(s, Buffer, written);
			item->length = stream_get_length(s);
			stream_detach(s);
			Length -= written;
			Buffer += written;

			wts_queue_send_item(channel->vcm->drdynvc_channel, item);
		}

		stream_free(s);
	}

	if (pBytesWritten != NULL)
		*pBytesWritten = Length;
	return TRUE;
}
Beispiel #15
0
RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, uint8* data, uint32 length, RECTANGLE_16* dst_rect)
{
	int pos;
	STREAM* s;
	uint32 blockLen;
	uint32 blockType;
	RFX_CONTEXT_CVT_PRIV* priv;
	RFX_MESSAGE* message;

	s = stream_new(0);

	message = rfx_message_new();
	if (dst_rect)
		memcpy(&message->dst_rect, dst_rect, sizeof(RECTANGLE_16));

	stream_attach(s, data, length);

	while (stream_get_left(s) > 6)
	{
		/* RFX_BLOCKT */
		stream_read_uint16(s, blockType); /* blockType (2 bytes) */
		stream_read_uint32(s, blockLen); /* blockLen (4 bytes) */

		DEBUG_RFX("blockType 0x%X blockLen %d", blockType, blockLen);

		if (blockLen == 0)
		{
			DEBUG_WARN("zero blockLen");
			break;
		}

		pos = stream_get_pos(s) - 6 + blockLen;

		if (blockType >= WBT_CONTEXT && blockType <= WBT_EXTENSION)
		{
			/* RFX_CODEC_CHANNELT */
			/* codecId (1 byte) must be set to 0x01 */
			/* channelId (1 byte) must be set to 0x00 */
			stream_seek(s, 2);
		}

		switch (blockType)
		{
			case WBT_SYNC:
				rfx_process_message_sync(context, s);
				break;

			case WBT_CODEC_VERSIONS:
				rfx_process_message_codec_versions(context, s);
				break;

			case WBT_CHANNELS:
				rfx_process_message_channels(context, s);
				break;

			case WBT_CONTEXT:
				rfx_process_message_context(context, s);
				break;

			case WBT_FRAME_BEGIN:
				rfx_process_message_frame_begin(context, message, s);
				break;

			case WBT_FRAME_END:
				rfx_process_message_frame_end(context, message, s);
				break;

			case WBT_REGION:
				rfx_process_message_region(context, message, s);
				break;

			case WBT_EXTENSION:
				priv = (RFX_CONTEXT_CVT_PRIV*) context->priv;
				if (priv->rfx_op_mode == RDVH_OPT)
					rfx_cvt_rdvh_opt_process_message_tileset(context, message, s);
				else
					rfx_cvt_process_message_tileset(context, message, s);
				break;

			default:
				DEBUG_WARN("unknown blockType 0x%X", blockType);
				break;
		}

		stream_set_pos(s, pos);
	}

	stream_detach(s);
	stream_free(s);

	return message;
}
Beispiel #16
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);
	stream_attach(s, cert->data, cert->length);

	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);

	stream_detach(s);
	stream_free(s);
}
Beispiel #17
0
int rts_recv_pdu_commands(rdpRpc* rpc, RTS_PDU* rts_pdu)
{
	int i;
	STREAM* s;
	UINT32 CommandType;

	DEBUG_RTS("numberOfCommands:%d", rts_pdu->header.numberOfCommands);

	if (rts_pdu->header.flags & RTS_FLAG_PING)
	{
		rts_send_keep_alive_pdu(rpc);
		return 0;
	}

	s = stream_new(0);
	stream_attach(s, rts_pdu->content, rts_pdu->header.frag_length);

	for (i = 0; i < rts_pdu->header.numberOfCommands; i++)
	{
		stream_read_UINT32(s, CommandType); /* CommandType (4 bytes) */

		DEBUG_RTS("CommandType: %s (0x%08X)", RTS_CMD_STRINGS[CommandType % 14], CommandType);

		switch (CommandType)
		{
			case RTS_CMD_RECEIVE_WINDOW_SIZE:
				rts_receive_window_size_command_read(rpc, s);
				break;

			case RTS_CMD_FLOW_CONTROL_ACK:
				rts_flow_control_ack_command_read(rpc, s);
				break;

			case RTS_CMD_CONNECTION_TIMEOUT:
				rts_connection_timeout_command_read(rpc, s);
				break;

			case RTS_CMD_COOKIE:
				rts_cookie_command_read(rpc, s);
				break;

			case RTS_CMD_CHANNEL_LIFETIME:
				rts_channel_lifetime_command_read(rpc, s);
				break;

			case RTS_CMD_CLIENT_KEEPALIVE:
				rts_client_keepalive_command_read(rpc, s);
				break;

			case RTS_CMD_VERSION:
				rts_version_command_read(rpc, s);
				break;

			case RTS_CMD_EMPTY:
				rts_empty_command_read(rpc, s);
				break;

			case RTS_CMD_PADDING:
				rts_padding_command_read(rpc, s);
				break;

			case RTS_CMD_NEGATIVE_ANCE:
				rts_negative_ance_command_read(rpc, s);
				break;

			case RTS_CMD_ANCE:
				rts_ance_command_read(rpc, s);
				break;

			case RTS_CMD_CLIENT_ADDRESS:
				rts_client_address_command_read(rpc, s);
				break;

			case RTS_CMD_ASSOCIATION_GROUP_ID:
				rts_association_group_id_command_read(rpc, s);
				break;

			case RTS_CMD_DESTINATION:
				rts_destination_command_read(rpc, s);
				break;

			case RTS_CMD_PING_TRAFFIC_SENT_NOTIFY:
				rts_ping_traffic_sent_notify_command_read(rpc, s);
				break;

			default:
				printf("Error: Unknown RTS Command Type: 0x%x\n", CommandType);
				stream_detach(s) ;
				stream_free(s) ;
				return -1;
				break;
		}
	}

	stream_detach(s);
	stream_free(s);

	return 0;
}
Beispiel #18
0
RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, BYTE* data, UINT32 length)
{
	int pos;
	STREAM* s;
	UINT32 blockLen;
	UINT32 blockType;
	RFX_MESSAGE* message;

	message = (RFX_MESSAGE*) malloc(sizeof(RFX_MESSAGE));
	ZeroMemory(message, sizeof(RFX_MESSAGE));

	s = stream_new(0);
	stream_attach(s, data, length);

	while (stream_get_left(s) > 6)
	{
		/* RFX_BLOCKT */
		stream_read_UINT16(s, blockType); /* blockType (2 bytes) */
		stream_read_UINT32(s, blockLen); /* blockLen (4 bytes) */

		DEBUG_RFX("blockType 0x%X blockLen %d", blockType, blockLen);

		if (blockLen == 0)
		{
			DEBUG_WARN("zero blockLen");
			break;
		}

		if (stream_get_left(s) < blockLen - 6)
		{
			DEBUG_WARN("rfx_process_message: packet too small for blocklen=%d", blockLen);
			break;
		}


		pos = stream_get_pos(s) - 6 + blockLen;

		if (blockType >= WBT_CONTEXT && blockType <= WBT_EXTENSION)
		{
			/* RFX_CODEC_CHANNELT */
			/* codecId (1 byte) must be set to 0x01 */
			/* channelId (1 byte) must be set to 0x00 */
			if (!stream_skip(s, 2))
			{
				DEBUG_WARN("rfx_process_message: unable to skip RFX_CODEC_CHANNELT");
				break;
			}
		}

		switch (blockType)
		{
			case WBT_SYNC:
				rfx_process_message_sync(context, s);
				break;

			case WBT_CODEC_VERSIONS:
				rfx_process_message_codec_versions(context, s);
				break;

			case WBT_CHANNELS:
				rfx_process_message_channels(context, s);
				break;

			case WBT_CONTEXT:
				rfx_process_message_context(context, s);
				break;

			case WBT_FRAME_BEGIN:
				rfx_process_message_frame_begin(context, message, s);
				break;

			case WBT_FRAME_END:
				rfx_process_message_frame_end(context, message, s);
				break;

			case WBT_REGION:
				rfx_process_message_region(context, message, s);
				break;

			case WBT_EXTENSION:
				rfx_process_message_tileset(context, message, s);
				break;

			default:
				DEBUG_WARN("unknown blockType 0x%X", blockType);
				break;
		}

		stream_set_pos(s, pos);
	}

	stream_detach(s);
	stream_free(s);

	return message;
}
Beispiel #19
0
int rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s)
{
	BYTE type;
	UINT16 length;
	UINT32 share_id;
	BYTE compressed_type;
	UINT16 compressed_len;
	UINT32 roff;
	UINT32 rlen;
	STREAM* comp_stream;

	if (!rdp_read_share_data_header(s, &length, &type, &share_id, &compressed_type, &compressed_len))
		return -1;

	comp_stream = s;

	if (compressed_type & PACKET_COMPRESSED)
	{
		if (stream_get_left(s) < compressed_len - 18)
		{
			printf("decompress_rdp: not enough bytes for compressed_len=%d\n", compressed_len);
			return -1;	
		}
		if (decompress_rdp(rdp->mppc_dec, s->p, compressed_len - 18, compressed_type, &roff, &rlen))
		{
			comp_stream = stream_new(0);
			comp_stream->data = rdp->mppc_dec->history_buf + roff;
			comp_stream->p = comp_stream->data;
			comp_stream->size = rlen;
		}
		else
		{
			printf("decompress_rdp() failed\n");
			return -1;
		}
		stream_seek(s, compressed_len - 18);
	}

#ifdef WITH_DEBUG_RDP
	/* if (type != DATA_PDU_TYPE_UPDATE) */
		DEBUG_RDP("recv %s Data PDU (0x%02X), length:%d",
				type < ARRAYSIZE(DATA_PDU_TYPE_STRINGS) ? DATA_PDU_TYPE_STRINGS[type] : "???", type, length);
#endif

	switch (type)
	{
		case DATA_PDU_TYPE_UPDATE:
			if (!update_recv(rdp->update, comp_stream))
				return -1;
			break;

		case DATA_PDU_TYPE_CONTROL:
			if (!rdp_recv_server_control_pdu(rdp, comp_stream))
				return -1;
			break;

		case DATA_PDU_TYPE_POINTER:
			if (!update_recv_pointer(rdp->update, comp_stream))
				return -1;
			break;

		case DATA_PDU_TYPE_INPUT:
			break;

		case DATA_PDU_TYPE_SYNCHRONIZE:
			if (!rdp_recv_synchronize_pdu(rdp, comp_stream))
				return -1;
			break;

		case DATA_PDU_TYPE_REFRESH_RECT:
			break;

		case DATA_PDU_TYPE_PLAY_SOUND:
			if (!update_recv_play_sound(rdp->update, comp_stream))
				return -1;
			break;

		case DATA_PDU_TYPE_SUPPRESS_OUTPUT:
			break;

		case DATA_PDU_TYPE_SHUTDOWN_REQUEST:
			break;

		case DATA_PDU_TYPE_SHUTDOWN_DENIED:
			break;

		case DATA_PDU_TYPE_SAVE_SESSION_INFO:
			if(!rdp_recv_save_session_info(rdp, comp_stream))
				return -1;
			break;

		case DATA_PDU_TYPE_FONT_LIST:
			break;

		case DATA_PDU_TYPE_FONT_MAP:
			if(!rdp_recv_font_map_pdu(rdp, comp_stream))
				return -1;
			break;

		case DATA_PDU_TYPE_SET_KEYBOARD_INDICATORS:
			break;

		case DATA_PDU_TYPE_BITMAP_CACHE_PERSISTENT_LIST:
			break;

		case DATA_PDU_TYPE_BITMAP_CACHE_ERROR:
			break;

		case DATA_PDU_TYPE_SET_KEYBOARD_IME_STATUS:
			break;

		case DATA_PDU_TYPE_OFFSCREEN_CACHE_ERROR:
			break;

		case DATA_PDU_TYPE_SET_ERROR_INFO:
			if (!rdp_recv_set_error_info_data_pdu(rdp, comp_stream))
				return -1;
			break;

		case DATA_PDU_TYPE_DRAW_NINEGRID_ERROR:
			break;

		case DATA_PDU_TYPE_DRAW_GDIPLUS_ERROR:
			break;

		case DATA_PDU_TYPE_ARC_STATUS:
			break;

		case DATA_PDU_TYPE_STATUS_INFO:
			break;

		case DATA_PDU_TYPE_MONITOR_LAYOUT:
			break;

		default:
			break;
	}

	if (comp_stream != s)
	{
		stream_detach(comp_stream);
		stream_free(comp_stream);
	}

	return 0;
}