📄 login_logout.c
字号:
/** * @file login_logout.c * * purple * * Purple is the legal property of its developers, whose names are too numerous * to list here. Please refer to the COPYRIGHT file distributed with this * source distribution. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include "debug.h"#include "internal.h"#include "server.h"#include "buddy_info.h"#include "buddy_list.h"#include "buddy_status.h"#include "char_conv.h"#include "crypt.h"#include "group.h"#include "header_info.h"#include "login_logout.h"#include "packet_parse.h"#include "qq.h"#include "qq_proxy.h"#include "send_core.h"#include "utils.h"#define QQ_LOGIN_DATA_LENGTH 416#define QQ_LOGIN_REPLY_OK_PACKET_LEN 139#define QQ_LOGIN_REPLY_REDIRECT_PACKET_LEN 11#define QQ_REQUEST_LOGIN_TOKEN_REPLY_OK 0x00#define QQ_LOGIN_REPLY_OK 0x00#define QQ_LOGIN_REPLY_REDIRECT 0x01#define QQ_LOGIN_REPLY_PWD_ERROR 0x05#define QQ_LOGIN_REPLY_MISC_ERROR 0xff /* defined by myself *//* for QQ 2003iii 0117, fixed value *//* static const guint8 login_23_51[29] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0x14, 0x11, 0x20, 0x03, 0x9d, 0xb2, 0xe6, 0xb3, 0x11, 0xb7, 0x13, 0x95, 0x67, 0xda, 0x2c, 0x01 }; *//* for QQ 2003iii 0304, fixed value *//*static const guint8 login_23_51[29] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x93, 0xfe, 0x85, 0xd3, 0xd9, 0x2a, 0x41, 0xc8, 0x0d, 0xff, 0xb6, 0x40, 0xb8, 0xac, 0x32, 0x01};*//* for QQ 2005? copy from lumaqq */static const gint8 login_23_51[29] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -122, -52, 76, 53, 44, -45, 115, 108, 20, -10, -10, -81, -61, -6, 51, -92, 1};static const gint8 login_53_68[16] = { -115, -117, -6, -20, -43, 82, 23, 74, -122, -7, -89, 117, -26, 50, -47, 109};static const gint8 login_100_bytes[100] = { 64, 11, 4, 2, 0, 1, 0, 0, 0, 0, 0, 3, 9, 0, 0, 0, 0, 0, 0, 0, 1, -23, 3, 1, 0, 0, 0, 0, 0, 1, -13, 3, 0, 0, 0, 0, 0, 0, 1, -19, 3, 0, 0, 0, 0, 0, 0, 1, -20, 3, 0, 0, 0, 0, 0, 0, 3, 5, 0, 0, 0, 0, 0, 0, 0, 3, 7, 0, 0, 0, 0, 0, 0, 0, 1, -18, 3, 0, 0, 0, 0, 0, 0, 1, -17, 3, 0, 0, 0, 0, 0, 0, 1, -21, 3, 0, 0, 0, 0, 0};/* fixed value, not affected by version, or mac address *//*static const guint8 login_53_68[16] = { 0x82, 0x2a, 0x91, 0xfd, 0xa5, 0xca, 0x67, 0x4c, 0xac, 0x81, 0x1f, 0x6f, 0x52, 0x05, 0xa7, 0xbf};*/typedef struct _qq_login_reply_ok qq_login_reply_ok_packet;typedef struct _qq_login_reply_redirect qq_login_reply_redirect_packet;struct _qq_login_reply_ok { guint8 result; guint8 *session_key; guint32 uid; guint8 client_ip[4]; /* those detected by server */ guint16 client_port; guint8 server_ip[4]; guint16 server_port; time_t login_time; guint8 unknown1[26]; guint8 unknown_server1_ip[4]; guint16 unknown_server1_port; guint8 unknown_server2_ip[4]; guint16 unknown_server2_port; guint16 unknown2; /* 0x0001 */ guint16 unknown3; /* 0x0000 */ guint8 unknown4[32]; guint8 unknown5[12]; guint8 last_client_ip[4]; time_t last_login_time; guint8 unknown6[8];};struct _qq_login_reply_redirect { guint8 result; guint32 uid; guint8 new_server_ip[4]; guint16 new_server_port;};extern gint /* defined in send_core.c */ _create_packet_head_seq(guint8 *buf, guint8 **cursor, PurpleConnection *gc, guint16 cmd, gboolean is_auto_seq, guint16 *seq);extern gint /* defined in send_core.c */ _qq_send_packet(PurpleConnection *gc, guint8 *buf, gint len, guint16 cmd);/* It is fixed to 16 bytes 0x01 for QQ2003, * Any value works (or a random 16 bytes string) */static guint8 *_gen_login_key(void){ return (guint8 *) g_strnfill(QQ_KEY_LENGTH, 0x01);}/* process login reply which says OK */static gint _qq_process_login_ok(PurpleConnection *gc, guint8 *data, gint len){ gint bytes; guint8 *cursor; qq_data *qd; qq_login_reply_ok_packet lrop; qd = (qq_data *) gc->proto_data; cursor = data; bytes = 0; /* 000-000: reply code */ bytes += read_packet_b(data, &cursor, len, &lrop.result); /* 001-016: session key */ lrop.session_key = g_memdup(cursor, QQ_KEY_LENGTH); cursor += QQ_KEY_LENGTH; bytes += QQ_KEY_LENGTH; purple_debug(PURPLE_DEBUG_INFO, "QQ", "Get session_key done\n"); /* 017-020: login uid */ bytes += read_packet_dw(data, &cursor, len, &lrop.uid); /* 021-024: server detected user public IP */ bytes += read_packet_data(data, &cursor, len, (guint8 *) &lrop.client_ip, 4); /* 025-026: server detected user port */ bytes += read_packet_w(data, &cursor, len, &lrop.client_port); /* 027-030: server detected itself ip 127.0.0.1 ? */ bytes += read_packet_data(data, &cursor, len, (guint8 *) &lrop.server_ip, 4); /* 031-032: server listening port */ bytes += read_packet_w(data, &cursor, len, &lrop.server_port); /* 033-036: login time for current session */ bytes += read_packet_dw(data, &cursor, len, (guint32 *) &lrop.login_time); /* 037-062: 26 bytes, unknown */ bytes += read_packet_data(data, &cursor, len, (guint8 *) &lrop.unknown1, 26); /* 063-066: unknown server1 ip address */ bytes += read_packet_data(data, &cursor, len, (guint8 *) &lrop.unknown_server1_ip, 4); /* 067-068: unknown server1 port */ bytes += read_packet_w(data, &cursor, len, &lrop.unknown_server1_port); /* 069-072: unknown server2 ip address */ bytes += read_packet_data(data, &cursor, len, (guint8 *) &lrop.unknown_server2_ip, 4); /* 073-074: unknown server2 port */ bytes += read_packet_w(data, &cursor, len, &lrop.unknown_server2_port); /* 075-076: 2 bytes unknown */ bytes += read_packet_w(data, &cursor, len, &lrop.unknown2); /* 077-078: 2 bytes unknown */ bytes += read_packet_w(data, &cursor, len, &lrop.unknown3); /* 079-110: 32 bytes unknown */ bytes += read_packet_data(data, &cursor, len, (guint8 *) &lrop.unknown4, 32); /* 111-122: 12 bytes unknown */ bytes += read_packet_data(data, &cursor, len, (guint8 *) &lrop.unknown5, 12); /* 123-126: login IP of last session */ bytes += read_packet_data(data, &cursor, len, (guint8 *) &lrop.last_client_ip, 4); /* 127-130: login time of last session */ bytes += read_packet_dw(data, &cursor, len, (guint32 *) &lrop.last_login_time); /* 131-138: 8 bytes unknown */ bytes += read_packet_data(data, &cursor, len, (guint8 *) &lrop.unknown6, 8); if (bytes != QQ_LOGIN_REPLY_OK_PACKET_LEN) { /* fail parsing login info */ purple_debug(PURPLE_DEBUG_WARNING, "QQ", "Fail parsing login info, expect %d bytes, read %d bytes\n", QQ_LOGIN_REPLY_OK_PACKET_LEN, bytes); } /* but we still go on as login OK */ qd->session_key = lrop.session_key; qd->session_md5 = _gen_session_md5(qd->uid, qd->session_key); qd->my_ip = gen_ip_str(lrop.client_ip); qd->my_port = lrop.client_port; qd->login_time = lrop.login_time; qd->last_login_time = lrop.last_login_time; qd->last_login_ip = gen_ip_str(lrop.last_client_ip); purple_connection_set_state(gc, PURPLE_CONNECTED); qd->logged_in = TRUE; /* must be defined after sev_finish_login */ /* now initiate QQ Qun, do it first as it may take longer to finish */ qq_group_init(gc); /* Now goes on updating my icon/nickname, not showing info_window */ qd->modifying_face = FALSE; qq_send_packet_get_info(gc, qd->uid, FALSE); /* grab my level */ qq_send_packet_get_level(gc, qd->uid); qq_send_packet_change_status(gc); /* refresh buddies */ qq_send_packet_get_buddies_list(gc, QQ_FRIENDS_LIST_POSITION_START); /* refresh groups */ qq_send_packet_get_all_list_with_group(gc, QQ_FRIENDS_LIST_POSITION_START); return QQ_LOGIN_REPLY_OK;}/* process login reply packet which includes redirected new server address */static gint _qq_process_login_redirect(PurpleConnection *gc, guint8 *data, gint len){ gint bytes, ret;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -