Exemple #1
0
static void
rdpdr_send_available(RDPCLIENT * This)
{

	uint8 magic[4] = "rDAD";
	uint32 driverlen, printerlen, bloblen;
	int i;
	STREAM s;
	PRINTER *printerinfo;

	s = channel_init(This, This->rdpdr.channel, announcedata_size(This));
	out_uint8a(s, magic, 4);
	out_uint32_le(s, This->num_devices);

	for (i = 0; i < This->num_devices; i++)
	{
		out_uint32_le(s, This->rdpdr_device[i].device_type);
		out_uint32_le(s, i);	/* RDP Device ID */
		/* Is it possible to use share names longer than 8 chars?
		   /astrand */
		out_uint8p(s, This->rdpdr_device[i].name, 8);

		switch (This->rdpdr_device[i].device_type)
		{
			case DEVICE_TYPE_PRINTER:
				printerinfo = (PRINTER *) This->rdpdr_device[i].pdevice_data;

				driverlen = 2 * strlen(printerinfo->driver) + 2;
				printerlen = 2 * strlen(printerinfo->printer) + 2;
				bloblen = printerinfo->bloblen;

				out_uint32_le(s, 24 + driverlen + printerlen + bloblen);	/* length of extra info */
				out_uint32_le(s, printerinfo->default_printer ? 2 : 0);
				out_uint8s(s, 8);	/* unknown */
				out_uint32_le(s, driverlen);
				out_uint32_le(s, printerlen);
				out_uint32_le(s, bloblen);
				rdp_out_unistr(This, s, printerinfo->driver, driverlen - 2);
				rdp_out_unistr(This, s, printerinfo->printer, printerlen - 2);
				out_uint8a(s, printerinfo->blob, bloblen);

				if (printerinfo->blob)
					xfree(printerinfo->blob);	/* Blob is sent twice if reconnecting */
				break;
			default:
				out_uint32(s, 0);
		}
	}
#if 0
	out_uint32_le(s, 0x20);	/* Device type 0x20 - smart card */
	out_uint32_le(s, 0);
	out_uint8p(s, "SCARD", 5);
	out_uint8s(s, 3);
	out_uint32(s, 0);
#endif

	s_mark_end(s);
	channel_send(This, s, This->rdpdr.channel);
}
Exemple #2
0
/* Output order capability set */
static void rdp_out_order_caps(STREAM s) {
	uint8 order_caps[32];

	memset(order_caps, 0, 32);
	order_caps[0] = 1; /* dest blt */
	order_caps[1] = 1; /* pat blt */
	order_caps[2] = 1; /* screen blt */
	order_caps[3] = (g_bitmap_cache ? 1 : 0); /* memblt */
	order_caps[4] = 0; /* triblt */
	order_caps[8] = 1; /* line */
	order_caps[9] = 1; /* line */
	order_caps[10] = 1; /* rect */
	order_caps[11] = (g_desktop_save ? 1 : 0); /* desksave */
	order_caps[13] = 1; /* memblt */
	order_caps[14] = 1; /* triblt */
	order_caps[20] = (g_polygon_ellipse_orders ? 1 : 0); /* polygon */
	order_caps[21] = (g_polygon_ellipse_orders ? 1 : 0); /* polygon2 */
	order_caps[22] = 1; /* polyline */
	order_caps[25] = (g_polygon_ellipse_orders ? 1 : 0); /* ellipse */
	order_caps[26] = (g_polygon_ellipse_orders ? 1 : 0); /* ellipse2 */
	order_caps[27] = 1; /* text2 */
	out_uint16_le(s, RDP_CAPSET_ORDER);
	out_uint16_le(s, RDP_CAPLEN_ORDER);

	out_uint8s(s, 20);
	/* Terminal desc, pad */
	out_uint16_le(s, 1);
	/* Cache X granularity */
	out_uint16_le(s, 20);
	/* Cache Y granularity */
	out_uint16(s, 0);
	/* Pad */
	out_uint16_le(s, 1);
	/* Max order level */
	out_uint16_le(s, 0x147);
	/* Number of fonts */
	out_uint16_le(s, 0x2a);
	/* Capability flags */
	out_uint8p(s, order_caps, 32);
	/* Orders supported */
	out_uint16_le(s, 0x6a1);
	/* Text capability flags */
	out_uint8s(s, 6);
	/* Pad */
	out_uint32_le(s, g_desktop_save == False ? 0 : 0x38400);
	/* Desktop cache size */
	out_uint32(s, 0);
	/* Unknown */
	out_uint32_le(s, 0x4e4);
	/* Unknown */
}
Exemple #3
0
/* Send a control PDU */
static void
rdp_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);
}
Exemple #4
0
static void
cliprdr_send_packet(uint16 type, uint16 status, uint8 * data, uint32 length)
{
	STREAM s;

	DEBUG_CLIPBOARD(("CLIPRDR send: type=%d, status=%d, length=%d\n", type, status, length));

	s = channel_init(cliprdr_channel, length + 12);
	out_uint16_le(s, type);
	out_uint16_le(s, status);
	out_uint32_le(s, length);
	out_uint8p(s, data, length);
	out_uint32(s, 0);	/* pad? */
	s_mark_end(s);
	channel_send(s, cliprdr_channel);
}
Exemple #5
0
/* Send a control PDU */
static BOOL
rdp_send_control(RDPCLIENT * This, uint16 action)
{
	STREAM s;

	s = rdp_init_data(This, 8);

	if(s == NULL)
		return False;

	out_uint16_le(s, action);
	out_uint16(s, 0);	/* userid */
	out_uint32(s, 0);	/* control id */

	s_mark_end(s);
	return rdp_send_data(This, s, RDP_DATA_PDU_CONTROL);
}
static void
iso_send_connection_request(char *username)
{
	STREAM s;
	int length = 30 + strlen(username);

	if (g_rdp_version >= RDP_V5 && g_negotiate_rdp_protocol)
		length += 8;

	s = tcp_init(length);

	out_uint8(s, 3);	/* version */
	out_uint8(s, 0);	/* reserved */
	out_uint16_be(s, length);	/* length */

	out_uint8(s, length - 5);	/* hdrlen */
	out_uint8(s, ISO_PDU_CR);
	out_uint16(s, 0);	/* dst_ref */
	out_uint16(s, 0);	/* src_ref */
	out_uint8(s, 0);	/* class */

	out_uint8p(s, "Cookie: mstshash=", strlen("Cookie: mstshash="));
	out_uint8p(s, username, strlen(username));

	out_uint8(s, 0x0d);	/* cookie termination string: CR+LF */
	out_uint8(s, 0x0a);

	if (g_rdp_version >= RDP_V5 && g_negotiate_rdp_protocol)
	{
		/* optional rdp protocol negotiation request for RDPv5 */
		out_uint8(s, RDP_NEG_REQ);
		out_uint8(s, 0);
		out_uint16(s, 8);
		out_uint32(s, PROTOCOL_SSL);
	}

	s_mark_end(s);
	tcp_send(s);
}
Exemple #7
0
static void
rdpdr_send_name(RDPCLIENT * This)
{
	uint8 magic[4] = "rDNC";
	STREAM s;
	uint32 hostlen;

	if (NULL == This->rdpdr_clientname)
	{
		This->rdpdr_clientname = This->hostname;
	}
	hostlen = (strlen(This->rdpdr_clientname) + 1) * 2;

	s = channel_init(This, This->rdpdr.channel, 16 + hostlen);
	out_uint8a(s, magic, 4);
	out_uint16_le(s, 0x63);	/* unknown */
	out_uint16_le(s, 0x72);
	out_uint32(s, 0);
	out_uint32_le(s, hostlen);
	rdp_out_unistr(This, s, This->rdpdr_clientname, hostlen - 2);
	s_mark_end(s);
	channel_send(This, s, This->rdpdr.channel);
}
static void
rdpdr_send_name(void)
{
	uint8 magic[4] = "rDNC";
	STREAM s;
	uint32 hostlen;

	if (NULL == g_rdpdr_clientname)
	{
		g_rdpdr_clientname = g_hostname;
	}
	hostlen = (strlen(g_rdpdr_clientname) + 1) * 2;

	s = channel_init(rdpdr_channel, 16 + hostlen);
	out_uint8a(s, magic, 4);
	out_uint16_le(s, 0x63);	/* unknown */
	out_uint16_le(s, 0x72);
	out_uint32(s, 0);
	out_uint32_le(s, hostlen);
	rdp_out_unistr(s, g_rdpdr_clientname, hostlen - 2);
	s_mark_end(s);
	channel_send(s, rdpdr_channel);
}
Exemple #9
0
/* Parse a logon info packet */
static void
rdp_send_logon_info(uint32 flags, char *domain, char *user,
                    char *password, char *program, char *directory)
{
    char *ipaddr = tcp_get_address();
    /* length of string in TS_INFO_PACKET excludes null terminator */
    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);

    /* length of strings in TS_EXTENDED_PACKET includes null terminator */
    int len_ip = 2 * strlen(ipaddr) + 2;
    int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll") + 2;

    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;
    uint8 security_verifier[16];

    if (g_rdp_version == RDP_V4 || 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
    {

        DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));

        if (g_redirect == True && g_redirect_cookie_len > 0)
        {
            len_password = g_redirect_cookie_len;
            len_password -= 2;	/* substract 2 bytes which is added below */
        }

        packetlen =
            /* size of TS_INFO_PACKET */
            4 +	/* CodePage */
            4 +	/* flags */
            2 +	/* cbDomain */
            2 +	/* cbUserName */
            2 +	/* cbPassword */
            2 +	/* cbAlternateShell */
            2 +	/* cbWorkingDir */
            2 + len_domain +	/* Domain */
            2 + len_user +	/* UserName */
            2 + len_password +	/* Password */
            2 + len_program +	/* AlternateShell */
            2 + len_directory +	/* WorkingDir */
            /* size of TS_EXTENDED_INFO_PACKET */
            2 +	/* clientAdressFamily */
            2 +	/* cbClientAdress */
            len_ip +	/* clientAddress */
            2 +	/* cbClientDir */
            len_dll +	/* clientDir */
            /* size of TS_TIME_ZONE_INFORMATION */
            4 +	/* Bias, (UTC = local time + bias */
            64 +	/* StandardName, 32 unicode char array, Descriptive standard time on client */
            16 +	/* StandardDate */
            4 +	/* StandardBias */
            64 +	/* DaylightName, 32 unicode char array */
            16 +	/* DaylightDate */
            4 +	/* DaylightBias */
            4 +	/* clientSessionId */
            4 +	/* performanceFlags */
            2 +	/* cbAutoReconnectCookie, either 0 or 0x001c */
            /* size of ARC_CS_PRIVATE_PACKET */
            28;	/* autoReconnectCookie */


        s = sec_init(sec_flags, packetlen);
        DEBUG_RDP5(("Called sec_init with packetlen %d\n", packetlen));

        /* TS_INFO_PACKET */
        out_uint32(s, 0);	/* Code Page */
        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);

        if (0 < len_domain)
            rdp_out_unistr(s, domain, len_domain);
        else
            out_uint16_le(s, 0);	/* mandatory 2 bytes null terminator */

        if (0 < len_user)
            rdp_out_unistr(s, user, len_user);
        else
            out_uint16_le(s, 0);	/* mandatory 2 bytes null terminator */

        if (0 < len_password)
        {
            if (g_redirect == True && 0 < g_redirect_cookie_len)
            {
                out_uint8p(s, g_redirect_cookie, g_redirect_cookie_len);
            }
            else
            {
                rdp_out_unistr(s, password, len_password);
            }
        }
        else
            out_uint16_le(s, 0);	/* mandatory 2 bytes null terminator */

        if (0 < len_program)
            rdp_out_unistr(s, program, len_program);
        else
            out_uint16_le(s, 0);	/* mandatory 2 bytes null terminator */

        if (0 < len_directory)
            rdp_out_unistr(s, directory, len_directory);
        else
            out_uint16_le(s, 0);	/* mandatory 2 bytes null terminator */

        /* TS_EXTENDED_INFO_PACKET */
        out_uint16_le(s, 2);	/* clientAddressFamily = AF_INET */
        out_uint16_le(s, len_ip);	/* cbClientAddress, Length of client ip */
        rdp_out_unistr(s, ipaddr, len_ip - 2);	/* clientAddress */
        out_uint16_le(s, len_dll);	/* cbClientDir */
        rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll - 2);	/* clientDir */

        /* TS_TIME_ZONE_INFORMATION */
        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);	/* DaylightBias */

        /* Rest of TS_EXTENDED_INFO_PACKET */
        out_uint32_le(s, 0);	/* clientSessionId (Ignored by server MUST be 0) */
        out_uint32_le(s, g_rdp5_performanceflags);

        /* Client Auto-Reconnect */
        if (g_has_reconnect_random)
        {
            out_uint16_le(s, 28);	/* cbAutoReconnectLen */
            /* ARC_CS_PRIVATE_PACKET */
            out_uint32_le(s, 28);	/* cbLen */
            out_uint32_le(s, 1);	/* Version */
            out_uint32_le(s, g_reconnect_logonid);	/* LogonId */
            rdssl_hmac_md5(g_reconnect_random, sizeof(g_reconnect_random),
                           g_client_random, SEC_RANDOM_SIZE, security_verifier);
            out_uint8a(s, security_verifier, sizeof(security_verifier));
        }
        else
        {
            out_uint16_le(s, 0);	/* cbAutoReconnectLen */
        }

    }
    s_mark_end(s);

    /* clear the redirect flag */
    g_redirect = False;

    sec_send(s, sec_flags);
}
Exemple #10
0
/* Parse a logon info packet */
static void
rdp_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 = NULL;
	//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
	{
#if 0
		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);

#endif
	}
	s_mark_end(s);
	sec_send(s, sec_flags);
}
Exemple #11
0
static void
rdpsnd_process_negotiate(STREAM in)
{
	uint16 in_format_count, i;
	uint8 pad;
	uint16 version;
	RD_WAVEFORMATEX *format;
	STREAM out;
	RD_BOOL device_available = False;
	int readcnt;
	int discardcnt;

	in_uint8s(in, 14);	/* initial bytes not valid from server */
	in_uint16_le(in, in_format_count);
	in_uint8(in, pad);
	in_uint16_le(in, version);
	in_uint8s(in, 1);	/* padding */

	DEBUG_SOUND(("RDPSND: RDPSND_NEGOTIATE(formats: %d, pad: 0x%02x, version: %x)\n",
		     (int) in_format_count, (unsigned) pad, (unsigned) version));

	if (rdpsnd_negotiated)
	{
		error("RDPSND: Extra RDPSND_NEGOTIATE in the middle of a session\n");
		/* Do a complete reset of the sound state */
		rdpsnd_reset_state();
	}

	if (!current_driver && g_rdpsnd)
		device_available = rdpsnd_auto_select();

	if (current_driver && !device_available && current_driver->wave_out_open())
	{
		current_driver->wave_out_close();
		device_available = True;
	}

	format_count = 0;
	if (s_check_rem(in, 18 * in_format_count))
	{
		for (i = 0; i < in_format_count; i++)
		{
			format = &formats[format_count];
			in_uint16_le(in, format->wFormatTag);
			in_uint16_le(in, format->nChannels);
			in_uint32_le(in, format->nSamplesPerSec);
			in_uint32_le(in, format->nAvgBytesPerSec);
			in_uint16_le(in, format->nBlockAlign);
			in_uint16_le(in, format->wBitsPerSample);
			in_uint16_le(in, format->cbSize);

			/* read in the buffer of unknown use */
			readcnt = format->cbSize;
			discardcnt = 0;
			if (format->cbSize > MAX_CBSIZE)
			{
				fprintf(stderr, "cbSize too large for buffer: %d\n",
					format->cbSize);
				readcnt = MAX_CBSIZE;
				discardcnt = format->cbSize - MAX_CBSIZE;
			}
			in_uint8a(in, format->cb, readcnt);
			in_uint8s(in, discardcnt);

			if (current_driver && current_driver->wave_out_format_supported(format))
			{
				format_count++;
				if (format_count == MAX_FORMATS)
					break;
			}
		}
	}

	out = rdpsnd_init_packet(RDPSND_NEGOTIATE | 0x200, 20 + 18 * format_count);

	uint32 flags = TSSNDCAPS_VOLUME;

	/* if sound is enabled, set snd caps to alive to enable
	   transmision of audio from server */
	if (g_rdpsnd)
	{
		flags |= TSSNDCAPS_ALIVE;
	}
	out_uint32_le(out, flags);	/* TSSNDCAPS flags */

	out_uint32(out, 0xffffffff);	/* volume */
	out_uint32(out, 0);	/* pitch */
	out_uint16(out, 0);	/* UDP port */

	out_uint16_le(out, format_count);
	out_uint8(out, 0);	/* padding */
	out_uint16_le(out, 2);	/* version */
	out_uint8(out, 0);	/* padding */

	for (i = 0; i < format_count; i++)
	{
		format = &formats[i];
		out_uint16_le(out, format->wFormatTag);
		out_uint16_le(out, format->nChannels);
		out_uint32_le(out, format->nSamplesPerSec);
		out_uint32_le(out, format->nAvgBytesPerSec);
		out_uint16_le(out, format->nBlockAlign);
		out_uint16_le(out, format->wBitsPerSample);
		out_uint16(out, 0);	/* cbSize */
	}

	s_mark_end(out);

	DEBUG_SOUND(("RDPSND: -> RDPSND_NEGOTIATE(formats: %d)\n", (int) format_count));

	rdpsnd_send(out);

	rdpsnd_negotiated = True;
}
/* Parse a logon info packet */
static void
rdp_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;
	uint8 security_verifier[16];

	if (g_rdp_version == RDP_V4 || 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);
		}
		/* TS_EXTENDED_INFO_PACKET */
		out_uint16_le(s, 2);	/* clientAddressFamily = AF_INET */
		out_uint16_le(s, len_ip + 2);	/* cbClientAddress, Length of client ip */
		rdp_out_unistr(s, ipaddr, len_ip);	/* clientAddress */
		out_uint16_le(s, len_dll + 2);	/* cbClientDir */
		rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll);	/* clientDir */

		/* TS_TIME_ZONE_INFORMATION */
		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);	/* DaylightBias */

		/* Rest of TS_EXTENDED_INFO_PACKET */
		out_uint32_le(s, 0xfffffffe);	/* clientSessionId, consider changing to 0 */
		out_uint32_le(s, g_rdp5_performanceflags);

		/* Client Auto-Reconnect */
		if (g_has_reconnect_random)
		{
			out_uint16_le(s, 28);	/* cbAutoReconnectLen */
			/* ARC_CS_PRIVATE_PACKET */
			out_uint32_le(s, 28);	/* cbLen */
			out_uint32_le(s, 1);	/* Version */
			out_uint32_le(s, g_reconnect_logonid);	/* LogonId */
			rdssl_hmac_md5(g_reconnect_random, sizeof(g_reconnect_random),
				       g_client_random, SEC_RANDOM_SIZE, security_verifier);
			out_uint8a(s, security_verifier, sizeof(security_verifier));
		}
		else
		{
			out_uint16_le(s, 0);	/* cbAutoReconnectLen */
		}

	}
	s_mark_end(s);
	sec_send(s, sec_flags);
}
Exemple #13
0
void
rdpsnd_process_negotiate(STREAM in)
{
	unsigned int in_format_count, i;
	WAVEFORMATEX *format;
	STREAM out;
	BOOL device_available = False;
	int readcnt;
	int discardcnt;

	in_uint8s(in, 14);	/* flags, volume, pitch, UDP port */
	in_uint16_le(in, in_format_count);
	in_uint8s(in, 4);	/* pad, status, pad */

	if (wave_out_open())
	{
		wave_out_close();
		device_available = True;
	}

	format_count = 0;
	if (s_check_rem(in, 18 * in_format_count))
	{
		for (i = 0; i < in_format_count; i++)
		{
			format = &formats[format_count];
			in_uint16_le(in, format->wFormatTag);
			in_uint16_le(in, format->nChannels);
			in_uint32_le(in, format->nSamplesPerSec);
			in_uint32_le(in, format->nAvgBytesPerSec);
			in_uint16_le(in, format->nBlockAlign);
			in_uint16_le(in, format->wBitsPerSample);
			in_uint16_le(in, format->cbSize);

			/* read in the buffer of unknown use */
			readcnt = format->cbSize;
			discardcnt = 0;
			if (format->cbSize > MAX_CBSIZE)
			{
				fprintf(stderr, "cbSize too large for buffer: %d\n",
					format->cbSize);
				readcnt = MAX_CBSIZE;
				discardcnt = format->cbSize - MAX_CBSIZE;
			}
			in_uint8a(in, format->cb, readcnt);
			in_uint8s(in, discardcnt);

			if (device_available && wave_out_format_supported(format))
			{
				format_count++;
				if (format_count == MAX_FORMATS)
					break;
			}
		}
	}

	out = rdpsnd_init_packet(RDPSND_NEGOTIATE | 0x200, 20 + 18 * format_count);
	out_uint32_le(out, 3);	/* flags */
	out_uint32(out, 0xffffffff);	/* volume */
	out_uint32(out, 0);	/* pitch */
	out_uint16(out, 0);	/* UDP port */

	out_uint16_le(out, format_count);
	out_uint8(out, 0x95);	/* pad? */
	out_uint16_le(out, 2);	/* status */
	out_uint8(out, 0x77);	/* pad? */

	for (i = 0; i < format_count; i++)
	{
		format = &formats[i];
		out_uint16_le(out, format->wFormatTag);
		out_uint16_le(out, format->nChannels);
		out_uint32_le(out, format->nSamplesPerSec);
		out_uint32_le(out, format->nAvgBytesPerSec);
		out_uint16_le(out, format->nBlockAlign);
		out_uint16_le(out, format->wBitsPerSample);
		out_uint16(out, 0);	/* cbSize */
	}

	s_mark_end(out);
	rdpsnd_send(out);
}