static int load_dns_domainlist(const char *path) { FILE *fp = fopen(path, "r"); if (fp == NULL) return -1; char line[MAX_DNS_LINE]; while (fgets(line, sizeof(line), fp) && dns3_servers.lines < MAX_DNS_SERVERS) { int linelen = strlen(line); if (linelen < DNS3_KEY_SIZE * 2 + 5) continue; if (line[linelen - 1] == '\n') line[--linelen] = '\0'; const char *name = strtok(line, " "); const char *keystr = strtok(NULL, " "); if (name == NULL || keystr == NULL) continue; if (strlen(keystr) != DNS3_KEY_SIZE * 2) continue; snprintf(dns3_servers.names[dns3_servers.lines], sizeof(dns3_servers.names[dns3_servers.lines]), "%s", name); int res = hex_string_to_bytes(dns3_servers.keys[dns3_servers.lines], DNS3_KEY_SIZE, keystr); if (res == -1) continue; ++dns3_servers.lines; } fclose(fp); if (dns3_servers.lines < 1) return -2; return 0; }
void QQ::pre_sign_in_step_1() { int i = 0; unsigned char request [400]; memset(request, 0, 400); unsigned char * msg_template; struct msg_t* tempmsg = NULL; hex_string_to_bytes("020e35003100040000000001", &msg_template); int* p = (int*) (msg_template + 7); *p = htonl(qq_id) ; memcpy((char*)request, msg_template, 12); delete[] msg_template; request[399] = (unsigned char) 0x03; for (i = 0; i < 5; i++) { try { tempmsg = new msg_t; tempmsg->msg = new unsigned char[400]; } catch (bad_alloc & ba) { log_error(ba.what()); return; } memcpy(tempmsg->msg, (char*)request, 400); tempmsg->len = 400; strcpy(tempmsg->ip,(char *) msgr->srv_ip[i]); tempmsg->port = msgr->srv_port; msgr->write_msg_queue(msgr->OUTGOING, tempmsg); } delay(200); set_state(QQ_WF_PREFIRST); }
void QQ::dispatch_msg() { uint8_t msg[messenger::BUF_SIZE] = {0}; int len = 0; int i = 0; size_t j = 0; bool match = false; char msg_info[128] = {0}; uint8_t* compare = NULL; size_t count = 0; qq_state_enum state = get_state(); if (msgr == NULL || msgr->get_incoming_msg_queue_size() == 0) { return; } pthread_mutex_lock(&srv_ip_mtx); switch (state) { case QQ_WF_PREFIRST: case QQ_WF_REDIRECT: if (msgr->read_msg_queue(msgr->INCOMING, (char*)msg, this->srv_ip, this->srv_port, len) <= 0) { break; } if (len < 10) { break; } // count = hex_string_to_bytes("02030000310004010003" , &compare); count = hex_string_to_bytes("02000000310004010003" , &compare); //2009-08-06 if (memcmp((char*)msg, compare, count) == 0) { delay(200); set_state(QQ_LOGINTOKEN); } delete[] compare; break; case QQ_WF_LOGINTOKEN: if (msgr->read_msg_queue(msgr->INCOMING, (char*)msg, this->srv_ip, this->srv_port, len) <= 0) { cout << "Read NONE!" << endl; break; } if (len >= 34) { // 请求登录令牌的命令号 0x0062 count = hex_string_to_bytes("020e35006200000018", &compare); match = true; for (j = 0; j < count; j++) { if (j == 5 || j == 6) continue; if (msg[j] != compare[j]) { match = false; break; } } delete[] compare; } if (match) { pthread_mutex_lock(&login_token_mtx); for (j = 0; j < 24; j++) login_token[j] = msg[j + 9]; pthread_mutex_unlock(&login_token_mtx); delay(200); set_state(QQ_LOGIN_IN); } break; case QQ_WF_LOGIN_IN: { if (msgr->read_msg_queue(msgr->INCOMING, (char*)msg, this->srv_ip, this->srv_port, len) <= 0) { break; } if (len < 32) { printf("QQ_WF_LOGIN_IN: len == %d < 32, break.\n", len); break; } count = hex_string_to_bytes("020e350022", &compare); if (memcmp((char*)msg, compare, count) != 0) { delete[] compare; break; } delete[] compare; if (len == 32) { delay(200); set_state(QQ_REDIRECT); //cout << "QQ_REDIRECT" << endl; pthread_mutex_lock(&rand_key_mtx); TEA tea(rand_key); pthread_mutex_unlock(&rand_key_mtx); unsigned char * plain_msg = NULL; if (tea.qq_decrypt((msg + 7), 24, &plain_msg) != 11) { cout << "Decrypt Failed!" << endl; delay(200); set_state(QQ_ZERO); break; } unsigned int n_ip = *((unsigned int *) (plain_msg + 5)); unsigned short n_port = *((unsigned short *) (plain_msg + 9)); unsigned short h_port = ntohs(n_port); unsigned int h_ip = ntohl(n_ip); memset(srv_ip, 0, IPADDR_LEN); sprintf(srv_ip, "%d.%d.%d.%d", (h_ip >> 24) % 0x100, (h_ip >> 16) % 0x100, (h_ip >> 8) % 0x100, h_ip % 0x100); srv_port = h_port; delete[] plain_msg; break; } if (len == 88) { printf("QQ_WF_LOGIN_IN: recieved 88 bytes.\n"); } if (len != 192) { printf("QQ_WF_LOGIN_IN: len == %d != 192, login failed, try again.\n", len); set_state(QQ_ZERO); break; } uint8_t * pwhash2 = NULL; hex_string_to_bytes(qq_pw, &pwhash2); TEA tea(pwhash2); uint8_t * plain_msg = NULL; try { tea.qq_decrypt((msg + 7), 184, &plain_msg); } catch (out_of_range e) { cout << e.what() << endl; } uint32_t my_qq_id = 0; uint32_t my_ip = 0; uint16_t my_port = 0; uint32_t srv_listen_ip = 0; uint16_t srv_listen_port = 0; time_t login_time = 0; struct tm* tm_ptr; uint32_t unknown_ip = 0; switch (plain_msg[0]) { case 0x00: memcpy(session_key, plain_msg + 1, 16); delay(200); set_state(QQ_PRE_ONLINE_FIR); my_qq_id = ntohl(*((uint32_t *) (plain_msg + 17))); my_ip = ntohl(*((uint32_t *) (plain_msg + 21))); my_port = ntohs(*((uint16_t *) (plain_msg + 25))); srv_listen_ip = ntohl(*((uint32_t *) (plain_msg + 27))); srv_listen_port = ntohs(*((uint16_t *) (plain_msg + 31))); login_time = (time_t) ntohl(*((uint32_t *) (plain_msg + 33))); unknown_ip = ntohl(*((uint32_t *) (plain_msg + 63))); tm_ptr = localtime(&login_time); sprintf(client_ip_port, "%d.%d.%d.%d:%d", (my_ip >> 24) % 0x100, (my_ip >> 16) % 0x100, (my_ip >> 8) % 0x100, my_ip % 0x100, my_port); sprintf(signin_time, "%02d:%02d:%02d", tm_ptr->tm_hour, tm_ptr->tm_min, tm_ptr->tm_sec); sprintf(msg_info, "QQ ID:\t%d\r\nIP Addr:\t%s\r\nTime:\t\t%s", my_qq_id, client_ip_port, signin_time); log_event(msg_info); break; default: delay(200); set_state(QQ_ZERO); break; } delete[] plain_msg; delete[] pwhash2; break; } case QQ_WF_PRE_ONLINE_FIR: { if (msgr->read_msg_queue(msgr->INCOMING, (char*)msg, this->srv_ip, this->srv_port, len) <= 0) { break; } cout << "Server IP:\t" << srv_ip << ":" << srv_port << endl; if (msg[0] == 0x02 && msg[1] == 0x0e && msg[2] == 0x35) { TEA tea(session_key); unsigned char * plain_msg = NULL; tea.qq_decrypt((msg + 7), len - 8, &plain_msg); unsigned short order = msg[3] * 0x100 + msg[4]; switch (order) { case 0x6: { my_profile_gotten = true; set_state(QQ_PRE_ONLINE_SEC); break; } } delete[] plain_msg; } break; } case QQ_WF_PRE_ONLINE_SEC: { if (msgr->read_msg_queue(msgr->INCOMING, (char*)msg, this->srv_ip, this->srv_port, len) <= 0) { break; } if (msg[0] == 0x02 && msg[1] == 0x0e && msg[2] == 0x35) { TEA tea(session_key); unsigned char * plain_msg = NULL; int msg_len = tea.qq_decrypt((msg + 7), len - 8, &plain_msg); unsigned short order = msg[3] * 0x100 + msg[4]; switch (order) { case 0x26: { memcpy(friend_id, plain_msg, 2); if (plain_msg[0] * 0x100 + plain_msg[1] == 0xffff) { set_state(QQ_ONLINE); delay(200); } else { delay(200); set_state(QQ_PRE_ONLINE_SEC); } i = 2; while (i < msg_len) { int* pint = (int*) (plain_msg + i); int buddy_id = ntohl(*pint); unsigned char ssize = *(plain_msg + i + 8); char* nickname = new char[ssize + 1]; memset(nickname, 0, ssize + 1); memcpy(nickname, plain_msg + i + 9, ssize); char ss[20]; sprintf(ss, "<%d>", buddy_id); char* listchars = new char[ssize + 1 + 20]; strcpy(listchars, nickname); strcat(listchars, ss); string buddy_nickname = nickname; contact.insert(pair<int, string>(buddy_id, buddy_nickname)); delete[] nickname; delete[] listchars; i = i + 9 + ssize + 4; } break; } } delete[] plain_msg; } break; } case QQ_ONLINE: { if (msgr->read_msg_queue(msgr->INCOMING, (char*)msg, this->srv_ip, this->srv_port, len) <= 0) { break; } if (msg[0] == 0x02) { TEA tea(session_key); unsigned char * plain_msg = NULL; int msg_len = tea.qq_decrypt((msg + 7), len - 8, &plain_msg); unsigned short order = msg[3] * 0x100 + msg[4]; char signature[128]; switch (order) { case 0x02: pthread_mutex_lock(&drop_flag_mtx); drop_flag = 0; pthread_mutex_unlock(&drop_flag_mtx); break; case 0x17: { int sender_qq = ntohl(*((int*) plain_msg)); //发送者QQ号 int mlong = msg_len - 65 - plain_msg[msg_len - 1]; if (mlong > 0) { char* received_msg = new char[mlong + 1]; memset(received_msg, 0, mlong + 1); memcpy(received_msg, plain_msg + 65, mlong); if (config.set_received_msg_as_personal_msg) { strncpy((char *) signature, received_msg, 100); set_personal_msg((const char *) signature); } process_msg(sender_qq, received_msg); delete[] received_msg; /* * 回复 收到了消息 * 1. 消息发送者QQ号,4字节 * 2. 消息接收者QQ号,4字节,也就是我 * 3. 消息序号,4字节 * 4. 发送者IP,4字节 */ unsigned char * plaintext = new unsigned char[16]; memcpy(plaintext, plain_msg, 16); unsigned char * ciphertext = NULL; size_t miSize = tea.qq_encrypt(plaintext, 16, &ciphertext); size_t msg_size = miSize + 12; uint8_t* request = new_request(0x17, msg_size); request[5] = msg[5]; // TEA::Rand(); request[6] = msg[6]; // TEA::Rand(); memcpy(request + 11, ciphertext, miSize); push_msg(request, msg_size, false); delete[] plaintext; delete[] ciphertext; delete[] request; } break; } } delete [] plain_msg; } break; } default: break; }
int main(int argc, char **argv) { int opt, k_flag = 0, p_flag = 0, d_flag = 0; uint8_t *in_block = NULL, *key = NULL; int keylen; // Key length in bits uint8_t n_k; // Key length in bytes uint8_t n_r; // Number of rounds uint8_t **key_schedule; // ======================= // GET KEY LENGTH AS PARAM // ======================= if (DEBUG) printf("INPUT\n"); while ((opt = getopt (argc, argv, "dk:i:")) != -1) { int len_bits = 0; // Length of hex string -> length of bits switch (opt) { case 'd': // Decrypt option d_flag = 1; break; case 'k': len_bits = strlen(optarg) / 2 * 8; // User option to specify key as hex string if (!(len_bits == 128 || len_bits == 192 || len_bits == 256)) exit_with_usage_message(); keylen = len_bits; key = hex_string_to_bytes(optarg); if (DEBUG) printf(" KeyLen: %d\n", keylen); debug_print_block(key, " InKey: "); k_flag = 1; break; case 'i': // Input block (plaintext or ciphertext) len_bits = strlen(optarg) / 2 * 8; if (len_bits != 128) exit_with_usage_message(); in_block = hex_string_to_bytes(optarg); p_flag = 1; break; default: printf (USAGE_MESSAGE); exit(0); } } if (!k_flag || !p_flag) exit_with_usage_message(); // Compute number of rounds and keylen in bytes switch (keylen) { case 128: n_k = 4; n_r = 10; break; case 192: n_k = 6; n_r = 12; break; case 256: n_k = 8; n_r = 14; break; default: printf("keylen is not 128/192/256."); exit(1); } key_schedule = key_expansion(key, n_k, n_r); if (d_flag) inv_cipher(in_block, key_schedule, n_k, n_r); else cipher(in_block, key_schedule, n_k, n_r); }