Example #1
0
/* Establish a connection up to the ISO layer */
RD_BOOL
iso_connect(char *server, char *username, RD_BOOL reconnect)
{
	uint8 code = 0;

	if (!tcp_connect(server))
		return False;

	if (reconnect)
	{
		iso_send_msg(ISO_PDU_CR);
	}
	else
	{
		iso_send_connection_request(username);
	}

	if (iso_recv_msg(&code, NULL) == NULL)
		return False;

	if (code != ISO_PDU_CC)
	{
		error("expected CC, got 0x%x\n", code);
		tcp_disconnect();
		return False;
	}

	return True;
}
Example #2
0
/* Establish a reconnection up to the ISO layer */
BOOL
iso_reconnect(RDPCLIENT * This, char *server, char *cookie)
{
	uint8 code = 0;

	if (!tcp_connect(This, server))
		return False;

	if (!iso_send_connection_request(This, cookie)) // BUGBUG should we really pass the cookie here?
		return False;

	if (iso_recv_msg(This, &code, NULL) == NULL)
		return False;

	if (code != ISO_PDU_CC)
	{
		error("expected CC, got 0x%x\n", code);
		tcp_disconnect(This);
		return False;
	}

	return True;
}
Example #3
0
/* Establish a connection up to the ISO layer */
RD_BOOL
iso_connect(char *server, char *username, RD_BOOL reconnect, uint32 * selected_protocol)
{
	STREAM s;
	uint8 code;

	g_negotiate_rdp_protocol = True;

      retry:
	*selected_protocol = PROTOCOL_RDP;
	code = 0;

	if (!tcp_connect(server))
		return False;

	if (reconnect)
	{
		iso_send_msg(ISO_PDU_CR);
	}
	else
	{
		iso_send_connection_request(username);
	}

	s = iso_recv_msg(&code, NULL);
	if (s == NULL)
		return False;

	if (code != ISO_PDU_CC)
	{
		error("expected CC, got 0x%x\n", code);
		tcp_disconnect();
		return False;
	}

	if (g_rdp_version >= RDP_V5 && s_check_rem(s, 8))
	{
		/* handle RDP_NEG_REQ response */
		const char *reason = NULL;

		uint8 type = 0, flags = 0;
		uint16 length = 0;
		uint32 data = 0;

		in_uint8(s, type);
		in_uint8(s, flags);
		in_uint16(s, length);
		in_uint32(s, data);

		if (type == RDP_NEG_FAILURE)
		{
			switch (data)
			{
				case SSL_REQUIRED_BY_SERVER:
					reason = "SSL required by server";
					break;
				case SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER:
					reason = "SSL with user authentication required by server";
					break;
				case SSL_NOT_ALLOWED_BY_SERVER:
					reason = "SSL not allowed by server";
					break;
				case SSL_CERT_NOT_ON_SERVER:
					reason = "SSL certificated not on server";
					break;
				case INCONSISTENT_FLAGS:
					reason = "inconsistent flags";
					break;
				case HYBRID_REQUIRED_BY_SERVER:
					reason = "hybrid authentication (CredSSP) required by server";
					break;
				default:
					reason = "unknown reason";
			}

			tcp_disconnect();
			warning("RDP protocol negotiation failed with reason: %s (error 0x%x),\n",
				reason, data);
			warning("retrying without negotiation using plain RDP protocol.\n");

			g_negotiate_rdp_protocol = False;
			goto retry;
		}

		if (type != RDP_NEG_RSP)
		{
			tcp_disconnect();
			error("expected RDP_NEG_RSP, got type = 0x%x\n", type);
			warning("retrying without negotiation using plain RDP protocol.\n");

			g_negotiate_rdp_protocol = False;
			goto retry;
		}

		/* handle negotiation response */
		if (data == PROTOCOL_SSL)
		{
			DEBUGMSG(1,(L"iso_connect: negotiation: PROTOCOL_SSL\n"));
			if (!tcp_tls_connect())
			{
				tcp_disconnect();
				DEBUGMSG(1,(L"iso_connect: negotiation: PROTOCOL_SSL FAILED\n"));
				return False;
			}

			/* do not use encryption when using TLS */
			g_encryption = False;
		}
		else if (data != PROTOCOL_RDP)
		{
			tcp_disconnect();
			error("unexpected protocol in neqotiation response, got data = 0x%x.\n",
			      data);
			return False;
		}

		*selected_protocol = data;
	}
	return True;
}
Example #4
0
/* Establish a connection up to the ISO layer */
RD_BOOL
iso_connect(char *server, char *username, char *domain, char *password,
	    RD_BOOL reconnect, uint32 * selected_protocol)
{
	STREAM s;
	uint8 code;
	uint32 neg_proto;

	g_negotiate_rdp_protocol = True;

	neg_proto = PROTOCOL_SSL;

#ifdef WITH_CREDSSP
	if (!g_use_password_as_pin)
		neg_proto |= PROTOCOL_HYBRID;
	else if (g_sc_csp_name || g_sc_reader_name || g_sc_card_name || g_sc_container_name)
		neg_proto |= PROTOCOL_HYBRID;
	else
		warning("Disables CredSSP due to missing smartcard information for SSO.\n");
#endif

      retry:
	*selected_protocol = PROTOCOL_RDP;
	code = 0;

	if (!tcp_connect(server))
		return False;

	iso_send_connection_request(username, neg_proto);

	s = iso_recv_msg(&code, NULL);
	if (s == NULL)
		return False;

	if (code != ISO_PDU_CC)
	{
		error("expected CC, got 0x%x\n", code);
		tcp_disconnect();
		return False;
	}

	if (g_rdp_version >= RDP_V5 && s_check_rem(s, 8))
	{
		/* handle RDP_NEG_REQ response */
		const char *reason = NULL;

		uint8 type = 0, flags = 0;
		uint16 length = 0;
		uint32 data = 0;

		in_uint8(s, type);
		in_uint8(s, flags);
		in_uint16(s, length);
		in_uint32(s, data);

		if (type == RDP_NEG_FAILURE)
		{
			RD_BOOL retry_without_neg = False;

			switch (data)
			{
				case SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER:
					reason = "SSL with user authentication required by server";
					break;
				case SSL_NOT_ALLOWED_BY_SERVER:
					reason = "SSL not allowed by server";
					retry_without_neg = True;
					break;
				case SSL_CERT_NOT_ON_SERVER:
					reason = "no valid authentication certificate on server";
					retry_without_neg = True;
					break;
				case INCONSISTENT_FLAGS:
					reason = "inconsistent negotiation flags";
					break;
				case SSL_REQUIRED_BY_SERVER:
					reason = "SSL required by server";
					break;
				case HYBRID_REQUIRED_BY_SERVER:
					reason = "CredSSP required by server";
					break;
				default:
					reason = "unknown reason";
			}

			tcp_disconnect();

			if (retry_without_neg)
			{
				fprintf(stderr,
					"Failed to negotiate protocol, retrying with plain RDP.\n");
				g_negotiate_rdp_protocol = False;
				goto retry;
			}

			fprintf(stderr, "Failed to connect, %s.\n", reason);
			return False;
		}

		if (type != RDP_NEG_RSP)
		{
			tcp_disconnect();
			error("Expected RDP_NEG_RSP, got type = 0x%x\n", type);
			return False;
		}

		/* handle negotiation response */
		if (data == PROTOCOL_SSL)
		{
			if (!tcp_tls_connect())
			{
				/* failed to connect using cssp, let retry with plain TLS */
				tcp_disconnect();
				neg_proto = PROTOCOL_RDP;
				goto retry;
			}
			/* do not use encryption when using TLS */
			g_encryption = False;
			fprintf(stderr, "Connection established using SSL.\n");
		}
#ifdef WITH_CREDSSP
		else if (data == PROTOCOL_HYBRID)
		{
			if (!cssp_connect(server, username, domain, password, s))
			{
				/* failed to connect using cssp, let retry with plain TLS */
				tcp_disconnect();
				neg_proto = PROTOCOL_SSL;
				goto retry;
			}

			/* do not use encryption when using TLS */
			fprintf(stderr, "Connection established using CredSSP.\n");
			g_encryption = False;
		}
#endif
		else if (data == PROTOCOL_RDP)
		{
			fprintf(stderr, "Connection established using plain RDP.\n");
		}
		else if (data != PROTOCOL_RDP)
		{
			tcp_disconnect();
			error("Unexpected protocol in negotiation response, got data = 0x%x.\n",
			      data);
			return False;
		}

		*selected_protocol = data;
	}
	return True;
}