/* Decrypts the given data. * Returns the decrypted data length. * * The output is preallocated with the maximum allowed data size. */ int _gnutls_decrypt(gnutls_session_t session, gnutls_datum_t *ciphertext, gnutls_datum_t *output, content_type_t *type, record_parameters_st *params, gnutls_uint64 *sequence) { int ret; const version_entry_st *vers = get_version(session); if (ciphertext->size == 0) return 0; if (vers && vers->tls13_sem) ret = decrypt_packet_tls13(session, ciphertext, output, type, params, sequence); else ret = decrypt_packet(session, ciphertext, output, *type, params, sequence); if (ret < 0) return gnutls_assert_val(ret); return ret; }
void take_encypt_string(char* dest, buffer_t *buffer) { size_t len; buffer_t string; clear_buffer(&string); take_buffer(&len, buffer, sizeof(len)); take_buffer(string.buff, buffer, len); decrypt_packet(&string,len); take_buffer(dest, &string, len); }
void take_encypt_string(buffer_t *buffer, char* dest) { size_t len; buffer_t string; clear_buffer(&string); take_buffer(buffer, &len, sizeof(len)); take_buffer(buffer, string.buff, len); decrypt_packet(&string,len); take_buffer(&string, dest, len); }
/* Non-blocking function reading available portion of a packet into the * ses's buffer, decrypting the length if encrypted, decrypting the * full portion if possible */ void read_packet() { int len; unsigned int maxlen; unsigned char blocksize; TRACE(("enter read_packet")); blocksize = ses.keys->recv_algo_crypt->blocksize; if (ses.readbuf == NULL || ses.readbuf->len < blocksize) { /* In the first blocksize of a packet */ /* Read the first blocksize of the packet, so we can decrypt it and * find the length of the whole packet */ read_packet_init(); /* If we don't have the length of decryptreadbuf, we didn't read * a whole blocksize and should exit */ if (ses.decryptreadbuf->len == 0) { TRACE(("leave read_packet: packetinit done")); return; } } /* Attempt to read the remainder of the packet, note that there * mightn't be any available (EAGAIN) */ assert(ses.readbuf != NULL); maxlen = ses.readbuf->len - ses.readbuf->pos; len = read(ses.sock, buf_getptr(ses.readbuf, maxlen), maxlen); buf_incrpos(ses.readbuf, len); if (len == 0) { dropbear_close("remote host closed connection"); } if (len < 0) { if (errno == EINTR || errno == EAGAIN) { TRACE(("leave read_packet: EINTR or EAGAIN")); return; } else { dropbear_exit("error reading"); } } if ((unsigned int)len == maxlen) { /* The whole packet has been read */ decrypt_packet(); /* The main select() loop in session.h will process_packet() to * handle the packet contents... */ } TRACE(("leave read_packet")); }
void handle_packet(const uchar *data, ushort size) { uchar *buf; int *bufsize; ushort psize; packet_t *pkt; if (_fromsv) { buf = _svbuf; bufsize = &_svbufsize; } else { buf = _clbuf; bufsize = &_clbufsize; } if (size+*bufsize >= BUFSIZE) { log_msg("dbg", "warning: buffer size exceeded in handle_packet.\r\n"); return; } memcpy(buf+*bufsize, data, size); *bufsize += size; psize = *(ushort *)buf; if (psize < 3) { log_msg("dbg", "warning: malformed packet (%.2X) incorrect size: %hu.\r\n", *(ushort *)data, psize); return; } if (*bufsize >= psize) { do { pkt = alloc_packet(buf, psize); if (decrypt_packet(pkt, _fromsv, &_isfirst) != 0) { log_msg("dbg", "error: decryption failed, missed key packet?\r\n"); } else { if (_fromsv) { handle_sv_packet(pkt); } else { handle_cl_packet(pkt); } } free(pkt); *bufsize -= psize; memcpy(buf, buf+psize, *bufsize); psize = *(ushort *)buf; } while (*bufsize >= psize && *bufsize > 0); } }
/*! * @brief Receive a new packet on the given remote endpoint. * @param remote Pointer to the \c Remote instance. * @param packet Pointer to a pointer that will receive the \c Packet data. * @return An indication of the result of processing the transmission request. */ static DWORD packet_receive_named_pipe(Remote *remote, Packet **packet) { DWORD headerBytes = 0, payloadBytesLeft = 0, res; PacketHeader header = { 0 }; LONG bytesRead; BOOL inHeader = TRUE; PUCHAR packetBuffer = NULL; PUCHAR payload = NULL; ULONG payloadLength; NamedPipeTransportContext* ctx = (NamedPipeTransportContext*)remote->transport->ctx; lock_acquire(remote->lock); dprintf("[PIPE PACKET RECEIVE] reading in the header from pipe handle: %p", ctx->pipe); // Read the packet length while (inHeader) { if (!ReadFile(ctx->pipe, ((PUCHAR)&header + headerBytes), sizeof(PacketHeader)-headerBytes, &bytesRead, NULL)) { SetLastError(ERROR_NOT_FOUND); goto out; } headerBytes += bytesRead; if (headerBytes != sizeof(PacketHeader)) { vdprintf("[PIPE] More bytes required"); continue; } inHeader = FALSE; } if (headerBytes != sizeof(PacketHeader)) { dprintf("[PIPE] we didn't get enough header bytes"); goto out; } vdprintf("[PIPE] the XOR key is: %02x%02x%02x%02x", header.xor_key[0], header.xor_key[1], header.xor_key[2], header.xor_key[3]); #ifdef DEBUGTRACE PUCHAR h = (PUCHAR)&header; dprintf("[PIPE] Packet header: [0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X]", h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7], h[8], h[9], h[10], h[11], h[12], h[13], h[14], h[15], h[16], h[17], h[18], h[19], h[20], h[21], h[22], h[23], h[24], h[25], h[26], h[27], h[28], h[29], h[30], h[31]); #endif // At this point, we might have read in a valid TLV packet, or we might have read in the first chunk of data // from a staged listener after a reconnect. We can figure this out rather lazily by assuming the following: // XOR keys are always 4 bytes that are non-zero. If the higher order byte of the xor key is zero, then it // isn't an XOR Key, instead it's the 4-byte length of the metsrv binary (because metsrv isn't THAT big). if (header.xor_key[3] == 0) { // looks like we have a metsrv instance, time to ignore it. int length = *(int*)&header.xor_key[0]; dprintf("[PIPE] discovered a length header, assuming it's metsrv of length %d", length); int bytesToRead = length - sizeof(PacketHeader) + sizeof(DWORD); char* buffer = (char*)malloc(bytesToRead); read_raw_bytes_to_buffer(ctx, buffer, bytesToRead, &bytesRead); free(buffer); // did something go wrong. if (bytesToRead != bytesRead) { dprintf("[PIPE] Failed to read all bytes when flushing the buffer: %u vs %u", bytesToRead, bytesRead); goto out; } // indicate success, but don't return a packet for processing SetLastError(ERROR_SUCCESS); *packet = NULL; } else { vdprintf("[PIPE] XOR key looks fine, moving on"); // xor the header data xor_bytes(header.xor_key, (PUCHAR)&header + sizeof(header.xor_key), sizeof(PacketHeader) - sizeof(header.xor_key)); #ifdef DEBUGTRACE PUCHAR h = (PUCHAR)&header; dprintf("[PIPE] Packet header: [0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X]", h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7], h[8], h[9], h[10], h[11], h[12], h[13], h[14], h[15], h[16], h[17], h[18], h[19], h[20], h[21], h[22], h[23], h[24], h[25], h[26], h[27], h[28], h[29], h[30], h[31]); #endif // if we don't have a GUID yet, we need to take the one given in the packet if (is_null_guid(remote->orig_config->session.session_guid)) { memcpy(remote->orig_config->session.session_guid, header.session_guid, sizeof(remote->orig_config->session.session_guid)); } payloadLength = ntohl(header.length) - sizeof(TlvHeader); dprintf("[PIPE] Payload length is %u 0x%08x", payloadLength, payloadLength); DWORD packetSize = sizeof(PacketHeader) + payloadLength; dprintf("[PIPE] total buffer size for the packet is %u 0x%08x", packetSize, packetSize); payloadBytesLeft = payloadLength; // Allocate the payload if (!(packetBuffer = (PUCHAR)malloc(packetSize))) { dprintf("[PIPE] Failed to create the packet buffer"); SetLastError(ERROR_NOT_ENOUGH_MEMORY); goto out; } dprintf("[PIPE] Allocated packet buffer at %p", packetBuffer); // we're done with the header data, so we need to re-encode it, as the packet decryptor is going to // handle the extraction for us. xor_bytes(header.xor_key, (LPBYTE)&header.session_guid[0], sizeof(PacketHeader) - sizeof(header.xor_key)); // Copy the packet header stuff over to the packet memcpy_s(packetBuffer, sizeof(PacketHeader), (LPBYTE)&header, sizeof(PacketHeader)); payload = packetBuffer + sizeof(PacketHeader); // Read the payload res = read_raw_bytes_to_buffer(ctx, payload, payloadLength, &bytesRead); dprintf("[PIPE] wanted %u read %u", payloadLength, bytesRead); // Didn't finish? if (bytesRead != payloadLength) { dprintf("[PIPE] Failed to get all the payload bytes"); SetLastError(res); goto out; } vdprintf("[PIPE] decrypting packet"); SetLastError(decrypt_packet(remote, packet, packetBuffer, packetSize)); free(packetBuffer); packetBuffer = NULL; } out: res = GetLastError(); // Cleanup if (packetBuffer) { free(packetBuffer); } lock_release(remote->lock); return res; }
/*! * @brief Windows-specific function to receive a new packet via one of the HTTP libs (WinInet or WinHTTP). * @param remote Pointer to the \c Remote instance. * @param packet Pointer to a pointer that will receive the \c Packet data. * @return An indication of the result of processing the transmission request. */ static DWORD packet_receive_http(Remote *remote, Packet **packet) { DWORD headerBytes = 0, payloadBytesLeft = 0, res; Packet *localPacket = NULL; PacketHeader header; LONG bytesRead; BOOL inHeader = TRUE; PUCHAR packetBuffer = NULL; ULONG payloadLength; HttpTransportContext* ctx = (HttpTransportContext*)remote->transport->ctx; HINTERNET hReq; BOOL hRes; DWORD retries = 5; lock_acquire(remote->lock); hReq = ctx->create_req(ctx, TRUE, "PACKET RECEIVE"); if (hReq == NULL) { goto out; } vdprintf("[PACKET RECEIVE HTTP] sending GET"); hRes = ctx->send_req(ctx, hReq, NULL, 0); if (!hRes) { dprintf("[PACKET RECEIVE HTTP] Failed send_req: %d %d", GetLastError(), WSAGetLastError()); SetLastError(ERROR_NOT_FOUND); goto out; } vdprintf("[PACKET RECEIVE HTTP] Waiting to see the response ..."); if (ctx->receive_response && !ctx->receive_response(hReq)) { vdprintf("[PACKET RECEIVE] Failed receive: %d", GetLastError()); SetLastError(ERROR_NOT_FOUND); goto out; } SetLastError(ctx->validate_response(hReq, ctx)); if (GetLastError() != ERROR_SUCCESS) { goto out; } // Read the packet length retries = 3; vdprintf("[PACKET RECEIVE HTTP] Start looping through the receive calls"); while (inHeader && retries > 0) { retries--; if (!ctx->read_response(hReq, (PUCHAR)&header + headerBytes, sizeof(PacketHeader)-headerBytes, &bytesRead)) { dprintf("[PACKET RECEIVE HTTP] Failed HEADER read_response: %d", GetLastError()); SetLastError(ERROR_NOT_FOUND); goto out; } vdprintf("[PACKET RECEIVE NHTTP] Data received: %u bytes", bytesRead); // If the response contains no data, this is fine, it just means the // remote side had nothing to tell us. Indicate this through a // ERROR_EMPTY response code so we can update the timestamp. if (bytesRead == 0) { SetLastError(ERROR_EMPTY); goto out; } headerBytes += bytesRead; if (headerBytes != sizeof(PacketHeader)) { continue; } inHeader = FALSE; } if (headerBytes != sizeof(PacketHeader)) { dprintf("[PACKET RECEIVE HTTP] headerBytes not valid"); SetLastError(ERROR_NOT_FOUND); goto out; } dprintf("[PACKET RECEIVE HTTP] decoding header"); PacketHeader encodedHeader; memcpy(&encodedHeader, &header, sizeof(PacketHeader)); xor_bytes(header.xor_key, (PUCHAR)&header + sizeof(header.xor_key), sizeof(PacketHeader) - sizeof(header.xor_key)); #ifdef DEBUGTRACE PUCHAR h = (PUCHAR)&header; vdprintf("[HTTP] Packet header: [0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X]", h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7], h[8], h[9], h[10], h[11], h[12], h[13], h[14], h[15], h[16], h[17], h[18], h[19], h[20], h[21], h[22], h[23], h[24], h[25], h[26], h[27], h[28], h[29], h[30], h[31]); #endif payloadLength = ntohl(header.length) - sizeof(TlvHeader); vdprintf("[REC HTTP] Payload length is %d", payloadLength); DWORD packetSize = sizeof(PacketHeader) + payloadLength; vdprintf("[REC HTTP] total buffer size for the packet is %d", packetSize); payloadBytesLeft = payloadLength; // Allocate the payload if (!(packetBuffer = (PUCHAR)malloc(packetSize))) { dprintf("[REC HTTP] Failed to create the packet buffer"); SetLastError(ERROR_NOT_ENOUGH_MEMORY); goto out; } dprintf("[REC HTTP] Allocated packet buffer at %p", packetBuffer); // Copy the packet header stuff over to the packet memcpy_s(packetBuffer, sizeof(PacketHeader), (LPBYTE)&encodedHeader, sizeof(PacketHeader)); LPBYTE payload = packetBuffer + sizeof(PacketHeader); // Read the payload retries = payloadBytesLeft; while (payloadBytesLeft > 0 && retries > 0) { vdprintf("[PACKET RECEIVE HTTP] reading more data from the body..."); retries--; if (!ctx->read_response(hReq, payload + payloadLength - payloadBytesLeft, payloadBytesLeft, &bytesRead)) { dprintf("[PACKET RECEIVE] Failed BODY read_response: %d", GetLastError()); SetLastError(ERROR_NOT_FOUND); goto out; } if (!bytesRead) { vdprintf("[PACKET RECEIVE HTTP] no bytes read, bailing out"); SetLastError(ERROR_NOT_FOUND); goto out; } vdprintf("[PACKET RECEIVE HTTP] bytes read: %u", bytesRead); payloadBytesLeft -= bytesRead; } // Didn't finish? if (payloadBytesLeft) { goto out; } #ifdef DEBUGTRACE h = (PUCHAR)&header.session_guid[0]; dprintf("[HTTP] Packet Session GUID: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7], h[8], h[9], h[10], h[11], h[12], h[13], h[14], h[15]); #endif if (is_null_guid(header.session_guid) || memcmp(remote->orig_config->session.session_guid, header.session_guid, sizeof(header.session_guid)) == 0) { dprintf("[HTTP] Session GUIDs match (or packet guid is null), decrypting packet"); SetLastError(decrypt_packet(remote, packet, packetBuffer, packetSize)); } else { dprintf("[HTTP] Session GUIDs don't match, looking for a pivot"); PivotContext* pivotCtx = pivot_tree_find(remote->pivot_sessions, header.session_guid); if (pivotCtx != NULL) { dprintf("[HTTP] Pivot found, dispatching packet on a thread (to avoid main thread blocking)"); SetLastError(pivot_packet_dispatch(pivotCtx, packetBuffer, packetSize)); // mark this packet buffer as NULL as the thread will clean it up packetBuffer = NULL; *packet = NULL; } else { dprintf("[HTTP] Session GUIDs don't match, can't find pivot!"); } } out: res = GetLastError(); dprintf("[HTTP] Cleaning up"); SAFE_FREE(packetBuffer); // Cleanup on failure if (res != ERROR_SUCCESS) { SAFE_FREE(localPacket); } if (hReq) { ctx->close_req(hReq); } lock_release(remote->lock); dprintf("[HTTP] Packet receive finished"); return res; }
int process_packet( qqclient* qq, qqpacket* p, bytebuffer* buf ) { if( !decrypt_packet( qq, p, buf ) ) return -1; if( qq->log_packet ){ DBG("[%d] recv packet ver:%x cmd: %x seqno: %x", qq->number, p->version, p->command, p->seqno ); hex_dump( p->buf->data, p->buf->len ); } switch( p->command ){ case QQ_CMD_TOUCH: prot_login_touch_reply( qq, p ); break; case QQ_CMD_LOGIN_REQUEST: prot_login_request_reply( qq, p ); break; case QQ_CMD_LOGIN_VERIFY: prot_login_verify_reply( qq, p ); break; case QQ_CMD_LOGIN_GET_INFO: prot_login_get_info_reply( qq, p ); break; case QQ_CMD_LOGIN_A4: prot_login_a4_reply( qq, p ); break; case QQ_CMD_LOGIN_GET_LIST: prot_login_get_list_reply( qq, p ); break; case QQ_CMD_LOGIN_SEND_INFO: prot_login_send_info_reply( qq, p ); break; case QQ_CMD_E9: prot_login_e9_reply( qq, p ); break; case QQ_CMD_EA: prot_login_ea_reply( qq, p ); break; case QQ_CMD_EC: prot_login_ec_reply( qq, p ); break; case QQ_CMD_ED: prot_login_ed_reply( qq, p ); break; case QQ_CMD_KEEP_ALIVE: prot_user_keep_alive_reply( qq, p ); break; case QQ_CMD_RECV_IM_09: case QQ_CMD_RECV_IM: prot_im_recv_msg( qq, p ); break; case QQ_CMD_CHANGE_STATUS: prot_user_change_status_reply( qq, p ); break; #ifndef NO_BUDDY_INFO case QQ_CMD_GET_BUDDY_LIST: prot_buddy_update_list_reply( qq, p ); break; case QQ_CMD_GET_BUDDY_ONLINE: prot_buddy_update_online_reply( qq, p ); break; case QQ_CMD_BUDDY_STATUS: prot_buddy_status( qq, p ); break; #endif #ifndef NO_QUN_INFO case QQ_CMD_QUN_CMD: prot_qun_cmd_reply( qq, p ); break; #endif case QQ_CMD_GET_KEY: prot_user_get_key_reply( qq, p ); break; case QQ_CMD_GET_NOTICE: prot_user_get_notice_reply( qq, p ); break; case QQ_CMD_CHECK_IP: prot_user_check_ip_reply( qq, p ); break; #ifndef NO_BUDDY_DETAIL_INFO case QQ_CMD_GET_BUDDY_SIGN: prot_buddy_update_signiture_reply( qq, p ); break; case QQ_CMD_ACCOUNT: prot_buddy_update_account_reply( qq, p ); break; case QQ_CMD_BUDDY_ALIAS: prot_buddy_update_alias_reply( qq, p ); break; case QQ_CMD_GET_BUDDY_EXTRA_INFO: prot_buddy_get_extra_info_reply( qq, p ); break; case QQ_CMD_BUDDY_INFO: prot_buddy_get_info_reply( qq, p ); break; #endif #ifndef NO_GROUP_INFO case QQ_CMD_GROUP_LABEL: prot_group_download_labels_reply( qq, p ); break; #endif case QQ_CMD_SEND_IM: break; case QQ_CMD_BROADCAST: prot_misc_broadcast( qq, p ); break; case QQ_CMD_GET_LEVEL: prot_user_get_level_reply( qq, p ); break; case QQ_CMD_ADDBUDDY_REQUEST: prot_buddy_request_addbuddy_reply( qq, p ); break; case QQ_CMD_ADDBUDDY_VERIFY: prot_buddy_verify_addbuddy_reply( qq, p ); break; case QQ_CMD_REQUEST_TOKEN: prot_user_request_token_reply( qq, p ); break; case QQ_CMD_DEL_BUDDY: prot_buddy_del_buddy_reply( qq, p ); break; default: DBG("unknown cmd: %x", p->command ); hex_dump( p->buf->data, p->buf->len ); break; } return 0; }
int process_packet( qqclient* qq, qqpacket* p, bytebuffer* buf ) { if( !decrypt_packet( qq, p, buf ) ) return -1; if( qq->log_packet ){ DBG("[%d] recv packet ver:%x cmd: %x seqno: %x", qq->number, p->version, p->command, p->seqno ); hex_dump( p->buf->data, p->buf->len ); } // memcpy(qq->mimnetwork->m_libevabuffer,p->buf->data,p->buf->len); qq->mimnetwork->m_packet=p; switch( p->command ){ case QQ_CMD_TOUCH: prot_login_touch_reply( qq, p ); break; case QQ_CMD_LOGIN_REQUEST: prot_login_request_reply( qq, p ); break; case QQ_CMD_LOGIN_VERIFY: prot_login_verify_reply( qq, p ); break; case QQ_CMD_LOGIN_GET_INFO: prot_login_get_info_reply( qq, p ); break; case QQ_CMD_LOGIN_A4: prot_login_a4_reply( qq, p ); break; case QQ_CMD_LOGIN_GET_LIST: prot_login_get_list_reply( qq, p ); break; case QQ_CMD_LOGIN_SEND_INFO: prot_login_send_info_reply( qq, p ); break; case QQ_CMD_E9: prot_login_e9_reply( qq, p ); break; case QQ_CMD_EA: prot_login_ea_reply( qq, p ); break; case QQ_CMD_EC: prot_login_ec_reply( qq, p ); break; case QQ_CMD_ED: prot_login_ed_reply( qq, p ); break; case QQ_CMD_KEEP_ALIVE: prot_user_keep_alive_reply( qq, p ); break; case QQ_CMD_RECV_IM_09: case QQ_CMD_RECV_IM: // MirandaQQ handles message by itself due to userhead/emoticon stuff // however ack is better handled by myqq3 in case of proto change prot_im_recv_msg( qq, p ); //prot_im_ack_recv( qq, p ); break; case QQ_CMD_CHANGE_STATUS: prot_user_change_status_reply( qq, p ); break; #ifndef NO_BUDDY_INFO case QQ_CMD_GET_BUDDY_LIST: prot_buddy_update_list_reply( qq, p ); break; case QQ_CMD_GET_BUDDY_ONLINE: prot_buddy_update_online_reply( qq, p ); break; case QQ_CMD_BUDDY_STATUS: prot_buddy_status( qq, p ); break; #endif #ifndef NO_QUN_INFO case QQ_CMD_QUN_CMD: prot_qun_cmd_reply( qq, p ); break; #endif case QQ_CMD_GET_KEY: prot_user_get_key_reply( qq, p ); break; case QQ_CMD_GET_NOTICE: prot_user_get_notice_reply( qq, p ); break; case QQ_CMD_CHECK_IP: prot_user_check_ip_reply( qq, p ); break; #ifndef NO_BUDDY_DETAIL_INFO case QQ_CMD_GET_BUDDY_SIGN: prot_buddy_update_signiture_reply( qq, p ); break; case QQ_CMD_ACCOUNT: prot_buddy_update_account_reply( qq, p ); break; case QQ_CMD_BUDDY_ALIAS: prot_buddy_update_alias_reply( qq, p ); break; case QQ_CMD_GET_BUDDY_EXTRA_INFO: prot_buddy_get_extra_info_reply( qq, p ); break; case QQ_CMD_BUDDY_INFO: prot_buddy_get_info_reply( qq, p ); break; #endif #ifndef NO_GROUP_INFO case QQ_CMD_GROUP_LABEL: prot_group_download_labels_reply( qq, p ); break; #endif case QQ_CMD_SEND_IM: break; case QQ_CMD_BROADCAST: prot_misc_broadcast( qq, p ); break; case QQ_CMD_GET_LEVEL: prot_user_get_level_reply( qq, p ); break; case QQ_CMD_ADDBUDDY_REQUEST: prot_buddy_request_addbuddy_reply( qq, p ); break; case QQ_CMD_ADDBUDDY_VERIFY: prot_buddy_verify_addbuddy_reply( qq, p ); break; case QQ_CMD_REQUEST_TOKEN: prot_user_request_token_reply( qq, p ); break; case QQ_CMD_DEL_BUDDY: prot_buddy_del_buddy_reply( qq, p ); break; case QQ_CMD_SEARCH_UID: prot_buddy_search_uid_reply( qq, p ); break; case 0xa6: // Weather prot_weather_reply( qq, p ); break; default: DBG("unknown cmd: %x", p->command ); hex_dump( p->buf->data, p->buf->len ); break; } /* qq->mimnetwork->m_packet=p; qq->mimnetwork->processPacket(qq->mimnetwork->m_libevabuffer,p->buf->len); */ return 0; }