/* Send a Licensing packet with Platform Challenge Response */ static void licence_send_authresp(rdpLicence * licence, uint8 * token, uint8 * crypt_hwid, uint8 * signature) { uint32 sec_flags = SEC_LICENSE_PKT; uint16 length = 58; STREAM s; s = sec_init(licence->sec, sec_flags, length + 2); /* Licensing Preamble (LICENSE_PREAMBLE) */ out_uint8(s, PLATFORM_CHALLENGE_RESPONSE); /* PLATFORM_CHALLENGE_RESPONSE */ out_uint8(s, 2); /* PREAMBLE_VERSION_2_0 */ out_uint16_le(s, length); /* Licensing Binary BLOB with EncryptedPlatformChallengeResponse: */ out_uint16_le(s, 1); /* wBlobType should be 0x0009 (BB_ENCRYPTED_DATA_BLOB) */ out_uint16_le(s, LICENCE_TOKEN_SIZE); /* wBlobLen */ out_uint8p(s, token, LICENCE_TOKEN_SIZE); /* RC4-encrypted challenge data */ /* Licensing Binary BLOB with EncryptedHWID: */ out_uint16_le(s, 1); /* wBlobType should be 0x0009 (BB_ENCRYPTED_DATA_BLOB) */ out_uint16_le(s, LICENCE_HWID_SIZE); /* wBlobLen */ out_uint8p(s, crypt_hwid, LICENCE_HWID_SIZE); /* RC4-encrypted Client Hardware Identification */ out_uint8p(s, signature, LICENCE_SIGNATURE_SIZE); /* MACData */ s_mark_end(s); sec_send(licence->sec, s, sec_flags); }
/* Send an authentication response packet */ static BOOL licence_send_authresp(RDPCLIENT * This, uint8 * token, uint8 * crypt_hwid, uint8 * signature) { uint32 sec_flags = SEC_LICENCE_NEG; uint16 length = 58; STREAM s; s = sec_init(This, sec_flags, length + 2); if(s == NULL) return False; out_uint8(s, LICENCE_TAG_AUTHRESP); out_uint8(s, 2); /* version */ out_uint16_le(s, length); out_uint16_le(s, 1); out_uint16_le(s, LICENCE_TOKEN_SIZE); out_uint8p(s, token, LICENCE_TOKEN_SIZE); out_uint16_le(s, 1); out_uint16_le(s, LICENCE_HWID_SIZE); out_uint8p(s, crypt_hwid, LICENCE_HWID_SIZE); out_uint8p(s, signature, LICENCE_SIGNATURE_SIZE); s_mark_end(s); return sec_send(This, s, sec_flags); }
/* Send an authentication response packet */ static void licence_send_authresp(uint8 *token, uint8 *crypt_hwid, uint8 *signature) { uint32 sec_flags = SEC_LICENCE_NEG; uint16 length = 58; STREAM s; s = sec_init(sec_flags, length + 2); out_uint16_le(s, LICENCE_TAG_AUTHRESP); out_uint16_le(s, length); out_uint16_le(s, 1); out_uint16_le(s, LICENCE_TOKEN_SIZE); out_uint8p(s, token, LICENCE_TOKEN_SIZE); out_uint16_le(s, 1); out_uint16_le(s, LICENCE_HWID_SIZE); out_uint8p(s, crypt_hwid, LICENCE_HWID_SIZE); out_uint8p(s, signature, LICENCE_SIGNATURE_SIZE); s_mark_end(s); sec_send(s, sec_flags); }
/* Send a platform challenge response packet */ static void licence_send_platform_challenge_response(uint8 * token, uint8 * crypt_hwid, uint8 * signature) { uint32 sec_flags = SEC_LICENSE_PKT; uint16 length = 58; STREAM s; s = sec_init(sec_flags, length + 2); out_uint8(s, LICENCE_TAG_PLATFORM_CHALLENGE_RESPONSE); out_uint8(s, ((g_rdp_version >= RDP_V5) ? 3 : 2)); /* version */ out_uint16_le(s, length); out_uint16_le(s, 1); out_uint16_le(s, LICENCE_TOKEN_SIZE); out_uint8p(s, token, LICENCE_TOKEN_SIZE); out_uint16_le(s, 1); out_uint16_le(s, LICENCE_HWID_SIZE); out_uint8p(s, crypt_hwid, LICENCE_HWID_SIZE); out_uint8p(s, signature, LICENCE_SIGNATURE_SIZE); s_mark_end(s); sec_send(s, sec_flags); }
void rdp_send_client_execute_pdu(rdpRdp * rdp) { STREAM s; size_t application_name_len, working_directory_len, arguments_len; char * application_name, * working_directory, * arguments; /* Still lacking proper packet initialization */ s = NULL; rdp_out_rail_pdu_header(s, RDP_RAIL_ORDER_EXEC, 12); application_name = xstrdup_out_unistr(rdp, rdp->app->application_name, &application_name_len); working_directory = xstrdup_out_unistr(rdp, rdp->app->working_directory, &working_directory_len); arguments = xstrdup_out_unistr(rdp, rdp->app->arguments, &arguments_len); out_uint16_le(s, RAIL_EXEC_FLAG_EXPAND_WORKINGDIRECTORY | RAIL_EXEC_FLAG_EXPAND_ARGUMENTS); // flags out_uint16_le(s, application_name_len); // ExeOrFileLength out_uint16_le(s, working_directory_len); // WorkingDirLength out_uint16_le(s, arguments_len); // ArgumentsLength out_uint8a(s, application_name, application_name_len + 2); // ExeOrFile out_uint8a(s, working_directory, working_directory_len + 2); // WorkingDir out_uint8a(s, arguments, arguments_len + 2); // Arguments xfree(application_name); xfree(working_directory); xfree(arguments); s_mark_end(s); sec_send(rdp->sec, s, rdp->settings->encryption ? SEC_ENCRYPT : 0); }
/* Send an authentication response packet */ static void licence_send_authresp(RDConnectionRef conn, uint8 * token, uint8 * crypt_hwid, uint8 * signature) { uint32 sec_flags = SEC_LICENCE_NEG; uint16 length = 58; RDStreamRef s; s = sec_init(conn, sec_flags, length + 2); out_uint8(s, LICENCE_TAG_AUTHRESP); out_uint8(s, 2); /* version */ out_uint16_le(s, length); out_uint16_le(s, 1); out_uint16_le(s, LICENCE_TOKEN_SIZE); out_uint8p(s, token, LICENCE_TOKEN_SIZE); out_uint16_le(s, 1); out_uint16_le(s, LICENCE_HWID_SIZE); out_uint8p(s, crypt_hwid, LICENCE_HWID_SIZE); out_uint8p(s, signature, LICENCE_SIGNATURE_SIZE); s_mark_end(s); sec_send(conn, s, sec_flags); }
/* Send a confirm active PDU */ static void rdp_send_confirm_active(void) { STREAM s; uint32 sec_flags = g_encryption ? (RDP5_FLAG | SEC_ENCRYPT) : RDP5_FLAG; uint16 caplen = RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER + RDP_CAPLEN_COLCACHE + RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL + RDP_CAPLEN_SHARE + RDP_CAPLEN_BRUSHCACHE + 0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */+ 4 /* w2k fix, sessionid */; if (g_use_rdp5) { caplen += RDP_CAPLEN_BMPCACHE2; caplen += RDP_CAPLEN_NEWPOINTER; } else { caplen += RDP_CAPLEN_BMPCACHE; caplen += RDP_CAPLEN_POINTER; } s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE)); out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE)); out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10)); /* Version 1 */ out_uint16_le(s, (g_mcs_userid + 1001)); out_uint32_le(s, g_rdp_shareid); out_uint16_le(s, 0x3ea); /* userid */ out_uint16_le(s, sizeof(RDP_SOURCE)); out_uint16_le(s, caplen); out_uint8p(s, RDP_SOURCE, sizeof(RDP_SOURCE)); out_uint16_le(s, 0xe); /* num_caps */ out_uint8s(s, 2); /* pad */ rdp_out_general_caps(s); rdp_out_bitmap_caps(s); rdp_out_order_caps(s); if (g_use_rdp5) { rdp_out_bmpcache2_caps(s); rdp_out_newpointer_caps(s); } else { rdp_out_bmpcache_caps(s); rdp_out_pointer_caps(s); } rdp_out_colcache_caps(s); rdp_out_activate_caps(s); rdp_out_control_caps(s); rdp_out_share_caps(s); rdp_out_brushcache_caps(s); rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* CAPSTYPE_INPUT */ rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c); /* CAPSTYPE_SOUND */ rdp_out_unknown_caps(s, 0x0e, 0x08, caps_0x0e); /* CAPSTYPE_FONT */ rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* CAPSTYPE_GLYPHCACHE */ s_mark_end(s); sec_send(s, sec_flags); }
int sec_fflush(FILE * F) { if (ftp->data_prot != prot_clear) { if (ftp->out_buffer.index > 0) { sec_write(fileno(F), ftp->out_buffer.data, ftp->out_buffer.index); ftp->out_buffer.index = 0; } sec_send(fileno(F), NULL, 0); } fflush(F); return 0; }
int Curl_sec_fflush_fd(struct connectdata *conn, int fd) { if(conn->data_prot != prot_clear) { if(conn->out_buffer.index > 0){ Curl_sec_write(conn, fd, conn->out_buffer.data, conn->out_buffer.index); conn->out_buffer.index = 0; } sec_send(conn, fd, NULL, 0); } return 0; }
/* Send a confirm active PDU */ static BOOL rdp_send_confirm_active(RDPCLIENT * This) { STREAM s; uint32 sec_flags = This->encryption ? (RDP5_FLAG | SEC_ENCRYPT) : RDP5_FLAG; uint16 caplen = RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER + RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE + RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL + RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + 0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */ + 4 /* w2k fix, why? */ ; s = sec_init(This, sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE)); if(s == NULL) return False; out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE)); out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10)); /* Version 1 */ out_uint16_le(s, (This->mcs_userid + 1001)); out_uint32_le(s, This->rdp_shareid); out_uint16_le(s, 0x3ea); /* userid */ out_uint16_le(s, sizeof(RDP_SOURCE)); out_uint16_le(s, caplen); out_uint8p(s, RDP_SOURCE, sizeof(RDP_SOURCE)); out_uint16_le(s, 0xd); /* num_caps */ out_uint8s(s, 2); /* pad */ rdp_out_general_caps(This, s); rdp_out_bitmap_caps(This, s); rdp_out_order_caps(This, s); This->use_rdp5 ? rdp_out_bmpcache2_caps(This, s) : rdp_out_bmpcache_caps(This, s); rdp_out_colcache_caps(s); rdp_out_activate_caps(s); rdp_out_control_caps(s); rdp_out_pointer_caps(s); rdp_out_share_caps(s); rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* international? */ rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c); rdp_out_unknown_caps(s, 0x0e, 0x08, caps_0x0e); rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* glyph cache? */ s_mark_end(s); return sec_send(This, s, sec_flags); }
/* Send a Licensing packet with Client License Information */ static void licence_present(rdpLicence * licence, uint8 * client_random, uint8 * rsa_data, uint8 * licence_data, int licence_size, uint8 * hwid, uint8 * signature) { uint32 sec_flags = SEC_LICENSE_PKT; uint16 length = 16 + SEC_RANDOM_SIZE + SEC_MODULUS_SIZE + SEC_PADDING_SIZE + licence_size + LICENCE_HWID_SIZE + LICENCE_SIGNATURE_SIZE; STREAM s; s = sec_init(licence->sec, sec_flags, length + 4); /* Licensing Preamble (LICENSE_PREAMBLE) */ out_uint8(s, LICENSE_INFO); /* bMsgType LICENSE_INFO */ out_uint8(s, 2); /* bVersion PREAMBLE_VERSION_2_0 */ out_uint16_le(s, length); /* Client License Information: */ out_uint32_le(s, 1); /* PreferredKeyExchangeAlg KEY_EXCHANGE_ALG_RSA */ out_uint16_le(s, 0); /* PlatformId, unknown platform and ISV */ out_uint16_le(s, 0x0201); /* PlatformId, build/version */ out_uint8p(s, client_random, SEC_RANDOM_SIZE); /* ClientRandom */ /* Licensing Binary Blob with EncryptedPreMasterSecret: */ out_uint16_le(s, 0); /* wBlobType should be 0x0002 (BB_RANDOM_BLOB) */ out_uint16_le(s, (SEC_MODULUS_SIZE + SEC_PADDING_SIZE)); /* wBlobLen */ out_uint8p(s, rsa_data, SEC_MODULUS_SIZE); /* 48 bit random number encrypted for server */ out_uint8s(s, SEC_PADDING_SIZE); /* Licensing Binary Blob with LicenseInfo: */ out_uint16_le(s, 1); /* wBlobType BB_DATA_BLOB */ out_uint16_le(s, licence_size); /* wBlobLen */ out_uint8p(s, licence_data, licence_size); /* CAL issued by servers license server */ /* Licensing Binary Blob with EncryptedHWID */ out_uint16_le(s, 1); /* wBlobType BB_DATA_BLOB */ out_uint16_le(s, LICENCE_HWID_SIZE); /* wBlobLen */ out_uint8p(s, hwid, LICENCE_HWID_SIZE); /* RC4-encrypted Client Hardware Identification */ out_uint8p(s, signature, LICENCE_SIGNATURE_SIZE); /* MACData */ s_mark_end(s); sec_send(licence->sec, s, sec_flags); }
int sec_write(int fd, const char* data, int length) { int len = ftp->buffer_size; int tx = 0; if (ftp->data_prot == prot_clear) return write(fd, data, length); len -= (*ftp->mech->overhead) (ftp->app_data, ftp->data_prot, len); while (length) { if (length < len) len = length; sec_send(fd, data, len); length -= len; data += len; tx += len; } return tx; }
/* Present an existing licence to the server */ static BOOL licence_present(RDPCLIENT * This, uint8 * client_random, uint8 * rsa_data, uint8 * licence_data, int licence_size, uint8 * hwid, uint8 * signature) { uint32 sec_flags = SEC_LICENCE_NEG; uint16 length = 16 + SEC_RANDOM_SIZE + SEC_MODULUS_SIZE + SEC_PADDING_SIZE + licence_size + LICENCE_HWID_SIZE + LICENCE_SIGNATURE_SIZE; STREAM s; s = sec_init(This, sec_flags, length + 4); if(s == NULL) return False; out_uint8(s, LICENCE_TAG_PRESENT); out_uint8(s, 2); /* version */ out_uint16_le(s, length); out_uint32_le(s, 1); out_uint16(s, 0); out_uint16_le(s, 0x0201); out_uint8p(s, client_random, SEC_RANDOM_SIZE); out_uint16(s, 0); out_uint16_le(s, (SEC_MODULUS_SIZE + SEC_PADDING_SIZE)); out_uint8p(s, rsa_data, SEC_MODULUS_SIZE); out_uint8s(s, SEC_PADDING_SIZE); out_uint16_le(s, 1); out_uint16_le(s, licence_size); out_uint8p(s, licence_data, licence_size); out_uint16_le(s, 1); out_uint16_le(s, LICENCE_HWID_SIZE); out_uint8p(s, hwid, LICENCE_HWID_SIZE); out_uint8p(s, signature, LICENCE_SIGNATURE_SIZE); s_mark_end(s); return sec_send(This, s, sec_flags); }
/* Send a Licensing packet with Client New License Request */ static void licence_send_request(rdpLicence * licence, uint8 * client_random, uint8 * rsa_data, char *user, char *host) { uint32 sec_flags = SEC_LICENSE_PKT; uint16 userlen = strlen(user) + 1; uint16 hostlen = strlen(host) + 1; uint16 length = 128 + userlen + hostlen; STREAM s; s = sec_init(licence->sec, sec_flags, length + 2); /* Licensing Preamble (LICENSE_PREAMBLE) */ out_uint8(s, NEW_LICENSE_REQUEST); /* NEW_LICENSE_REQUEST */ out_uint8(s, 2); /* PREAMBLE_VERSION_2_0 */ out_uint16_le(s, length); out_uint32_le(s, 1); /* PreferredKeyExchangeAlg KEY_EXCHANGE_ALG_RSA */ out_uint16_le(s, 0); /* PlatformId, unknown platform and ISV */ out_uint16_le(s, 0xff01); /* PlatformId, build/version */ out_uint8p(s, client_random, SEC_RANDOM_SIZE); /* ClientRandom */ /* Licensing Binary Blob with EncryptedPreMasterSecret: */ out_uint16_le(s, 0); /* wBlobType should be 0x0002 (BB_RANDOM_BLOB) */ out_uint16_le(s, (SEC_MODULUS_SIZE + SEC_PADDING_SIZE)); /* wBlobLen */ out_uint8p(s, rsa_data, SEC_MODULUS_SIZE); /* 48 bit random number encrypted for server */ out_uint8s(s, SEC_PADDING_SIZE); /* Licensing Binary Blob with ClientUserName: */ out_uint16_le(s, LICENCE_TAG_USER); /* wBlobType BB_CLIENT_USER_NAME_BLOB */ out_uint16_le(s, userlen); /* wBlobLen */ out_uint8p(s, user, userlen); /* Licensing Binary Blob with ClientMachineName: */ out_uint16_le(s, LICENCE_TAG_HOST); /* wBlobType BB_CLIENT_MACHINE_NAME_BLOB */ out_uint16_le(s, hostlen); /* wBlobLen */ out_uint8p(s, host, hostlen); s_mark_end(s); sec_send(licence->sec, s, sec_flags); }
int sec_write(int fd, char *dataptr, int length) { int len = buffer_size; int tx = 0; if(data_prot == prot_clear) return write(fd, dataptr, length); len -= (*mech->overhead)(app_data, data_prot, len); while(length){ if(length < len) len = length; sec_send(fd, dataptr, len); length -= len; dataptr += len; tx += len; } return tx; }
int Curl_sec_write(struct connectdata *conn, int fd, char *buffer, int length) { int len = conn->buffer_size; int tx = 0; if(conn->data_prot == prot_clear) return write(fd, buffer, length); len -= (conn->mech->overhead)(conn->app_data, conn->data_prot, len); while(length){ if(length < len) len = length; sec_send(conn, fd, buffer, len); length -= len; buffer += len; tx += len; } return tx; }
/* Send a confirm active PDU */ static void rdp_send_confirm_active(void) { STREAM s; uint32 sec_flags = g_encryption ? (RDP5_FLAG | SEC_ENCRYPT) : RDP5_FLAG; uint16 caplen = RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER + RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE + RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL + RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ; s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE)); out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE)); out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10)); /* Version 1 */ out_uint16_le(s, (g_mcs_userid + 1001)); out_uint32_le(s, g_rdp_shareid); out_uint16_le(s, 0x3ea); /* userid */ out_uint16_le(s, sizeof(RDP_SOURCE)); out_uint16_le(s, caplen); out_uint8p(s, RDP_SOURCE, sizeof(RDP_SOURCE)); out_uint16_le(s, 0xd); /* num_caps */ out_uint8s(s, 2); /* pad */ rdp_out_general_caps(s); rdp_out_bitmap_caps(s); rdp_out_order_caps(s); rdp_out_bmpcache_caps(s); rdp_out_colcache_caps(s); rdp_out_activate_caps(s); rdp_out_control_caps(s); rdp_out_pointer_caps(s); rdp_out_share_caps(s); rdp_out_unknown_caps(s); s_mark_end(s); sec_send(s, sec_flags); }
/* Send an RDP data packet */ static void rdp_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); }
/* Send a new licence request packet */ static void licence_send_new_licence_request(uint8 * client_random, uint8 * rsa_data, char *user, char *host) { uint32 sec_flags = SEC_LICENSE_PKT; uint16 userlen = strlen(user) + 1; uint16 hostlen = strlen(host) + 1; uint16 length = 24 + SEC_RANDOM_SIZE + SEC_MODULUS_SIZE + SEC_PADDING_SIZE + userlen + hostlen; STREAM s; s = sec_init(sec_flags, length + 2); out_uint8(s, LICENCE_TAG_NEW_LICENCE_REQUEST); out_uint8(s, ((g_rdp_version >= RDP_V5) ? 3 : 2)); /* version */ out_uint16_le(s, length); out_uint32_le(s, 1); // KEY_EXCHANGE_ALG_RSA out_uint16(s, 0); out_uint16_le(s, 0xff01); out_uint8p(s, client_random, SEC_RANDOM_SIZE); out_uint16_le(s, 2); out_uint16_le(s, (SEC_MODULUS_SIZE + SEC_PADDING_SIZE)); out_uint8p(s, rsa_data, SEC_MODULUS_SIZE); out_uint8s(s, SEC_PADDING_SIZE); /* Username LICENSE_BINARY_BLOB */ out_uint16_le(s, BB_CLIENT_USER_NAME_BLOB); out_uint16_le(s, userlen); out_uint8p(s, user, userlen); /* Machinename LICENSE_BINARY_BLOB */ out_uint16_le(s, BB_CLIENT_MACHINE_NAME_BLOB); out_uint16_le(s, hostlen); out_uint8p(s, host, hostlen); s_mark_end(s); sec_send(s, sec_flags); }
/* Send a licence info packet to server */ static void licence_info(uint8 * client_random, uint8 * rsa_data, uint8 * licence_data, int licence_size, uint8 * hwid, uint8 * signature) { uint32 sec_flags = SEC_LICENSE_PKT; uint16 length = 24 + SEC_RANDOM_SIZE + SEC_MODULUS_SIZE + SEC_PADDING_SIZE + licence_size + LICENCE_HWID_SIZE + LICENCE_SIGNATURE_SIZE; STREAM s; s = sec_init(sec_flags, length + 2); out_uint8(s, LICENCE_TAG_LICENCE_INFO); out_uint8(s, ((g_rdp_version >= RDP_V5) ? 3 : 2)); /* version */ out_uint16_le(s, length); out_uint32_le(s, 1); out_uint16(s, 0); out_uint16_le(s, 0x0201); out_uint8p(s, client_random, SEC_RANDOM_SIZE); out_uint16_le(s, 2); out_uint16_le(s, (SEC_MODULUS_SIZE + SEC_PADDING_SIZE)); out_uint8p(s, rsa_data, SEC_MODULUS_SIZE); out_uint8s(s, SEC_PADDING_SIZE); out_uint16_le(s, 1); out_uint16_le(s, licence_size); out_uint8p(s, licence_data, licence_size); out_uint16_le(s, 1); out_uint16_le(s, LICENCE_HWID_SIZE); out_uint8p(s, hwid, LICENCE_HWID_SIZE); out_uint8p(s, signature, LICENCE_SIGNATURE_SIZE); s_mark_end(s); sec_send(s, sec_flags); }
/* Send a licence request packet */ static BOOL licence_send_request(RDPCLIENT * This, uint8 * client_random, uint8 * rsa_data, char *user, char *host) { uint32 sec_flags = SEC_LICENCE_NEG; uint16 userlen = (uint16)strlen(user) + 1; uint16 hostlen = (uint16)strlen(host) + 1; uint16 length = 128 + userlen + hostlen; STREAM s; s = sec_init(This, sec_flags, length + 2); if(s == NULL) return False; out_uint8(s, LICENCE_TAG_REQUEST); out_uint8(s, 2); /* version */ out_uint16_le(s, length); out_uint32_le(s, 1); out_uint16(s, 0); out_uint16_le(s, 0xff01); out_uint8p(s, client_random, SEC_RANDOM_SIZE); out_uint16(s, 0); out_uint16_le(s, (SEC_MODULUS_SIZE + SEC_PADDING_SIZE)); out_uint8p(s, rsa_data, SEC_MODULUS_SIZE); out_uint8s(s, SEC_PADDING_SIZE); out_uint16_le(s, LICENCE_TAG_USER); out_uint16_le(s, userlen); out_uint8p(s, user, userlen); out_uint16_le(s, LICENCE_TAG_HOST); out_uint16_le(s, hostlen); out_uint8p(s, host, hostlen); s_mark_end(s); return sec_send(This, s, sec_flags); }
/* Send an RDP data packet */ static BOOL rdp_send_data(RDPCLIENT * This, STREAM s, uint8 data_pdu_type) { uint16 length; s_pop_layer(s, rdp_hdr); length = (uint16)(s->end - s->p); out_uint16_le(s, length); out_uint16_le(s, (RDP_PDU_DATA | 0x10)); out_uint16_le(s, (This->mcs_userid + 1001)); out_uint32_le(s, This->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 */ return sec_send(This, s, This->encryption ? SEC_ENCRYPT : 0); }
/* Present an existing licence to the server */ static void licence_present(RDConnectionRef conn, uint8 * client_random, uint8 * rsa_data, uint8 * licence_data, int licence_size, uint8 * hwid, uint8 * signature) { uint32 sec_flags = SEC_LICENCE_NEG; uint16 length = 16 + SEC_RANDOM_SIZE + SEC_MODULUS_SIZE + SEC_PADDING_SIZE + licence_size + LICENCE_HWID_SIZE + LICENCE_SIGNATURE_SIZE; RDStreamRef s; s = sec_init(conn, sec_flags, length + 4); out_uint8(s, LICENCE_TAG_PRESENT); out_uint8(s, 2); /* version */ out_uint16_le(s, length); out_uint32_le(s, 1); out_uint16(s, 0); out_uint16_le(s, 0x0201); out_uint8p(s, client_random, SEC_RANDOM_SIZE); out_uint16(s, 0); out_uint16_le(s, (SEC_MODULUS_SIZE + SEC_PADDING_SIZE)); out_uint8p(s, rsa_data, SEC_MODULUS_SIZE); out_uint8s(s, SEC_PADDING_SIZE); out_uint16_le(s, 1); out_uint16_le(s, licence_size); out_uint8p(s, licence_data, licence_size); out_uint16_le(s, 1); out_uint16_le(s, LICENCE_HWID_SIZE); out_uint8p(s, hwid, LICENCE_HWID_SIZE); out_uint8p(s, signature, LICENCE_SIGNATURE_SIZE); s_mark_end(s); sec_send(conn, s, sec_flags); }
/* Send a licence request packet */ static void licence_send_request(uint8 *client_random, uint8 *rsa_data, char *user, char *host) { uint32 sec_flags = SEC_LICENCE_NEG; uint16 userlen = strlen(user) + 1; uint16 hostlen = strlen(host) + 1; uint16 length = 120 + userlen + hostlen; STREAM s; s = sec_init(sec_flags, length + 2); out_uint16_le(s, LICENCE_TAG_REQUEST); out_uint16_le(s, length); out_uint32_le(s, 1); out_uint16(s, 0); out_uint16_le(s, 0xff01); out_uint8p(s, client_random, SEC_RANDOM_SIZE); out_uint16(s, 0); out_uint16_le(s, (SEC_MODULUS_SIZE + SEC_PADDING_SIZE)); out_uint8p(s, rsa_data, SEC_MODULUS_SIZE); out_uint8s(s, SEC_PADDING_SIZE); out_uint16(s, LICENCE_TAG_USER); out_uint16(s, userlen); out_uint8p(s, user, userlen); out_uint16(s, LICENCE_TAG_HOST); out_uint16(s, hostlen); out_uint8p(s, host, hostlen); s_mark_end(s); 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(); /* 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); }
/* 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); }