diff libpurple/protocols/qq/qq_base.c @ 24095:25f62d21b3f8

disapproval of revision '8cebefbc6cd5d84acb69c74e69e8821f11dd225d'
author Daniel Atallah <daniel.atallah@gmail.com>
date Mon, 15 Sep 2008 03:04:07 +0000
parents 147ada94a1d8
children bcfc98c7a55f
line wrap: on
line diff
--- a/libpurple/protocols/qq/qq_base.c	Thu Sep 11 13:25:07 2008 +0000
+++ b/libpurple/protocols/qq/qq_base.c	Mon Sep 15 03:04:07 2008 +0000
@@ -48,7 +48,7 @@
 	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
+	0x95, 0x67, 0xda, 0x2c, 0x01 
 }; */
 
 /* for QQ 2003iii 0304, fixed value */
@@ -139,7 +139,7 @@
 {
 	guint8 src[QQ_KEY_LENGTH + QQ_KEY_LENGTH];
 	gint bytes = 0;
-
+	
 	bytes += qq_put32(src + bytes, uid);
 	bytes += qq_putdata(src + bytes, session_key, QQ_KEY_LENGTH);
 
@@ -161,7 +161,7 @@
 	bytes += qq_get8(&lrop.result, data + bytes);
 	/* 001-016: session key */
 	bytes += qq_getdata(lrop.session_key, sizeof(lrop.session_key), data + bytes);
-	purple_debug_info("QQ", "Got session_key\n");
+	purple_debug(PURPLE_DEBUG_INFO, "QQ", "Got session_key\n");
 	/* 017-020: login uid */
 	bytes += qq_get32(&lrop.uid, data + bytes);
 	/* 021-024: server detected user public IP */
@@ -200,16 +200,16 @@
 	bytes += qq_getdata((guint8 *) &lrop.unknown6, 8, data + bytes);
 
 	if (bytes != QQ_LOGIN_REPLY_OK_PACKET_LEN) {	/* fail parsing login info */
-		purple_debug_warning("QQ",
+		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 */
 
 	memcpy(qd->session_key, lrop.session_key, sizeof(qd->session_key));
 	get_session_md5(qd->session_md5, qd->uid, qd->session_key);
-
+	
 	qd->my_ip.s_addr = lrop.client_ip.s_addr;
-
+	
 	qd->my_port = lrop.client_port;
 	qd->login_time = lrop.login_time;
 	qd->last_login_time = lrop.last_login_time;
@@ -237,19 +237,39 @@
 	bytes += qq_get16(&lrrp.new_server_port, data + bytes);
 
 	if (bytes != QQ_LOGIN_REPLY_REDIRECT_PACKET_LEN) {
-		purple_debug_error("QQ",
+		purple_debug(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_MISC;
 	}
-
+	
 	/* redirect to new server, do not disconnect or connect here
 	 * those connect should be called at packet_process */
-	qd->redirect_ip.s_addr = lrrp.new_server_ip.s_addr;
-	qd->redirect_port = lrrp.new_server_port;
+	if (qd->real_hostname) {
+		purple_debug(PURPLE_DEBUG_INFO, "QQ", "free real_hostname\n");
+		g_free(qd->real_hostname);
+		qd->real_hostname = NULL;
+	}
+	qd->real_hostname = g_strdup( inet_ntoa(lrrp.new_server_ip) );
+	qd->real_port = lrrp.new_server_port;
+
 	return QQ_LOGIN_REPLY_REDIRECT;
 }
 
+/* process login reply which says wrong password */
+static gint8 process_login_wrong_pwd(PurpleConnection *gc, guint8 *data, gint len)
+{
+	gchar *server_reply, *server_reply_utf8;
+	server_reply = g_new0(gchar, len);
+	g_memmove(server_reply, data + 1, len - 1);
+	server_reply_utf8 = qq_to_utf8(server_reply, QQ_CHARSET_DEFAULT);
+	purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Wrong password, server msg in UTF8: %s\n", server_reply_utf8);
+	g_free(server_reply);
+	g_free(server_reply_utf8);
+
+	return QQ_LOGIN_REPLY_ERR_PWD;
+}
+
 /* request before login */
 void qq_send_packet_token(PurpleConnection *gc)
 {
@@ -261,9 +281,9 @@
 	qd = (qq_data *) gc->proto_data;
 
 	bytes += qq_put8(buf + bytes, 0);
-
+	
 	qd->send_seq++;
-	qq_send_cmd_encrypted(gc, QQ_CMD_TOKEN, qd->send_seq, buf, bytes, TRUE);
+	qq_send_data(qd, QQ_CMD_TOKEN, qd->send_seq, TRUE, buf, bytes);
 }
 
 /* send login packet to QQ server */
@@ -292,14 +312,14 @@
 	memset(raw_data, 0, QQ_LOGIN_DATA_LENGTH);
 
 	encrypted_data = g_newa(guint8, QQ_LOGIN_DATA_LENGTH + 16);	/* 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(raw_data + bytes, (guint8 *) "", 0, qd->password_twice_md5);
 	g_return_if_fail(encrypted_len == 16);
 	bytes += encrypted_len;
-
+	
 	/* 016-016 */
 	bytes += qq_put8(raw_data + bytes, 0x00);
 	/* 017-020, used to be IP, now zero */
@@ -329,15 +349,14 @@
 	bytes += qq_putdata(buf + bytes, encrypted_data, encrypted_len);
 
 	qd->send_seq++;
-	qq_send_cmd_encrypted(gc, QQ_CMD_LOGIN, qd->send_seq, buf, bytes, TRUE);
+	qq_send_data(qd, QQ_CMD_LOGIN, qd->send_seq, TRUE, buf, bytes);
 }
 
-guint8 qq_process_token_reply(PurpleConnection *gc, guint8 *buf, gint buf_len)
+guint8 qq_process_token_reply(PurpleConnection *gc, gchar *error_msg, guint8 *buf, gint buf_len)
 {
 	qq_data *qd;
 	guint8 ret;
 	int token_len;
-	gchar *error_msg;
 
 	g_return_val_if_fail(buf != NULL && buf_len != 0, -1);
 
@@ -345,37 +364,30 @@
 	qd = (qq_data *) gc->proto_data;
 
 	ret = buf[0];
-
+	
 	if (ret != QQ_TOKEN_REPLY_OK) {
-		purple_debug_error("QQ", "Failed to request token: %d\n", buf[0]);
+		purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Unknown request login token reply code : %d\n", buf[0]);
 		qq_hex_dump(PURPLE_DEBUG_WARNING, "QQ",
 				buf, buf_len,
 				">>> [default] decrypt and dump");
 		error_msg = try_dump_as_gbk(buf, buf_len);
-		if (error_msg == NULL) {
-				error_msg = g_strdup_printf( _("Invalid token reply code, 0x%02X"), ret);
-		}
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_msg);
-		g_free(error_msg);
 		return ret;
 	}
-
+	
 	token_len = buf_len-2;
 	if (token_len <= 0) {
 		error_msg = g_strdup_printf( _("Invalid token len, %d"), token_len);
-		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_msg);
-		g_free(error_msg);
 		return -1;
 	}
-
+	
 	if (buf[1] != token_len) {
-		purple_debug_info("QQ",
+		purple_debug(PURPLE_DEBUG_INFO, "QQ",
 				"Invalid token len. Packet specifies length of %d, actual length is %d\n", buf[1], buf_len-2);
 	}
 	qq_hex_dump(PURPLE_DEBUG_INFO, "QQ",
 			buf+2, token_len,
 			"<<< got a token -> [default] decrypt and dump");
-
+			
 	qd->token = g_new0(guint8, token_len);
 	qd->token_len = token_len;
 	g_memmove(qd->token, buf + 2, qd->token_len);
@@ -390,85 +402,48 @@
 
 	qd = (qq_data *) gc->proto_data;
 	for (i = 0; i < 4; i++)
-		qq_send_cmd(gc, QQ_CMD_LOGOUT, qd->password_twice_md5, QQ_KEY_LENGTH);
+		qq_send_cmd_detail(qd, QQ_CMD_LOGOUT, 0xffff, FALSE, qd->password_twice_md5, QQ_KEY_LENGTH);
 
-	qd->is_login = FALSE;	/* update login status AFTER sending logout packets */
+	qd->logged_in = FALSE;	/* update login status AFTER sending logout packets */
 }
 
 /* process the login reply packet */
-guint8 qq_process_login_reply( PurpleConnection *gc, guint8 *data, gint data_len)
+guint8 qq_process_login_reply(guint8 *data, gint data_len, PurpleConnection *gc)
 {
 	qq_data *qd;
-	guint8 ret = data[0];
-	gchar *server_reply, *server_reply_utf8;
-	gchar *error_msg;
+	gchar* error_msg;
 
 	g_return_val_if_fail(data != NULL && data_len != 0, QQ_LOGIN_REPLY_ERR_MISC);
 
 	qd = (qq_data *) gc->proto_data;
 
-	switch (ret) {
+	switch (data[0]) {
 		case QQ_LOGIN_REPLY_OK:
-			purple_debug_info("QQ", "Login OK\n");
+			purple_debug(PURPLE_DEBUG_INFO, "QQ", "Login reply is OK\n");
 			return process_login_ok(gc, data, data_len);
 		case QQ_LOGIN_REPLY_REDIRECT:
-			purple_debug_info("QQ", "Redirect new server\n");
+			purple_debug(PURPLE_DEBUG_INFO, "QQ", "Login reply is redirect\n");
 			return process_login_redirect(gc, data, data_len);
-
-		case QQ_LOGIN_REPLY_REDIRECT_EX:
-			purple_debug_error("QQ", "Extend redirect new server, not supported yet\n");
-			error_msg = g_strdup( _("Unable login for not support Redirect_EX now") );
-			return QQ_LOGIN_REPLY_REDIRECT_EX;
-
 		case QQ_LOGIN_REPLY_ERR_PWD:
-			server_reply = g_strndup((gchar *)data + 1, data_len - 1);
-			server_reply_utf8 = qq_to_utf8(server_reply, QQ_CHARSET_DEFAULT);
-
-			purple_debug_error("QQ", "Error password: %s\n", server_reply_utf8);
-			error_msg = g_strdup_printf( _("Error password: %s"), server_reply_utf8);
-
-			g_free(server_reply);
-			g_free(server_reply_utf8);
-
-			if (!purple_account_get_remember_password(gc->account)) {
-				purple_account_set_password(gc->account, NULL);
-			}
-
-			purple_connection_error_reason(gc,
-				PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, error_msg);
-			g_free(error_msg);
-
-			return QQ_LOGIN_REPLY_ERR_PWD;
-
+			purple_debug(PURPLE_DEBUG_INFO, "QQ", "Login reply is error password\n");
+			return process_login_wrong_pwd(gc, data, data_len);
 		case QQ_LOGIN_REPLY_NEED_REACTIVE:
-			server_reply = g_strndup((gchar *)data + 1, data_len - 1);
-			server_reply_utf8 = qq_to_utf8(server_reply, QQ_CHARSET_DEFAULT);
-
-			purple_debug_error("QQ", "Need active: %s\n", server_reply_utf8);
-			error_msg = g_strdup_printf( _("Need active: %s"), server_reply_utf8);
-
-			g_free(server_reply);
-			g_free(server_reply_utf8);
-			break;
-
+		case QQ_LOGIN_REPLY_REDIRECT_EX:
+			purple_debug(PURPLE_DEBUG_INFO, "QQ", "Login reply is not actived or redirect extend\n");
 		default:
-			purple_debug_error("QQ",
-				"Unable login for unknow reply code 0x%02X\n", data[0]);
-			qq_hex_dump(PURPLE_DEBUG_WARNING, "QQ",
-				data, data_len,
-				">>> [default] decrypt and dump");
-			error_msg = try_dump_as_gbk(data, data_len);
-			if (error_msg == NULL) {
-				error_msg = g_strdup_printf(
-					_("Unable login for unknow reply code 0x%02X"), data[0] );
-			}
-			break;
+		break;
 	}
 
-	purple_connection_error_reason(gc,
-		PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_msg);
-	g_free(error_msg);
-	return ret;
+	purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Unknown reply code: 0x%02X\n", data[0]);
+			qq_hex_dump(PURPLE_DEBUG_WARNING, "QQ",
+			data, data_len,
+			">>> [default] decrypt and dump");
+	error_msg = try_dump_as_gbk(data, data_len);
+	if (error_msg)	{
+			purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_msg);
+			g_free(error_msg);
+	}
+	return QQ_LOGIN_REPLY_ERR_MISC;
 }
 
 /* send keep-alive packet to QQ server (it is a heart-beat) */
@@ -485,11 +460,11 @@
 	 * the amount of online QQ users, my ip and port */
 	bytes += qq_put32(raw_data + bytes, qd->uid);
 
-	qq_send_cmd(gc, QQ_CMD_KEEP_ALIVE, raw_data, 4);
+	qq_send_cmd(qd, QQ_CMD_KEEP_ALIVE, raw_data, 4);
 }
 
 /* parse the return of keep-alive packet, it includes some system information */
-gboolean qq_process_keep_alive(guint8 *data, gint data_len, PurpleConnection *gc)
+gboolean qq_process_keep_alive(guint8 *data, gint data_len, PurpleConnection *gc) 
 {
 	qq_data *qd;
 	gchar **segments;
@@ -503,7 +478,7 @@
 	/* the last one is 60, don't know what it is */
 	if (NULL == (segments = split_data(data, data_len, "\x1f", 6)))
 			return TRUE;
-
+			
 	/* segments[0] and segment[1] are all 0x30 ("0") */
 	qd->total_online = strtol(segments[2], NULL, 10);
 	if(0 == qd->total_online) {
@@ -513,9 +488,9 @@
 	qd->my_ip.s_addr = inet_addr(segments[3]);
 	qd->my_port = strtol(segments[4], NULL, 10);
 
-	purple_debug_info("QQ", "keep alive, %s:%d\n",
+	purple_debug(PURPLE_DEBUG_INFO, "QQ", "keep alive, %s:%d\n",
 		inet_ntoa(qd->my_ip), qd->my_port);
-
+	
 	g_strfreev(segments);
 	return TRUE;
 }