pidgin.openq: 90c15125: 2008.09.29 - ccpaging <ccpaging(at)gmail...
csyfek at gmail.com
csyfek at gmail.com
Wed Oct 22 12:12:09 EDT 2008
-----------------------------------------------------------------
Revision: 90c151258460738e65e185d6578aa105947be39c
Ancestor: 3b08f7550aaf9d7fee867e516c48c1b499acf866
Author: csyfek at gmail.com
Date: 2008-10-22T14:41:13
Branch: im.pidgin.pidgin.openq
URL: http://d.pidgin.im/viewmtn/revision/info/90c151258460738e65e185d6578aa105947be39c
Modified files:
libpurple/protocols/qq/ChangeLog
libpurple/protocols/qq/buddy_opt.c
libpurple/protocols/qq/group_join.c
libpurple/protocols/qq/im.c libpurple/protocols/qq/qq.h
libpurple/protocols/qq/qq_base.c
libpurple/protocols/qq/qq_network.c
libpurple/protocols/qq/qq_process.c
ChangeLog:
2008.09.29 - ccpaging <ccpaging(at)gmail.com>
* 'Check Password' function for protocol 2007/2008
-------------- next part --------------
============================================================
--- libpurple/protocols/qq/ChangeLog 8accecbe4de9e216da003053988ae37e8ef3ee41
+++ libpurple/protocols/qq/ChangeLog ab8413952b32c214208ee08689cfeb9fb1842590
@@ -1,3 +1,6 @@
+2008.09.29 - ccpaging <ccpaging(at)gmail.com>
+ * 'Check Password' function for protocol 2007/2008
+
2008.09.28 - ccpaging <ccpaging(at)gmail.com>
* The source is only for debug, not for user:
1. Implement new QQ protocol 2007/2008, include login and change status
============================================================
--- libpurple/protocols/qq/buddy_opt.c 9ac9005db536eb3c2d5c5e624f6980e8059c7947
+++ libpurple/protocols/qq/buddy_opt.c 1ad59837690955ed441eefa00f3cb57ba6b562df
@@ -512,7 +512,7 @@ PurpleBuddy *qq_create_buddy(PurpleConne
g_return_val_if_fail(gc->account != NULL && uid != 0, NULL);
qd = (qq_data *) gc->proto_data;
- if (is_known || uid == qd->uid) {
+ if (is_known) {
group_name = g_strdup_printf(PURPLE_GROUP_QQ_FORMAT,
purple_account_get_username(gc->account));
} else {
@@ -529,7 +529,7 @@ PurpleBuddy *qq_create_buddy(PurpleConne
purple_blist_remove_buddy(buddy);
buddy = purple_buddy_new(gc->account, buddy_name, NULL);
- if ( !is_known && uid != qd->uid) {
+ if ( !is_known) {
if (purple_privacy_check(gc->account, buddy_name)) {
purple_privacy_deny(gc->account, buddy_name, TRUE, FALSE);
} else {
============================================================
--- libpurple/protocols/qq/group_join.c 63e1f568d5d68fde30ee60df8409c9e1dc7142be
+++ libpurple/protocols/qq/group_join.c c15599835c9b2709a1a28685f4ab27dda474f440
@@ -39,6 +39,7 @@
#include "group_opt.h"
#include "group_conv.h"
#include "group_search.h"
+#include "group_im.h"
#include "qq_define.h"
#include "packet_parse.h"
#include "qq_network.h"
@@ -226,6 +227,9 @@ void qq_process_group_cmd_join_group_aut
gint bytes;
guint32 id;
qq_data *qd;
+ qq_group *group;
+ gchar *msg;
+ time_t now = time(NULL);
g_return_if_fail(data != NULL && len > 0);
qd = (qq_data *) gc->proto_data;
@@ -239,7 +243,14 @@ void qq_process_group_cmd_join_group_aut
bytes += qq_get32(&id, data + bytes);
g_return_if_fail(id > 0);
- qq_got_attention(gc, _("Successed join to Qun"));
+ group = qq_room_search_id(gc, id);
+ if (group != NULL) {
+ msg = g_strdup_printf(_("Successed join to Qun %s (%d)"), group->title_utf8, group->ext_id);
+ qq_room_got_chat_in(gc, group, 0, msg, now);
+ g_free(msg);
+ } else {
+ qq_got_attention(gc, _("Successed join to Qun"));
+ }
}
/* process group cmd reply "join group" */
============================================================
--- libpurple/protocols/qq/im.c d588d868095010ea523fc9eec5e4a6ae29ec562e
+++ libpurple/protocols/qq/im.c b4ccbe8ec5e04eaaf3a822baa7b4f5243ef4eee0
@@ -298,24 +298,21 @@ void qq_got_attention(PurpleConnection *
{
qq_data *qd;
gchar *from;
- PurpleBuddy *b;
- qq_buddy *qq_b;
+ PurpleBuddy *buddy;
time_t now = time(NULL);
qd = (qq_data *) gc->proto_data;
- from = uid_to_purple_name(qd->uid);
g_return_if_fail(qd->uid > 0);
- b = purple_find_buddy(gc->account, from);
- if (b == NULL) {
- qq_create_buddy(gc, qd->uid, FALSE, TRUE);
- b = purple_find_buddy(gc->account, from);
+ from = uid_to_purple_name(qd->uid);
+ buddy = purple_find_buddy(gc->account, from);
+ if (buddy == NULL) {
+ qq_create_buddy(gc, qd->uid, TRUE, TRUE);
}
- qq_b = (b == NULL) ? NULL : (qq_buddy *) b->proto_data;
- g_return_if_fail(qq_b != NULL);
serv_got_im(gc, from, msg, PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NOTIFY, now);
+ g_free(from);
}
/* process received normal text IM */
============================================================
--- libpurple/protocols/qq/qq.h 3c49a8915a49a2154922055de6d87055f1ad02e8
+++ libpurple/protocols/qq/qq.h d26c31d328344a1c5294faaf3db28274313b7de7
@@ -60,8 +60,8 @@ struct _qq_login_data {
guint8 *token_ex; /* get from server */
guint16 token_ex_len;
- guint8 pwd_2nd_md5[QQ_KEY_LENGTH]; /* password in md5 (or md5' md5) */
- guint8 pwd_4th_md5[QQ_KEY_LENGTH];
+ guint8 pwd_md5[QQ_KEY_LENGTH]; /* password in md5 (or md5' md5) */
+ guint8 pwd_twice_md5[QQ_KEY_LENGTH];
guint8 *login_token;
guint16 login_token_len;
@@ -73,7 +73,7 @@ struct _qq_redirect_data {
guint8 b1;
guint32 w1;
guint32 w2;
- guint32 ip;
+ struct in_addr ip;
};
struct _qq_add_request {
============================================================
--- libpurple/protocols/qq/qq_base.c e15aef0275ac56af6b9891d8ee558e0d1ed8b5fe
+++ libpurple/protocols/qq/qq_base.c cb86dc8d3fe13810cd75d0c81284a800fccc4d56
@@ -34,16 +34,13 @@
#include "qq_crypt.h"
#include "group.h"
#include "qq_define.h"
+#include "qq_network.h"
#include "qq_base.h"
#include "packet_parse.h"
#include "qq.h"
#include "qq_network.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
-
/* generate a md5 key using uid and session_key */
static void get_session_md5(guint8 *session_md5, guint32 uid, guint8 *session_key)
{
@@ -71,7 +68,13 @@ static gint8 process_login_ok(PurpleConn
qd = (qq_data *) gc->proto_data;
qq_show_packet("Login reply", data, len);
- /* FIXME, check QQ_LOGIN_REPLY_OK_PACKET_LEN here */
+ if (len < 139) {
+ purple_connection_error_reason(gc,
+ PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
+ _("Can not decrypt get server reply"));
+ return QQ_LOGIN_REPLY_ERR;
+ }
+
bytes = 0;
bytes += qq_get8(&ret, data + bytes);
bytes += qq_getdata(qd->session_key, sizeof(qd->session_key), data + bytes);
@@ -134,11 +137,9 @@ static gint8 process_login_ok(PurpleConn
tm_local->tm_hour, tm_local->tm_min, tm_local->tm_sec);
/* unknow 9 bytes, 0x(00 0a 00 0a 01 00 00 0e 10) */
- if (bytes != QQ_LOGIN_REPLY_OK_PACKET_LEN) { /* fail parsing login info */
- 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 */
+ if (len > 139) {
+ purple_debug_warning("QQ", "Login reply more than expected %d bytes, read %d bytes\n", 139, bytes);
+ }
return QQ_LOGIN_REPLY_OK;
}
@@ -155,6 +156,13 @@ static gint8 process_login_redirect(Purp
} packet;
+ if (len < 11) {
+ purple_connection_error_reason(gc,
+ PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
+ _("Can not decrypt get server reply"));
+ return QQ_LOGIN_REPLY_ERR;
+ }
+
qd = (qq_data *) gc->proto_data;
bytes = 0;
/* 000-000: reply code */
@@ -166,11 +174,8 @@ static gint8 process_login_redirect(Purp
/* 009-010: redirected new server port */
bytes += qq_get16(&packet.new_server_port, data + bytes);
- if (bytes != QQ_LOGIN_REPLY_REDIRECT_PACKET_LEN) {
- purple_debug_error("QQ",
- "Fail parsing login redirect packet, expect %d bytes, read %d bytes\n",
- QQ_LOGIN_REPLY_REDIRECT_PACKET_LEN, bytes);
- return QQ_LOGIN_REPLY_ERR;
+ if (len > 11) {
+ purple_debug_error("QQ", "Login redirect more than expected %d bytes, read %d bytes\n", 11, bytes);
}
/* redirect to new server, do not disconnect or connect here
@@ -239,15 +244,15 @@ void qq_request_login(PurpleConnection *
g_return_if_fail(qd->ld.token != NULL && qd->ld.token_len > 0);
- raw_data = g_newa(guint8, QQ_LOGIN_DATA_LENGTH);
- memset(raw_data, 0, QQ_LOGIN_DATA_LENGTH);
+ raw_data = g_newa(guint8, MAX_PACKET_SIZE - 16);
+ memset(raw_data, 0, MAX_PACKET_SIZE - 16);
- encrypted = g_newa(guint8, QQ_LOGIN_DATA_LENGTH + 16); /* 16 bytes more */
+ encrypted = g_newa(guint8, MAX_PACKET_SIZE); /* 16 bytes more */
bytes = 0;
/* now generate the encrypted data
* 000-015 use password_twice_md5 as key to encrypt empty string */
- encrypted_len = qq_encrypt(encrypted, (guint8 *) "", 0, qd->ld.pwd_2nd_md5);
+ encrypted_len = qq_encrypt(encrypted, (guint8 *) "", 0, qd->ld.pwd_twice_md5);
g_return_if_fail(encrypted_len == 16);
bytes += qq_putdata(raw_data + bytes, encrypted, encrypted_len);
@@ -270,8 +275,10 @@ void qq_request_login(PurpleConnection *
/* 100 bytes unknown */
bytes += qq_putdata(raw_data + bytes, login_100_bytes, 100);
/* all zero left */
+ memset(raw_data + bytes, 0, 416 - bytes);
+ bytes = 416;
- encrypted_len = qq_encrypt(encrypted, raw_data, QQ_LOGIN_DATA_LENGTH, qd->ld.random_key);
+ encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.random_key);
buf = g_newa(guint8, MAX_PACKET_SIZE);
memset(buf, 0, MAX_PACKET_SIZE);
@@ -350,7 +357,7 @@ void qq_request_logout(PurpleConnection
qd = (qq_data *) gc->proto_data;
for (i = 0; i < 4; i++)
- qq_send_cmd(gc, QQ_CMD_LOGOUT, qd->ld.pwd_2nd_md5, QQ_KEY_LENGTH);
+ qq_send_cmd(gc, QQ_CMD_LOGOUT, qd->ld.pwd_twice_md5, QQ_KEY_LENGTH);
qd->is_login = FALSE; /* update login status AFTER sending logout packets */
}
@@ -502,15 +509,19 @@ void qq_request_get_server(PurpleConnect
g_return_if_fail(gc != NULL && gc->proto_data != NULL);
qd = (qq_data *) gc->proto_data;
- raw_data = g_newa(guint8, QQ_LOGIN_DATA_LENGTH);
- memset(raw_data, 0, QQ_LOGIN_DATA_LENGTH);
+ raw_data = g_newa(guint8, sizeof(qd->redirect_data));
+ memset(raw_data, 0, sizeof(qd->redirect_data));
- encrypted = g_newa(guint8, QQ_LOGIN_DATA_LENGTH + 16); /* 16 bytes more */
+ encrypted = g_newa(guint8, sizeof(qd->redirect_data) + 16); /* 16 bytes more */
bytes = 0;
- bytes += qq_putdata(raw_data + bytes, (guint8 *)&qd->redirect_data, sizeof(qd->redirect_data));
+ bytes += qq_put16(raw_data + bytes, qd->redirect_data.ret);
+ bytes += qq_put8(raw_data + bytes, qd->redirect_data.b1);
+ bytes += qq_put32(raw_data + bytes, qd->redirect_data.w1);
+ bytes += qq_put32(raw_data + bytes, qd->redirect_data.w2);
+ bytes += qq_putIP(raw_data + bytes, &(qd->redirect_data.ip));
- encrypted_len = qq_encrypt(encrypted, raw_data, QQ_LOGIN_DATA_LENGTH, qd->ld.random_key);
+ encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.random_key);
buf = g_newa(guint8, MAX_PACKET_SIZE);
memset(buf, 0, MAX_PACKET_SIZE);
@@ -519,34 +530,44 @@ void qq_request_get_server(PurpleConnect
bytes += qq_putdata(buf + bytes, encrypted, encrypted_len);
qd->send_seq++;
- qq_send_cmd_encrypted(gc, QQ_CMD_LOGIN, qd->send_seq, buf, bytes, TRUE);
+ qq_send_cmd_encrypted(gc, QQ_CMD_GET_SERVER, qd->send_seq, buf, bytes, TRUE);
}
guint16 qq_process_get_server(PurpleConnection *gc, guint8 *data, gint data_len)
{
qq_data *qd;
- qq_redirect_data *redirect;
+ gint bytes;
g_return_val_if_fail (gc != NULL && gc->proto_data != NULL, QQ_LOGIN_REPLY_ERR);
qd = (qq_data *) gc->proto_data;
g_return_val_if_fail (data != NULL, QQ_LOGIN_REPLY_ERR);
- if (data_len < sizeof(qq_redirect_data)) {
+
+ /* qq_show_packet("Get Server", data, data_len); */
+ bytes = 0;
+ bytes += qq_get16(&qd->redirect_data.ret, data + bytes);
+ if (qd->redirect_data.ret == 0) {
+ memset(&qd->redirect_data, 0, sizeof(qd->redirect_data));
+ qd->redirect_ip.s_addr = 0;
+ return QQ_LOGIN_REPLY_OK;
+ }
+
+ if (data_len < 15) {
purple_connection_error_reason(gc,
- PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+ PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
_("Can not decrypt get server reply"));
return QQ_LOGIN_REPLY_ERR;
}
- redirect = (qq_redirect_data *)data;
- if (redirect->ret == 0) {
- memset(&qd->redirect_data, 0, sizeof(qd->redirect_data));
- qd->redirect_ip.s_addr = 0;
- return QQ_LOGIN_REPLY_OK;
- }
+ bytes += qq_get8(&qd->redirect_data.b1, data + bytes);
+ bytes += qq_get32(&qd->redirect_data.w1, data + bytes);
+ bytes += qq_get32(&qd->redirect_data.w2, data + bytes);
+ bytes += qq_getIP(&qd->redirect_data.ip, data + bytes);
+ purple_debug_info("QQ", "Get server %d-%d-%d%d, %s\n",
+ qd->redirect_data.ret, qd->redirect_data.b1, qd->redirect_data.w1, qd->redirect_data.w2,
+ inet_ntoa(qd->redirect_data.ip));
- g_memmove(&qd->redirect_data, redirect, sizeof(qd->redirect_data));
- g_memmove(&qd->redirect_ip, &redirect->ip, sizeof(qd->redirect_ip));
+ g_memmove(&qd->redirect_ip, &qd->redirect_data.ip, sizeof(qd->redirect_ip));
return QQ_LOGIN_REPLY_REDIRECT;
}
@@ -577,7 +598,7 @@ void qq_request_token_ex(PurpleConnectio
bytes += qq_put8(raw_data + bytes, 0); /* fragment index */
bytes += qq_put16(raw_data + bytes, 0); /* captcha token */
- encrypted_len = qq_encrypt(encrypted, raw_data, QQ_LOGIN_DATA_LENGTH, qd->ld.random_key);
+ encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.random_key);
buf = g_newa(guint8, MAX_PACKET_SIZE);
memset(buf, 0, MAX_PACKET_SIZE);
@@ -617,7 +638,7 @@ void qq_request_token_ex_next(PurpleConn
bytes += qq_put16(raw_data + bytes, qd->captcha.token_len); /* captcha token */
bytes += qq_putdata(raw_data + bytes, qd->captcha.token, qd->captcha.token_len);
- encrypted_len = qq_encrypt(encrypted, raw_data, QQ_LOGIN_DATA_LENGTH, qd->ld.random_key);
+ encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.random_key);
buf = g_newa(guint8, MAX_PACKET_SIZE);
memset(buf, 0, MAX_PACKET_SIZE);
@@ -662,7 +683,7 @@ static void request_token_ex_code(Purple
bytes += qq_put16(raw_data + bytes, qd->captcha.token_len); /* captcha token */
bytes += qq_putdata(raw_data + bytes, qd->captcha.token, qd->captcha.token_len);
- encrypted_len = qq_encrypt(encrypted, raw_data, QQ_LOGIN_DATA_LENGTH, qd->ld.random_key);
+ encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.random_key);
buf = g_newa(guint8, MAX_PACKET_SIZE);
memset(buf, 0, MAX_PACKET_SIZE);
@@ -783,8 +804,8 @@ guint8 qq_process_token_ex(PurpleConnect
ret = data[0];
bytes = 0;
- bytes += qq_get8(&sub_cmd, data + bytes);
- bytes += 2;
+ bytes += qq_get8(&sub_cmd, data + bytes); /* 03: ok; 04: need verifying */
+ bytes += 2; /* 0x(00 05) */
bytes += qq_get8(&reply, data + bytes);
bytes += qq_get16(&(qd->ld.token_ex_len), data + bytes);
@@ -794,7 +815,7 @@ guint8 qq_process_token_ex(PurpleConnect
if(reply != 1)
{
- purple_debug_info("QQ", "Captcha verified\n");
+ purple_debug_info("QQ", "Captcha verified, result %d\n", reply);
return QQ_LOGIN_REPLY_OK;
}
@@ -863,8 +884,9 @@ void qq_request_check_pwd_2007(PurpleCon
gint bytes;
guint8 *encrypted;
gint encrypted_len;
+ gint count;
static guint8 header[] = {
- 0x00, 0x5F, 0x00, 0x00, 0x08, 0x04, 0x01, 0x0E
+ 0x00, 0x5F, 0x00, 0x00, 0x08, 0x04, 0x01, 0xE0
};
g_return_if_fail(gc != NULL && gc->proto_data != NULL);
@@ -879,39 +901,35 @@ void qq_request_check_pwd_2007(PurpleCon
/* Encrypted password and put in encrypted */
bytes = 0;
- bytes += qq_putdata(raw_data + bytes, qd->ld.pwd_2nd_md5, sizeof(qd->ld.pwd_2nd_md5));
- bytes += qq_put16(raw_data + bytes, 0);
- bytes += qq_put16(raw_data + bytes, 0);
+ bytes += qq_putdata(raw_data + bytes, qd->ld.pwd_md5, sizeof(qd->ld.pwd_md5));
+ bytes += qq_put16(raw_data + bytes, rand() & 0);
+ bytes += qq_put16(raw_data + bytes, rand() & 0xffff);
- encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.pwd_4th_md5);
-
+ encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.pwd_twice_md5);
/* create packet */
bytes = 0;
bytes += qq_putdata(raw_data + bytes, header, sizeof(header));
/* token get from qq_process_token_ex */
- bytes += qq_put16(raw_data + bytes, qd->ld.token_ex_len);
+ bytes += qq_put8(raw_data + bytes, qd->ld.token_ex_len);
bytes += qq_putdata(raw_data + bytes, qd->ld.token_ex, qd->ld.token_ex_len);
/* password encrypted */
bytes += qq_put16(raw_data + bytes, encrypted_len);
bytes += qq_putdata(raw_data + bytes, encrypted, encrypted_len);
- /* some random data */
- bytes += qq_put16(raw_data + bytes, 0x0014);
- bytes += qq_put32(raw_data + bytes, rand() & 0xffff);
- bytes += qq_put32(raw_data + bytes, rand() & 0xffff);
- bytes += qq_put32(raw_data + bytes, rand() & 0xffff);
- bytes += qq_put32(raw_data + bytes, rand() & 0xffff);
- bytes += qq_put32(raw_data + bytes, rand() & 0xffff);
+ /* random data, 20 bytes */
+ bytes += qq_put16(raw_data + bytes, 0x0014); /* length of next segment*/
+ count = 0x14;
+ while (count--) bytes += qq_put8(raw_data + bytes, rand() & 0xff);
/* put length into first 2 bytes */
qq_put16(raw_data, bytes - 2);
/* tail */
+ bytes += qq_put8(raw_data + bytes, 0); /* length of next segment */
+ bytes += qq_put8(raw_data + bytes, 0x03); /* length of next segment */
bytes += qq_put8(raw_data + bytes, 0);
- bytes += qq_put8(raw_data + bytes, 0x03);
- bytes += qq_put8(raw_data + bytes, 0);
- bytes += qq_put8(raw_data + bytes, qd->ld.pwd_2nd_md5[1]);
- bytes += qq_put8(raw_data + bytes, qd->ld.pwd_2nd_md5[2]);
-
+ bytes += qq_put8(raw_data + bytes, qd->ld.pwd_md5[1]);
+ bytes += qq_put8(raw_data + bytes, qd->ld.pwd_md5[2]);
+ qq_show_packet("QQ", raw_data, bytes);
/* Encrypted by random key*/
- encrypted_len = qq_encrypt(encrypted, raw_data, QQ_LOGIN_DATA_LENGTH, qd->ld.random_key);
+ encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.random_key);
buf = g_newa(guint8, MAX_PACKET_SIZE);
memset(buf, 0, MAX_PACKET_SIZE);
@@ -920,7 +938,7 @@ void qq_request_check_pwd_2007(PurpleCon
bytes += qq_putdata(buf + bytes, encrypted, encrypted_len);
qd->send_seq++;
- qq_send_cmd_encrypted(gc, QQ_CMD_LOGIN, qd->send_seq, buf, bytes, TRUE);
+ qq_send_cmd_encrypted(gc, QQ_CMD_CHECK_PWD, qd->send_seq, buf, bytes, TRUE);
}
guint8 qq_process_check_pwd_2007( PurpleConnection *gc, guint8 *data, gint data_len)
@@ -960,7 +978,7 @@ guint8 qq_process_check_pwd_2007( Purple
switch (ret)
{
- case 0x34: /* invalid password */
+ case 0x34: /* invalid password, 2nd byte is 0xc6 */
if (!purple_account_get_remember_password(gc->account)) {
purple_account_set_password(gc->account, NULL);
}
@@ -987,13 +1005,13 @@ guint8 qq_process_check_pwd_2007( Purple
}
qq_hex_dump(PURPLE_DEBUG_WARNING, "QQ", data, data_len,
">>> [default] decrypt and dump");
- bytes = 1;
+ bytes = 11;
bytes += qq_get16(&msg_len, data + bytes);
msg = g_strndup((gchar *)data + bytes, msg_len);
msg_utf8 = qq_to_utf8(msg, QQ_CHARSET_DEFAULT);
- purple_debug_error("QQ", "%s: %s\n", error, msg_utf8);
+ purple_debug_error("QQ", "%s:\n%s\n", error, msg_utf8);
purple_connection_error_reason(gc, reason, msg_utf8);
g_free(error);
@@ -1100,39 +1118,37 @@ void qq_request_check_pwd_2008(PurpleCon
/* Encrypted password and put in encrypted */
bytes = 0;
- bytes += qq_putdata(raw_data + bytes, qd->ld.pwd_2nd_md5, sizeof(qd->ld.pwd_2nd_md5));
+ bytes += qq_putdata(raw_data + bytes, qd->ld.pwd_md5, sizeof(qd->ld.pwd_md5));
bytes += qq_put16(raw_data + bytes, 0);
- bytes += qq_put16(raw_data + bytes, (guint16) (rand() & 0xffff));
+ bytes += qq_put16(raw_data + bytes, rand() & 0xffff);
- encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.pwd_4th_md5);
+ encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.pwd_twice_md5);
/* create packet */
bytes = 0;
bytes += qq_putdata(raw_data + bytes, header, sizeof(header));
/* token get from qq_request_token_ex */
- bytes += qq_put16(raw_data + bytes, qd->ld.token_ex_len);
+ bytes += qq_put8(raw_data + bytes, qd->ld.token_ex_len);
bytes += qq_putdata(raw_data + bytes, qd->ld.token_ex, qd->ld.token_ex_len);
- bytes += qq_put8(raw_data + bytes, 0);
/* password encrypted */
bytes += qq_put16(raw_data + bytes, encrypted_len);
bytes += qq_putdata(raw_data + bytes, encrypted, encrypted_len);
- bytes += qq_put8(raw_data + bytes, 0);
/* len of unknown + len of CRC32 */
- bytes += qq_put8(raw_data + bytes, sizeof(unknown) + 4);
+ bytes += qq_put16(raw_data + bytes, sizeof(unknown) + 4);
bytes += qq_putdata(raw_data + bytes, unknown, sizeof(unknown));
bytes += qq_put32(
raw_data + bytes, crc32(0xFFFFFFFF, unknown, sizeof(unknown)));
/* put length into first 2 bytes */
qq_put16(raw_data, bytes - 2);
/* tail */
+ bytes += qq_put16(raw_data + bytes, 0x0003);
bytes += qq_put8(raw_data + bytes, 0);
- bytes += qq_put8(raw_data + bytes, 0x03);
- bytes += qq_put8(raw_data + bytes, 0);
- bytes += qq_put8(raw_data + bytes, qd->ld.pwd_2nd_md5[1]);
- bytes += qq_put8(raw_data + bytes, qd->ld.pwd_2nd_md5[2]);
+ bytes += qq_put8(raw_data + bytes, qd->ld.pwd_md5[1]);
+ bytes += qq_put8(raw_data + bytes, qd->ld.pwd_md5[2]);
+ qq_show_packet("Check password", raw_data, bytes);
/* Encrypted by random key*/
- encrypted_len = qq_encrypt(encrypted, raw_data, QQ_LOGIN_DATA_LENGTH, qd->ld.random_key);
+ encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.random_key);
buf = g_newa(guint8, MAX_PACKET_SIZE);
memset(buf, 0, MAX_PACKET_SIZE);
@@ -1141,7 +1157,7 @@ void qq_request_check_pwd_2008(PurpleCon
bytes += qq_putdata(buf + bytes, encrypted, encrypted_len);
qd->send_seq++;
- qq_send_cmd_encrypted(gc, QQ_CMD_LOGIN, qd->send_seq, buf, bytes, TRUE);
+ qq_send_cmd_encrypted(gc, QQ_CMD_CHECK_PWD, qd->send_seq, buf, bytes, TRUE);
}
void qq_request_login_2007(PurpleConnection *gc)
@@ -1184,11 +1200,11 @@ void qq_request_login_2007(PurpleConnect
/* Encrypted password and put in encrypted */
bytes = 0;
- bytes += qq_putdata(raw_data + bytes, qd->ld.pwd_2nd_md5, sizeof(qd->ld.pwd_2nd_md5));
+ bytes += qq_putdata(raw_data + bytes, qd->ld.pwd_md5, sizeof(qd->ld.pwd_md5));
bytes += qq_put16(raw_data + bytes, 0);
bytes += qq_put16(raw_data + bytes, 0xffff);
- encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.pwd_4th_md5);
+ encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.pwd_twice_md5);
/* create packet */
bytes = 0;
@@ -1196,8 +1212,8 @@ void qq_request_login_2007(PurpleConnect
/* password encrypted */
bytes += qq_put16(raw_data + bytes, encrypted_len);
bytes += qq_putdata(raw_data + bytes, encrypted, encrypted_len);
- /* put data which NULL string encrypted by key pwd_4th_md5 */
- encrypted_len = qq_encrypt(encrypted, (guint8 *) "", 0, qd->ld.pwd_4th_md5);
+ /* put data which NULL string encrypted by key pwd_twice_md5 */
+ encrypted_len = qq_encrypt(encrypted, (guint8 *) "", 0, qd->ld.pwd_twice_md5);
g_return_if_fail(encrypted_len == 16);
bytes += qq_putdata(raw_data + bytes, encrypted, encrypted_len);
/* unknow fill */
@@ -1337,11 +1353,11 @@ void qq_request_login_2008(PurpleConnect
/* Encrypted password and put in encrypted */
bytes = 0;
- bytes += qq_putdata(raw_data + bytes, qd->ld.pwd_2nd_md5, sizeof(qd->ld.pwd_2nd_md5));
+ bytes += qq_putdata(raw_data + bytes, qd->ld.pwd_md5, sizeof(qd->ld.pwd_md5));
bytes += qq_put16(raw_data + bytes, 0);
bytes += qq_put16(raw_data + bytes, 0xffff);
- encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.pwd_4th_md5);
+ encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.pwd_twice_md5);
/* create packet */
bytes = 0;
@@ -1350,8 +1366,8 @@ void qq_request_login_2008(PurpleConnect
/* password encrypted */
bytes += qq_put16(raw_data + bytes, encrypted_len);
bytes += qq_putdata(raw_data + bytes, encrypted, encrypted_len);
- /* put data which NULL string encrypted by key pwd_4th_md5 */
- encrypted_len = qq_encrypt(encrypted, (guint8 *) "", 0, qd->ld.pwd_4th_md5);
+ /* put data which NULL string encrypted by key pwd_twice_md5 */
+ encrypted_len = qq_encrypt(encrypted, (guint8 *) "", 0, qd->ld.pwd_twice_md5);
g_return_if_fail(encrypted_len == 16);
bytes += qq_putdata(raw_data + bytes, encrypted, encrypted_len);
/* unknow 19 bytes zero filled*/
============================================================
--- libpurple/protocols/qq/qq_network.c 8c495458bcb243c0f708a8cc7a357f7006fd2acb
+++ libpurple/protocols/qq/qq_network.c e980710f438f68c435ac95ed09bcdf732e091bb3
@@ -309,6 +309,8 @@ static gboolean packet_process(PurpleCon
switch (cmd) {
case QQ_CMD_TOKEN:
case QQ_CMD_GET_SERVER:
+ case QQ_CMD_TOKEN_EX:
+ case QQ_CMD_CHECK_PWD:
case QQ_CMD_LOGIN:
ret = qq_proc_login_cmds(gc, cmd, seq, buf + bytes, bytes_not_read, update_class, ship32);
if (ret != QQ_LOGIN_REPLY_OK) {
@@ -715,13 +717,11 @@ static void set_all_keys(PurpleConnectio
passwd = purple_account_get_password(purple_connection_get_account(gc));
/* use twice-md5 of user password as session key since QQ 2003iii */
- dest = qd->ld.pwd_2nd_md5;
+ dest = qd->ld.pwd_md5;
qq_get_md5(dest, dest_len, (guint8 *)passwd, strlen(passwd));
- qq_get_md5(dest, dest_len, dest, dest_len);
- dest = qd->ld.pwd_4th_md5;
- qq_get_md5(dest, dest_len, qd->ld.pwd_2nd_md5, dest_len);
- qq_get_md5(dest, dest_len, dest, dest_len);
+ dest = qd->ld.pwd_twice_md5;
+ qq_get_md5(dest, dest_len, qd->ld.pwd_md5, dest_len);
}
/* the callback function after socket is built
@@ -1021,8 +1021,8 @@ void qq_disconnect(PurpleConnection *gc)
qq_trans_remove_all(gc);
memset(qd->ld.random_key, 0, sizeof(qd->ld.random_key));
- memset(qd->ld.pwd_2nd_md5, 0, sizeof(qd->ld.pwd_2nd_md5));
- memset(qd->ld.pwd_4th_md5, 0, sizeof(qd->ld.pwd_4th_md5));
+ memset(qd->ld.pwd_md5, 0, sizeof(qd->ld.pwd_md5));
+ memset(qd->ld.pwd_twice_md5, 0, sizeof(qd->ld.pwd_twice_md5));
memset(qd->ld.login_key, 0, sizeof(qd->ld.login_key));
memset(qd->session_key, 0, sizeof(qd->session_key));
memset(qd->session_md5, 0, sizeof(qd->session_md5));
============================================================
--- libpurple/protocols/qq/qq_process.c 82531c57433cf8601a7eaf021afbe4d130178663
+++ libpurple/protocols/qq/qq_process.c 7c955b87acfcc3bf8479b01528e843d7b73d8cf4
@@ -607,18 +607,18 @@ guint8 qq_proc_login_cmds(PurpleConnecti
if (data_len >= 0) {
purple_debug_warning("QQ", "Decrypt login packet by random_key, %d bytes\n", data_len);
} else {
- data_len = qq_decrypt(data, rcved, rcved_len, qd->ld.pwd_4th_md5);
+ data_len = qq_decrypt(data, rcved, rcved_len, qd->ld.pwd_twice_md5);
if (data_len >= 0) {
- purple_debug_warning("QQ", "Decrypt login packet by pwd_4th_md5, %d bytes\n", data_len);
+ purple_debug_warning("QQ", "Decrypt login packet by pwd_twice_md5, %d bytes\n", data_len);
}
}
break;
case QQ_CMD_LOGIN:
default:
if (qd->client_version > 2005) {
- data_len = qq_decrypt(data, rcved, rcved_len, qd->ld.pwd_4th_md5);
+ data_len = qq_decrypt(data, rcved, rcved_len, qd->ld.pwd_twice_md5);
if (data_len >= 0) {
- purple_debug_warning("QQ", "Decrypt login packet by pwd_4th_md5\n");
+ purple_debug_warning("QQ", "Decrypt login packet by pwd_twice_md5\n");
} else {
data_len = qq_decrypt(data, rcved, rcved_len, qd->ld.login_key);
if (data_len >= 0) {
@@ -631,9 +631,9 @@ guint8 qq_proc_login_cmds(PurpleConnecti
if (data_len >= 0) {
purple_debug_warning("QQ", "Decrypt login packet by random_key\n");
} else {
- data_len = qq_decrypt(data, rcved, rcved_len, qd->ld.pwd_2nd_md5);
+ data_len = qq_decrypt(data, rcved, rcved_len, qd->ld.pwd_twice_md5);
if (data_len >= 0) {
- purple_debug_warning("QQ", "Decrypt login packet by pwd_2nd_md5\n");
+ purple_debug_warning("QQ", "Decrypt login packet by pwd_twice_md5\n");
}
}
}
More information about the Commits
mailing list