|
/*000-015 用MD5 加密任意字符*/ qq_encrypt("LINUXQQ",7,qc->pass_encrypted,data_raw,&len);
/*016 -051 固定内容*/ bcopy(login_16_51,&data_raw[16],35);
/*52-52 登录模式*/ data_raw[52] = qc->login_mode;
/*053 -068 固定内容*/ bcopy(login_53_68,&data_raw[53],16);
/*69-69 登录令牌长度*/ data_raw[69] = login_token_len; /*复制登录令牌*/ bcopy(login_token,&data_raw[70],login_token_len);
/*固定内容*/ data_raw[70 + login_token_len ] = 0x01; data_raw[70 + login_token_len +1] = 0x40;
len = 70 + login_token_len +2;
/*未知内容*/ bcopy(login_unknown_fixed,&data_raw[len],sizeof(login_unknown_fixed)); len+=sizeof(login_unknown_fixed);
len = 416;
/*用TEA 加密这416 数据,密钥是我们随机得到的init_key*/ qq_encrypt(data_raw,416,qc->init_key,data_encrypted,&len);
p = buff_tx;
/*创建发送报文*/ /*所有报文用0x02 开头*/ p[0] = 0x02; /*版本是QQ2005beta2*/ *((uint16_t*)&p[1]) = htons(0x0d51); /*命令是0x0022 表示登录请求*/ *((uint16_t*)&p[3]) = htons(0x0022); /*随机得到一个报文序号*/ qc->seq = rand()e535; *((uint16_t*)&p[5]) = htons(qc->seq); /*QQ 号码*/ *((uint32_t*)&p[7]) = htonl(qc->id); /* 放置加密的密钥*/ bcopy(qc->init_key,&p[11],16); /*我们加密过的登录数据*/ bcopy(data_encrypted,&p[27],len);
len = 27 + len; /*报文结束*/ p[len] = 0x03;
/*发送登录数据*/ e = write(qc->server,buff_tx,len+1);
if(e!=(len+1)){ close(qc->server); qc->server = -1; return -EFAULT;
}
/** 准备接收数据/ bzero(&timeout,sizeof(timeout));
/*1S 超时*/ timeout.tv_sec = 1; timeout.tv_usec = 0;
FD_ZERO(&fds); FD_SET(qc->server, &fds);
/*我们等待8个数据包*/ for(i=0;i<8;i++){
e = select(qc->server+1,&fds,NULL,NULL,&timeout);
if(e==-1e==0){ fprintf(stderr,"receive data timeout\n"); close(qc->server); qc->server = -1; qc->login_retry++; if(qc->login_retry>16){
fprintf(stderr,"too many times retried.\n");
return -EFAULT; } /*失败了重新试*/ return qq_login(qc,id,pass,login_mode,
local_ip,local_port, inet_ntoa(in),ntohs(tmp16)); } |