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