Пример #1
0
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;
}
Пример #2
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;
}
Пример #3
0
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;
}
Пример #4
0
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 );
}
Пример #5
0
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
}
Пример #6
0
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;
}
Пример #7
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{
Пример #8
0
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;
}
Пример #9
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. ");
		}
	}
}
Пример #10
0
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;
}
Пример #11
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( 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;
}