pidgin.openq: 2fa69c96: 2008.09.30 - ccpaging <ccpaging(at)gmail...

csyfek at gmail.com csyfek at gmail.com
Wed Oct 22 12:11:48 EDT 2008


-----------------------------------------------------------------
Revision: 2fa69c961d2404c06ff3f8307112ef5095995530
Ancestor: 90c151258460738e65e185d6578aa105947be39c
Author: csyfek at gmail.com
Date: 2008-10-22T14:42:23
Branch: im.pidgin.pidgin.openq
URL: http://d.pidgin.im/viewmtn/revision/info/2fa69c961d2404c06ff3f8307112ef5095995530

Modified files:
        libpurple/protocols/qq/ChangeLog libpurple/protocols/qq/qq.c
        libpurple/protocols/qq/qq.h libpurple/protocols/qq/qq_base.c
        libpurple/protocols/qq/qq_base.h
        libpurple/protocols/qq/qq_process.c

ChangeLog: 

2008.09.30 - ccpaging <ccpaging(at)gmail.com>
	* Successfully login using 2007/2008 protocols

-------------- next part --------------
============================================================
--- libpurple/protocols/qq/ChangeLog	ab8413952b32c214208ee08689cfeb9fb1842590
+++ libpurple/protocols/qq/ChangeLog	b29ecb8e886615ccbb95b04f60c3075e96e8eb3b
@@ -1,3 +1,6 @@
+2008.09.30 - ccpaging <ccpaging(at)gmail.com>
+	* Successfully login using 2007/2008 protocols
+
 2008.09.29 - ccpaging <ccpaging(at)gmail.com>
 	* 'Check Password' function for protocol 2007/2008
 
============================================================
--- libpurple/protocols/qq/qq.c	3ef664c2e4c8d8df0d6170a45b2b2ca9c726d650
+++ libpurple/protocols/qq/qq.c	6026eaa9bcbb6d84fb4c4c0bb68c08cbfe214bea
@@ -219,6 +219,7 @@ static void qq_close(PurpleConnection *g
 
 	qq_disconnect(gc);
 
+	if (qd->redirect) g_free(qd->redirect);
 	if (qd->ld.token) g_free(qd->ld.token);
 	if (qd->ld.token_ex) g_free(qd->ld.token_ex);
 	if (qd->captcha.token) g_free(qd->captcha.token);
============================================================
--- libpurple/protocols/qq/qq.h	d26c31d328344a1c5294faaf3db28274313b7de7
+++ libpurple/protocols/qq/qq.h	60c4be21cd74de760555ba4a330770554c71e4ca
@@ -41,7 +41,6 @@ typedef struct _qq_add_request qq_add_re
 typedef struct _qq_interval qq_interval;
 typedef struct _qq_net_stat qq_net_stat;
 typedef struct _qq_add_request qq_add_request;
-typedef struct _qq_redirect_data qq_redirect_data;
 typedef struct _qq_login_data qq_login_data;
 typedef struct _qq_captcha_data qq_captcha_data;
 
@@ -68,14 +67,6 @@ struct _qq_login_data {
 	guint8 login_key[QQ_KEY_LENGTH];
 };
 
-struct _qq_redirect_data {
-	guint16 ret;
-	guint8 b1;
-	guint32 w1;
-	guint32 w2;
-	struct in_addr ip;
-};
-
 struct _qq_add_request {
 	guint32 uid;
 	PurpleConnection *gc;
@@ -150,7 +141,8 @@ struct _qq_data {
 
 	struct in_addr redirect_ip;
 	guint16 redirect_port;
-	qq_redirect_data redirect_data;
+	guint8 *redirect;
+	guint8 redirect_len;
 
 	guint check_watcher;
 	guint connect_watcher;
============================================================
--- libpurple/protocols/qq/qq_base.c	cb86dc8d3fe13810cd75d0c81284a800fccc4d56
+++ libpurple/protocols/qq/qq_base.c	28e364ec00620f7d5751cf7dd568b4f13c1de426
@@ -509,17 +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, sizeof(qd->redirect_data));
-	memset(raw_data, 0, sizeof(qd->redirect_data));
+	raw_data = g_newa(guint8, 128);
+	memset(raw_data, 0, 128);
 
-	encrypted = g_newa(guint8, sizeof(qd->redirect_data) + 16);	/* 16 bytes more */
+	encrypted = g_newa(guint8, 128 + 16);	/* 16 bytes more */
 
 	bytes = 0;
-	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));
+	if (qd->redirect == NULL) {
+		/* first packet to get server */
+		qd->redirect_len = 15;
+		qd->redirect = g_realloc(qd->redirect, qd->redirect_len);
+		memset(qd->redirect, 0, qd->redirect_len);
+	}
+	bytes += qq_putdata(raw_data + bytes, qd->redirect, qd->redirect_len);
 
 	encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.random_key);
 
@@ -537,6 +539,7 @@ guint16 qq_process_get_server(PurpleConn
 {
 	qq_data *qd;
 	gint bytes;
+	guint16 ret;
 
 	g_return_val_if_fail (gc != NULL && gc->proto_data != NULL, QQ_LOGIN_REPLY_ERR);
 	qd = (qq_data *) gc->proto_data;
@@ -545,9 +548,9 @@ guint16 qq_process_get_server(PurpleConn
 	
 	/* 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));
+	bytes += qq_get16(&ret, data + bytes);
+	if (ret == 0) {
+		/* Notice: do not clear redirect_data here. It will be used in login*/
 		qd->redirect_ip.s_addr = 0;
 		return QQ_LOGIN_REPLY_OK;
 	}
@@ -559,15 +562,13 @@ guint16 qq_process_get_server(PurpleConn
 		return QQ_LOGIN_REPLY_ERR;
 	}
 
-	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));
+	qd->redirect_len = data_len;
+	qd->redirect = g_realloc(qd->redirect, qd->redirect_len);
+	qq_getdata(qd->redirect, qd->redirect_len, data);
+	qq_show_packet("Redirect to", qd->redirect, qd->redirect_len);
 
-	g_memmove(&qd->redirect_ip, &qd->redirect_data.ip, sizeof(qd->redirect_ip));
+	qq_getIP(&qd->redirect_ip, data + 11);
+	purple_debug_info("QQ", "Get server %s\n", inet_ntoa(qd->redirect_ip));
 	return QQ_LOGIN_REPLY_REDIRECT;
 }
 
@@ -809,10 +810,8 @@ guint8 qq_process_token_ex(PurpleConnect
 	bytes += qq_get8(&reply, data + bytes);
 
 	bytes += qq_get16(&(qd->ld.token_ex_len), data + bytes);
-	if (qd->ld.token_ex != NULL)	g_free(qd->ld.token_ex);
-	qd->ld.token_ex = g_new0(guint8, qd->ld.token_ex_len);
+	qd->ld.token_ex = g_realloc(qd->ld.token_ex, qd->ld.token_ex_len);
 	bytes += qq_getdata(qd->ld.token_ex, qd->ld.token_ex_len , data + bytes);
-
 	if(reply != 1)
 	{
 		purple_debug_info("QQ", "Captcha verified, result %d\n", reply);
@@ -877,17 +876,20 @@ static guint32 crc32(guint32 crc, const 
 	return crc ^ 0xffffffffL;
 }
 
-void qq_request_check_pwd_2007(PurpleConnection *gc)
+void qq_request_check_pwd(PurpleConnection *gc)
 {
 	qq_data *qd;
 	guint8 *buf, *raw_data;
 	gint bytes;
 	guint8 *encrypted;
 	gint encrypted_len;
-	gint count;
 	static guint8 header[] = {
 			0x00, 0x5F, 0x00, 0x00, 0x08, 0x04, 0x01, 0xE0
 	};
+	static guint8 unknown[] = {
+			0xDB, 0xB9, 0xF3, 0x0B, 0xF9, 0x13, 0x87, 0xB2,
+			0xE6, 0x20, 0x43, 0xBE, 0x53, 0xCA, 0x65, 0x03
+	};
 
 	g_return_if_fail(gc != NULL && gc->proto_data != NULL);
 	qd = (qq_data *) gc->proto_data;
@@ -902,32 +904,36 @@ void qq_request_check_pwd_2007(PurpleCon
 	/* Encrypted password and put in encrypted */
 	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, 0);
 	bytes += qq_put16(raw_data + bytes, rand() & 0xffff);
 
 	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 */
+	/* token get from qq_request_token_ex */
 	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);
-	/* 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);
+	/* len of unknown + len of CRC32 */
+	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);
+	qq_put8(raw_data + 1, 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_put16(raw_data + bytes, 0x0003);
 	bytes += qq_put8(raw_data + bytes, 0);
 	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);
+
+	/* qq_show_packet("Check password", raw_data, bytes); */
 	/* Encrypted by random key*/
 	encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.random_key);
 
@@ -941,13 +947,13 @@ void qq_request_check_pwd_2007(PurpleCon
 	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)
+guint8 qq_process_check_pwd( PurpleConnection *gc, guint8 *data, gint data_len)
 {
 	qq_data *qd;
 	int bytes;
 	guint8 ret;
-	guint16 unknown_len;
 	gchar *error = NULL;
+	guint16 unknow_token_len;
 	gchar *msg, *msg_utf8;
 	guint16 msg_len;
 	PurpleConnectionError reason = PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED;
@@ -957,100 +963,34 @@ guint8 qq_process_check_pwd_2007( Purple
 	g_return_val_if_fail(gc != NULL  && gc->proto_data != NULL, QQ_LOGIN_REPLY_ERR);
 	qd = (qq_data *) gc->proto_data;
 
-	bytes = 2;	// skip 2 bytes
-	bytes += qq_get8(&ret, data + bytes);
-	bytes += 4;  // skip 4 bytes
-	/* 2 unknow */
-	bytes += qq_get16(&unknown_len, data + bytes);
-	bytes += unknown_len;
-	bytes += qq_get16(&unknown_len, data + bytes);
-	bytes += unknown_len;
-	if (ret == QQ_LOGIN_REPLY_OK) {
-		/* get login_token */
-		bytes += qq_get16(&qd->ld.login_token_len, data + bytes);
-		if (qd->ld.login_token != NULL) g_free(qd->ld.login_token);
-		qd->ld.login_token = g_new0(guint8, qd->ld.login_token_len);
-		bytes += qq_getdata(qd->ld.login_token, qd->ld.login_token_len, data + bytes);
-		/* get login_key */
-		bytes += qq_getdata(qd->ld.login_key, sizeof(qd->ld.login_key), data + bytes);
-		return QQ_LOGIN_REPLY_OK;
-	}
+	/* qq_show_packet("Check password reply", data, data_len); */
 
-	switch (ret)
-	{
-		case 0x34:		/* invalid password, 2nd byte is 0xc6 */
-			if (!purple_account_get_remember_password(gc->account)) {
-				purple_account_set_password(gc->account, NULL);
-			}
-			error = g_strdup(_("Error password"));
-			reason = PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED;
-			break;
-		case 0x33:		/* need activation */
-		case 0x51:		/* need activation */
-			error = g_strdup(_("Need active"));
-			reason = PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED;
-			break;
-		case 0xBF:		/* uid is not exist */
-			error = g_strdup(_("invalid user name"));
-			reason = PURPLE_CONNECTION_ERROR_INVALID_USERNAME;
-			break;
-		default:
-			qq_hex_dump(PURPLE_DEBUG_WARNING, "QQ", data, data_len,
-					">>> [default] decrypt and dump");
-			error = g_strdup_printf(
-						_("Unknow reply code when checking password (0x%02X)"),
-						ret );
-			reason = PURPLE_CONNECTION_ERROR_OTHER_ERROR;
-			break;
-	}
-	qq_hex_dump(PURPLE_DEBUG_WARNING, "QQ", data, data_len,
-			">>> [default] decrypt and dump");
-	bytes = 11;
-	bytes += qq_get16(&msg_len, data + bytes);
+	bytes = 0;
+	bytes += qq_get16(&unknow_token_len, data + bytes);	/* maybe total length */
+	bytes += qq_get8(&ret, data + bytes);
+	bytes += 4; /* 0x(00 00 6d b9) */
+	/* unknow_token_len may 0 when not reply ok*/
+	bytes += qq_get16(&unknow_token_len, data + bytes);	/* 0x0020 */
+	bytes += unknow_token_len;
+	bytes += qq_get16(&unknow_token_len, data + bytes);	/* 0x0020 */
+	bytes += unknow_token_len;
 
-	msg = g_strndup((gchar *)data + bytes, msg_len);
-	msg_utf8 = qq_to_utf8(msg, QQ_CHARSET_DEFAULT);
-
-	purple_debug_error("QQ", "%s:\n%s\n", error, msg_utf8);
-	purple_connection_error_reason(gc, reason, msg_utf8);
-
-	g_free(error);
-	g_free(msg);
-	g_free(msg_utf8);
-	return QQ_LOGIN_REPLY_ERR;
-}
-
-guint8 qq_process_check_pwd_2008( PurpleConnection *gc, guint8 *data, gint data_len)
-{
-	qq_data *qd;
-	int bytes;
-	guint8 ret;
-	gchar *error = NULL;
-	gchar *msg, *msg_utf8;
-	guint16 msg_len;
-	PurpleConnectionError reason = PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED;
-
-	g_return_val_if_fail(data != NULL && data_len != 0, QQ_LOGIN_REPLY_ERR);
-
-	g_return_val_if_fail(gc != NULL  && gc->proto_data != NULL, QQ_LOGIN_REPLY_ERR);
-	qd = (qq_data *) gc->proto_data;
-
-	bytes = 1;	// skip 1 bytes, always 0
-	bytes += qq_get8(&ret, data + bytes);
-	if (ret == 0x97) {
+	if (ret == 0) {
 		/* get login_token */
-		bytes += qq_get16(&qd->ld.login_token_len, data);
+		bytes += qq_get16(&qd->ld.login_token_len, data + bytes);
 		if (qd->ld.login_token != NULL) g_free(qd->ld.login_token);
 		qd->ld.login_token = g_new0(guint8, qd->ld.login_token_len);
 		bytes += qq_getdata(qd->ld.login_token, qd->ld.login_token_len, data + bytes);
+		qq_show_packet("Get login token", qd->ld.login_token, qd->ld.login_token_len);
 		/* get login_key */
 		bytes += qq_getdata(qd->ld.login_key, sizeof(qd->ld.login_key), data + bytes);
+		qq_show_packet("Get login key", qd->ld.login_key, sizeof(qd->ld.login_key));
 		return QQ_LOGIN_REPLY_OK;
 	}
 
 	switch (ret)
 	{
-		case 0xc6:		/* invalid password */
+		case 0x34:		/* invalid password */
 			if (!purple_account_get_remember_password(gc->account)) {
 				purple_account_set_password(gc->account, NULL);
 			}
@@ -1076,7 +1016,6 @@ guint8 qq_process_check_pwd_2008( Purple
 			break;
 	}
 
-	bytes = 11;
 	bytes += qq_get16(&msg_len, data + bytes);
 
 	msg = g_strndup((gchar *)data + bytes, msg_len);
@@ -1091,75 +1030,6 @@ guint8 qq_process_check_pwd_2008( Purple
 	return QQ_LOGIN_REPLY_ERR;
 }
 
-void qq_request_check_pwd_2008(PurpleConnection *gc)
-{
-	qq_data *qd;
-	guint8 *buf, *raw_data;
-	gint bytes;
-	guint8 *encrypted;
-	gint encrypted_len;
-	static guint8 header[] = {
-			0x00, 0x5F, 0x00, 0x00, 0x08, 0x04, 0x01, 0xE0
-	};
-	static guint8 unknown[] = {
-			0xDB, 0xB9, 0xF3, 0x0B, 0xF9, 0x13, 0x87, 0xB2,
-			0xE6, 0x20, 0x43, 0xBE, 0x53, 0xCA, 0x65, 0x03
-	};
-
-	g_return_if_fail(gc != NULL && gc->proto_data != NULL);
-	qd = (qq_data *) gc->proto_data;
-
-	g_return_if_fail(qd->ld.token != NULL && qd->ld.token_len > 0);
-
-	raw_data = g_newa(guint8, MAX_PACKET_SIZE - 16);
-	memset(raw_data, 0, MAX_PACKET_SIZE - 16);
-
-	encrypted = g_newa(guint8, MAX_PACKET_SIZE);	/* 16 bytes more */
-
-	/* Encrypted password and put in encrypted */
-	bytes = 0;
-	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, rand() & 0xffff);
-
-	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_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);
-	/* len of unknown + len of CRC32 */
-	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, 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, bytes, qd->ld.random_key);
-
-	buf = g_newa(guint8, MAX_PACKET_SIZE);
-	memset(buf, 0, MAX_PACKET_SIZE);
-	bytes = 0;
-	bytes += qq_putdata(buf + bytes, qd->ld.random_key, QQ_KEY_LENGTH);
-	bytes += qq_putdata(buf + bytes, encrypted, encrypted_len);
-
-	qd->send_seq++;
-	qq_send_cmd_encrypted(gc, QQ_CMD_CHECK_PWD, qd->send_seq, buf, bytes, TRUE);
-}
-
 void qq_request_login_2007(PurpleConnection *gc)
 {
 	qq_data *qd;
@@ -1208,7 +1078,7 @@ void qq_request_login_2007(PurpleConnect
 
 	/* create packet */
 	bytes = 0;
-	bytes += qq_put16(raw_data + bytes, 0);
+	bytes += qq_put16(raw_data + bytes, 0);		/* Unknow */
 	/* password encrypted */
 	bytes += qq_put16(raw_data + bytes, encrypted_len);
 	bytes += qq_putdata(raw_data + bytes, encrypted, encrypted_len);
@@ -1216,28 +1086,30 @@ void qq_request_login_2007(PurpleConnect
 	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 */
+	/* unknow fill 0 */
 	memset(raw_data + bytes, 0, 19);
 	bytes += 19;
 	bytes += qq_putdata(raw_data + bytes, login_1_16, sizeof(login_1_16));
 
-	bytes += qq_put8(raw_data + bytes, (guint8)rand() & 0xff);
+	bytes += qq_put8(raw_data + bytes, rand() & 0xff);
 	bytes += qq_put8(raw_data + bytes, qd->login_mode);
 	/* unknow 10 bytes zero filled*/
 	memset(raw_data + bytes, 0, 10);
 	bytes += 10;
 	/* redirect data, 15 bytes */
-	bytes += qq_putdata(raw_data + bytes, (guint8 *)&qd->redirect_data, sizeof(qd->redirect_data));
+	bytes += qq_putdata(raw_data + bytes, qd->redirect, qd->redirect_len);
 	/* unknow fill */
 	bytes += qq_putdata(raw_data + bytes, login_2_16, sizeof(login_2_16));
 	/* captcha token get from qq_process_token_ex */
-	bytes += qq_put8(raw_data + bytes, qd->captcha.token_len);
-	bytes += qq_putdata(raw_data + bytes, qd->captcha.token, qd->captcha.token_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);
 	/* unknow fill */
 	bytes += qq_putdata(raw_data + bytes, login_3_83, sizeof(login_3_83));
 	memset(raw_data + bytes, 0, 332 - sizeof(login_3_83));
 	bytes += 332 - sizeof(login_3_83);
 
+	qq_show_packet("Login", raw_data, bytes);
+
 	encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.login_key);
 
 	buf = g_newa(guint8, MAX_PACKET_SIZE);
@@ -1362,7 +1234,6 @@ void qq_request_login_2008(PurpleConnect
 	/* create packet */
 	bytes = 0;
 	bytes += qq_put16(raw_data + bytes, 0);		/* Unknow */
-	bytes += qq_put8(raw_data + bytes, 0);		/* Separator */
 	/* password encrypted */
 	bytes += qq_put16(raw_data + bytes, encrypted_len);
 	bytes += qq_putdata(raw_data + bytes, encrypted, encrypted_len);
@@ -1387,12 +1258,12 @@ void qq_request_login_2008(PurpleConnect
 	memset(raw_data + bytes, 0, 10);
 	bytes += 10;
 	/* redirect data, 15 bytes */
-	bytes += qq_putdata(raw_data + bytes, (guint8 *)&qd->redirect_data, sizeof(qd->redirect_data));
+	bytes += qq_putdata(raw_data + bytes, qd->redirect, qd->redirect_len);
 	/* unknow fill */
 	bytes += qq_putdata(raw_data + bytes, login_2_16, sizeof(login_2_16));
 	/* captcha token get from qq_process_token_ex */
-	bytes += qq_put8(raw_data + bytes, qd->captcha.token_len);
-	bytes += qq_putdata(raw_data + bytes, qd->captcha.token, qd->captcha.token_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);
 	/* unknow fill */
 	bytes += qq_putdata(raw_data + bytes, login_3_18, sizeof(login_3_18));
 	bytes += qq_put8(raw_data + bytes , sizeof(login_4_16));
@@ -1401,7 +1272,7 @@ void qq_request_login_2008(PurpleConnect
 	memset(raw_data + bytes, 0, 10);
 	bytes += 10;
 	/* redirect data, 15 bytes */
-	bytes += qq_putdata(raw_data + bytes, (guint8 *)&qd->redirect_data, sizeof(qd->redirect_data));
+	bytes += qq_putdata(raw_data + bytes, qd->redirect, qd->redirect_len);
 	/* unknow fill */
 	bytes += qq_putdata(raw_data + bytes, login_5_6, sizeof(login_5_6));
 	bytes += qq_put8(raw_data + bytes , sizeof(login_6_16));
@@ -1410,6 +1281,7 @@ void qq_request_login_2008(PurpleConnect
 	memset(raw_data + bytes, 0, 249);
 	bytes += 249;
 
+	qq_show_packet("Login request", raw_data, bytes);
 	encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.login_key);
 
 	buf = g_newa(guint8, MAX_PACKET_SIZE);
============================================================
--- libpurple/protocols/qq/qq_base.h	50d174aa4b537a8df7d8cc35713d83765e22b125
+++ libpurple/protocols/qq/qq_base.h	3d8a80825363d0941c79352ba552c5a03b87bc89
@@ -61,12 +61,9 @@ void qq_captcha_input_dialog(PurpleConne
 guint8 qq_process_token_ex(PurpleConnection *gc, guint8 *buf, gint buf_len);
 void qq_captcha_input_dialog(PurpleConnection *gc,qq_captcha_data *captcha);
 
-void qq_request_check_pwd_2007(PurpleConnection *gc);
-guint8 qq_process_check_pwd_2007( PurpleConnection *gc, guint8 *data, gint data_len);
+void qq_request_check_pwd(PurpleConnection *gc);
+guint8 qq_process_check_pwd( PurpleConnection *gc, guint8 *data, gint data_len);
 
-void qq_request_check_pwd_2008(PurpleConnection *gc);
-guint8 qq_process_check_pwd_2008( PurpleConnection *gc, guint8 *data, gint data_len);
-
 void qq_request_login_2007(PurpleConnection *gc);
 guint8 qq_process_login_2007( PurpleConnection *gc, guint8 *data, gint data_len);
 
============================================================
--- libpurple/protocols/qq/qq_process.c	7c955b87acfcc3bf8479b01528e843d7b73d8cf4
+++ libpurple/protocols/qq/qq_process.c	704cd19e09d79732c04337624136c8529cef47f9
@@ -663,11 +663,7 @@ guint8 qq_proc_login_cmds(PurpleConnecti
 		case QQ_CMD_TOKEN_EX:
 			ret_8 = qq_process_token_ex(gc, data, data_len);
 			if (ret_8 == QQ_LOGIN_REPLY_OK) {
-				if (qd->client_version == 2008) {
-					qq_request_check_pwd_2008(gc);
-				} else {
-					qq_request_check_pwd_2007(gc);
-				}
+				qq_request_check_pwd(gc);
 			} else if (ret_8 == QQ_LOGIN_REPLY_NEXT_TOKEN_EX) {
 				qq_request_token_ex_next(gc);
 			} else if (ret_8 == QQ_LOGIN_REPLY_CAPTCHA_DLG) {
@@ -678,11 +674,7 @@ guint8 qq_proc_login_cmds(PurpleConnecti
 			}
 			break;
 		case QQ_CMD_CHECK_PWD:
-			if (qd->client_version == 2008) {
-				ret_8 = qq_process_check_pwd_2008(gc, data, data_len);
-			} else {
-				ret_8 = qq_process_check_pwd_2007(gc, data, data_len);
-			}
+			ret_8 = qq_process_check_pwd(gc, data, data_len);
 			if (ret_8 != QQ_LOGIN_REPLY_OK) {
 				return  ret_8;
 			}


More information about the Commits mailing list