Example #1
0
void rdp_capability_set_finish(STREAM* s, uint8* header, uint16 type)
{
	uint16 length;

	length = s->p - header;
	stream_set_mark(s, header);
	rdp_write_capability_set_header(s, length, type);
	stream_set_mark(s, header + length);
}
Example #2
0
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;
}
Example #3
0
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;
}
Example #4
0
void cliprdr_process_long_format_names(cliprdrPlugin* cliprdr, STREAM* s, uint32 length, uint16 flags)
{
	int num_formats;
	uint8* start_mark;
	uint8* end_mark;
	CLIPRDR_FORMAT_NAME* format_name;

	num_formats = 0;
	stream_get_mark(s, start_mark);
	stream_get_mark(s, end_mark);
	end_mark += length;

	while (s->p < end_mark)
	{
		stream_seek_uint32(s);
		stream_seek(s, 32);
		num_formats++;
	}

	stream_set_mark(s, start_mark);

	cliprdr->format_names = (CLIPRDR_FORMAT_NAME*) xmalloc(sizeof(CLIPRDR_FORMAT_NAME) * num_formats);
	cliprdr->num_format_names = num_formats;
	num_formats = 0;

	while (s->p < end_mark)
	{
		format_name = &cliprdr->format_names[num_formats++];
		stream_read_uint32(s, format_name->id);

		format_name->name = freerdp_uniconv_in(cliprdr->uniconv, s->p, 32);
		format_name->length = strlen(format_name->name);
		stream_seek(s, 32);
	}
}
Example #5
0
boolean rdp_client_connect_demand_active(rdpRdp* rdp, STREAM* s)
{
	uint8* mark;
	uint16 width;
	uint16 height;

	width = rdp->settings->width;
	height = rdp->settings->height;

	stream_get_mark(s, mark);

	if (!rdp_recv_demand_active(rdp, s))
	{
		stream_set_mark(s, mark);
		stream_seek(s, RDP_PACKET_HEADER_LENGTH);

		if (rdp_recv_out_of_sequence_pdu(rdp, s) != True)
			return False;

		return True;
	}

	if (!rdp_send_confirm_active(rdp))
		return False;

	/**
	 * The server may request a different desktop size during Deactivation-Reactivation sequence.
	 * In this case, the UI should be informed and do actual window resizing at this point.
	 */
	if (width != rdp->settings->width || height != rdp->settings->height)
	{
		IFCALL(rdp->update->DesktopResize, rdp->update);
	}

	/**
	 * [MS-RDPBCGR] 1.3.1.1 - 8.
	 * The client-to-server PDUs sent during this phase have no dependencies on any of the server-to-
	 * client PDUs; they may be sent as a single batch, provided that sequencing is maintained.
	 */

	if (!rdp_send_client_synchronize_pdu(rdp))
		return False;
	if (!rdp_send_client_control_pdu(rdp, CTRLACTION_COOPERATE))
		return False;
	if (!rdp_send_client_control_pdu(rdp, CTRLACTION_REQUEST_CONTROL))
		return False;
	if (!rdp_send_client_persistent_key_list_pdu(rdp))
		return False;
	if (!rdp_send_client_font_list_pdu(rdp, FONTLIST_FIRST | FONTLIST_LAST))
		return False;

	rdp->state = CONNECTION_STATE_ACTIVE;
	update_reset_state(rdp->update);

	return True;
}
Example #6
0
boolean tsmf_codec_check_media_type(STREAM* s)
{
	uint8* m;
	boolean ret;
	TS_AM_MEDIA_TYPE mediatype;

	stream_get_mark(s, m);
	ret = tsmf_codec_parse_media_type(&mediatype, s);
	stream_set_mark(s, m);

	return ret;
}
Example #7
0
tbool rdp_client_connect_demand_active(rdpRdp* rdp, STREAM* s)
{
	uint8* mark;
	uint16 width;
	uint16 height;
	uint16 channelId;

	width = rdp->settings->width;
	height = rdp->settings->height;

	stream_get_mark(s, mark);

	if (!rdp_recv_demand_active(rdp, s))
	{
		stream_set_mark(s, mark);
		rdp_recv_get_active_header(rdp, s, &channelId);
		/* Was stream_seek(s, RDP_PACKET_HEADER_MAX_LENGTH);
		 * but the headers aren't always that length,
		 * so that could result in a bad offset.
		 */

		if (rdp_recv_out_of_sequence_pdu(rdp, s) == false)
			return false;

		return true;
	}

	if (rdp->disconnect)
		return true;

	if (!rdp_send_confirm_active(rdp))
		return false;

	input_register_client_callbacks(rdp->input);

	/**
	 * The server may request a different desktop size during Deactivation-Reactivation sequence.
	 * In this case, the UI should be informed and do actual window resizing at this point.
	 */
	if (width != rdp->settings->width || height != rdp->settings->height)
	{
		IFCALL(rdp->update->DesktopResize, rdp->update->context);
	}

	rdp->state = CONNECTION_STATE_FINALIZATION;
	update_reset_state(rdp->update);

	rdp_client_connect_finalize(rdp);

	return true;
}
Example #8
0
File: nego.c Project: 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;
}
Example #9
0
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;
}
Example #10
0
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;
}
Example #11
0
static tbool rdp_recv_tpkt_pdu(rdpRdp* rdp, STREAM* s)
{
	uint16 length;
	uint16 pduType;
	uint16 pduLength;
	uint16 pduSource;
	uint16 channelId;
	uint16 securityFlags;
	uint8* nextp;

	if (!rdp_read_header(rdp, s, &length, &channelId))
	{
		printf("Incorrect RDP header.\n");
		return false;
	}

	if (rdp->settings->encryption)
	{
		rdp_read_security_header(s, &securityFlags);
		if (securityFlags & (SEC_ENCRYPT|SEC_REDIRECTION_PKT))
		{
			if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
			{
				printf("rdp_decrypt failed\n");
				return false;
			}
		}
		if (securityFlags & SEC_REDIRECTION_PKT)
		{
			/*
			 * [MS-RDPBCGR] 2.2.13.2.1
			 *  - no share control header, nor the 2 byte pad
			 */
			s->p -= 2;
			rdp_recv_enhanced_security_redirection_packet(rdp, s);
			return true;
		}
	}

	if (channelId != MCS_GLOBAL_CHANNEL_ID)
	{
		freerdp_channel_process(rdp->instance, s, channelId);
	}
	else
	{
		while (stream_get_left(s) > 3)
		{
			stream_get_mark(s, nextp);
			rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource);
			nextp += pduLength;

			rdp->settings->pdu_source = pduSource;

			switch (pduType)
			{
				case PDU_TYPE_DATA:
					if (!rdp_recv_data_pdu(rdp, s))
					{
						printf("rdp_recv_data_pdu failed\n");
						return false;
					}
					break;

				case PDU_TYPE_DEACTIVATE_ALL:
					if (!rdp_recv_deactivate_all(rdp, s))
						return false;
					break;

				case PDU_TYPE_SERVER_REDIRECTION:
					rdp_recv_enhanced_security_redirection_packet(rdp, s);
					break;

				default:
					printf("incorrect PDU type: 0x%04X\n", pduType);
					break;
			}
			stream_set_mark(s, nextp);
		}
	}

	return true;
}
Example #12
0
void rdp_write_confirm_active(STREAM* s, rdpSettings* settings)
{
	uint8 *bm, *em, *lm;
	uint16 numberCapabilities;
	uint16 lengthSourceDescriptor;
	uint16 lengthCombinedCapabilities;

	lengthSourceDescriptor = sizeof(SOURCE_DESCRIPTOR);

	stream_write_uint32(s, settings->share_id); /* shareId (4 bytes) */
	stream_write_uint16(s, 0x03EA); /* originatorId (2 bytes) */
	stream_write_uint16(s, lengthSourceDescriptor);/* lengthSourceDescriptor (2 bytes) */

	stream_get_mark(s, lm);
	stream_seek_uint16(s); /* lengthCombinedCapabilities (2 bytes) */
	stream_write(s, SOURCE_DESCRIPTOR, lengthSourceDescriptor); /* sourceDescriptor */

	stream_get_mark(s, bm);
	stream_seek_uint16(s); /* numberCapabilities (2 bytes) */
	stream_write_uint16(s, 0); /* pad2Octets (2 bytes) */

	/* Capability Sets */
	numberCapabilities = 15;
	rdp_write_general_capability_set(s, settings);
	rdp_write_bitmap_capability_set(s, settings);
	rdp_write_order_capability_set(s, settings);
	rdp_write_bitmap_cache_capability_set(s, settings);
	rdp_write_pointer_capability_set(s, settings);
	rdp_write_input_capability_set(s, settings);
	rdp_write_brush_capability_set(s, settings);
	rdp_write_glyph_cache_capability_set(s, settings);
	rdp_write_offscreen_bitmap_cache_capability_set(s, settings);
	rdp_write_virtual_channel_capability_set(s, settings);
	rdp_write_sound_capability_set(s, settings);
	rdp_write_share_capability_set(s, settings);
	rdp_write_control_capability_set(s, settings);
	rdp_write_color_cache_capability_set(s, settings);
	rdp_write_window_activation_capability_set(s, settings);

	if (settings->offscreen_bitmap_cache)
	{
		numberCapabilities++;
		rdp_write_offscreen_bitmap_cache_capability_set(s, settings);
	}

	if (settings->received_caps[CAPSET_TYPE_MULTI_FRAGMENT_UPDATE])
	{
		numberCapabilities++;
		rdp_write_multifragment_update_capability_set(s, settings);
	}

	if (settings->received_caps[CAPSET_TYPE_LARGE_POINTER])
	{
		numberCapabilities++;
		rdp_write_large_pointer_capability_set(s, settings);
	}

	if (settings->received_caps[CAPSET_TYPE_SURFACE_COMMANDS])
	{
		numberCapabilities++;
		rdp_write_surface_commands_capability_set(s, settings);
	}

#if 0
	if (settings->received_caps[CAPSET_TYPE_BITMAP_CODECS])
	{
		numberCapabilities++;
		rdp_write_bitmap_codecs_capability_set(s, settings);
	}

#endif

	if (settings->received_caps[CAPSET_TYPE_FRAME_ACKNOWLEDGE])
	{
		if (settings->frame_acknowledge)
		{
			numberCapabilities++;
			rdp_write_frame_acknowledge_capability_set(s, settings);
		}
	}

	stream_get_mark(s, em);

	stream_set_mark(s, lm); /* go back to lengthCombinedCapabilities */
	lengthCombinedCapabilities = (em - bm);
	stream_write_uint16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */

	stream_set_mark(s, bm); /* go back to numberCapabilities */
	stream_write_uint16(s, numberCapabilities); /* numberCapabilities (2 bytes) */

	stream_set_mark(s, em);
}
Example #13
0
void rdp_read_demand_active(STREAM* s, rdpSettings* settings)
{
	uint16 type;
	uint16 length;
	uint8 *bm, *em;
	uint16 numberCapabilities;
	uint16 lengthSourceDescriptor;
	uint16 lengthCombinedCapabilities;

	printf("Demand Active PDU\n");

	stream_read_uint32(s, settings->share_id); /* shareId (4 bytes) */
	stream_read_uint16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */
	stream_read_uint16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */
	stream_seek(s, lengthSourceDescriptor); /* sourceDescriptor */
	stream_read_uint16(s, numberCapabilities); /* numberCapabilities (2 bytes) */
	stream_seek(s, 2); /* pad2Octets (2 bytes) */

	/* capabilitySets */
	while (numberCapabilities > 0)
	{
		stream_get_mark(s, bm);

		rdp_read_capability_set_header(s, &length, &type);
		printf("%s Capability Set (0x%02X), length:%d\n", CAPSET_TYPE_STRINGS[type], type, length);
		settings->received_caps[type] = True;
		em = bm + length;

		switch (type)
		{
			case CAPSET_TYPE_GENERAL:
				rdp_read_general_capability_set(s, settings);
				break;

			case CAPSET_TYPE_BITMAP:
				rdp_read_bitmap_capability_set(s, settings);
				break;

			case CAPSET_TYPE_ORDER:
				rdp_read_order_capability_set(s, settings);
				break;

			case CAPSET_TYPE_BITMAP_CACHE:
				rdp_read_bitmap_cache_capability_set(s, settings);
				break;

			case CAPSET_TYPE_CONTROL:
				rdp_read_control_capability_set(s, settings);
				break;

			case CAPSET_TYPE_ACTIVATION:
				rdp_read_window_activation_capability_set(s, settings);
				break;

			case CAPSET_TYPE_POINTER:
				rdp_read_pointer_capability_set(s, settings);
				break;

			case CAPSET_TYPE_SHARE:
				rdp_read_share_capability_set(s, settings);
				break;

			case CAPSET_TYPE_COLOR_CACHE:
				rdp_read_color_cache_capability_set(s, settings);
				break;

			case CAPSET_TYPE_SOUND:
				rdp_read_sound_capability_set(s, settings);
				break;

			case CAPSET_TYPE_INPUT:
				rdp_read_input_capability_set(s, settings);
				break;

			case CAPSET_TYPE_FONT:
				rdp_read_font_capability_set(s, settings);
				break;

			case CAPSET_TYPE_BRUSH:
				rdp_read_brush_capability_set(s, settings);
				break;

			case CAPSET_TYPE_GLYPH_CACHE:
				rdp_read_glyph_cache_capability_set(s, settings);
				break;

			case CAPSET_TYPE_OFFSCREEN_CACHE:
				rdp_read_offscreen_bitmap_cache_capability_set(s, settings);
				break;

			case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT:
				rdp_read_bitmap_cache_host_support_capability_set(s, settings);
				break;

			case CAPSET_TYPE_BITMAP_CACHE_V2:
				rdp_read_bitmap_cache_v2_capability_set(s, settings);
				break;

			case CAPSET_TYPE_VIRTUAL_CHANNEL:
				rdp_read_virtual_channel_capability_set(s, settings);
				break;

			case CAPSET_TYPE_DRAW_NINE_GRID_CACHE:
				rdp_read_draw_nine_grid_cache_capability_set(s, settings);
				break;

			case CAPSET_TYPE_DRAW_GDI_PLUS:
				rdp_read_draw_gdiplus_cache_capability_set(s, settings);
				break;

			case CAPSET_TYPE_RAIL:
				rdp_read_remote_programs_capability_set(s, settings);
				break;

			case CAPSET_TYPE_WINDOW:
				rdp_read_window_list_capability_set(s, settings);
				break;

			case CAPSET_TYPE_COMP_DESK:
				rdp_read_desktop_composition_capability_set(s, settings);
				break;

			case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE:
				rdp_read_multifragment_update_capability_set(s, settings);
				break;

			case CAPSET_TYPE_LARGE_POINTER:
				rdp_read_large_pointer_capability_set(s, settings);
				break;

			case CAPSET_TYPE_SURFACE_COMMANDS:
				rdp_read_surface_commands_capability_set(s, settings);
				break;

			case CAPSET_TYPE_BITMAP_CODECS:
				rdp_read_bitmap_codecs_capability_set(s, settings);
				break;

			case CAPSET_TYPE_FRAME_ACKNOWLEDGE:
				rdp_read_frame_acknowledge_capability_set(s, settings);
				break;

			default:
				break;
		}

		if (s->p != em)
			printf("incorrect offset, actual:%d expected:%d\n", (int) (s->p - bm), (int) (em - bm));

		stream_set_mark(s, em);
		numberCapabilities--;
	}
}