libpurple/protocols/qq/qq_base.c

branch
openq
changeset 24344
712295f3bf6d
parent 24343
9c695a1f475b
child 24345
8c97fe081183
equal deleted inserted replaced
24343:9c695a1f475b 24344:712295f3bf6d
32 #include "buddy_list.h" 32 #include "buddy_list.h"
33 #include "char_conv.h" 33 #include "char_conv.h"
34 #include "qq_crypt.h" 34 #include "qq_crypt.h"
35 #include "group.h" 35 #include "group.h"
36 #include "qq_define.h" 36 #include "qq_define.h"
37 #include "qq_network.h"
37 #include "qq_base.h" 38 #include "qq_base.h"
38 #include "packet_parse.h" 39 #include "packet_parse.h"
39 #include "qq.h" 40 #include "qq.h"
40 #include "qq_network.h" 41 #include "qq_network.h"
41 #include "utils.h" 42 #include "utils.h"
42 43
43 #define QQ_LOGIN_DATA_LENGTH 416
44 #define QQ_LOGIN_REPLY_OK_PACKET_LEN 139
45 #define QQ_LOGIN_REPLY_REDIRECT_PACKET_LEN 11
46
47 /* generate a md5 key using uid and session_key */ 44 /* generate a md5 key using uid and session_key */
48 static void get_session_md5(guint8 *session_md5, guint32 uid, guint8 *session_key) 45 static void get_session_md5(guint8 *session_md5, guint32 uid, guint8 *session_key)
49 { 46 {
50 guint8 src[QQ_KEY_LENGTH + QQ_KEY_LENGTH]; 47 guint8 src[QQ_KEY_LENGTH + QQ_KEY_LENGTH];
51 gint bytes = 0; 48 gint bytes = 0;
69 struct tm *tm_local; 66 struct tm *tm_local;
70 67
71 qd = (qq_data *) gc->proto_data; 68 qd = (qq_data *) gc->proto_data;
72 qq_show_packet("Login reply", data, len); 69 qq_show_packet("Login reply", data, len);
73 70
74 /* FIXME, check QQ_LOGIN_REPLY_OK_PACKET_LEN here */ 71 if (len < 139) {
72 purple_connection_error_reason(gc,
73 PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
74 _("Can not decrypt get server reply"));
75 return QQ_LOGIN_REPLY_ERR;
76 }
77
75 bytes = 0; 78 bytes = 0;
76 bytes += qq_get8(&ret, data + bytes); 79 bytes += qq_get8(&ret, data + bytes);
77 bytes += qq_getdata(qd->session_key, sizeof(qd->session_key), data + bytes); 80 bytes += qq_getdata(qd->session_key, sizeof(qd->session_key), data + bytes);
78 get_session_md5(qd->session_md5, qd->uid, qd->session_key); 81 get_session_md5(qd->session_md5, qd->uid, qd->session_key);
79 purple_debug_info("QQ", "Got session_key\n"); 82 purple_debug_info("QQ", "Got session_key\n");
132 purple_debug_info("QQ", "Time: %d-%d-%d, %d:%d:%d\n", 135 purple_debug_info("QQ", "Time: %d-%d-%d, %d:%d:%d\n",
133 (1900 +tm_local->tm_year), (1 + tm_local->tm_mon), tm_local->tm_mday, 136 (1900 +tm_local->tm_year), (1 + tm_local->tm_mon), tm_local->tm_mday,
134 tm_local->tm_hour, tm_local->tm_min, tm_local->tm_sec); 137 tm_local->tm_hour, tm_local->tm_min, tm_local->tm_sec);
135 /* unknow 9 bytes, 0x(00 0a 00 0a 01 00 00 0e 10) */ 138 /* unknow 9 bytes, 0x(00 0a 00 0a 01 00 00 0e 10) */
136 139
137 if (bytes != QQ_LOGIN_REPLY_OK_PACKET_LEN) { /* fail parsing login info */ 140 if (len > 139) {
138 purple_debug_warning("QQ", 141 purple_debug_warning("QQ", "Login reply more than expected %d bytes, read %d bytes\n", 139, bytes);
139 "Fail parsing login info, expect %d bytes, read %d bytes\n", 142 }
140 QQ_LOGIN_REPLY_OK_PACKET_LEN, bytes);
141 } /* but we still go on as login OK */
142 return QQ_LOGIN_REPLY_OK; 143 return QQ_LOGIN_REPLY_OK;
143 } 144 }
144 145
145 /* process login reply packet which includes redirected new server address */ 146 /* process login reply packet which includes redirected new server address */
146 static gint8 process_login_redirect(PurpleConnection *gc, guint8 *data, gint len) 147 static gint8 process_login_redirect(PurpleConnection *gc, guint8 *data, gint len)
152 guint32 uid; 153 guint32 uid;
153 struct in_addr new_server_ip; 154 struct in_addr new_server_ip;
154 guint16 new_server_port; 155 guint16 new_server_port;
155 } packet; 156 } packet;
156 157
158
159 if (len < 11) {
160 purple_connection_error_reason(gc,
161 PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
162 _("Can not decrypt get server reply"));
163 return QQ_LOGIN_REPLY_ERR;
164 }
157 165
158 qd = (qq_data *) gc->proto_data; 166 qd = (qq_data *) gc->proto_data;
159 bytes = 0; 167 bytes = 0;
160 /* 000-000: reply code */ 168 /* 000-000: reply code */
161 bytes += qq_get8(&packet.result, data + bytes); 169 bytes += qq_get8(&packet.result, data + bytes);
164 /* 005-008: redirected new server IP */ 172 /* 005-008: redirected new server IP */
165 bytes += qq_getIP(&packet.new_server_ip, data + bytes); 173 bytes += qq_getIP(&packet.new_server_ip, data + bytes);
166 /* 009-010: redirected new server port */ 174 /* 009-010: redirected new server port */
167 bytes += qq_get16(&packet.new_server_port, data + bytes); 175 bytes += qq_get16(&packet.new_server_port, data + bytes);
168 176
169 if (bytes != QQ_LOGIN_REPLY_REDIRECT_PACKET_LEN) { 177 if (len > 11) {
170 purple_debug_error("QQ", 178 purple_debug_error("QQ", "Login redirect more than expected %d bytes, read %d bytes\n", 11, bytes);
171 "Fail parsing login redirect packet, expect %d bytes, read %d bytes\n",
172 QQ_LOGIN_REPLY_REDIRECT_PACKET_LEN, bytes);
173 return QQ_LOGIN_REPLY_ERR;
174 } 179 }
175 180
176 /* redirect to new server, do not disconnect or connect here 181 /* redirect to new server, do not disconnect or connect here
177 * those connect should be called at packet_process */ 182 * those connect should be called at packet_process */
178 qd->redirect_ip.s_addr = packet.new_server_ip.s_addr; 183 qd->redirect_ip.s_addr = packet.new_server_ip.s_addr;
237 g_return_if_fail(gc != NULL && gc->proto_data != NULL); 242 g_return_if_fail(gc != NULL && gc->proto_data != NULL);
238 qd = (qq_data *) gc->proto_data; 243 qd = (qq_data *) gc->proto_data;
239 244
240 g_return_if_fail(qd->ld.token != NULL && qd->ld.token_len > 0); 245 g_return_if_fail(qd->ld.token != NULL && qd->ld.token_len > 0);
241 246
242 raw_data = g_newa(guint8, QQ_LOGIN_DATA_LENGTH); 247 raw_data = g_newa(guint8, MAX_PACKET_SIZE - 16);
243 memset(raw_data, 0, QQ_LOGIN_DATA_LENGTH); 248 memset(raw_data, 0, MAX_PACKET_SIZE - 16);
244 249
245 encrypted = g_newa(guint8, QQ_LOGIN_DATA_LENGTH + 16); /* 16 bytes more */ 250 encrypted = g_newa(guint8, MAX_PACKET_SIZE); /* 16 bytes more */
246 251
247 bytes = 0; 252 bytes = 0;
248 /* now generate the encrypted data 253 /* now generate the encrypted data
249 * 000-015 use password_twice_md5 as key to encrypt empty string */ 254 * 000-015 use password_twice_md5 as key to encrypt empty string */
250 encrypted_len = qq_encrypt(encrypted, (guint8 *) "", 0, qd->ld.pwd_2nd_md5); 255 encrypted_len = qq_encrypt(encrypted, (guint8 *) "", 0, qd->ld.pwd_twice_md5);
251 g_return_if_fail(encrypted_len == 16); 256 g_return_if_fail(encrypted_len == 16);
252 bytes += qq_putdata(raw_data + bytes, encrypted, encrypted_len); 257 bytes += qq_putdata(raw_data + bytes, encrypted, encrypted_len);
253 258
254 /* 016-016 */ 259 /* 016-016 */
255 bytes += qq_put8(raw_data + bytes, 0x00); 260 bytes += qq_put8(raw_data + bytes, 0x00);
268 /* 070-093, login token, normally 24 bytes */ 273 /* 070-093, login token, normally 24 bytes */
269 bytes += qq_putdata(raw_data + bytes, qd->ld.token, qd->ld.token_len); 274 bytes += qq_putdata(raw_data + bytes, qd->ld.token, qd->ld.token_len);
270 /* 100 bytes unknown */ 275 /* 100 bytes unknown */
271 bytes += qq_putdata(raw_data + bytes, login_100_bytes, 100); 276 bytes += qq_putdata(raw_data + bytes, login_100_bytes, 100);
272 /* all zero left */ 277 /* all zero left */
273 278 memset(raw_data + bytes, 0, 416 - bytes);
274 encrypted_len = qq_encrypt(encrypted, raw_data, QQ_LOGIN_DATA_LENGTH, qd->ld.random_key); 279 bytes = 416;
280
281 encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.random_key);
275 282
276 buf = g_newa(guint8, MAX_PACKET_SIZE); 283 buf = g_newa(guint8, MAX_PACKET_SIZE);
277 memset(buf, 0, MAX_PACKET_SIZE); 284 memset(buf, 0, MAX_PACKET_SIZE);
278 bytes = 0; 285 bytes = 0;
279 bytes += qq_putdata(buf + bytes, qd->ld.random_key, QQ_KEY_LENGTH); 286 bytes += qq_putdata(buf + bytes, qd->ld.random_key, QQ_KEY_LENGTH);
348 gint i; 355 gint i;
349 qq_data *qd; 356 qq_data *qd;
350 357
351 qd = (qq_data *) gc->proto_data; 358 qd = (qq_data *) gc->proto_data;
352 for (i = 0; i < 4; i++) 359 for (i = 0; i < 4; i++)
353 qq_send_cmd(gc, QQ_CMD_LOGOUT, qd->ld.pwd_2nd_md5, QQ_KEY_LENGTH); 360 qq_send_cmd(gc, QQ_CMD_LOGOUT, qd->ld.pwd_twice_md5, QQ_KEY_LENGTH);
354 361
355 qd->is_login = FALSE; /* update login status AFTER sending logout packets */ 362 qd->is_login = FALSE; /* update login status AFTER sending logout packets */
356 } 363 }
357 364
358 /* for QQ 2003iii 0117, fixed value */ 365 /* for QQ 2003iii 0117, fixed value */
500 gint encrypted_len; 507 gint encrypted_len;
501 508
502 g_return_if_fail(gc != NULL && gc->proto_data != NULL); 509 g_return_if_fail(gc != NULL && gc->proto_data != NULL);
503 qd = (qq_data *) gc->proto_data; 510 qd = (qq_data *) gc->proto_data;
504 511
505 raw_data = g_newa(guint8, QQ_LOGIN_DATA_LENGTH); 512 raw_data = g_newa(guint8, sizeof(qd->redirect_data));
506 memset(raw_data, 0, QQ_LOGIN_DATA_LENGTH); 513 memset(raw_data, 0, sizeof(qd->redirect_data));
507 514
508 encrypted = g_newa(guint8, QQ_LOGIN_DATA_LENGTH + 16); /* 16 bytes more */ 515 encrypted = g_newa(guint8, sizeof(qd->redirect_data) + 16); /* 16 bytes more */
509 516
510 bytes = 0; 517 bytes = 0;
511 bytes += qq_putdata(raw_data + bytes, (guint8 *)&qd->redirect_data, sizeof(qd->redirect_data)); 518 bytes += qq_put16(raw_data + bytes, qd->redirect_data.ret);
512 519 bytes += qq_put8(raw_data + bytes, qd->redirect_data.b1);
513 encrypted_len = qq_encrypt(encrypted, raw_data, QQ_LOGIN_DATA_LENGTH, qd->ld.random_key); 520 bytes += qq_put32(raw_data + bytes, qd->redirect_data.w1);
521 bytes += qq_put32(raw_data + bytes, qd->redirect_data.w2);
522 bytes += qq_putIP(raw_data + bytes, &(qd->redirect_data.ip));
523
524 encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.random_key);
514 525
515 buf = g_newa(guint8, MAX_PACKET_SIZE); 526 buf = g_newa(guint8, MAX_PACKET_SIZE);
516 memset(buf, 0, MAX_PACKET_SIZE); 527 memset(buf, 0, MAX_PACKET_SIZE);
517 bytes = 0; 528 bytes = 0;
518 bytes += qq_putdata(buf + bytes, qd->ld.random_key, QQ_KEY_LENGTH); 529 bytes += qq_putdata(buf + bytes, qd->ld.random_key, QQ_KEY_LENGTH);
519 bytes += qq_putdata(buf + bytes, encrypted, encrypted_len); 530 bytes += qq_putdata(buf + bytes, encrypted, encrypted_len);
520 531
521 qd->send_seq++; 532 qd->send_seq++;
522 qq_send_cmd_encrypted(gc, QQ_CMD_LOGIN, qd->send_seq, buf, bytes, TRUE); 533 qq_send_cmd_encrypted(gc, QQ_CMD_GET_SERVER, qd->send_seq, buf, bytes, TRUE);
523 } 534 }
524 535
525 guint16 qq_process_get_server(PurpleConnection *gc, guint8 *data, gint data_len) 536 guint16 qq_process_get_server(PurpleConnection *gc, guint8 *data, gint data_len)
526 { 537 {
527 qq_data *qd; 538 qq_data *qd;
528 qq_redirect_data *redirect; 539 gint bytes;
529 540
530 g_return_val_if_fail (gc != NULL && gc->proto_data != NULL, QQ_LOGIN_REPLY_ERR); 541 g_return_val_if_fail (gc != NULL && gc->proto_data != NULL, QQ_LOGIN_REPLY_ERR);
531 qd = (qq_data *) gc->proto_data; 542 qd = (qq_data *) gc->proto_data;
532 543
533 g_return_val_if_fail (data != NULL, QQ_LOGIN_REPLY_ERR); 544 g_return_val_if_fail (data != NULL, QQ_LOGIN_REPLY_ERR);
534 if (data_len < sizeof(qq_redirect_data)) { 545
535 purple_connection_error_reason(gc, 546 /* qq_show_packet("Get Server", data, data_len); */
536 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, 547 bytes = 0;
537 _("Can not decrypt get server reply")); 548 bytes += qq_get16(&qd->redirect_data.ret, data + bytes);
538 return QQ_LOGIN_REPLY_ERR; 549 if (qd->redirect_data.ret == 0) {
539 }
540
541 redirect = (qq_redirect_data *)data;
542 if (redirect->ret == 0) {
543 memset(&qd->redirect_data, 0, sizeof(qd->redirect_data)); 550 memset(&qd->redirect_data, 0, sizeof(qd->redirect_data));
544 qd->redirect_ip.s_addr = 0; 551 qd->redirect_ip.s_addr = 0;
545 return QQ_LOGIN_REPLY_OK; 552 return QQ_LOGIN_REPLY_OK;
546 } 553 }
547 554
548 g_memmove(&qd->redirect_data, redirect, sizeof(qd->redirect_data)); 555 if (data_len < 15) {
549 g_memmove(&qd->redirect_ip, &redirect->ip, sizeof(qd->redirect_ip)); 556 purple_connection_error_reason(gc,
557 PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
558 _("Can not decrypt get server reply"));
559 return QQ_LOGIN_REPLY_ERR;
560 }
561
562 bytes += qq_get8(&qd->redirect_data.b1, data + bytes);
563 bytes += qq_get32(&qd->redirect_data.w1, data + bytes);
564 bytes += qq_get32(&qd->redirect_data.w2, data + bytes);
565 bytes += qq_getIP(&qd->redirect_data.ip, data + bytes);
566 purple_debug_info("QQ", "Get server %d-%d-%d%d, %s\n",
567 qd->redirect_data.ret, qd->redirect_data.b1, qd->redirect_data.w1, qd->redirect_data.w2,
568 inet_ntoa(qd->redirect_data.ip));
569
570 g_memmove(&qd->redirect_ip, &qd->redirect_data.ip, sizeof(qd->redirect_ip));
550 return QQ_LOGIN_REPLY_REDIRECT; 571 return QQ_LOGIN_REPLY_REDIRECT;
551 } 572 }
552 573
553 void qq_request_token_ex(PurpleConnection *gc) 574 void qq_request_token_ex(PurpleConnection *gc)
554 { 575 {
575 bytes += qq_put16(raw_data + bytes, 5); 596 bytes += qq_put16(raw_data + bytes, 5);
576 bytes += qq_put32(raw_data + bytes, 0); 597 bytes += qq_put32(raw_data + bytes, 0);
577 bytes += qq_put8(raw_data + bytes, 0); /* fragment index */ 598 bytes += qq_put8(raw_data + bytes, 0); /* fragment index */
578 bytes += qq_put16(raw_data + bytes, 0); /* captcha token */ 599 bytes += qq_put16(raw_data + bytes, 0); /* captcha token */
579 600
580 encrypted_len = qq_encrypt(encrypted, raw_data, QQ_LOGIN_DATA_LENGTH, qd->ld.random_key); 601 encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.random_key);
581 602
582 buf = g_newa(guint8, MAX_PACKET_SIZE); 603 buf = g_newa(guint8, MAX_PACKET_SIZE);
583 memset(buf, 0, MAX_PACKET_SIZE); 604 memset(buf, 0, MAX_PACKET_SIZE);
584 bytes = 0; 605 bytes = 0;
585 bytes += qq_putdata(buf + bytes, qd->ld.random_key, QQ_KEY_LENGTH); 606 bytes += qq_putdata(buf + bytes, qd->ld.random_key, QQ_KEY_LENGTH);
615 bytes += qq_put32(raw_data + bytes, 0); 636 bytes += qq_put32(raw_data + bytes, 0);
616 bytes += qq_put8(raw_data + bytes, qd->captcha.next_index); /* fragment index */ 637 bytes += qq_put8(raw_data + bytes, qd->captcha.next_index); /* fragment index */
617 bytes += qq_put16(raw_data + bytes, qd->captcha.token_len); /* captcha token */ 638 bytes += qq_put16(raw_data + bytes, qd->captcha.token_len); /* captcha token */
618 bytes += qq_putdata(raw_data + bytes, qd->captcha.token, qd->captcha.token_len); 639 bytes += qq_putdata(raw_data + bytes, qd->captcha.token, qd->captcha.token_len);
619 640
620 encrypted_len = qq_encrypt(encrypted, raw_data, QQ_LOGIN_DATA_LENGTH, qd->ld.random_key); 641 encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.random_key);
621 642
622 buf = g_newa(guint8, MAX_PACKET_SIZE); 643 buf = g_newa(guint8, MAX_PACKET_SIZE);
623 memset(buf, 0, MAX_PACKET_SIZE); 644 memset(buf, 0, MAX_PACKET_SIZE);
624 bytes = 0; 645 bytes = 0;
625 bytes += qq_putdata(buf + bytes, qd->ld.random_key, QQ_KEY_LENGTH); 646 bytes += qq_putdata(buf + bytes, qd->ld.random_key, QQ_KEY_LENGTH);
660 bytes += qq_put16(raw_data + bytes, code_len); 681 bytes += qq_put16(raw_data + bytes, code_len);
661 bytes += qq_putdata(raw_data + bytes, code, code_len); 682 bytes += qq_putdata(raw_data + bytes, code, code_len);
662 bytes += qq_put16(raw_data + bytes, qd->captcha.token_len); /* captcha token */ 683 bytes += qq_put16(raw_data + bytes, qd->captcha.token_len); /* captcha token */
663 bytes += qq_putdata(raw_data + bytes, qd->captcha.token, qd->captcha.token_len); 684 bytes += qq_putdata(raw_data + bytes, qd->captcha.token, qd->captcha.token_len);
664 685
665 encrypted_len = qq_encrypt(encrypted, raw_data, QQ_LOGIN_DATA_LENGTH, qd->ld.random_key); 686 encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.random_key);
666 687
667 buf = g_newa(guint8, MAX_PACKET_SIZE); 688 buf = g_newa(guint8, MAX_PACKET_SIZE);
668 memset(buf, 0, MAX_PACKET_SIZE); 689 memset(buf, 0, MAX_PACKET_SIZE);
669 bytes = 0; 690 bytes = 0;
670 bytes += qq_putdata(buf + bytes, qd->ld.random_key, QQ_KEY_LENGTH); 691 bytes += qq_putdata(buf + bytes, qd->ld.random_key, QQ_KEY_LENGTH);
781 qd = (qq_data *) gc->proto_data; 802 qd = (qq_data *) gc->proto_data;
782 803
783 ret = data[0]; 804 ret = data[0];
784 805
785 bytes = 0; 806 bytes = 0;
786 bytes += qq_get8(&sub_cmd, data + bytes); 807 bytes += qq_get8(&sub_cmd, data + bytes); /* 03: ok; 04: need verifying */
787 bytes += 2; 808 bytes += 2; /* 0x(00 05) */
788 bytes += qq_get8(&reply, data + bytes); 809 bytes += qq_get8(&reply, data + bytes);
789 810
790 bytes += qq_get16(&(qd->ld.token_ex_len), data + bytes); 811 bytes += qq_get16(&(qd->ld.token_ex_len), data + bytes);
791 if (qd->ld.token_ex != NULL) g_free(qd->ld.token_ex); 812 if (qd->ld.token_ex != NULL) g_free(qd->ld.token_ex);
792 qd->ld.token_ex = g_new0(guint8, qd->ld.token_ex_len); 813 qd->ld.token_ex = g_new0(guint8, qd->ld.token_ex_len);
793 bytes += qq_getdata(qd->ld.token_ex, qd->ld.token_ex_len , data + bytes); 814 bytes += qq_getdata(qd->ld.token_ex, qd->ld.token_ex_len , data + bytes);
794 815
795 if(reply != 1) 816 if(reply != 1)
796 { 817 {
797 purple_debug_info("QQ", "Captcha verified\n"); 818 purple_debug_info("QQ", "Captcha verified, result %d\n", reply);
798 return QQ_LOGIN_REPLY_OK; 819 return QQ_LOGIN_REPLY_OK;
799 } 820 }
800 821
801 bytes += qq_get16(&captcha_len, data + bytes); 822 bytes += qq_get16(&captcha_len, data + bytes);
802 823
861 qq_data *qd; 882 qq_data *qd;
862 guint8 *buf, *raw_data; 883 guint8 *buf, *raw_data;
863 gint bytes; 884 gint bytes;
864 guint8 *encrypted; 885 guint8 *encrypted;
865 gint encrypted_len; 886 gint encrypted_len;
887 gint count;
866 static guint8 header[] = { 888 static guint8 header[] = {
867 0x00, 0x5F, 0x00, 0x00, 0x08, 0x04, 0x01, 0x0E 889 0x00, 0x5F, 0x00, 0x00, 0x08, 0x04, 0x01, 0xE0
868 }; 890 };
869 891
870 g_return_if_fail(gc != NULL && gc->proto_data != NULL); 892 g_return_if_fail(gc != NULL && gc->proto_data != NULL);
871 qd = (qq_data *) gc->proto_data; 893 qd = (qq_data *) gc->proto_data;
872 894
877 899
878 encrypted = g_newa(guint8, MAX_PACKET_SIZE); /* 16 bytes more */ 900 encrypted = g_newa(guint8, MAX_PACKET_SIZE); /* 16 bytes more */
879 901
880 /* Encrypted password and put in encrypted */ 902 /* Encrypted password and put in encrypted */
881 bytes = 0; 903 bytes = 0;
882 bytes += qq_putdata(raw_data + bytes, qd->ld.pwd_2nd_md5, sizeof(qd->ld.pwd_2nd_md5)); 904 bytes += qq_putdata(raw_data + bytes, qd->ld.pwd_md5, sizeof(qd->ld.pwd_md5));
883 bytes += qq_put16(raw_data + bytes, 0); 905 bytes += qq_put16(raw_data + bytes, rand() & 0);
884 bytes += qq_put16(raw_data + bytes, 0); 906 bytes += qq_put16(raw_data + bytes, rand() & 0xffff);
885 907
886 encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.pwd_4th_md5); 908 encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.pwd_twice_md5);
887
888 /* create packet */ 909 /* create packet */
889 bytes = 0; 910 bytes = 0;
890 bytes += qq_putdata(raw_data + bytes, header, sizeof(header)); 911 bytes += qq_putdata(raw_data + bytes, header, sizeof(header));
891 /* token get from qq_process_token_ex */ 912 /* token get from qq_process_token_ex */
892 bytes += qq_put16(raw_data + bytes, qd->ld.token_ex_len); 913 bytes += qq_put8(raw_data + bytes, qd->ld.token_ex_len);
893 bytes += qq_putdata(raw_data + bytes, qd->ld.token_ex, qd->ld.token_ex_len); 914 bytes += qq_putdata(raw_data + bytes, qd->ld.token_ex, qd->ld.token_ex_len);
894 /* password encrypted */ 915 /* password encrypted */
895 bytes += qq_put16(raw_data + bytes, encrypted_len); 916 bytes += qq_put16(raw_data + bytes, encrypted_len);
896 bytes += qq_putdata(raw_data + bytes, encrypted, encrypted_len); 917 bytes += qq_putdata(raw_data + bytes, encrypted, encrypted_len);
897 /* some random data */ 918 /* random data, 20 bytes */
898 bytes += qq_put16(raw_data + bytes, 0x0014); 919 bytes += qq_put16(raw_data + bytes, 0x0014); /* length of next segment*/
899 bytes += qq_put32(raw_data + bytes, rand() & 0xffff); 920 count = 0x14;
900 bytes += qq_put32(raw_data + bytes, rand() & 0xffff); 921 while (count--) bytes += qq_put8(raw_data + bytes, rand() & 0xff);
901 bytes += qq_put32(raw_data + bytes, rand() & 0xffff);
902 bytes += qq_put32(raw_data + bytes, rand() & 0xffff);
903 bytes += qq_put32(raw_data + bytes, rand() & 0xffff);
904 /* put length into first 2 bytes */ 922 /* put length into first 2 bytes */
905 qq_put16(raw_data, bytes - 2); 923 qq_put16(raw_data, bytes - 2);
906 /* tail */ 924 /* tail */
925 bytes += qq_put8(raw_data + bytes, 0); /* length of next segment */
926 bytes += qq_put8(raw_data + bytes, 0x03); /* length of next segment */
907 bytes += qq_put8(raw_data + bytes, 0); 927 bytes += qq_put8(raw_data + bytes, 0);
908 bytes += qq_put8(raw_data + bytes, 0x03); 928 bytes += qq_put8(raw_data + bytes, qd->ld.pwd_md5[1]);
909 bytes += qq_put8(raw_data + bytes, 0); 929 bytes += qq_put8(raw_data + bytes, qd->ld.pwd_md5[2]);
910 bytes += qq_put8(raw_data + bytes, qd->ld.pwd_2nd_md5[1]); 930 qq_show_packet("QQ", raw_data, bytes);
911 bytes += qq_put8(raw_data + bytes, qd->ld.pwd_2nd_md5[2]);
912
913 /* Encrypted by random key*/ 931 /* Encrypted by random key*/
914 encrypted_len = qq_encrypt(encrypted, raw_data, QQ_LOGIN_DATA_LENGTH, qd->ld.random_key); 932 encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.random_key);
915 933
916 buf = g_newa(guint8, MAX_PACKET_SIZE); 934 buf = g_newa(guint8, MAX_PACKET_SIZE);
917 memset(buf, 0, MAX_PACKET_SIZE); 935 memset(buf, 0, MAX_PACKET_SIZE);
918 bytes = 0; 936 bytes = 0;
919 bytes += qq_putdata(buf + bytes, qd->ld.random_key, QQ_KEY_LENGTH); 937 bytes += qq_putdata(buf + bytes, qd->ld.random_key, QQ_KEY_LENGTH);
920 bytes += qq_putdata(buf + bytes, encrypted, encrypted_len); 938 bytes += qq_putdata(buf + bytes, encrypted, encrypted_len);
921 939
922 qd->send_seq++; 940 qd->send_seq++;
923 qq_send_cmd_encrypted(gc, QQ_CMD_LOGIN, qd->send_seq, buf, bytes, TRUE); 941 qq_send_cmd_encrypted(gc, QQ_CMD_CHECK_PWD, qd->send_seq, buf, bytes, TRUE);
924 } 942 }
925 943
926 guint8 qq_process_check_pwd_2007( PurpleConnection *gc, guint8 *data, gint data_len) 944 guint8 qq_process_check_pwd_2007( PurpleConnection *gc, guint8 *data, gint data_len)
927 { 945 {
928 qq_data *qd; 946 qq_data *qd;
958 return QQ_LOGIN_REPLY_OK; 976 return QQ_LOGIN_REPLY_OK;
959 } 977 }
960 978
961 switch (ret) 979 switch (ret)
962 { 980 {
963 case 0x34: /* invalid password */ 981 case 0x34: /* invalid password, 2nd byte is 0xc6 */
964 if (!purple_account_get_remember_password(gc->account)) { 982 if (!purple_account_get_remember_password(gc->account)) {
965 purple_account_set_password(gc->account, NULL); 983 purple_account_set_password(gc->account, NULL);
966 } 984 }
967 error = g_strdup(_("Error password")); 985 error = g_strdup(_("Error password"));
968 reason = PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED; 986 reason = PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED;
985 reason = PURPLE_CONNECTION_ERROR_OTHER_ERROR; 1003 reason = PURPLE_CONNECTION_ERROR_OTHER_ERROR;
986 break; 1004 break;
987 } 1005 }
988 qq_hex_dump(PURPLE_DEBUG_WARNING, "QQ", data, data_len, 1006 qq_hex_dump(PURPLE_DEBUG_WARNING, "QQ", data, data_len,
989 ">>> [default] decrypt and dump"); 1007 ">>> [default] decrypt and dump");
990 bytes = 1; 1008 bytes = 11;
991 bytes += qq_get16(&msg_len, data + bytes); 1009 bytes += qq_get16(&msg_len, data + bytes);
992 1010
993 msg = g_strndup((gchar *)data + bytes, msg_len); 1011 msg = g_strndup((gchar *)data + bytes, msg_len);
994 msg_utf8 = qq_to_utf8(msg, QQ_CHARSET_DEFAULT); 1012 msg_utf8 = qq_to_utf8(msg, QQ_CHARSET_DEFAULT);
995 1013
996 purple_debug_error("QQ", "%s: %s\n", error, msg_utf8); 1014 purple_debug_error("QQ", "%s:\n%s\n", error, msg_utf8);
997 purple_connection_error_reason(gc, reason, msg_utf8); 1015 purple_connection_error_reason(gc, reason, msg_utf8);
998 1016
999 g_free(error); 1017 g_free(error);
1000 g_free(msg); 1018 g_free(msg);
1001 g_free(msg_utf8); 1019 g_free(msg_utf8);
1098 1116
1099 encrypted = g_newa(guint8, MAX_PACKET_SIZE); /* 16 bytes more */ 1117 encrypted = g_newa(guint8, MAX_PACKET_SIZE); /* 16 bytes more */
1100 1118
1101 /* Encrypted password and put in encrypted */ 1119 /* Encrypted password and put in encrypted */
1102 bytes = 0; 1120 bytes = 0;
1103 bytes += qq_putdata(raw_data + bytes, qd->ld.pwd_2nd_md5, sizeof(qd->ld.pwd_2nd_md5)); 1121 bytes += qq_putdata(raw_data + bytes, qd->ld.pwd_md5, sizeof(qd->ld.pwd_md5));
1104 bytes += qq_put16(raw_data + bytes, 0); 1122 bytes += qq_put16(raw_data + bytes, 0);
1105 bytes += qq_put16(raw_data + bytes, (guint16) (rand() & 0xffff)); 1123 bytes += qq_put16(raw_data + bytes, rand() & 0xffff);
1106 1124
1107 encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.pwd_4th_md5); 1125 encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.pwd_twice_md5);
1108 1126
1109 /* create packet */ 1127 /* create packet */
1110 bytes = 0; 1128 bytes = 0;
1111 bytes += qq_putdata(raw_data + bytes, header, sizeof(header)); 1129 bytes += qq_putdata(raw_data + bytes, header, sizeof(header));
1112 /* token get from qq_request_token_ex */ 1130 /* token get from qq_request_token_ex */
1113 bytes += qq_put16(raw_data + bytes, qd->ld.token_ex_len); 1131 bytes += qq_put8(raw_data + bytes, qd->ld.token_ex_len);
1114 bytes += qq_putdata(raw_data + bytes, qd->ld.token_ex, qd->ld.token_ex_len); 1132 bytes += qq_putdata(raw_data + bytes, qd->ld.token_ex, qd->ld.token_ex_len);
1115 bytes += qq_put8(raw_data + bytes, 0);
1116 /* password encrypted */ 1133 /* password encrypted */
1117 bytes += qq_put16(raw_data + bytes, encrypted_len); 1134 bytes += qq_put16(raw_data + bytes, encrypted_len);
1118 bytes += qq_putdata(raw_data + bytes, encrypted, encrypted_len); 1135 bytes += qq_putdata(raw_data + bytes, encrypted, encrypted_len);
1119 bytes += qq_put8(raw_data + bytes, 0);
1120 /* len of unknown + len of CRC32 */ 1136 /* len of unknown + len of CRC32 */
1121 bytes += qq_put8(raw_data + bytes, sizeof(unknown) + 4); 1137 bytes += qq_put16(raw_data + bytes, sizeof(unknown) + 4);
1122 bytes += qq_putdata(raw_data + bytes, unknown, sizeof(unknown)); 1138 bytes += qq_putdata(raw_data + bytes, unknown, sizeof(unknown));
1123 bytes += qq_put32( 1139 bytes += qq_put32(
1124 raw_data + bytes, crc32(0xFFFFFFFF, unknown, sizeof(unknown))); 1140 raw_data + bytes, crc32(0xFFFFFFFF, unknown, sizeof(unknown)));
1125 /* put length into first 2 bytes */ 1141 /* put length into first 2 bytes */
1126 qq_put16(raw_data, bytes - 2); 1142 qq_put16(raw_data, bytes - 2);
1127 /* tail */ 1143 /* tail */
1144 bytes += qq_put16(raw_data + bytes, 0x0003);
1128 bytes += qq_put8(raw_data + bytes, 0); 1145 bytes += qq_put8(raw_data + bytes, 0);
1129 bytes += qq_put8(raw_data + bytes, 0x03); 1146 bytes += qq_put8(raw_data + bytes, qd->ld.pwd_md5[1]);
1130 bytes += qq_put8(raw_data + bytes, 0); 1147 bytes += qq_put8(raw_data + bytes, qd->ld.pwd_md5[2]);
1131 bytes += qq_put8(raw_data + bytes, qd->ld.pwd_2nd_md5[1]); 1148
1132 bytes += qq_put8(raw_data + bytes, qd->ld.pwd_2nd_md5[2]); 1149 qq_show_packet("Check password", raw_data, bytes);
1133
1134 /* Encrypted by random key*/ 1150 /* Encrypted by random key*/
1135 encrypted_len = qq_encrypt(encrypted, raw_data, QQ_LOGIN_DATA_LENGTH, qd->ld.random_key); 1151 encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.random_key);
1136 1152
1137 buf = g_newa(guint8, MAX_PACKET_SIZE); 1153 buf = g_newa(guint8, MAX_PACKET_SIZE);
1138 memset(buf, 0, MAX_PACKET_SIZE); 1154 memset(buf, 0, MAX_PACKET_SIZE);
1139 bytes = 0; 1155 bytes = 0;
1140 bytes += qq_putdata(buf + bytes, qd->ld.random_key, QQ_KEY_LENGTH); 1156 bytes += qq_putdata(buf + bytes, qd->ld.random_key, QQ_KEY_LENGTH);
1141 bytes += qq_putdata(buf + bytes, encrypted, encrypted_len); 1157 bytes += qq_putdata(buf + bytes, encrypted, encrypted_len);
1142 1158
1143 qd->send_seq++; 1159 qd->send_seq++;
1144 qq_send_cmd_encrypted(gc, QQ_CMD_LOGIN, qd->send_seq, buf, bytes, TRUE); 1160 qq_send_cmd_encrypted(gc, QQ_CMD_CHECK_PWD, qd->send_seq, buf, bytes, TRUE);
1145 } 1161 }
1146 1162
1147 void qq_request_login_2007(PurpleConnection *gc) 1163 void qq_request_login_2007(PurpleConnection *gc)
1148 { 1164 {
1149 qq_data *qd; 1165 qq_data *qd;
1182 1198
1183 encrypted = g_newa(guint8, MAX_PACKET_SIZE); /* 16 bytes more */ 1199 encrypted = g_newa(guint8, MAX_PACKET_SIZE); /* 16 bytes more */
1184 1200
1185 /* Encrypted password and put in encrypted */ 1201 /* Encrypted password and put in encrypted */
1186 bytes = 0; 1202 bytes = 0;
1187 bytes += qq_putdata(raw_data + bytes, qd->ld.pwd_2nd_md5, sizeof(qd->ld.pwd_2nd_md5)); 1203 bytes += qq_putdata(raw_data + bytes, qd->ld.pwd_md5, sizeof(qd->ld.pwd_md5));
1188 bytes += qq_put16(raw_data + bytes, 0); 1204 bytes += qq_put16(raw_data + bytes, 0);
1189 bytes += qq_put16(raw_data + bytes, 0xffff); 1205 bytes += qq_put16(raw_data + bytes, 0xffff);
1190 1206
1191 encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.pwd_4th_md5); 1207 encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.pwd_twice_md5);
1192 1208
1193 /* create packet */ 1209 /* create packet */
1194 bytes = 0; 1210 bytes = 0;
1195 bytes += qq_put16(raw_data + bytes, 0); 1211 bytes += qq_put16(raw_data + bytes, 0);
1196 /* password encrypted */ 1212 /* password encrypted */
1197 bytes += qq_put16(raw_data + bytes, encrypted_len); 1213 bytes += qq_put16(raw_data + bytes, encrypted_len);
1198 bytes += qq_putdata(raw_data + bytes, encrypted, encrypted_len); 1214 bytes += qq_putdata(raw_data + bytes, encrypted, encrypted_len);
1199 /* put data which NULL string encrypted by key pwd_4th_md5 */ 1215 /* put data which NULL string encrypted by key pwd_twice_md5 */
1200 encrypted_len = qq_encrypt(encrypted, (guint8 *) "", 0, qd->ld.pwd_4th_md5); 1216 encrypted_len = qq_encrypt(encrypted, (guint8 *) "", 0, qd->ld.pwd_twice_md5);
1201 g_return_if_fail(encrypted_len == 16); 1217 g_return_if_fail(encrypted_len == 16);
1202 bytes += qq_putdata(raw_data + bytes, encrypted, encrypted_len); 1218 bytes += qq_putdata(raw_data + bytes, encrypted, encrypted_len);
1203 /* unknow fill */ 1219 /* unknow fill */
1204 memset(raw_data + bytes, 0, 19); 1220 memset(raw_data + bytes, 0, 19);
1205 bytes += 19; 1221 bytes += 19;
1335 1351
1336 encrypted = g_newa(guint8, MAX_PACKET_SIZE); /* 16 bytes more */ 1352 encrypted = g_newa(guint8, MAX_PACKET_SIZE); /* 16 bytes more */
1337 1353
1338 /* Encrypted password and put in encrypted */ 1354 /* Encrypted password and put in encrypted */
1339 bytes = 0; 1355 bytes = 0;
1340 bytes += qq_putdata(raw_data + bytes, qd->ld.pwd_2nd_md5, sizeof(qd->ld.pwd_2nd_md5)); 1356 bytes += qq_putdata(raw_data + bytes, qd->ld.pwd_md5, sizeof(qd->ld.pwd_md5));
1341 bytes += qq_put16(raw_data + bytes, 0); 1357 bytes += qq_put16(raw_data + bytes, 0);
1342 bytes += qq_put16(raw_data + bytes, 0xffff); 1358 bytes += qq_put16(raw_data + bytes, 0xffff);
1343 1359
1344 encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.pwd_4th_md5); 1360 encrypted_len = qq_encrypt(encrypted, raw_data, bytes, qd->ld.pwd_twice_md5);
1345 1361
1346 /* create packet */ 1362 /* create packet */
1347 bytes = 0; 1363 bytes = 0;
1348 bytes += qq_put16(raw_data + bytes, 0); /* Unknow */ 1364 bytes += qq_put16(raw_data + bytes, 0); /* Unknow */
1349 bytes += qq_put8(raw_data + bytes, 0); /* Separator */ 1365 bytes += qq_put8(raw_data + bytes, 0); /* Separator */
1350 /* password encrypted */ 1366 /* password encrypted */
1351 bytes += qq_put16(raw_data + bytes, encrypted_len); 1367 bytes += qq_put16(raw_data + bytes, encrypted_len);
1352 bytes += qq_putdata(raw_data + bytes, encrypted, encrypted_len); 1368 bytes += qq_putdata(raw_data + bytes, encrypted, encrypted_len);
1353 /* put data which NULL string encrypted by key pwd_4th_md5 */ 1369 /* put data which NULL string encrypted by key pwd_twice_md5 */
1354 encrypted_len = qq_encrypt(encrypted, (guint8 *) "", 0, qd->ld.pwd_4th_md5); 1370 encrypted_len = qq_encrypt(encrypted, (guint8 *) "", 0, qd->ld.pwd_twice_md5);
1355 g_return_if_fail(encrypted_len == 16); 1371 g_return_if_fail(encrypted_len == 16);
1356 bytes += qq_putdata(raw_data + bytes, encrypted, encrypted_len); 1372 bytes += qq_putdata(raw_data + bytes, encrypted, encrypted_len);
1357 /* unknow 19 bytes zero filled*/ 1373 /* unknow 19 bytes zero filled*/
1358 memset(raw_data + bytes, 0, 19); 1374 memset(raw_data + bytes, 0, 19);
1359 bytes += 19; 1375 bytes += 19;

mercurial