int CAimProto::aim_chat_invite(HANDLE hServerConn, unsigned short &seqno, char* chat_cookie, unsigned short exchange, unsigned short instance, char* sn, char* msg) { unsigned short offset = 0; unsigned short chat_cookie_len = (unsigned short)mir_strlen(chat_cookie); unsigned short sn_len = (unsigned short)mir_strlen(sn); unsigned short msg_len = (unsigned short)mir_strlen(msg); char* buf = (char*)alloca(SNAC_SIZE + 64 + chat_cookie_len + sn_len + msg_len); aim_writesnac(0x04, 0x06, offset, buf); aim_writegeneric(8, "\0\0\0\0\0\0\0\0", offset, buf); // ICBM Cookie aim_writeshort(2, offset, buf); // ICBM Channel aim_writechar((unsigned char)sn_len, offset, buf); // Screen Name Length aim_writegeneric(sn_len, sn, offset, buf); // Screen Name aim_writeshort(0x05, offset, buf); // Rendezvous Message Data TLV aim_writeshort(49 + msg_len + chat_cookie_len, offset, buf); // TLV size aim_writeshort(0, offset, buf); // Message Type (0) - Request aim_writegeneric(8, "\0\0\0\0\0\0\0\0", offset, buf); // ICBM Cookie (same as above) aim_writegeneric(16, AIM_CAP_CHAT, offset, buf); // Capability aim_writetlvshort(0x0a, 1, offset, buf); // Sequence Number TLV aim_writetlv(0x0f, 0, NULL, offset, buf); // Request Host Caps Check TLV aim_writetlv(0x0c, msg_len, msg, offset, buf); // Invitation Message TLV aim_writeshort(0x2711, offset, buf); // Capability TLV aim_writeshort(chat_cookie_len + 5, offset, buf); // Length aim_writeshort(exchange, offset, buf); // Value - Exchange aim_writechar((unsigned char)chat_cookie_len, offset, buf); // Value - Cookie Length aim_writegeneric(chat_cookie_len, chat_cookie, offset, buf); // Value - Cookie aim_writeshort(instance, offset, buf); // Value - Instance return aim_sendflap(hServerConn, 0x02, offset, buf, seqno); }
int CAimProto::aim_request_avatar(HANDLE hServerConn, unsigned short &seqno, const char* sn, unsigned short bart_type, const char* hash, unsigned short hash_size) { unsigned short offset = 0; unsigned char sn_length = (unsigned char)mir_strlen(sn); char* buf = (char*)alloca(SNAC_SIZE + sn_length + hash_size + 12); aim_writesnac(0x10, 0x06, offset, buf); aim_writechar(sn_length, offset, buf); // screen name length aim_writegeneric(sn_length, sn, offset, buf); // screen name aim_writechar(1, offset, buf); // number of BART ID aim_writebartid(bart_type, 0, hash_size, hash, offset, buf); return aim_sendflap(hServerConn, 0x02, offset, buf, seqno); }
int CAimProto::aim_chatnav_room_info(HANDLE hServerConn, unsigned short &seqno, char* chat_cookie, unsigned short exchange, unsigned short instance) { unsigned short offset = 0; unsigned short chat_cookie_len = (unsigned short)mir_strlen(chat_cookie); char* buf = (char*)alloca(SNAC_SIZE + 7 + chat_cookie_len); aim_writesnac(0x0d, 0x04, offset, buf); aim_writeshort(exchange, offset, buf); // Exchange aim_writechar((unsigned char)chat_cookie_len, offset, buf); // Chat Cookie Length aim_writegeneric(chat_cookie_len, chat_cookie, offset, buf); // Chat Cookie aim_writeshort(instance, offset, buf); // Last Instance aim_writechar(1, offset, buf); // Detail return aim_sendflap(hServerConn, 0x02, offset, buf, seqno); }
int CAimProto::aim_file_ad(HANDLE hServerConn, unsigned short &seqno, char* sn, char* icbm_cookie, bool deny, unsigned short) { unsigned short frag_offset = 0; char msg_frag[10 + AIM_CAPS_LENGTH + TLV_HEADER_SIZE * 2 + 6]; aim_writeshort(deny ? 1 : 2, frag_offset, msg_frag); // icbm accept / deny aim_writegeneric(8, icbm_cookie, frag_offset, msg_frag); // icbm cookie aim_writegeneric(AIM_CAPS_LENGTH, AIM_CAP_FILE_TRANSFER, frag_offset, msg_frag); // uuid // if (max_ver > 1) // aim_writetlvshort(0x12,2,frag_offset,msg_frag); // max protocol version unsigned short sn_length = (unsigned short)mir_strlen(sn); unsigned short offset = 0; char* buf = (char*)alloca(SNAC_SIZE + TLV_HEADER_SIZE + 21 + frag_offset + sn_length); aim_writesnac(0x04, 0x06, offset, buf); // msg to host aim_writegeneric(8, icbm_cookie, offset, buf); // icbm cookie aim_writeshort(2, offset, buf); // icbm channel aim_writechar((unsigned char)sn_length, offset, buf); // screen name length aim_writegeneric(sn_length, sn, offset, buf); // screen name aim_writetlv(0x05, frag_offset, msg_frag, offset, buf); // icbm tags debugLogA("%s a file transfer.", deny ? "Denying" : "Accepting"); return aim_sendflap(hServerConn, 0x02, offset, buf, seqno) == 0; }
int CAimProto::aim_chatnav_create(HANDLE hServerConn, unsigned short &seqno, char* room, unsigned short exchage) { //* Join Pseudo Room (Get's the info we need for the real connection) unsigned short room_len = (unsigned short)mir_strlen(room); unsigned short offset = 0; char* buf = (char*)alloca(SNAC_SIZE + 10 + room_len + 26); aim_writesnac(0x0d, 0x08, offset, buf); aim_writeshort(exchage, offset, buf); // Exchange aim_writechar(6, offset, buf); // Command Length aim_writegeneric(6, "create", offset, buf); // Command aim_writeshort(0xffff, offset, buf); // Last Instance aim_writechar(1, offset, buf); // Detail aim_writeshort(3, offset, buf); // Number of TLVs aim_writetlv(0xd3, room_len, room, offset, buf); // Room Name aim_writetlv(0xd6, 8, "us-ascii", offset, buf); // Character Set aim_writetlv(0xd7, 2, "en", offset, buf); // Language Encoding return aim_sendflap(hServerConn, 0x02, offset, buf, seqno); }
int CAimProto::aim_query_profile(HANDLE hServerConn, unsigned short &seqno, char* sn) { unsigned short offset = 0; unsigned short sn_length = (unsigned short)mir_strlen(sn); char* buf = (char*)alloca(SNAC_SIZE + 5 + sn_length); aim_writesnac(0x02, 0x15, offset, buf); aim_writelong(0x01, offset, buf); aim_writechar((unsigned char)sn_length, offset, buf); aim_writegeneric(sn_length, sn, offset, buf); return aim_sendflap(hServerConn, 0x02, offset, buf, seqno) == 0; }
int CAimProto::aim_typing_notification(HANDLE hServerConn, unsigned short &seqno, char* sn, unsigned short type) { unsigned short offset = 0; unsigned short sn_length = (unsigned short)mir_strlen(sn); char* buf = (char*)alloca(SNAC_SIZE + sn_length + 13); aim_writesnac(0x04, 0x14, offset, buf); aim_writegeneric(8, "\0\0\0\0\0\0\0\0", offset, buf); // icbm cookie aim_writeshort(1, offset, buf); // icbm channel aim_writechar((unsigned char)sn_length, offset, buf); // screen name length aim_writegeneric(sn_length, sn, offset, buf); // screen name aim_writeshort(type, offset, buf); // typing event return aim_sendflap(hServerConn, 0x02, offset, buf, seqno); }
int CAimProto::aim_chat_deny(HANDLE hServerConn, unsigned short &seqno, char* sn, char* icbm_cookie) { unsigned short offset = 0; unsigned short sn_length = (unsigned short)mir_strlen(sn); char* buf = (char*)alloca(SNAC_SIZE + 20 + sn_length); aim_writesnac(0x04, 0x0b, offset, buf); aim_writegeneric(8, icbm_cookie, offset, buf); // ICBM Cookie aim_writeshort(2, offset, buf); // Channel aim_writechar((unsigned char)sn_length, offset, buf); // Screen Name length aim_writegeneric(sn_length, sn, offset, buf); // Screen Name aim_writeshort(3, offset, buf); // Error code aim_writeshort(2, offset, buf); // Error code aim_writeshort(1, offset, buf); // Error code return aim_sendflap(hServerConn, 0x02, offset, buf, seqno) == 0; }
int proxy_initialize_send(HANDLE connection, char* sn, char* cookie) { const char sn_length = (char)strlen(sn); const int len = sn_length + 21 + TLV_HEADER_SIZE + AIM_CAPS_LENGTH; char* buf= (char*)_malloca(len); unsigned short offset=0; aim_writeshort(len-2, offset, buf); aim_writegeneric(10, "\x04\x4a\0\x02\0\0\0\0\0\0", offset, buf); aim_writechar((unsigned char)sn_length, offset, buf); // screen name len aim_writegeneric(sn_length, sn, offset, buf); // screen name aim_writegeneric(8, cookie, offset, buf); // icbm cookie aim_writetlv(1, AIM_CAPS_LENGTH, AIM_CAP_FILE_TRANSFER, offset, buf); return Netlib_Send(connection, buf, offset, 0) >= 0 ? 0 : -1; }
int CAimProto::aim_send_message(HANDLE hServerConn, unsigned short &seqno, const char* sn, char* amsg, bool auto_response, bool blast) { aimString str(amsg); const char* msg = str.getBuf(); const unsigned short msg_len = str.getSize(); unsigned short tlv_offset = 0; char* tlv_buf = (char*)alloca(5 + msg_len + 8); char icbm_cookie[8]; Utils_GetRandom(icbm_cookie, sizeof(icbm_cookie)); aim_writegeneric(5, "\x05\x01\x00\x01\x01", tlv_offset, tlv_buf); // icbm im capabilities aim_writeshort(0x0101, tlv_offset, tlv_buf); // icbm im text tag aim_writeshort(msg_len + 4, tlv_offset, tlv_buf); // icbm im text tag length aim_writeshort(str.isUnicode() ? 2 : 0, tlv_offset, tlv_buf); // character set aim_writeshort(0, tlv_offset, tlv_buf); // language aim_writegeneric(msg_len, msg, tlv_offset, tlv_buf); // message text unsigned short offset = 0; unsigned short sn_length = (unsigned short)mir_strlen(sn); char* buf = (char*)alloca(SNAC_SIZE + 8 + 3 + sn_length + TLV_HEADER_SIZE * 3 + tlv_offset); aim_writesnac(0x04, 0x06, offset, buf, get_random()); aim_writegeneric(8, icbm_cookie, offset, buf); // icbm cookie aim_writeshort(0x01, offset, buf); // channel aim_writechar((unsigned char)sn_length, offset, buf); // screen name len aim_writegeneric(sn_length, sn, offset, buf); // screen name aim_writetlv(0x02, tlv_offset, tlv_buf, offset, buf); if (!blast) { if (auto_response) aim_writetlv(0x04, 0, 0, offset, buf); // auto-response message else { aim_writetlv(0x03, 0, 0, offset, buf); // message ack request aim_writetlv(0x06, 0, 0, offset, buf); // offline message storage } } return aim_sendflap(hServerConn, 0x02, offset, buf, seqno) ? 0 : *(int*)icbm_cookie & 0x7fffffff; }
int CAimProto::aim_chat_join_room(HANDLE hServerConn, unsigned short &seqno, char* chat_cookie, unsigned short exchange, unsigned short instance, unsigned short id) { unsigned short offset = 0; unsigned short cookie_len = (unsigned short)mir_strlen(chat_cookie); char* buf = (char*)alloca(SNAC_SIZE + TLV_HEADER_SIZE * 2 + cookie_len + 8); aim_writesnac(0x01, 0x04, offset, buf, id); aim_writeshort(0x0e, offset, buf); // Service request for Chat aim_writeshort(0x01, offset, buf); // Tag aim_writeshort(cookie_len + 5, offset, buf); // Length aim_writeshort(exchange, offset, buf); // Value - Exchange aim_writechar((unsigned char)cookie_len, offset, buf); // Value - Cookie Length aim_writegeneric(cookie_len, chat_cookie, offset, buf); // Value - Cookie aim_writeshort(instance, offset, buf); // Value - Instance if (!getByte(AIM_KEY_DSSL, 0)) aim_writetlv(0x8c, 0, NULL, offset, buf); // Request SSL connection return aim_sendflap(hServerConn, 0x02, offset, buf, seqno); }
// used when requesting a regular file transfer int CAimProto::aim_send_file(HANDLE hServerConn, unsigned short &seqno, unsigned long ip, unsigned short port, bool force_proxy, file_transfer *ft) { char msg_frag[2048]; unsigned short frag_offset = 0; aim_writeshort(0, frag_offset, msg_frag); // request type aim_writegeneric(8, ft->icbm_cookie, frag_offset, msg_frag); // icbm cookie aim_writegeneric(AIM_CAPS_LENGTH, AIM_CAP_FILE_TRANSFER, frag_offset, msg_frag); // uuid aim_writetlvshort(0x0a, ++ft->req_num, frag_offset, msg_frag); // request number aim_writetlvlong(0x02, ip, frag_offset, msg_frag); // ip aim_writetlvlong(0x16, ~ip, frag_offset, msg_frag); // ip check aim_writetlvshort(0x05, port, frag_offset, msg_frag); // port aim_writetlvshort(0x17, ~port, frag_offset, msg_frag); // port ip check if (force_proxy) aim_writetlv(0x10, 0, 0, frag_offset, msg_frag); // request proxy transfer else aim_writetlvlong(0x03, m_internal_ip, frag_offset, msg_frag); // ip if (ft->req_num == 1) { if (ft->message) { aimString dscr(ft->message); const char* charset = dscr.isUnicode() ? "unicode-2-0" : "us-ascii"; const unsigned short charset_len = (unsigned short)mir_strlen(charset); const char* desc_msg = dscr.getBuf(); const unsigned short desc_len = dscr.getSize(); aim_writetlv(0x0e, 2, "en", frag_offset, msg_frag); // language used by the data aim_writetlv(0x0d, charset_len, charset, frag_offset, msg_frag);// charset used by the data aim_writetlv(0x0c, desc_len, desc_msg, frag_offset, msg_frag); // invitaion text } aim_writetlv(0x0f, 0, 0, frag_offset, msg_frag); // request host check const char* fname = get_fname(ft->file); const unsigned short fnlen = (unsigned short)mir_strlen(fname); char* fblock = (char*)alloca(9 + fnlen); *(unsigned short*)&fblock[0] = _htons(ft->pfts.totalFiles > 1 ? 2 : 1); // single file transfer *(unsigned short*)&fblock[2] = _htons(ft->pfts.totalFiles); // number of files *(unsigned long*)&fblock[4] = _htonl(ft->pfts.totalBytes); // total bytes in files memcpy(&fblock[8], fname, fnlen + 1); const char* enc = is_utf(fname) ? "utf-8" : "us-ascii"; aim_writetlv(0x2711, 9 + fnlen, fblock, frag_offset, msg_frag); // extra data, file names, size aim_writetlv(0x2712, 8, enc, frag_offset, msg_frag); // character set used by data // aim_writetlvlong64(0x2713,ft->pfts.totalBytes,frag_offset,msg_frag); // file length debugLogA("Attempting to Send a file to a buddy."); } else { aim_writetlvshort(0x14, 0x0a, frag_offset, msg_frag); // Counter proposal reason } unsigned short offset = 0; unsigned short sn_length = (unsigned short)mir_strlen(ft->sn); char* buf = (char*)alloca(SNAC_SIZE + TLV_HEADER_SIZE * 2 + 12 + frag_offset + sn_length); aim_writesnac(0x04, 0x06, offset, buf); // msg to host aim_writegeneric(8, ft->icbm_cookie, offset, buf); // icbm cookie aim_writeshort(2, offset, buf); // icbm channel aim_writechar((unsigned char)sn_length, offset, buf); // screen name length aim_writegeneric(sn_length, ft->sn, offset, buf); // screen name aim_writetlv(0x05, frag_offset, msg_frag, offset, buf); // icbm tags aim_writetlv(0x03, 0, 0, offset, buf); // request ack char cip[20]; long_ip_to_char_ip(ip, cip); debugLogA("IP for Buddy to connect to: %s:%u", cip, port); return aim_sendflap(hServerConn, 0x02, offset, buf, seqno) == 0; }