⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rdp.c

📁 rdesktop is a client for Microsoft Windows NT Terminal Server, Windows 2000 Terminal Services, Wind
💻 C
📖 第 1 页 / 共 3 页
字号:
/* -*- c-basic-offset: 8 -*-   rdesktop: A Remote Desktop Protocol client.   Protocol services - RDP layer   Copyright (C) Matthew Chapman 1999-2005   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include <time.h>#include <errno.h>#include <unistd.h>#include "rdesktop.h"#ifdef HAVE_ICONV#ifdef HAVE_ICONV_H#include <iconv.h>#endif#ifndef ICONV_CONST#define ICONV_CONST ""#endif#endifextern uint16 g_mcs_userid;extern char g_username[64];extern char g_codepage[16];extern BOOL g_bitmap_compression;extern BOOL g_orders;extern BOOL g_encryption;extern BOOL g_desktop_save;extern BOOL g_polygon_ellipse_orders;extern BOOL g_use_rdp5;extern uint16 g_server_rdp_version;extern uint32 g_rdp5_performanceflags;extern int g_server_depth;extern int g_width;extern int g_height;extern BOOL g_bitmap_cache;extern BOOL g_bitmap_cache_persist_enable;extern BOOL g_numlock_sync;uint8 *g_next_packet;uint32 g_rdp_shareid;extern RDPCOMP g_mppc_dict;/* Session Directory support */extern BOOL g_redirect;extern char g_redirect_server[64];extern char g_redirect_domain[16];extern char g_redirect_password[64];extern char g_redirect_username[64];extern char g_redirect_cookie[128];extern uint32 g_redirect_flags;/* END Session Directory support */#if WITH_DEBUGstatic uint32 g_packetno;#endif#ifdef HAVE_ICONVstatic BOOL g_iconv_works = True;#endif/* Receive an RDP packet */static STREAMrdp_recv(uint8 * type){	static STREAM rdp_s;	uint16 length, pdu_type;	uint8 rdpver;	if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end) || (g_next_packet == NULL))	{		rdp_s = sec_recv(&rdpver);		if (rdp_s == NULL)			return NULL;		if (rdpver == 0xff)		{			g_next_packet = rdp_s->end;			*type = 0;			return rdp_s;		}		else if (rdpver != 3)		{			/* rdp5_process should move g_next_packet ok */			rdp5_process(rdp_s);			*type = 0;			return rdp_s;		}		g_next_packet = rdp_s->p;	}	else	{		rdp_s->p = g_next_packet;	}	in_uint16_le(rdp_s, length);	/* 32k packets are really 8, keepalive fix */	if (length == 0x8000)	{		g_next_packet += 8;		*type = 0;		return rdp_s;	}	in_uint16_le(rdp_s, pdu_type);	in_uint8s(rdp_s, 2);	/* userid */	*type = pdu_type & 0xf;#if WITH_DEBUG	DEBUG(("RDP packet #%d, (type %x)\n", ++g_packetno, *type));	hexdump(g_next_packet, length);#endif /*  */	g_next_packet += length;	return rdp_s;}/* Initialise an RDP data packet */static STREAMrdp_init_data(int maxlen){	STREAM s;	s = sec_init(g_encryption ? SEC_ENCRYPT : 0, maxlen + 18);	s_push_layer(s, rdp_hdr, 18);	return s;}/* Send an RDP data packet */static voidrdp_send_data(STREAM s, uint8 data_pdu_type){	uint16 length;	s_pop_layer(s, rdp_hdr);	length = s->end - s->p;	out_uint16_le(s, length);	out_uint16_le(s, (RDP_PDU_DATA | 0x10));	out_uint16_le(s, (g_mcs_userid + 1001));	out_uint32_le(s, g_rdp_shareid);	out_uint8(s, 0);	/* pad */	out_uint8(s, 1);	/* streamid */	out_uint16_le(s, (length - 14));	out_uint8(s, data_pdu_type);	out_uint8(s, 0);	/* compress_type */	out_uint16(s, 0);	/* compress_len */	sec_send(s, g_encryption ? SEC_ENCRYPT : 0);}/* Output a string in Unicode */voidrdp_out_unistr(STREAM s, char *string, int len){#ifdef HAVE_ICONV	size_t ibl = strlen(string), obl = len + 2;	static iconv_t iconv_h = (iconv_t) - 1;	char *pin = string, *pout = (char *) s->p;	memset(pout, 0, len + 4);	if (g_iconv_works)	{		if (iconv_h == (iconv_t) - 1)		{			size_t i = 1, o = 4;			if ((iconv_h = iconv_open(WINDOWS_CODEPAGE, g_codepage)) == (iconv_t) - 1)			{				warning("rdp_out_unistr: iconv_open[%s -> %s] fail %d\n",					g_codepage, WINDOWS_CODEPAGE, (int) iconv_h);				g_iconv_works = False;				rdp_out_unistr(s, string, len);				return;			}			if (iconv(iconv_h, (ICONV_CONST char **) &pin, &i, &pout, &o) ==			    (size_t) - 1)			{				iconv_close(iconv_h);				iconv_h = (iconv_t) - 1;				warning("rdp_out_unistr: iconv(1) fail, errno %d\n", errno);				g_iconv_works = False;				rdp_out_unistr(s, string, len);				return;			}			pin = string;			pout = (char *) s->p;		}		if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)		{			iconv_close(iconv_h);			iconv_h = (iconv_t) - 1;			warning("rdp_out_unistr: iconv(2) fail, errno %d\n", errno);			g_iconv_works = False;			rdp_out_unistr(s, string, len);			return;		}		s->p += len + 2;	}	else#endif	{		int i = 0, j = 0;		len += 2;		while (i < len)		{			s->p[i++] = string[j++];			s->p[i++] = 0;		}		s->p += len;	}}/* Input a string in Unicode * * Returns str_len of string */intrdp_in_unistr(STREAM s, char *string, int uni_len){#ifdef HAVE_ICONV	size_t ibl = uni_len, obl = uni_len;	char *pin = (char *) s->p, *pout = string;	static iconv_t iconv_h = (iconv_t) - 1;	if (g_iconv_works)	{		if (iconv_h == (iconv_t) - 1)		{			if ((iconv_h = iconv_open(g_codepage, WINDOWS_CODEPAGE)) == (iconv_t) - 1)			{				warning("rdp_in_unistr: iconv_open[%s -> %s] fail %d\n",					WINDOWS_CODEPAGE, g_codepage, (int) iconv_h);				g_iconv_works = False;				return rdp_in_unistr(s, string, uni_len);			}		}		if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)		{			iconv_close(iconv_h);			iconv_h = (iconv_t) - 1;			warning("rdp_in_unistr: iconv fail, errno %d\n", errno);			g_iconv_works = False;			return rdp_in_unistr(s, string, uni_len);		}		/* we must update the location of the current STREAM for future reads of s->p */		s->p += uni_len;		return pout - string;	}	else#endif	{		int i = 0;		while (i < uni_len / 2)		{			in_uint8a(s, &string[i++], 1);			in_uint8s(s, 1);		}		return i - 1;	}}/* Parse a logon info packet */static voidrdp_send_logon_info(uint32 flags, char *domain, char *user,		    char *password, char *program, char *directory){	char *ipaddr = tcp_get_address();	int len_domain = 2 * strlen(domain);	int len_user = 2 * strlen(user);	int len_password = 2 * strlen(password);	int len_program = 2 * strlen(program);	int len_directory = 2 * strlen(directory);	int len_ip = 2 * strlen(ipaddr);	int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll");	int packetlen = 0;	uint32 sec_flags = g_encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;	STREAM s;	time_t t = time(NULL);	time_t tzone;	if (!g_use_rdp5 || 1 == g_server_rdp_version)	{		DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));		s = sec_init(sec_flags, 18 + len_domain + len_user + len_password			     + len_program + len_directory + 10);		out_uint32(s, 0);		out_uint32_le(s, flags);		out_uint16_le(s, len_domain);		out_uint16_le(s, len_user);		out_uint16_le(s, len_password);		out_uint16_le(s, len_program);		out_uint16_le(s, len_directory);		rdp_out_unistr(s, domain, len_domain);		rdp_out_unistr(s, user, len_user);		rdp_out_unistr(s, password, len_password);		rdp_out_unistr(s, program, len_program);		rdp_out_unistr(s, directory, len_directory);	}	else	{		flags |= RDP_LOGON_BLOB;		DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));		packetlen = 4 +	/* Unknown uint32 */			4 +	/* flags */			2 +	/* len_domain */			2 +	/* len_user */			(flags & RDP_LOGON_AUTO ? 2 : 0) +	/* len_password */			(flags & RDP_LOGON_BLOB ? 2 : 0) +	/* Length of BLOB */			2 +	/* len_program */			2 +	/* len_directory */			(0 < len_domain ? len_domain : 2) +	/* domain */			len_user + (flags & RDP_LOGON_AUTO ? len_password : 0) + 0 +	/* We have no 512 byte BLOB. Perhaps we must? */			(flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO) ? 2 : 0) +	/* After the BLOB is a unknown int16. If there is a BLOB, that is. */			(0 < len_program ? len_program : 2) + (0 < len_directory ? len_directory : 2) + 2 +	/* Unknown (2) */			2 +	/* Client ip length */			len_ip +	/* Client ip */			2 +	/* DLL string length */			len_dll +	/* DLL string */			2 +	/* Unknown */			2 +	/* Unknown */			64 +	/* Time zone #0 */			2 +	/* Unknown */			64 +	/* Time zone #1 */			32;	/* Unknown */		s = sec_init(sec_flags, packetlen);		DEBUG_RDP5(("Called sec_init with packetlen %d\n", packetlen));		out_uint32(s, 0);	/* Unknown */		out_uint32_le(s, flags);		out_uint16_le(s, len_domain);		out_uint16_le(s, len_user);		if (flags & RDP_LOGON_AUTO)		{			out_uint16_le(s, len_password);		}		if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))		{			out_uint16_le(s, 0);		}		out_uint16_le(s, len_program);		out_uint16_le(s, len_directory);		if (0 < len_domain)			rdp_out_unistr(s, domain, len_domain);		else			out_uint16_le(s, 0);		rdp_out_unistr(s, user, len_user);		if (flags & RDP_LOGON_AUTO)		{			rdp_out_unistr(s, password, len_password);		}		if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))		{			out_uint16_le(s, 0);		}		if (0 < len_program)		{			rdp_out_unistr(s, program, len_program);		}		else		{			out_uint16_le(s, 0);		}		if (0 < len_directory)		{			rdp_out_unistr(s, directory, len_directory);		}		else		{			out_uint16_le(s, 0);		}		out_uint16_le(s, 2);		out_uint16_le(s, len_ip + 2);	/* Length of client ip */		rdp_out_unistr(s, ipaddr, len_ip);		out_uint16_le(s, len_dll + 2);		rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll);		tzone = (mktime(gmtime(&t)) - mktime(localtime(&t))) / 60;		out_uint32_le(s, tzone);		rdp_out_unistr(s, "GTB, normaltid", 2 * strlen("GTB, normaltid"));		out_uint8s(s, 62 - 2 * strlen("GTB, normaltid"));		out_uint32_le(s, 0x0a0000);		out_uint32_le(s, 0x050000);		out_uint32_le(s, 3);		out_uint32_le(s, 0);		out_uint32_le(s, 0);		rdp_out_unistr(s, "GTB, sommartid", 2 * strlen("GTB, sommartid"));		out_uint8s(s, 62 - 2 * strlen("GTB, sommartid"));		out_uint32_le(s, 0x30000);		out_uint32_le(s, 0x050000);		out_uint32_le(s, 2);		out_uint32(s, 0);		out_uint32_le(s, 0xffffffc4);		out_uint32_le(s, 0xfffffffe);		out_uint32_le(s, g_rdp5_performanceflags);		out_uint32(s, 0);	}	s_mark_end(s);	sec_send(s, sec_flags);}/* Send a control PDU */static voidrdp_send_control(uint16 action){	STREAM s;	s = rdp_init_data(8);	out_uint16_le(s, action);	out_uint16(s, 0);	/* userid */	out_uint32(s, 0);	/* control id */	s_mark_end(s);	rdp_send_data(s, RDP_DATA_PDU_CONTROL);}/* Send a synchronisation PDU */static voidrdp_send_synchronise(void){	STREAM s;	s = rdp_init_data(4);	out_uint16_le(s, 1);	/* type */	out_uint16_le(s, 1002);	s_mark_end(s);	rdp_send_data(s, RDP_DATA_PDU_SYNCHRONISE);}/* Send a single input event */voidrdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, uint16 param2){	STREAM s;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -