Beispiel #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);
}
Beispiel #2
0
static STREAM
cssp_encode_tspasswordcreds(char *username, char *password, char *domain)
{
	STREAM out, h1, h2;
	struct stream tmp = { 0 };
	struct stream message = { 0 };

	memset(&tmp, 0, sizeof(tmp));
	memset(&message, 0, sizeof(message));

	// domainName [0]
	s_realloc(&tmp, 4 + strlen(domain) * sizeof(uint16));
	s_reset(&tmp);
	rdp_out_unistr(&tmp, domain, strlen(domain) * sizeof(uint16));
	s_mark_end(&tmp);
	h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp);
	h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 0, h2);
	s_realloc(&message, s_length(&message) + s_length(h1));
	out_uint8p(&message, h1->data, s_length(h1));
	s_mark_end(&message);
	s_free(h2);
	s_free(h1);

	// userName [1]
	s_realloc(&tmp, 4 + strlen(username) * sizeof(uint16));
	s_reset(&tmp);
	rdp_out_unistr(&tmp, username, strlen(username) * sizeof(uint16));
	s_mark_end(&tmp);

	h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp);
	h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 1, h2);
	s_realloc(&message, s_length(&message) + s_length(h1));
	out_uint8p(&message, h1->data, s_length(h1));
	s_mark_end(&message);
	s_free(h2);
	s_free(h1);

	// password [2]
	s_realloc(&tmp, 4 + strlen(password) * sizeof(uint16));
	s_reset(&tmp);
	rdp_out_unistr(&tmp, password, strlen(password) * sizeof(uint16));
	s_mark_end(&tmp);
	h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp);
	h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 2, h2);
	s_realloc(&message, s_length(&message) + s_length(h1));
	out_uint8p(&message, h1->data, s_length(h1));
	s_mark_end(&message);
	s_free(h2);
	s_free(h1);

	// build message
	out = ber_wrap_hdr_data(BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED, &message);

	// cleanup
	xfree(tmp.data);
	xfree(message.data);
	return out;
}
Beispiel #3
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);
}
Beispiel #5
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);
}
Beispiel #6
0
/* Output a string in Unicode */
void
rdp_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 %p\n",
                        g_codepage, WINDOWS_CODEPAGE, 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;
    }
}
Beispiel #7
0
static STREAM
cssp_encode_tssmartcardcreds(char *username, char *password, char *domain)
{
	STREAM out, h1, h2;
	struct stream tmp = { 0 };
	struct stream message = { 0 };

	// pin [0]
	s_realloc(&tmp, strlen(password) * sizeof(uint16));
	s_reset(&tmp);
	rdp_out_unistr(&tmp, password, strlen(password) * sizeof(uint16));
	s_mark_end(&tmp);
	h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp);
	h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 0, h2);
	s_realloc(&message, s_length(&message) + s_length(h1));
	out_uint8p(&message, h1->data, s_length(h1));
	s_mark_end(&message);
	s_free(h2);
	s_free(h1);

	// cspData[1]        
	h2 = cssp_encode_tscspdatadetail(AT_KEYEXCHANGE, g_sc_card_name, g_sc_reader_name,
					 g_sc_container_name, g_sc_csp_name);
	h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 1, h2);
	s_realloc(&message, s_length(&message) + s_length(h1));
	out_uint8p(&message, h1->data, s_length(h1));
	s_mark_end(&message);
	s_free(h2);
	s_free(h1);

	// userHint [2]
	if (username && strlen(username))
	{
		s_realloc(&tmp, strlen(username) * sizeof(uint16));
		s_reset(&tmp);
		rdp_out_unistr(&tmp, username, strlen(username) * sizeof(uint16));
		s_mark_end(&tmp);
		h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp);
		h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 2, h2);
		s_realloc(&message, s_length(&message) + s_length(h1));
		out_uint8p(&message, h1->data, s_length(h1));
		s_mark_end(&message);
		s_free(h2);
		s_free(h1);
	}

	// domainHint [3]
	if (domain && strlen(domain))
	{
		s_realloc(&tmp, strlen(domain) * sizeof(uint16));
		s_reset(&tmp);
		rdp_out_unistr(&tmp, domain, strlen(domain) * sizeof(uint16));
		s_mark_end(&tmp);
		h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp);
		h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 3, h2);
		s_realloc(&message, s_length(&message) + s_length(h1));
		out_uint8p(&message, h1->data, s_length(h1));
		s_mark_end(&message);
		s_free(h2);
		s_free(h1);
	}

	s_mark_end(&message);

	// build message
	out = ber_wrap_hdr_data(BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED, &message);

	// cleanup
	free(tmp.data);
	free(message.data);
	return out;
}
Beispiel #8
0
static STREAM
cssp_encode_tscspdatadetail(unsigned char keyspec, char *card, char *reader, char *container,
			    char *csp)
{
	STREAM out;
	STREAM h1, h2;
	struct stream tmp = { 0 };
	struct stream message = { 0 };

	// keySpec [0]
	s_realloc(&tmp, sizeof(uint8));
	s_reset(&tmp);
	out_uint8(&tmp, keyspec);
	s_mark_end(&tmp);
	h2 = ber_wrap_hdr_data(BER_TAG_INTEGER, &tmp);
	h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 0, h2);
	s_realloc(&message, s_length(&message) + s_length(h1));
	out_uint8p(&message, h1->data, s_length(h1));
	s_mark_end(&message);
	s_free(h2);
	s_free(h1);

	// cardName [1]
	if (card)
	{
		s_realloc(&tmp, 4 + strlen(card) * sizeof(uint16));
		s_reset(&tmp);
		rdp_out_unistr(&tmp, card, strlen(card) * sizeof(uint16));
		s_mark_end(&tmp);
		h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp);
		h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 1, h2);
		s_realloc(&message, s_length(&message) + s_length(h1));
		out_uint8p(&message, h1->data, s_length(h1));
		s_mark_end(&message);
		s_free(h2);
		s_free(h1);
	}

	// readerName [2]
	if (reader)
	{
		s_realloc(&tmp, 4 + strlen(reader) * sizeof(uint16));
		s_reset(&tmp);
		rdp_out_unistr(&tmp, reader, strlen(reader) * sizeof(uint16));
		s_mark_end(&tmp);
		h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp);
		h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 2, h2);
		s_realloc(&message, s_length(&message) + s_length(h1));
		out_uint8p(&message, h1->data, s_length(h1));
		s_mark_end(&message);
		s_free(h2);
		s_free(h1);
	}

	// containerName [3]
	if (container)
	{
		s_realloc(&tmp, 4 + strlen(container) * sizeof(uint16));
		s_reset(&tmp);
		rdp_out_unistr(&tmp, container, strlen(container) * sizeof(uint16));
		s_mark_end(&tmp);
		h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp);
		h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 3, h2);
		s_realloc(&message, s_length(&message) + s_length(h1));
		out_uint8p(&message, h1->data, s_length(h1));
		s_mark_end(&message);
		s_free(h2);
		s_free(h1);
	}

	// cspName [4]
	if (csp)
	{
		s_realloc(&tmp, 4 + strlen(csp) * sizeof(uint16));
		s_reset(&tmp);
		rdp_out_unistr(&tmp, csp, strlen(csp) * sizeof(uint16));
		s_mark_end(&tmp);
		h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp);
		h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 4, h2);
		s_realloc(&message, s_length(&message) + s_length(h1));
		out_uint8p(&message, h1->data, s_length(h1));
		s_mark_end(&message);
		s_free(h2);
		s_free(h1);
	}

	s_mark_end(&message);

	// build message
	out = ber_wrap_hdr_data(BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED, &message);

	// cleanup
	free(tmp.data);
	free(message.data);
	return out;
}
Beispiel #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();
	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);
}
Beispiel #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;
	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);
}
Beispiel #11
0
/* Output a string in Unicode */
void
rdp_out_unistr(RDPCLIENT * This, STREAM s, wchar_t *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 (This->rdp.iconv_works)
	{
		if (iconv_h == (iconv_t) - 1)
		{
			size_t i = 1, o = 4;
			if ((iconv_h = iconv_open(WINDOWS_CODEPAGE, This->codepage)) == (iconv_t) - 1)
			{
				warning("rdp_out_unistr: iconv_open[%s -> %s] fail %d\n",
					This->codepage, WINDOWS_CODEPAGE, (int) iconv_h);

				This->rdp.iconv_works = False;
				rdp_out_unistr(This, 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);

				This->rdp.iconv_works = False;
				rdp_out_unistr(This, 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);

			This->rdp.iconv_works = False;
			rdp_out_unistr(This, s, string, len);
			return;
		}

		s->p += len + 2;

	}
	else
#endif
	// TODO
	{
		int i = 0, j = 0;

		len += 2;

		while (i < len)
		{
			int c = string[j++];
			s->p[i++] = (c >> 0) & 0xFF;
			s->p[i++] = (c >> 8) & 0xFF;
		}

		s->p += len;
	}
}