Mercurial > pidgin.yaz
diff libpurple/protocols/qq/qq_process.c @ 23753:5f454b975a99
2008.08.10 - csyfek <csyfek(at)gmail.com>
* Commit to Pidgin
2008.08.06 - ccpaging <ecc_hy(at)hotmail.com>
* Rename names of variables, Group, to Room
* Functions of group_network merged into qq_network and qq_process
* Canceled managing glist of group packet, add sub_cmdd and room_id to transaction
* Fixed error of demo group:
If 'room list' and 'room infor' are not setup, response received from server will emits
'room_id = 0' packet.
2008.08.04 - ccpaging <ecc_hy(at)hotmail.com>
* Use new crypt/decrypt functions
* Rename crypt.c/h to qq_crypt.c/h
* Clean code of decrypt functions
* Fixed decryption failure
2008.08.04 - csyfek <csyfek(at)gmail.com>
* Update AUTHORS
author | SHiNE CsyFeK <csyfek@gmail.com> |
---|---|
date | Sun, 10 Aug 2008 04:32:14 +0000 |
parents | eba700811832 |
children | 967344bc404d e16982ad923f |
line wrap: on
line diff
--- a/libpurple/protocols/qq/qq_process.c Sat Aug 09 23:23:48 2008 +0000 +++ b/libpurple/protocols/qq/qq_process.c Sun Aug 10 04:32:14 2008 +0000 @@ -37,8 +37,17 @@ #include "group_info.h" #include "group_free.h" #include "char_conv.h" -#include "crypt.h" -#include "group_network.h" +#include "qq_crypt.h" + +#include "group_conv.h" +#include "group_find.h" +#include "group_internal.h" +#include "group_im.h" +#include "group_info.h" +#include "group_join.h" +#include "group_opt.h" +#include "group_search.h" + #include "header_info.h" #include "qq_base.h" #include "im.h" @@ -49,28 +58,24 @@ #include "sys_msg.h" #include "utils.h" +enum { + QQ_ROOM_CMD_REPLY_OK = 0x00, + QQ_ROOM_CMD_REPLY_SEARCH_ERROR = 0x02, + QQ_ROOM_CMD_REPLY_NOT_MEMBER = 0x0a +}; + /* default process, decrypt and dump */ -static void process_cmd_unknow(PurpleConnection *gc,gchar *title, guint8 *buf, gint buf_len, guint16 cmd, guint16 seq) +static void process_cmd_unknow(PurpleConnection *gc,gchar *title, guint8 *data, gint data_len, guint16 cmd, guint16 seq) { qq_data *qd; - guint8 *data; - gint data_len; gchar *msg_utf8 = NULL; - g_return_if_fail(buf != NULL && buf_len != 0); + g_return_if_fail(data != NULL && data_len != 0); - qq_show_packet(title, buf, buf_len); + qq_show_packet(title, data, data_len); qd = (qq_data *) gc->proto_data; - data_len = buf_len; - data = g_newa(guint8, data_len); - memset(data, 0, data_len); - if ( !qq_decrypt(buf, buf_len, qd->session_key, data, &data_len )) { - purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Fail decrypt packet with default process\n"); - return; - } - qq_hex_dump(PURPLE_DEBUG_WARNING, "QQ", data, data_len, ">>> [%d] %s -> [default] decrypt and dump", @@ -78,13 +83,39 @@ msg_utf8 = try_dump_as_gbk(data, data_len); if (msg_utf8) { + purple_notify_info(gc, NULL, msg_utf8, NULL); g_free(msg_utf8); } } void qq_proc_cmd_server(PurpleConnection *gc, - guint16 cmd, guint16 seq, guint8 *data, gint data_len) + guint16 cmd, guint16 seq, guint8 *rcved, gint rcved_len) { + qq_data *qd; + + guint8 *data; + gint data_len; + + g_return_if_fail (gc != NULL && gc->proto_data != NULL); + qd = (qq_data *) gc->proto_data; + + data = g_newa(guint8, rcved_len); + data_len = qq_decrypt(data, rcved, rcved_len, qd->session_key); + if (data_len < 0) { + purple_debug(PURPLE_DEBUG_WARNING, "QQ", + "Can not decrypt server cmd by session key, [%05d], 0x%04X %s, len %d\n", + seq, cmd, qq_get_cmd_desc(cmd), rcved_len); + qq_show_packet("Can not decrypted", rcved, rcved_len); + return; + } + + if (data_len <= 0) { + purple_debug(PURPLE_DEBUG_WARNING, "QQ", + "Server cmd decrypted is empty, [%05d], 0x%04X %s, len %d\n", + seq, cmd, qq_get_cmd_desc(cmd), rcved_len); + return; + } + /* now process the packet */ switch (cmd) { case QQ_CMD_RECV_IM: @@ -134,7 +165,7 @@ qq_send_packet_get_buddies_list(gc, 0); /* refresh groups */ - qq_send_packet_get_all_list_with_group(gc, 0); + qq_send_packet_get_buddies_and_rooms(gc, 0); return; } @@ -168,14 +199,223 @@ } } +static void process_room_cmd_notify(PurpleConnection *gc, + guint8 room_cmd, guint8 room_id, guint8 reply_cmd, guint8 reply, guint8 *data, gint data_len) +{ + gchar *msg, *msg_utf8; + g_return_if_fail(data != NULL && data_len > 0); + + msg = g_strndup((gchar *) data, data_len); /* it will append 0x00 */ + msg_utf8 = qq_to_utf8(msg, QQ_CHARSET_DEFAULT); + g_free(msg); + + msg = g_strdup_printf(_( + "Reply %s(0x%02X )\n" + "Sent %s(0x%02X )\n" + "Room id %d, reply [0x%02X]: \n" + "%s"), + qq_get_room_cmd_desc(reply_cmd), reply_cmd, + qq_get_room_cmd_desc(room_cmd), room_cmd, + room_id, reply, msg_utf8); + + purple_notify_error(gc, NULL, _("Failed room reply"), msg); + g_free(msg); + g_free(msg_utf8); +} + +void qq_proc_room_cmd_reply(PurpleConnection *gc, + guint16 seq, guint8 room_cmd, guint32 room_id, guint8 *rcved, gint rcved_len) +{ + qq_data *qd; + guint8 *data; + gint data_len; + qq_group *group; + gint bytes; + guint8 reply_cmd, reply; + + g_return_if_fail (gc != NULL && gc->proto_data != NULL); + qd = (qq_data *) gc->proto_data; + + data = g_newa(guint8, rcved_len); + data_len = qq_decrypt(data, rcved, rcved_len, qd->session_key); + if (data_len < 0) { + purple_debug(PURPLE_DEBUG_WARNING, "QQ", + "Can not decrypt room cmd by session key, [%05d], 0x%02X %s for %d, len %d\n", + seq, room_cmd, qq_get_room_cmd_desc(room_cmd), room_id, rcved_len); + qq_show_packet("Can not decrypted", rcved, rcved_len); + return; + } + + if (room_id <= 0) { + purple_debug(PURPLE_DEBUG_WARNING, "QQ", + "Invaild room id, [%05d], 0x%02X %s for %d, len %d\n", + seq, room_cmd, qq_get_room_cmd_desc(room_cmd), room_id, rcved_len); + return; + } + + if (data_len <= 2) { + purple_debug(PURPLE_DEBUG_WARNING, "QQ", + "Invaild len of room cmd decrypted, [%05d], 0x%02X %s for %d, len %d\n", + seq, room_cmd, qq_get_room_cmd_desc(room_cmd), room_id, rcved_len); + return; + } + + group = qq_room_search_id(gc, room_id); + if (group == NULL) { + purple_debug(PURPLE_DEBUG_WARNING, "QQ", + "Missing room id in [%05d], 0x%02X %s for %d, len %d\n", + seq, room_cmd, qq_get_room_cmd_desc(room_cmd), room_id, rcved_len); + } + + bytes = 0; + bytes += qq_get8(&reply_cmd, data + bytes); + bytes += qq_get8(&reply, data + bytes); + + if (reply_cmd != room_cmd) { + purple_debug(PURPLE_DEBUG_WARNING, "QQ", + "Missing room cmd in reply 0x%02X %s, [%05d], 0x%02X %s for %d, len %d\n", + reply_cmd, qq_get_room_cmd_desc(reply_cmd), + seq, room_cmd, qq_get_room_cmd_desc(room_cmd), room_id, rcved_len); + } + + /* now process the packet */ + if (reply != QQ_ROOM_CMD_REPLY_OK) { + if (group != NULL) { + qq_set_pending_id(&qd->joining_groups, group->ext_id, FALSE); + } + + switch (reply) { /* this should be all errors */ + case QQ_ROOM_CMD_REPLY_NOT_MEMBER: + if (group != NULL) { + purple_debug(PURPLE_DEBUG_WARNING, + "QQ", + _("You are not a member of group \"%s\"\n"), group->group_name_utf8); + group->my_status = QQ_GROUP_MEMBER_STATUS_NOT_MEMBER; + qq_group_refresh(gc, group); + } + break; + case QQ_ROOM_CMD_REPLY_SEARCH_ERROR: + if (qd->roomlist != NULL) { + if (purple_roomlist_get_in_progress(qd->roomlist)) + purple_roomlist_set_in_progress(qd->roomlist, FALSE); + } + default: + process_room_cmd_notify(gc, room_cmd, room_id, reply_cmd, reply, data + bytes, data_len - bytes); + } + return; + } + + /* seems ok so far, so we process the reply according to sub_cmd */ + switch (reply_cmd) { + case QQ_ROOM_CMD_GET_INFO: + qq_process_room_cmd_get_info(data + bytes, data_len - bytes, gc); + if (group != NULL) { + qq_send_cmd_group_get_members_info(gc, group); + qq_send_cmd_group_get_online_members(gc, group); + } + break; + case QQ_ROOM_CMD_CREATE: + qq_group_process_create_group_reply(data + bytes, data_len - bytes, gc); + break; + case QQ_ROOM_CMD_CHANGE_INFO: + qq_group_process_modify_info_reply(data + bytes, data_len - bytes, gc); + break; + case QQ_ROOM_CMD_MEMBER_OPT: + qq_group_process_modify_members_reply(data + bytes, data_len - bytes, gc); + break; + case QQ_ROOM_CMD_ACTIVATE: + qq_group_process_activate_group_reply(data + bytes, data_len - bytes, gc); + break; + case QQ_ROOM_CMD_SEARCH: + qq_process_group_cmd_search_group(data + bytes, data_len - bytes, gc); + break; + case QQ_ROOM_CMD_JOIN: + qq_process_group_cmd_join_group(data + bytes, data_len - bytes, gc); + break; + case QQ_ROOM_CMD_AUTH: + qq_process_group_cmd_join_group_auth(data + bytes, data_len - bytes, gc); + break; + case QQ_ROOM_CMD_QUIT: + qq_process_group_cmd_exit_group(data + bytes, data_len - bytes, gc); + break; + case QQ_ROOM_CMD_SEND_MSG: + qq_process_group_cmd_im(data + bytes, data_len - bytes, gc); + break; + case QQ_ROOM_CMD_GET_ONLINES: + qq_process_room_cmd_get_onlines(data + bytes, data_len - bytes, gc); + if (group != NULL) + qq_group_conv_refresh_online_member(gc, group); + break; + case QQ_ROOM_CMD_GET_MEMBER_INFO: + qq_process_room_cmd_get_members(data + bytes, data_len - bytes, gc); + if (group != NULL) + qq_group_conv_refresh_online_member(gc, group); + break; + default: + purple_debug(PURPLE_DEBUG_WARNING, "QQ", + "Unknow room cmd 0x%02X %s\n", + reply_cmd, qq_get_room_cmd_desc(reply_cmd)); + } +} + void qq_proc_cmd_reply(PurpleConnection *gc, - guint16 cmd, guint16 seq, guint8 *data, gint data_len) + guint16 cmd, guint16 seq, guint8 *rcved, gint rcved_len) { + qq_data *qd; + + guint8 *data; + gint data_len; + + gboolean ret_bool = FALSE; guint8 ret_8 = 0; guint16 ret_16 = 0; guint32 ret_32 = 0; gchar *error_msg = NULL; + g_return_if_fail(rcved_len > 0); + + g_return_if_fail (gc != NULL && gc->proto_data != NULL); + qd = (qq_data *) gc->proto_data; + + data = g_newa(guint8, rcved_len); + if (cmd == QQ_CMD_TOKEN) { + g_memmove(data, rcved, rcved_len); + data_len = rcved_len; + } else if (cmd == QQ_CMD_LOGIN) { + /* May use password_twice_md5 in the past version like QQ2005*/ + data_len = qq_decrypt(data, rcved, rcved_len, qd->inikey); + if (data_len >= 0) { + purple_debug(PURPLE_DEBUG_WARNING, "QQ", + "Decrypt login reply packet with inikey, %d bytes\n", data_len); + } else { + data_len = qq_decrypt(data, rcved, rcved_len, qd->password_twice_md5); + if (data_len >= 0) { + purple_debug(PURPLE_DEBUG_WARNING, "QQ", + "Decrypt login reply packet with password_twice_md5, %d bytes\n", data_len); + } else { + purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, + _("Can not decrypt login reply")); + return; + } + } + } else { + data_len = qq_decrypt(data, rcved, rcved_len, qd->session_key); + if (data_len < 0) { + purple_debug(PURPLE_DEBUG_WARNING, "QQ", + "Can not reply by session key, [%05d], 0x%04X %s, len %d\n", + seq, cmd, qq_get_cmd_desc(cmd), rcved_len); + qq_show_packet("Can not decrypted", rcved, rcved_len); + return; + } + } + + if (data_len <= 0) { + purple_debug(PURPLE_DEBUG_WARNING, "QQ", + "Reply decrypted is empty, [%05d], 0x%04X %s, len %d\n", + seq, cmd, qq_get_cmd_desc(cmd), rcved_len); + return; + } + switch (cmd) { case QQ_CMD_TOKEN: ret_8 = qq_process_token_reply(gc, error_msg, data, data_len); @@ -246,14 +486,11 @@ qq_send_packet_get_buddies_online(gc, 0); } break; - case QQ_CMD_GROUP_CMD: - qq_process_group_cmd_reply(data, data_len, seq, gc); - break; - case QQ_CMD_GET_ALL_LIST_WITH_GROUP: - ret_32 = qq_process_get_all_list_with_group_reply(data, data_len, gc); + case QQ_CMD_GET_BUDDIES_AND_ROOMS: + ret_32 = qq_process_get_buddies_and_rooms(data, data_len, gc); if (ret_32 > 0 && ret_32 < 0xffffffff) { purple_debug(PURPLE_DEBUG_INFO, "QQ", "Requesting for more buddies and groups\n"); - qq_send_packet_get_all_list_with_group(gc, ret_32); + qq_send_packet_get_buddies_and_rooms(gc, ret_32); } else { purple_debug(PURPLE_DEBUG_INFO, "QQ", "All buddies and groups received\n"); }