コード例 #1
0
ファイル: rdp.c プロジェクト: RPG-7/reactos
/* Process a system pointer PDU */
void
process_system_pointer_pdu(STREAM s)
{
	uint16 system_pointer_type;

	in_uint16(s, system_pointer_type);
	switch (system_pointer_type)
	{
		case RDP_NULL_POINTER:
			ui_set_null_cursor();
			break;

		default:
			unimpl("System pointer message 0x%x\n", system_pointer_type);
	}
}
コード例 #2
0
ファイル: licence.c プロジェクト: z0x010/rdesktop
/* Process an licence issue packet */
static void
licence_process_issue(STREAM s)
{
	RC4_KEY crypt_key;
	uint32 length;
	uint16 check;

	in_uint8s(s, 2);	/* 3d 45 - unknown */
	in_uint16_le(s, length);
	if (!s_check_rem(s, length))
		return;

	RC4_set_key(&crypt_key, 16, licence_key);
	RC4(&crypt_key, length, s->p, s->p);

	in_uint16(s, check);
	if (check != 0)
		return;

	licence_issued = True;
	save_licence(s->p, length-2);
}
コード例 #3
0
ファイル: licence.c プロジェクト: HBelusca/NasuTek-Odyssey
/* Process an licence issue packet */
static void
licence_process_issue(STREAM s)
{
	void * crypt_key;
	uint32 length;
	uint16 check;
	int i;

	in_uint8s(s, 2);	/* 3d 45 - unknown */
	in_uint16_le(s, length);
	if (!s_check_rem(s, length))
		return;

	crypt_key = ssl_rc4_info_create();
	ssl_rc4_set_key(crypt_key, (char *)g_licence_key, 16);
	ssl_rc4_crypt(crypt_key, (char *)s->p, (char *)s->p, length);
	ssl_rc4_info_delete(crypt_key);

	in_uint16(s, check);
	if (check != 0)
		return;

	g_licence_issued = True;

	in_uint8s(s, 2);	/* pad */

	/* advance to fourth string */
	length = 0;
	for (i = 0; i < 4; i++)
	{
		in_uint8s(s, length);
		in_uint32_le(s, length);
		if (!s_check_rem(s, length))
			return;
	}

	g_licence_issued = True;
	save_licence(s->p, length);
}
コード例 #4
0
ファイル: licence.c プロジェクト: hoangduit/reactos
/* Process an licence issue packet */
static void
licence_process_issue(RDPCLIENT * This, STREAM s)
{
	RC4_KEY crypt_key;
	uint32 length;
	uint16 check;
	int i;

	in_uint8s(s, 2);	/* 3d 45 - unknown */
	in_uint16_le(s, length);
	if (!s_check_rem(s, length))
		return;

	RC4_set_key(&crypt_key, 16, This->licence.key);
	RC4(&crypt_key, length, s->p, s->p);

	in_uint16(s, check);
	if (check != 0)
		return;

	This->licence_issued = True;

	in_uint8s(s, 2);	/* pad */

	/* advance to fourth string */
	length = 0;
	for (i = 0; i < 4; i++)
	{
		in_uint8s(s, length);
		in_uint32_le(s, length);
		if (!s_check_rem(s, length))
			return;
	}

	This->licence_issued = True;
	save_licence(This, s->p, length);
}
コード例 #5
0
ファイル: licence.c プロジェクト: 3990995/CoRD
/* Process an licence issue packet */
static void
licence_process_issue(RDConnectionRef conn, RDStreamRef s)
{
	RC4_KEY crypt_key;
	uint32 length;
	uint16 check;
	int i;

	in_uint8s(s, 2);	/* 3d 45 - unknown */
	in_uint16_le(s, length);
	if (!s_check_rem(s, length))
		return;

	RC4_set_key(&crypt_key, 16, conn->licenseKey);
	RC4(&crypt_key, length, s->p, s->p);

	in_uint16(s, check);
	if (check != 0)
		return;

	conn->licenseIssued = True;

	in_uint8s(s, 2);	/* pad */

	/* advance to fourth string */
	length = 0;
	for (i = 0; i < 4; i++)
	{
		in_uint8s(s, length);
		in_uint32_le(s, length);
		if (!s_check_rem(s, length))
			return;
	}

	conn->licenseIssued = True;
	save_licence(s->p, length);
}
コード例 #6
0
ファイル: rdp.c プロジェクト: RPG-7/reactos
/* Process data PDU */
static BOOL
process_data_pdu(STREAM s, uint32 * ext_disc_reason)
{
	uint8 data_pdu_type;
	uint8 ctype;
	uint16 clen;
	uint32 len;

	uint32 roff, rlen;

	struct stream *ns = &(g_mppc_dict.ns);

	in_uint8s(s, 6);	/* shareid, pad, streamid */
	in_uint16(s, len);
	in_uint8(s, data_pdu_type);
	in_uint8(s, ctype);
	in_uint16(s, clen);
	clen -= 18;

	if (ctype & RDP_MPPC_COMPRESSED)
	{
		if (len > RDP_MPPC_DICT_SIZE)
			error("error decompressed packet size exceeds max\n");
		if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
			error("error while decompressing packet\n");

		/* len -= 18; */

		/* allocate memory and copy the uncompressed data into the temporary stream */
		ns->data = (uint8 *) xrealloc(ns->data, rlen);

		memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);

		ns->size = rlen;
		ns->end = (ns->data + ns->size);
		ns->p = ns->data;
		ns->rdp_hdr = ns->p;

		s = ns;
	}

	switch (data_pdu_type)
	{
		case RDP_DATA_PDU_UPDATE:
			process_update_pdu(s);
			break;

		case RDP_DATA_PDU_CONTROL:
			DEBUG(("Received Control PDU\n"));
			break;

		case RDP_DATA_PDU_SYNCHRONISE:
			DEBUG(("Received Sync PDU\n"));
			break;

		case RDP_DATA_PDU_POINTER:
			process_pointer_pdu(s);
			break;

		case RDP_DATA_PDU_BELL:
			ui_bell();
			break;

		case RDP_DATA_PDU_LOGON:
			DEBUG(("Received Logon PDU\n"));
			/* User logged on */
			break;

		case RDP_DATA_PDU_DISCONNECT:
			process_disconnect_pdu(s, ext_disc_reason);
			return True;

		default:
			unimpl("data PDU %d\n", data_pdu_type);
	}
	return False;
}
コード例 #7
0
ファイル: rdesktop.c プロジェクト: z0x010/rdesktop
void
save_licence(unsigned char *data, int length)
{
	char *fpath;		/* file path for licence */
	char *fname, *fnamewrk;	/* file name for licence .inkl path. */
	char *home;
	uint32 y;
	struct flock fnfl;
	int fnfd, fnwrkfd, i, wlen;
	struct stream s, *s_ptr;
	uint32 len;

	/* Construct a stream, so that we can use macros to extract the
	 * licence.
	 */
	s_ptr = &s;
	s_ptr->p = data;
	/* Skip first two bytes */
	in_uint16(s_ptr, len);

	/* Skip three strings */
	for (i = 0; i < 3; i++)
	{
		in_uint32(s_ptr, len);
		s_ptr->p += len;
		/* Make sure that we won't be past the end of data after
		 * reading the next length value
		 */
		if ((s_ptr->p) + 4 > data + length)
		{
			printf("Error in parsing licence key.\n");
			printf("Strings %d end value %x > supplied length (%x)\n", i,
			       (unsigned int) s_ptr->p, (unsigned int) data + length);
			return;
		}
	}
	in_uint32(s_ptr, len);
	if (s_ptr->p + len > data + length)
	{
		printf("Error in parsing licence key.\n");
		printf("End of licence %x > supplied length (%x)\n",
		       (unsigned int) s_ptr->p + len, (unsigned int) data + length);
		return;
	}

	home = getenv("HOME");
	if (home == NULL)
		return;

	/* set and create the directory -- if it doesn't exist. */
	fpath = xmalloc(strlen(home) + 11);
	STRNCPY(fpath, home, strlen(home) + 1);

	sprintf(fpath, "%s/.rdesktop", fpath);
	if (mkdir(fpath, 0700) == -1 && errno != EEXIST)
	{
		perror("mkdir");
		exit(1);
	}

	/* set the real licence filename, and put a write lock on it. */
	fname = xmalloc(strlen(fpath) + strlen(hostname) + 10);
	sprintf(fname, "%s/licence.%s", fpath, hostname);
	fnfd = open(fname, O_RDONLY);
	if (fnfd != -1)
	{
		fnfl.l_type = F_WRLCK;
		fnfl.l_whence = SEEK_SET;
		fnfl.l_start = 0;
		fnfl.l_len = 1;
		fcntl(fnfd, F_SETLK, &fnfl);
	}

	/* create a temporary licence file */
	fnamewrk = xmalloc(strlen(fname) + 12);
	for (y = 0;; y++)
	{
		sprintf(fnamewrk, "%s.%lu", fname, (long unsigned int) y);
		fnwrkfd = open(fnamewrk, O_WRONLY | O_CREAT | O_EXCL, 0600);
		if (fnwrkfd == -1)
		{
			if (errno == EINTR || errno == EEXIST)
				continue;
			perror("create");
			exit(1);
		}
		break;
	}
	/* write to the licence file */
	for (y = 0; y < len;)
	{
		do
		{
			wlen = write(fnwrkfd, s_ptr->p + y, len - y);
		}
		while (wlen == -1 && errno == EINTR);
		if (wlen < 1)
		{
			perror("write");
			unlink(fnamewrk);
			exit(1);
		}
		y += wlen;
	}

	/* close the file and rename it to fname */
	if (close(fnwrkfd) == -1)
	{
		perror("close");
		unlink(fnamewrk);
		exit(1);
	}
	if (rename(fnamewrk, fname) == -1)
	{
		perror("rename");
		unlink(fnamewrk);
		exit(1);
	}
	/* close the file lock on fname */
	if (fnfd != -1)
	{
		fnfl.l_type = F_UNLCK;
		fnfl.l_whence = SEEK_SET;
		fnfl.l_start = 0;
		fnfl.l_len = 1;
		fcntl(fnfd, F_SETLK, &fnfl);
		close(fnfd);
	}

}
コード例 #8
0
ファイル: iso.c プロジェクト: gvsurenderreddy/rdesktopce_rdp5
/* 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;
}
コード例 #9
0
ファイル: rdp.c プロジェクト: hoangduit/reactos
/* Process data PDU */
static BOOL
process_data_pdu(RDPCLIENT * This, STREAM s, uint32 * ext_disc_reason)
{
	uint8 data_pdu_type;
	uint8 ctype;
	uint16 clen;
	uint32 len;

	uint32 roff, rlen;

	struct stream *ns = &(This->mppc_dict.ns);

	in_uint8s(s, 6);	/* shareid, pad, streamid */
	in_uint16(s, len);
	in_uint8(s, data_pdu_type);
	in_uint8(s, ctype);
	in_uint16(s, clen);
	clen -= 18;

	if (ctype & RDP_MPPC_COMPRESSED)
	{
		void * p;

		if (len > RDP_MPPC_DICT_SIZE)
			error("error decompressed packet size exceeds max\n");
		if (mppc_expand(This, s->p, clen, ctype, &roff, &rlen) == -1)
			error("error while decompressing packet\n");

		/* len -= 18; */

		/* allocate memory and copy the uncompressed data into the temporary stream */
		p = realloc(ns->data, rlen);

		if(p == NULL)
		{
			This->disconnect_reason = 262;
			return True;
		}

		ns->data = (uint8 *) p;

		memcpy((ns->data), (unsigned char *) (This->mppc_dict.hist + roff), rlen);

		ns->size = rlen;
		ns->end = (ns->data + ns->size);
		ns->p = ns->data;
		ns->rdp_hdr = ns->p;

		s = ns;
	}

	switch (data_pdu_type)
	{
		case RDP_DATA_PDU_UPDATE:
			process_update_pdu(This, s);
			break;

		case RDP_DATA_PDU_CONTROL:
			DEBUG(("Received Control PDU\n"));
			break;

		case RDP_DATA_PDU_SYNCHRONISE:
			DEBUG(("Received Sync PDU\n"));
			break;

		case RDP_DATA_PDU_POINTER:
			process_pointer_pdu(This, s);
			break;

		case RDP_DATA_PDU_BELL:
			ui_bell(This);
			break;

		case RDP_DATA_PDU_LOGON:
			DEBUG(("Received Logon PDU\n"));
			event_logon(This);
			/* User logged on */
			break;

		case RDP_DATA_PDU_DISCONNECT:
			process_disconnect_pdu(s, ext_disc_reason);

			/* We used to return true and disconnect immediately here, but
			 * Windows Vista sends a disconnect PDU with reason 0 when
			 * reconnecting to a disconnected session, and MSTSC doesn't
			 * drop the connection.  I think we should just save the status.
			 */
			break;

		default:
			unimpl("data PDU %d\n", data_pdu_type);
	}
	return False;
}
コード例 #10
0
ファイル: iso.c プロジェクト: BojanCendio/rdesktop
/* 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;
}