⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 login_logout.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	guint8 *cursor;	gchar *new_server_str;	qq_data *qd;	qq_login_reply_redirect_packet lrrp;	qd = (qq_data *) gc->proto_data;	cursor = data;	bytes = 0;	/* 000-000: reply code */	bytes += read_packet_b(data, &cursor, len, &lrrp.result);	/* 001-004: login uid */	bytes += read_packet_dw(data, &cursor, len, &lrrp.uid);	/* 005-008: redirected new server IP */	bytes += read_packet_data(data, &cursor, len, lrrp.new_server_ip, 4);	/* 009-010: redirected new server port */	bytes += read_packet_w(data, &cursor, len, &lrrp.new_server_port);	if (bytes != QQ_LOGIN_REPLY_REDIRECT_PACKET_LEN) {		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);		ret = QQ_LOGIN_REPLY_MISC_ERROR;	} else {		/* start new connection */		new_server_str = gen_ip_str(lrrp.new_server_ip);		purple_debug(PURPLE_DEBUG_WARNING, "QQ",			   "Redirected to new server: %s:%d\n", new_server_str, lrrp.new_server_port);		qq_connect(gc->account, new_server_str, lrrp.new_server_port, qd->use_tcp, TRUE);		g_free(new_server_str);		ret = QQ_LOGIN_REPLY_REDIRECT;	}	return ret;}/* process login reply which says wrong password */static gint _qq_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_PWD_ERROR;}/* request before login */void qq_send_packet_request_login_token(PurpleConnection *gc){	qq_data *qd;	guint8 *buf, *cursor;	guint16 seq_ret;	gint bytes;	qd = (qq_data *) gc->proto_data;	buf = g_newa(guint8, MAX_PACKET_SIZE);	cursor = buf;	bytes = 0;	bytes += _create_packet_head_seq(buf, &cursor, gc, QQ_CMD_REQUEST_LOGIN_TOKEN, TRUE, &seq_ret);	bytes += create_packet_dw(buf, &cursor, qd->uid);	bytes += create_packet_b(buf, &cursor, 0);	bytes += create_packet_b(buf, &cursor, QQ_PACKET_TAIL);	if (bytes == (cursor - buf))	/* packet creation OK */		_qq_send_packet(gc, buf, bytes, QQ_CMD_REQUEST_LOGIN_TOKEN);	else		purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Fail create request login token packet\n");}/* send login packet to QQ server */static void qq_send_packet_login(PurpleConnection *gc, guint8 token_length, guint8 *token){	qq_data *qd;	guint8 *buf, *cursor, *raw_data, *encrypted_data;	guint16 seq_ret;	gint encrypted_len, bytes;	gint pos;	qd = (qq_data *) gc->proto_data;	buf = g_newa(guint8, MAX_PACKET_SIZE);	raw_data = g_newa(guint8, QQ_LOGIN_DATA_LENGTH);	encrypted_data = g_newa(guint8, QQ_LOGIN_DATA_LENGTH + 16);	/* 16 bytes more */	qd->inikey = _gen_login_key();	/* now generate the encrypted data	 * 000-015 use pwkey as key to encrypt empty string */	qq_crypt(ENCRYPT, (guint8 *) "", 0, qd->pwkey, raw_data, &encrypted_len);	/* 016-016 */	raw_data[16] = 0x00;	/* 017-020, used to be IP, now zero */	*((guint32 *) (raw_data + 17)) = 0x00000000;	/* 021-022, used to be port, now zero */	*((guint16 *) (raw_data + 21)) = 0x0000;	/* 023-051, fixed value, unknown */	g_memmove(raw_data + 23, login_23_51, 29);	/* 052-052, login mode */	raw_data[52] = qd->login_mode;	/* 053-068, fixed value, maybe related to per machine */	g_memmove(raw_data + 53, login_53_68, 16);	/* 069, login token length */	raw_data[69] = token_length;	pos = 70;	/* 070-093, login token, normally 24 bytes */	g_memmove(raw_data + pos, token, token_length);	pos += token_length;	/* 100 bytes unknown */	g_memmove(raw_data + pos, login_100_bytes, 100);	pos += 100;	/* all zero left */	memset(raw_data+pos, 0, QQ_LOGIN_DATA_LENGTH - pos);	qq_crypt(ENCRYPT, raw_data, QQ_LOGIN_DATA_LENGTH, qd->inikey, encrypted_data, &encrypted_len);	cursor = buf;	bytes = 0;	bytes += _create_packet_head_seq(buf, &cursor, gc, QQ_CMD_LOGIN, TRUE, &seq_ret);	bytes += create_packet_dw(buf, &cursor, qd->uid);	bytes += create_packet_data(buf, &cursor, qd->inikey, QQ_KEY_LENGTH);	bytes += create_packet_data(buf, &cursor, encrypted_data, encrypted_len);	bytes += create_packet_b(buf, &cursor, QQ_PACKET_TAIL);	if (bytes == (cursor - buf))	/* packet creation OK */		_qq_send_packet(gc, buf, bytes, QQ_CMD_LOGIN);	else		purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Fail create login packet\n");}void qq_process_request_login_token_reply(guint8 *buf, gint buf_len, PurpleConnection *gc){        qq_data *qd;	gchar *hex_dump;        g_return_if_fail(buf != NULL && buf_len != 0);        qd = (qq_data *) gc->proto_data;	if (buf[0] == QQ_REQUEST_LOGIN_TOKEN_REPLY_OK) {		if (buf[1] != buf_len-2) {			purple_debug(PURPLE_DEBUG_INFO, "QQ", 					"Malformed login token reply packet. Packet specifies length of %d, actual length is %d\n", buf[1], buf_len-2);			purple_debug(PURPLE_DEBUG_INFO, "QQ",					"Attempting to proceed with the actual packet length.\n");		}		hex_dump = hex_dump_to_str(buf+2, buf_len-2);		purple_debug(PURPLE_DEBUG_INFO, "QQ",                                   "<<< got a token with %d bytes -> [default] decrypt and dump\n%s", buf_len-2, hex_dump);		qq_send_packet_login(gc, buf_len-2, buf+2);	} else {		purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Unknown request login token reply code : %d\n", buf[0]);		hex_dump = hex_dump_to_str(buf, buf_len);                purple_debug(PURPLE_DEBUG_WARNING, "QQ",           		           ">>> %d bytes -> [default] decrypt and dump\n%s",	                           buf_len, hex_dump);               		try_dump_as_gbk(buf, buf_len);		purple_connection_error(gc, _("Request login token error!"));	}			g_free(hex_dump);}/* send logout packets to QQ server */void qq_send_packet_logout(PurpleConnection *gc){	gint i;	qq_data *qd;	qd = (qq_data *) gc->proto_data;	for (i = 0; i < 4; i++)		qq_send_cmd(gc, QQ_CMD_LOGOUT, FALSE, 0xffff, FALSE, qd->pwkey, QQ_KEY_LENGTH);	qd->logged_in = FALSE;	/* update login status AFTER sending logout packets */}/* process the login reply packet */void qq_process_login_reply(guint8 *buf, gint buf_len, PurpleConnection *gc){	gint len, ret, bytes;	guint8 *data;	qq_data *qd;	gchar *hex_dump;	g_return_if_fail(buf != NULL && buf_len != 0);	qd = (qq_data *) gc->proto_data;	len = buf_len;	data = g_newa(guint8, len);	if (qq_crypt(DECRYPT, buf, buf_len, qd->pwkey, data, &len)) {		/* should be able to decrypt with pwkey */		purple_debug(PURPLE_DEBUG_INFO, "QQ", "Decrypt login reply packet with pwkey, %d bytes\n", len);		if (data[0] == QQ_LOGIN_REPLY_OK) {			ret = _qq_process_login_ok(gc, data, len);		} else {			purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Unknown login reply code : %d\n", data[0]);			ret = QQ_LOGIN_REPLY_MISC_ERROR;		}	} else {		/* decrypt with pwkey error */		len = buf_len;	/* reset len, decrypt will fail if len is too short */		if (qq_crypt(DECRYPT, buf, buf_len, qd->inikey, data, &len)) {			/* decrypt ok with inipwd, it might be password error */			purple_debug(PURPLE_DEBUG_WARNING, "QQ", 					"Decrypt login reply packet with inikey, %d bytes\n", len);			bytes = 0;			switch (data[0]) {			case QQ_LOGIN_REPLY_REDIRECT:				ret = _qq_process_login_redirect(gc, data, len);				break;			case QQ_LOGIN_REPLY_PWD_ERROR:				ret = _qq_process_login_wrong_pwd(gc, data, len);				break;			default:				purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Unknown reply code: %d\n", data[0]);				hex_dump = hex_dump_to_str(data, len);		                purple_debug(PURPLE_DEBUG_WARNING, "QQ",                		           ">>> %d bytes -> [default] decrypt and dump\n%s",		                           buf_len, hex_dump);				g_free(hex_dump);                		try_dump_as_gbk(data, len);				ret = QQ_LOGIN_REPLY_MISC_ERROR;			}		} else {	/* no idea how to decrypt */			purple_debug(PURPLE_DEBUG_ERROR, "QQ", "No idea how to decrypt login reply\n");			ret = QQ_LOGIN_REPLY_MISC_ERROR;		}	}	switch (ret) {	case QQ_LOGIN_REPLY_PWD_ERROR:		gc->wants_to_die = TRUE;		purple_connection_error(gc, _("Incorrect password."));		break;	case QQ_LOGIN_REPLY_MISC_ERROR:		purple_connection_error(gc, _("Unable to login, check debug log"));		break;	case QQ_LOGIN_REPLY_OK:		purple_debug(PURPLE_DEBUG_INFO, "QQ", "Login replys OK, everything is fine\n");		break;	case QQ_LOGIN_REPLY_REDIRECT:		/* the redirect has been done in _qq_process_login_reply */		break;	default:{;		}	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -