void prot_login_send_info_reply( struct qqclient* qq, qqpacket* p ) { bytebuffer *buf = p->buf; // hex_dump( buf->data, buf->len ); uchar result = get_byte( buf ); if( result != 0 ) { DBG("login result = %d", result ); qqclient_set_process( qq, P_ERROR ); return; } get_data( buf, qq->data.session_key, sizeof(qq->data.session_key) ); DBG("session key: " ); hex_dump( qq->data.session_key, 16 ); if( qq->number != get_int( buf ) ) { DBG("qq->number is wrong?"); } qq->client_ip = get_int( buf ); qq->client_port = get_word( buf ); qq->local_ip = get_int( buf ); qq->local_port = get_word( buf ); qq->login_time = get_int( buf ); get_byte( buf ); //03 get_byte( buf ); //mode buf->pos += 96; qq->last_login_time = get_int( buf ); //prepare IM key uchar data[20]; *(uint*)data = htonl( qq->number ); memcpy( data+4, qq->data.session_key, 16 ); //md5 md5_state_t mst; md5_init( &mst ); md5_append( &mst, (md5_byte_t*)data, 20 ); md5_finish( &mst, (md5_byte_t*)qq->data.im_key ); // time_t t; t = CN_TIME( qq->last_login_time ); DBG("last login time: %s", ctime( &t ) ); qqclient_set_process( qq, P_LOGIN ); //get information prot_user_change_status( qq ); prot_user_get_level( qq ); #ifndef NO_GROUP_INFO group_update_list( qq ); #endif #ifndef NO_BUDDY_INFO buddy_update_list( qq ); #endif #ifndef NO_QUN_INFO qun_update_all( qq ); #endif qq->online_clock = 0; }
EXPORT uint libqq_refresh( qqclient* qq ) { char event[16]; qqclient_set_process( qq, qq->process ); sprintf( event, "status^$%d", qq->mode ); qqclient_put_event( qq, event ); buddy_put_event( qq ); group_put_event( qq ); qun_put_event( qq ); qqclient_set_process( qq, qq->process ); return qq->number; }
EXPORT uint webqq_get_number( user* u ) { qqclient* qq = (qqclient*)u->qq; char event[16]; qqclient_set_process( qq, qq->process ); sprintf( event, "status^$%d", qq->mode ); qqclient_put_event( qq, event ); buddy_put_event( qq ); group_put_event( qq ); qun_put_event( qq ); qqclient_set_process( qq, qq->process ); return qq->number; }
static void process_sys_im( struct qqclient* qq, qqpacket* p, qqmessage* msg ) { bytebuffer *buf = p->buf; msg->msg_time = time(NULL); uchar content_type; content_type = get_byte( buf ); uchar len = get_byte( buf ); get_data( buf, (uchar*)msg->msg_content, len ); msg->msg_content[len] = 0; buddy_msg_callback( qq, msg->from, msg->msg_time, msg->msg_content ); if( strstr( msg->msg_content, "另一地点登录" ) != NULL ){ qqclient_set_process( qq, P_BUSY ); }else{ qqclient_set_process( qq, P_ERROR ); } DBG("sysim(type:%x): %s", content_type, msg->msg_content ); }
void prot_login_verify_reply( struct qqclient* qq, qqpacket* p ) { bytebuffer *buf = p->buf; get_word( buf ); //length or sth.. int code = get_byte( buf ); switch( code ) { case 0x00: get_token( buf, &qq->data.login_info_token ); qq->data.login_info_unknown1 = get_int( buf ); qq->server_time = get_int( buf ); get_token( buf, &qq->data.login_info_data ); get_token( buf, &qq->data.login_info_magic ); get_data( buf, qq->data.login_info_key1, 16 ); get_word( buf ); //00 00 get_data( buf, qq->data.login_info_key3, 16 ); get_word( buf ); //00 00 //success prot_login_get_info( qq ); return; case 0x33: case 0x51: // qqclient_set_process( qq, P_DENIED ); DBG("Denied."); break; case 0xBF: DBG("No this number."); case 0x34: DBG("Wrong password."); qqclient_set_process( qq, P_WRONGPASS ); break; default: hex_dump( buf->data, buf->len ); break; } buf->pos = 11; uchar len = get_word( buf ); char msg[256]; get_data( buf, (uchar*)msg, len ); msg[len] = 0; DBG( msg ); //failed }
void prot_login_request_reply( struct qqclient* qq, qqpacket* p ) { bytebuffer *buf = p->buf; token answer_token; token png_token; uchar next = 0; uchar result = get_byte( buf ); //03: ok 04: need verifying get_byte( buf ); //00 get_byte( buf ); //05 uchar png_data = get_byte( buf ); get_int( buf ); //需要验证码时为00 00 01 23,不需要时为全0 get_token( buf, &answer_token ); if( png_data == 1 ) { //there's data for the png picture int len; len = get_word( buf ); uchar* data; NEW( data, len ); if( !data ) return; get_data( buf, data, len ); get_byte( buf ); //00 next = get_byte( buf ); char path[PATH_LEN]; sprintf( path, "%s/%u.png", qq->verify_dir, qq->number ); FILE *fp; if( next ) { fp = fopen( path, "wb" ); } else { fp = fopen( path, "ab" ); DBG("got png at %s", path ); } if( fp ) { fwrite( data, len, 1, fp ); fclose( fp ); } DEL( data ); get_token( buf, &png_token ); } //parse the data we got if( png_data ) { if( next ) { prot_login_request( qq, &png_token, 0, 1 ); } else { qq->data.verify_token = answer_token; qqclient_set_process( qq, P_VERIFYING ); } } else { DBG("process verify password"); qq->data.token_c = answer_token; prot_login_verify( qq ); } result = 0; }
void prot_user_request_token_reply( struct qqclient* qq, qqpacket* p ) { bytebuffer *buf = p->buf; uchar cmd = get_byte( buf ); get_word( buf ); //0006 uchar verify = get_byte( buf ); if( verify ){ char *url, *data, *session; int datalen = KB(4); DBG (("need verifying...")); if( buf->pos == buf->len ) { puts("Verifying code is incorrect!"); return; //verify code wrong. } int len, ret; len = get_word( buf ); if( len >= 128 ){ DBG (("url is too long.")); return; } NEW( char*, data, datalen ); NEW( char*, url, 128 ); NEW( char*, session, 128 ); get_data( buf, (uchar*)url, len ); ret = http_request( &qq->http_sock, url, session, data, &datalen ); if( ret == 0 ){ char path[PATH_LEN]; sprintf( path, "%s/%u.jpg", qq->verify_dir, qq->number ); FILE *fp; fp = fopen( path, "wb" ); DBG (("got png at %s", path )); if( fp ){ fwrite( data, datalen, 1, fp ); fclose( fp ); } strncpy( qq->data.qqsession, session, 127 ); qqclient_set_process( qq, P_VERIFYING ); puts("You need to input the verifying code."); }else{ DBG (("http_request failed. ret=%d", ret )); } DEL( data ); DEL( url ); DEL( session ); }else{
int packetmgr_check_packet( struct qqclient* qq, int timeout ) { qqpacketmgr *mgr = &qq->packetmgr; qqpacket* p; time_t timeout_time = time(NULL) - timeout; //when locked, cannot recv packet till unlock. do{ p = loop_search( &mgr->sent_loop, (void*)timeout_time, timeout_searcher ); if( p ){ loop_remove( &mgr->sent_loop, p ); } if( p ){ if( p->send_times >= 10 ){ MSG("[%u] Failed to send the packet. command: %x\n", qq->number, p->command ); if( p->command == QQ_CMD_SEND_IM ){ buddy_msg_callback( qq, 10000, time(NULL), "刚才某条消息发送失败。" ); } //make an event to tell the program that we have a //problem. char event[64]; sprintf( event, "sendfailed^$%d^$%d", p->command, p->seqno ); qqclient_put_event( qq, event ); delete_func( p ); mgr->failed_packets ++; //To avoid too many failed packets, just shut it down. if( mgr->failed_packets > 5 || qq->process != P_LOGIN ){ qqclient_set_process( qq, P_ERROR ); } }else{ DBG("[%u] resend packet cmd: %x", qq->number, p->command ); packetmgr_put_urge( qq, p, 1 ); } } }while( 0 && p ); check_ready_packets(qq); return 0; }
static void check_ready_packets( qqclient* qq ) { qqpacketmgr* mgr = &qq->packetmgr; if( !loop_is_empty(&mgr->sent_loop) || loop_is_empty(&mgr->ready_loop) ) return; //if tcp, we send one by one, otherwise send them all if( loop_is_empty(&mgr->sent_loop) ) //good luck, get a packet and send it. { qqpacket* p = loop_pop_from_head( &mgr->ready_loop ); if( p && p->buf ){ //remove p from ready packets if( p->head!=0x02 || p->tail !=0x03 ){ DBG("Fatal error: p->command=%x p->head: %x p->tail: %x", p->command, p->head, p->tail ); delete_func( p ); return; } int ret = qqsocket_send( qq->socket, p->buf->data, p->buf->len ); // DBG("[%d] out packet cmd: %x", p->command ); if( ret != p->buf->len ){ DBG("send packet failed. ret(%d)!=p->len(%d)", ret, p->buf->len ); delete_func( p ); qqclient_set_process( qq, P_ERROR ); }else{ if( p->need_ack ){ p->time_alive = time(NULL); loop_push_to_tail( &mgr->sent_loop, p ); }else{ delete_func( p ); } } }else{ DBG("no packet. "); } } }
void* packetmgr_recv( void* data ) { int ret; qqpacket* p; qqclient* qq = (qqclient*)data; qqpacketmgr* mgr = &qq->packetmgr; uchar* recv_buf; int pos; NEW( recv_buf, PACKET_SIZE ); p = packetmgr_new_packet( qq ); if( !p || !recv_buf ){ DBG("error: p=%x buf=%x", p, recv_buf ); DEL( p ); DEL( recv_buf ); return NULL; } pos = 0; while( qq->process != P_INIT ){ ret = qqsocket_recv( qq->socket, recv_buf, PACKET_SIZE-pos ); if( ret <= 0 ){ if( qq->process != P_INIT ){ // DBG("ret=%d", ret ); SLEEP(1); continue; }else{ break; } } pos += ret; //TCP only if( qq->network == TCP || qq->network == PROXY_HTTP ){ if ( pos > 2 ){ if( !qq->proxy_established && qq->network == PROXY_HTTP ){ if( strstr( (char*)recv_buf, "200" )!=NULL ){ DBG("proxy server reply ok!"); qq->proxy_established = 1; prot_login_touch( qq ); //手动添加到发送队列。 qqpacket* t; while( (t = loop_pop_from_tail( &mgr->temp_loop )) ) loop_push_to_head( &mgr->ready_loop, t ); //检查待发送包 check_ready_packets( qq ); }else{ DBG("proxy server reply failure!"); recv_buf[ret]=0; DBG( "%s", recv_buf ); qqclient_set_process( qq, P_ERROR ); } }else{ int len = ntohs(*(ushort*)recv_buf); if( pos >= len ) //a packet is O.K. { if( handle_packet( qq, p, recv_buf, len ) < 0 ) { pos = 0; continue; } pos -= len; //copy data to buf if( pos > 0 ){ memmove( recv_buf, recv_buf+len, pos ); } }else if( pos == PACKET_SIZE ){ DBG("error: pos: 0x%x ", pos ); pos = 0; } } } }else{ //UDP handle_packet( qq, p, recv_buf, ret ); pos = 0; } } DEL( recv_buf ); packetmgr_del_packet( mgr, p ); DBG("end."); return NULL; }
void prot_user_request_token_reply( struct qqclient* qq, qqpacket* p ) { bytebuffer *buf = p->buf; uchar cmd = get_byte( buf ); get_word( buf ); //0006 uchar verify = get_byte( buf ); if( verify ){ char *url, *data, *session; int datalen = KB(4); DBG("need verifying..."); if( buf->pos == buf->len ) { puts("Verifying code is incorrect!"); return; //verify code wrong. } int len, ret; len = get_word( buf ); if( len >= 128 ){ DBG("url is too long."); return; } NEW( data, datalen ); NEW( url, 128 ); NEW( session, 128 ); get_data( buf, (uchar*)url, len ); ret = http_request( &qq->http_sock, url, session, data, &datalen ); if( ret == 0 ){ char path[PATH_LEN]; sprintf( path, "%s/%u.jpg", qq->verify_dir, qq->number ); FILE *fp; fp = fopen( path, "wb" ); DBG("got png at %s", path ); if( fp ){ fwrite( data, datalen, 1, fp ); fclose( fp ); } strncpy( qq->data.qqsession, session, 127 ); qqclient_set_process( qq, P_VERIFYING ); puts("You need to input the verifying code."); }else{ DBG("http_request failed. ret=%d", ret ); } DEL( data ); DEL( url ); DEL( session ); }else{ get_token( buf, &qq->data.user_token ); qq->data.user_token_time = time(NULL); DBG("got token"); qqbuddy *b = buddy_get( qq, qq->data.operating_number, 0 ); if( b ){ switch( qq->data.operation ){ case OP_ADDBUDDY: if( b->verify_flag == VF_VERIFY ){ prot_buddy_verify_addbuddy( qq, 02, qq->data.operating_number ); }else if( b->verify_flag == VF_OK ){ prot_buddy_verify_addbuddy( qq, 00, qq->data.operating_number ); } break; case OP_DELBUDDY: prot_buddy_del_buddy( qq, qq->data.operating_number ); break; } } } cmd = 0; }