コード例 #1
0
ファイル: nego.c プロジェクト: ydal/FreeRDP
boolean nego_recv(rdpTransport* transport, STREAM* s, void* extra)
{
    uint8 li;
    uint8 type;
    rdpNego* nego = (rdpNego*) extra;

    if (tpkt_read_header(s) == 0)
        return false;

    li = tpdu_read_connection_confirm(s);

    if (li > 6)
    {
        /* rdpNegData (optional) */

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

        switch (type)
        {
        case TYPE_RDP_NEG_RSP:
            nego_process_negotiation_response(nego, s);
            break;

        case TYPE_RDP_NEG_FAILURE:
            nego_process_negotiation_failure(nego, s);
            break;
        }
    }
    else
    {
        nego->state = NEGO_STATE_FINAL;
    }

    return true;
}
コード例 #2
0
ファイル: nego.c プロジェクト: pevik/debian-freerdp
BOOL nego_read_request(rdpNego* nego, wStream* s)
{
	BYTE li;
	BYTE c;
	BYTE type;

	tpkt_read_header(s);

	if (!tpdu_read_connection_request(s, &li))
		return FALSE;

	if (li != Stream_GetRemainingLength(s) + 6)
	{
		fprintf(stderr, "Incorrect TPDU length indicator.\n");
		return FALSE;
	}

	if (Stream_GetRemainingLength(s) > 8)
	{
		/* Optional routingToken or cookie, ending with CR+LF */
		while (Stream_GetRemainingLength(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_GetRemainingLength(s) >= 8)
	{
		/* rdpNegData (optional) */

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

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

		nego_process_negotiation_request(nego, s);
	}

	return TRUE;
}
コード例 #3
0
ファイル: nego.c プロジェクト: effort/FreeRDP
BOOL nego_read_request(rdpNego* nego, STREAM* s)
{
	BYTE li;
	BYTE c;
	BYTE type;

	tpkt_read_header(s);
	if(!tpdu_read_connection_request(s, &li))
		return FALSE;

	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_BYTE(s, c);

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

			stream_peek_BYTE(s, c);

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

			stream_seek_BYTE(s);
			break;
		}
	}

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

		stream_read_BYTE(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;
}
コード例 #4
0
ファイル: nego.c プロジェクト: FreeRDP/FreeRDP
BOOL nego_read_request(rdpNego* nego, wStream* s)
{
	BYTE li;
	BYTE type;
	UINT16 length;

	if (!tpkt_read_header(s, &length))
		return FALSE;

	if (!tpdu_read_connection_request(s, &li))
		return FALSE;

	if (li != Stream_GetRemainingLength(s) + 6)
	{
		WLog_ERR(TAG, "Incorrect TPDU length indicator.");
		return FALSE;
	}

	if (!nego_read_request_token_or_cookie(nego, s))
	{
		WLog_ERR(TAG, "Failed to parse routing token or cookie.");
		return FALSE;
	}

	if (Stream_GetRemainingLength(s) >= 8)
	{
		/* rdpNegData (optional) */
		Stream_Read_UINT8(s, type); /* Type */

		if (type != TYPE_RDP_NEG_REQ)
		{
			WLog_ERR(TAG, "Incorrect negotiation request type %"PRIu8"", type);
			return FALSE;
		}

		nego_process_negotiation_request(nego, s);
	}

	return TRUE;
}
コード例 #5
0
ファイル: nego.c プロジェクト: AMV007/FreeRDP
int nego_recv(rdpTransport* transport, wStream* s, void* extra)
{
	BYTE li;
	BYTE type;
	UINT16 length;
	rdpNego* nego = (rdpNego*) extra;

	length = tpkt_read_header(s);

	if (length == 0)
		return -1;

	if (!tpdu_read_connection_confirm(s, &li))
		return -1;

	if (li > 6)
	{
		/* rdpNegData (optional) */

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

		switch (type)
		{
			case TYPE_RDP_NEG_RSP:
				nego_process_negotiation_response(nego, s);

				WLog_DBG(TAG, "selected_protocol: %d", nego->SelectedProtocol);

				/* enhanced security selected ? */

				if (nego->SelectedProtocol)
				{
					if ((nego->SelectedProtocol == PROTOCOL_NLA) &&
						(!nego->EnabledProtocols[PROTOCOL_NLA]))
					{
						nego->state = NEGO_STATE_FAIL;
					}
					if ((nego->SelectedProtocol == PROTOCOL_TLS) &&
						(!nego->EnabledProtocols[PROTOCOL_TLS]))
					{
						nego->state = NEGO_STATE_FAIL;
					}
				}
				else if (!nego->EnabledProtocols[PROTOCOL_RDP])
				{
					nego->state = NEGO_STATE_FAIL;
				}
				break;

			case TYPE_RDP_NEG_FAILURE:
				nego_process_negotiation_failure(nego, s);
				break;
		}
	}
	else if (li == 6)
	{
		WLog_DBG(TAG, "no rdpNegData");

		if (!nego->EnabledProtocols[PROTOCOL_RDP])
			nego->state = NEGO_STATE_FAIL;
		else
			nego->state = NEGO_STATE_FINAL;
	}
	else
	{
		WLog_ERR(TAG, "invalid negotiation response");
		nego->state = NEGO_STATE_FAIL;
	}

	return 0;
}
コード例 #6
0
ファイル: transport.c プロジェクト: racoon00/FreeRDP
int transport_check_fds(rdpTransport* transport)
{
	int pos;
	int status;
	uint16 length;
	STREAM* received;

	wait_obj_clear(transport->recv_event);

	status = transport_read_nonblocking(transport);

	if (status < 0)
		return status;

	while ((pos = stream_get_pos(transport->recv_buffer)) > 0)
	{
		stream_set_pos(transport->recv_buffer, 0);
		if (tpkt_verify_header(transport->recv_buffer)) /* TPKT */
		{
			/* Ensure the TPKT header is available. */
			if (pos <= 4)
			{
				stream_set_pos(transport->recv_buffer, pos);
				return 0;
			}
			length = tpkt_read_header(transport->recv_buffer);
		}
		else /* Fast Path */
		{
			/* Ensure the Fast Path header is available. */
			if (pos <= 2)
			{
				stream_set_pos(transport->recv_buffer, pos);
				return 0;
			}
			length = fastpath_read_header(NULL, transport->recv_buffer);
		}

		if (length == 0)
		{
			printf("transport_check_fds: protocol error, not a TPKT or Fast Path header.\n");
			freerdp_hexdump(stream_get_head(transport->recv_buffer), pos);
			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);
		
		if (transport->recv_callback(transport, received, transport->recv_extra) == False)
			status = -1;
	
		stream_free(received);

		if (status < 0)
			return status;
	}

	return 0;
}
コード例 #7
0
ファイル: nego.c プロジェクト: effort/FreeRDP
BOOL nego_recv(rdpTransport* transport, STREAM* s, void* extra)
{
	BYTE li;
	BYTE type;
	UINT16 length;
	rdpNego* nego = (rdpNego*) extra;

	length = tpkt_read_header(s);

	if (length == 0)
		return FALSE;

	if(!tpdu_read_connection_confirm(s, &li))
		return FALSE;

	if (li > 6)
	{
		/* rdpNegData (optional) */

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

		switch (type)
		{
			case TYPE_RDP_NEG_RSP:
				nego_process_negotiation_response(nego, s);

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

				/* enhanced security selected ? */

				if (nego->selected_protocol)
				{
					if ((nego->selected_protocol == PROTOCOL_NLA) &&
						(!nego->enabled_protocols[PROTOCOL_NLA]))
					{
						nego->state = NEGO_STATE_FAIL;
					}
					if ((nego->selected_protocol == PROTOCOL_TLS) &&
						(!nego->enabled_protocols[PROTOCOL_TLS]))
					{
						nego->state = NEGO_STATE_FAIL;
					}
				}
				else if (!nego->enabled_protocols[PROTOCOL_RDP])
				{
					nego->state = NEGO_STATE_FAIL;
				}
				break;

			case TYPE_RDP_NEG_FAILURE:
				nego_process_negotiation_failure(nego, s);
				break;
		}
	}
	else if (li == 6)
	{
		DEBUG_NEGO("no rdpNegData");

		if (!nego->enabled_protocols[PROTOCOL_RDP])
			nego->state = NEGO_STATE_FAIL;
		else
			nego->state = NEGO_STATE_FINAL;
	}
	else
	{
		printf("invalid negotiation response\n");
		nego->state = NEGO_STATE_FAIL;
	}

	return TRUE;
}
コード例 #8
0
ファイル: transport.c プロジェクト: Cyclic/FreeRDP
int transport_check_fds(rdpTransport** ptransport)
{
	int pos;
	int status;
	uint16 length;
	STREAM* received;
	rdpTransport* transport = *ptransport;

	wait_obj_clear(transport->recv_event);

	status = transport_read_nonblocking(transport);

	if (status < 0)
		return status;

	while ((pos = stream_get_pos(transport->recv_buffer)) > 0)
	{
		stream_set_pos(transport->recv_buffer, 0);
		if (tpkt_verify_header(transport->recv_buffer)) /* TPKT */
		{
			/* Ensure the TPKT header is available. */
			if (pos <= 4)
			{
				stream_set_pos(transport->recv_buffer, pos);
				return 0;
			}
			length = tpkt_read_header(transport->recv_buffer);
		}
		else /* Fast Path */
		{
			/* Ensure the Fast Path header is available. */
			if (pos <= 2)
			{
				stream_set_pos(transport->recv_buffer, pos);
				return 0;
			}
			/* Fastpath header can be two or three bytes long. */
			length = fastpath_header_length(transport->recv_buffer);
			if (pos < length)
			{
				stream_set_pos(transport->recv_buffer, pos);
				return 0;
			}
			length = fastpath_read_header(NULL, transport->recv_buffer);
		}

		if (length == 0)
		{
			printf("transport_check_fds: protocol error, not a TPKT or Fast Path header.\n");
			freerdp_hexdump(stream_get_head(transport->recv_buffer), pos);
			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);

		if (transport->recv_callback(transport, received, transport->recv_extra) == false)
			status = -1;

		stream_free(received);

		if (status < 0)
			return status;

		/* transport might now have been freed by rdp_client_redirect and a new rdp->transport created */
		transport = *ptransport;

		if (transport->process_single_pdu)
		{
			/* one at a time but set event if data buffered
			 * so the main loop will call freerdp_check_fds asap */
			if (stream_get_pos(transport->recv_buffer) > 0)
				wait_obj_set(transport->recv_event);
			break;
		}

	}

	return 0;
}
コード例 #9
0
ファイル: nego.c プロジェクト: rafcabezas/FreeRDP
boolean nego_recv(rdpTransport* transport, STREAM* s, void* extra)
{
	uint8 li;
	uint8 type;
	rdpNego* nego = (rdpNego*) extra;

	if (tpkt_read_header(s) == 0)
		return false;

	li = tpdu_read_connection_confirm(s);

	if (li > 6)
	{
		/* rdpNegData (optional) */

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

		switch (type)
		{
			case TYPE_RDP_NEG_RSP:
				nego_process_negotiation_response(nego, s);

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

				/* enhanced security selected ? */

				if (nego->selected_protocol)
				{
					if ((nego->selected_protocol == PROTOCOL_NLA) &&
							(!nego->enabled_protocols[PROTOCOL_NLA]))
					{
						nego->state = NEGO_STATE_FAIL;
					}
					if ((nego->selected_protocol == PROTOCOL_TLS) &&
						(!nego->enabled_protocols[PROTOCOL_TLS]))
					{
						nego->state = NEGO_STATE_FAIL;
					}
				}
				else if (!nego->enabled_protocols[PROTOCOL_RDP])
				{
					nego->state = NEGO_STATE_FAIL;
				}
				break;

			case TYPE_RDP_NEG_FAILURE:
				nego_process_negotiation_failure(nego, s);
				break;
		}
	}
	else
	{
		DEBUG_NEGO("no rdpNegData");

		if (!nego->enabled_protocols[PROTOCOL_RDP])
			nego->state = NEGO_STATE_FAIL;
		else
			nego->state = NEGO_STATE_FINAL;
	}

	return true;
}
コード例 #10
0
ファイル: transport.c プロジェクト: 4hosi/FreeRDP
int transport_check_fds(rdpTransport** ptransport)
{
	int pos;
	int status;
	UINT16 length;
	int recv_status;
	STREAM* received;
	rdpTransport* transport = *ptransport;

#ifdef _WIN32
	WSAResetEvent(transport->TcpIn->wsa_event);
#endif
	ResetEvent(transport->ReceiveEvent);

	status = transport_read_nonblocking(transport);

	if (status < 0)
		return status;

	while ((pos = stream_get_pos(transport->ReceiveBuffer)) > 0)
	{
		stream_set_pos(transport->ReceiveBuffer, 0);

		if (tpkt_verify_header(transport->ReceiveBuffer)) /* TPKT */
		{
			/* Ensure the TPKT header is available. */
			if (pos <= 4)
			{
				stream_set_pos(transport->ReceiveBuffer, pos);
				return 0;
			}

			length = tpkt_read_header(transport->ReceiveBuffer);
		}
		else if (nla_verify_header(transport->ReceiveBuffer))
		{
			/* TSRequest */

			/* Ensure the TSRequest header is available. */
			if (pos <= 4)
			{
				stream_set_pos(transport->ReceiveBuffer, pos);
				return 0;
			}

			/* TSRequest header can be 2, 3 or 4 bytes long */
			length = nla_header_length(transport->ReceiveBuffer);

			if (pos < length)
			{
				stream_set_pos(transport->ReceiveBuffer, pos);
				return 0;
			}

			length = nla_read_header(transport->ReceiveBuffer);
		}
		else /* Fast Path */
		{
			/* Ensure the Fast Path header is available. */
			if (pos <= 2)
			{
				stream_set_pos(transport->ReceiveBuffer, pos);
				return 0;
			}

			/* Fastpath header can be two or three bytes long. */
			length = fastpath_header_length(transport->ReceiveBuffer);

			if (pos < length)
			{
				stream_set_pos(transport->ReceiveBuffer, pos);
				return 0;
			}

			length = fastpath_read_header(NULL, transport->ReceiveBuffer);
		}

		if (length == 0)
		{
			printf("transport_check_fds: protocol error, not a TPKT or Fast Path header.\n");
			winpr_HexDump(stream_get_head(transport->ReceiveBuffer), pos);
			return -1;
		}

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

		received = transport->ReceiveBuffer;
		transport->ReceiveBuffer = transport_receive_pool_take(transport);

		stream_set_pos(received, length);
		stream_seal(received);
		stream_set_pos(received, 0);

		/**
		 * ReceiveCallback return values:
		 *
		 * -1: synchronous failure
		 *  0: synchronous success
		 *  1: asynchronous return
		 */

		recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra);

		transport_receive_pool_return(transport, received);

		if (recv_status < 0)
			status = -1;

		if (status < 0)
			return status;

		/* transport might now have been freed by rdp_client_redirect and a new rdp->transport created */
		transport = *ptransport;
	}

	return 0;
}
コード例 #11
0
ファイル: transport.c プロジェクト: lenky0401/FreeRDP
int transport_check_fds(rdpTransport* transport)
{
	int pos;
	int status;
	UINT16 length;
	int recv_status;
	wStream* received;

	if (!transport)
		return -1;

#ifdef _WIN32
	WSAResetEvent(transport->TcpIn->wsa_event);
#endif
	ResetEvent(transport->ReceiveEvent);

	status = transport_read_nonblocking(transport);

	if (status < 0)
		return status;

	while ((pos = Stream_GetPosition(transport->ReceiveBuffer)) > 0)
	{
		Stream_SetPosition(transport->ReceiveBuffer, 0);

		if (tpkt_verify_header(transport->ReceiveBuffer)) /* TPKT */
		{
			/* Ensure the TPKT header is available. */
			if (pos <= 4)
			{
				Stream_SetPosition(transport->ReceiveBuffer, pos);
				return 0;
			}

			length = tpkt_read_header(transport->ReceiveBuffer);
		}
		else if (nla_verify_header(transport->ReceiveBuffer))
		{
			/* TSRequest */

			/* Ensure the TSRequest header is available. */
			if (pos <= 4)
			{
				Stream_SetPosition(transport->ReceiveBuffer, pos);
				return 0;
			}

			/* TSRequest header can be 2, 3 or 4 bytes long */
			length = nla_header_length(transport->ReceiveBuffer);

			if (pos < length)
			{
				Stream_SetPosition(transport->ReceiveBuffer, pos);
				return 0;
			}

			length = nla_read_header(transport->ReceiveBuffer);
		}
		else /* Fast Path */
		{
			/* Ensure the Fast Path header is available. */
			if (pos <= 2)
			{
				Stream_SetPosition(transport->ReceiveBuffer, pos);
				return 0;
			}

			/* Fastpath header can be two or three bytes long. */
			length = fastpath_header_length(transport->ReceiveBuffer);

			if (pos < length)
			{
				Stream_SetPosition(transport->ReceiveBuffer, pos);
				return 0;
			}

			length = fastpath_read_header(NULL, transport->ReceiveBuffer);
		}

		if (length == 0)
		{
			fprintf(stderr, "transport_check_fds: protocol error, not a TPKT or Fast Path header.\n");
			winpr_HexDump(Stream_Buffer(transport->ReceiveBuffer), pos);
			return -1;
		}

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

		received = transport->ReceiveBuffer;
		transport->ReceiveBuffer = StreamPool_Take(transport->ReceivePool, 0);

		Stream_SetPosition(received, length);
		Stream_SealLength(received);
		Stream_SetPosition(received, 0);

		/**
		 * status:
		 * 	-1: error
		 * 	 0: success
		 * 	 1: redirection
		 */

		recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra);

		if (recv_status == 1)
		{
			/**
			 * Last call to ReceiveCallback resulted in a session redirection,
			 * which means the current rdpTransport* transport pointer has been freed.
			 * Return 0 for success, the rest of this function is meant for non-redirected cases.
			 */
			return 0;
		}

		Stream_Release(received);

		if (recv_status < 0)
			status = -1;

		if (status < 0)
			return status;
	}

	return 0;
}
コード例 #12
0
ファイル: transport.c プロジェクト: AlessioLeo/FreeRDP
int transport_check_fds(rdpTransport** ptransport)
{
	int pos;
	int status;
	UINT16 length;
	int recv_status;
	wStream* received;
	rdpTransport* transport = *ptransport;

#ifdef _WIN32
	WSAResetEvent(transport->TcpIn->wsa_event);
#endif
	ResetEvent(transport->ReceiveEvent);

	status = transport_read_nonblocking(transport);

	if (status < 0)
		return status;

	while ((pos = Stream_GetPosition(transport->ReceiveBuffer)) > 0)
	{
		Stream_SetPosition(transport->ReceiveBuffer, 0);

		if (tpkt_verify_header(transport->ReceiveBuffer)) /* TPKT */
		{
			/* Ensure the TPKT header is available. */
			if (pos <= 4)
			{
				Stream_SetPosition(transport->ReceiveBuffer, pos);
				return 0;
			}

			length = tpkt_read_header(transport->ReceiveBuffer);
		}
		else if (nla_verify_header(transport->ReceiveBuffer))
		{
			/* TSRequest */

			/* Ensure the TSRequest header is available. */
			if (pos <= 4)
			{
				Stream_SetPosition(transport->ReceiveBuffer, pos);
				return 0;
			}

			/* TSRequest header can be 2, 3 or 4 bytes long */
			length = nla_header_length(transport->ReceiveBuffer);

			if (pos < length)
			{
				Stream_SetPosition(transport->ReceiveBuffer, pos);
				return 0;
			}

			length = nla_read_header(transport->ReceiveBuffer);
		}
		else /* Fast Path */
		{
			/* Ensure the Fast Path header is available. */
			if (pos <= 2)
			{
				Stream_SetPosition(transport->ReceiveBuffer, pos);
				return 0;
			}

			/* Fastpath header can be two or three bytes long. */
			length = fastpath_header_length(transport->ReceiveBuffer);

			if (pos < length)
			{
				Stream_SetPosition(transport->ReceiveBuffer, pos);
				return 0;
			}

			length = fastpath_read_header(NULL, transport->ReceiveBuffer);
		}

		if (length == 0)
		{
			fprintf(stderr, "transport_check_fds: protocol error, not a TPKT or Fast Path header.\n");
			winpr_HexDump(Stream_Buffer(transport->ReceiveBuffer), pos);
			return -1;
		}

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

		received = transport->ReceiveBuffer;
		transport->ReceiveBuffer = StreamPool_Take(transport->ReceivePool, 0);

		Stream_SetPosition(received, length);
		Stream_SealLength(received);
		Stream_SetPosition(received, 0);

		recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra);

		if (transport == *ptransport)
			/* transport might now have been freed by rdp_client_redirect and a new rdp->transport created */
			/* so only release if still valid */
			Stream_Release(received);
			

		if (recv_status < 0)
			status = -1;

		if (status < 0)
			return status;

		/* transport might now have been freed by rdp_client_redirect and a new rdp->transport created */
		transport = *ptransport;
	}

	return 0;
}