00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "evalogin.h"
00021 #ifdef _WIN32
00022 #include <winsock.h>
00023 #else
00024 #include <arpa/inet.h>
00025 #endif
00026 #include <string.h>
00027 #include <stdlib.h>
00028 #include "evacrypt.h"
00029 #include "evautil.h"
00030
00031 LoginPacket::LoginPacket(unsigned char loginMode)
00032 : OutPacket(QQ_CMD_LOGIN, true),
00033 mLoginMode(loginMode)
00034 {
00035 }
00036
00037 LoginPacket::LoginPacket(const LoginPacket &rhs)
00038 :OutPacket(rhs)
00039 {
00040 mLoginMode = rhs.getLoginMode();
00041 }
00042
00043 LoginPacket::~LoginPacket()
00044 {
00045 }
00046
00047 LoginPacket &LoginPacket::operator=(const LoginPacket &rhs)
00048 {
00049 *((OutPacket *)this) = (OutPacket)rhs;
00050 mLoginMode = rhs.getLoginMode();
00051 return *this;
00052 }
00053
00054 int LoginPacket::putBody(unsigned char *buf)
00055 {
00056 memcpy(buf, iniKey, QQ_KEY_LENGTH);
00057
00058 int pos = 16;
00059
00060 if(!getPasswordKey()){
00061 fprintf(stderr, "LoginPacket->putBody: no password key avalible\n");
00062 return 0;
00063 }
00064
00065 unsigned char *login = new unsigned char[QQ_LOGIN_DATA_LENGTH];
00066 EvaCrypt::encrypt(NULL, 0, getPasswordKey(), login, &pos);
00067
00068 memcpy(login+pos, login_16_51, 36);
00069 pos+=36;
00070
00071 login[pos++] = mLoginMode;
00072
00073 memcpy(login+pos, login_53_68, 16);
00074 pos+=16;
00075
00076 login[pos++] = getLoginTokenLength();
00077 memcpy(login+pos, getLoginToken(), getLoginTokenLength());
00078 pos += getLoginTokenLength();
00079
00080 memcpy(login+pos, login_94_193, 100);
00081 pos+= 100;
00082
00083 memset(login+pos, 0, QQ_LOGIN_DATA_LENGTH - pos);
00084
00085 unsigned char *encrypted = new unsigned char[MAX_PACKET_SIZE];
00086 int enLen=200;
00087 EvaCrypt::encrypt(login, QQ_LOGIN_DATA_LENGTH, iniKey, encrypted, &enLen);
00088
00089 memcpy(buf+QQ_KEY_LENGTH, encrypted, enLen);
00090
00091 delete login;
00092 delete encrypted;
00093 return QQ_KEY_LENGTH + enLen;
00094 }
00095
00096
00097
00098 LoginReplyPacket::LoginReplyPacket(unsigned char *buf, int len)
00099 : InPacket(buf, len)
00100 {
00101 }
00102
00103 LoginReplyPacket::LoginReplyPacket(const LoginReplyPacket &rhs)
00104 : InPacket(rhs)
00105 {
00106 replyCode = rhs.getReplyCode();
00107 redirectedIP = rhs.getRedirectedIP();
00108 redirectedPort = rhs.getRedirectedPort();
00109
00110 qqNum = rhs.getQQ();
00111 IP = rhs.getMyIP();
00112 port = rhs.getMyPort();
00113 loginTime = rhs.getLoginTime();
00114 serverIP = rhs.getServerIP();
00115 serverPort = rhs.getServerPort();
00116 lastLoginIP = rhs.getLastLoginIP();
00117 lastLoginTime = rhs.getLastLoginTime();
00118 replyMessage = rhs.getReplyMessage();
00119 }
00120
00121 LoginReplyPacket &LoginReplyPacket::operator=(const LoginReplyPacket &rhs)
00122 {
00123 *((InPacket *)this) = (InPacket)rhs;
00124 replyCode = rhs.getReplyCode();
00125 redirectedIP = rhs.getRedirectedIP();
00126 redirectedPort = rhs.getRedirectedPort();
00127
00128 qqNum = rhs.getQQ();
00129 IP = rhs.getMyIP();
00130 port = rhs.getMyPort();
00131 loginTime = rhs.getLoginTime();
00132 serverIP = rhs.getServerIP();
00133 serverPort = rhs.getServerPort();
00134 lastLoginIP = rhs.getLastLoginIP();
00135 lastLoginTime = rhs.getLastLoginTime();
00136 replyMessage = rhs.getReplyMessage();
00137 return *this;
00138 }
00139
00140 void LoginReplyPacket::parseBody()
00141 {
00142 replyCode = decryptedBuf[0];
00143 switch(replyCode) {
00144 case QQ_LOGIN_REPLY_OK:
00145 {
00146 short tmp2;
00147 unsigned int tmp4;
00148 setSessionKey(decryptedBuf+1);
00149
00150
00151 char *fsbuf = new char[QQ_KEY_LENGTH + 4];
00152 tmp4 = htonl(getQQ());
00153 memcpy(fsbuf, &tmp4, 4);
00154 memcpy(fsbuf+4, getSessionKey(), QQ_KEY_LENGTH);
00155 setFileSessionKey((unsigned char *)EvaUtil::doMd5(fsbuf, 4 + QQ_KEY_LENGTH));
00156 delete fsbuf;
00157
00158 memcpy(&tmp4, decryptedBuf + QQ_KEY_LENGTH + 1, 4);
00159 qqNum = ntohl(tmp4);
00160
00161 memcpy(&tmp4, decryptedBuf + 21, 4);
00162 IP = ntohl(tmp4);
00163
00164 memcpy(&tmp2, decryptedBuf+25, 2);
00165 port = ntohs(tmp2);
00166
00167 memcpy(&tmp4, decryptedBuf + 27, 4);
00168 serverIP = ntohl(tmp4);
00169
00170 memcpy(&tmp2, decryptedBuf+31, 2);
00171 serverPort = ntohs(tmp2);
00172
00173 memcpy(&tmp4, decryptedBuf+33, 4);
00174 loginTime = ntohl(tmp4);
00175
00176
00177
00178
00179 setFileShareToken(decryptedBuf+39);
00180
00181
00182 setClientKey(decryptedBuf+79, 32);
00183
00184
00185 memcpy(&tmp4, decryptedBuf+123, 4);
00186 lastLoginIP = ntohl(lastLoginIP);
00187
00188 memcpy(&tmp4, decryptedBuf+127, 4);
00189 lastLoginTime = ntohl(tmp4);
00190
00191 break;
00192 }
00193 case QQ_LOGIN_REPLY_PWD_ERROR:
00194
00195 {
00196 char *tmpMsg = new char[bodyLength];
00197 memcpy(tmpMsg, decryptedBuf+1, bodyLength-1);
00198 tmpMsg[bodyLength-1]=0;
00199 replyMessage.assign(tmpMsg);
00200 delete tmpMsg;
00201 break;
00202 }
00203 case QQ_LOGIN_REPLY_REDIRECT:
00204
00205 {
00206 short tmp2;
00207 int tmp4;
00208
00209 memcpy(&tmp4, decryptedBuf + 1, 4);
00210 qqNum = ntohl(tmp4);
00211
00212 memcpy(&tmp4, decryptedBuf+5, 4);
00213 redirectedIP = ntohl(tmp4);
00214
00215 memcpy(&tmp2, decryptedBuf+9, 2);
00216 redirectedPort = ntohs(tmp2);
00217 break;
00218 }
00219 default:
00220 replyCode = QQ_LOGIN_REPLY_MISC_ERROR;
00221 {
00222 printf("login unknown reply(first byte is reply code)\n");
00223 for(int i=0; i<bodyLength; i++){
00224 if(!(i%8)) printf("\n%d: ",i);
00225 char t = decryptedBuf[i];
00226 printf("%2x ", (uint8_t)t);
00227 }
00228 printf("\n");
00229 }
00230 break;
00231 }
00232 }
00233
00234
00235
00236 LogoutPacket::LogoutPacket()
00237 : OutPacket(QQ_CMD_LOGOUT, false)
00238 {
00239 sequence = 0xFFFF;
00240 }
00241
00242 LogoutPacket::LogoutPacket(const LogoutPacket &rhs)
00243 : OutPacket(rhs)
00244 {
00245 }
00246
00247 LogoutPacket &LogoutPacket::operator=(const LogoutPacket &rhs)
00248 {
00249 *((OutPacket *)this) = (OutPacket)rhs;
00250 return *this;
00251 }
00252
00253 int LogoutPacket::putBody(unsigned char *buf)
00254 {
00255 unsigned char *pwKey = Packet::getPasswordKey();
00256 if(pwKey==NULL){
00257 fprintf(stderr, "LogoutPacket->putBody: no password key avalible\n");
00258 return 0;
00259 }
00260 memcpy(buf, pwKey, QQ_KEY_LENGTH);
00261 return QQ_KEY_LENGTH;
00262 }
00263
00264
00265
00266 KeepAlivePacket::KeepAlivePacket()
00267 : OutPacket(QQ_CMD_KEEP_ALIVE, true)
00268 {
00269 }
00270
00271 KeepAlivePacket::KeepAlivePacket(const KeepAlivePacket &rhs)
00272 : OutPacket(rhs)
00273 {
00274 }
00275
00276 KeepAlivePacket &KeepAlivePacket::operator=(const KeepAlivePacket &rhs )
00277 {
00278 *((OutPacket *)this) = (OutPacket)rhs;
00279 return *this;
00280 }
00281
00282 int KeepAlivePacket::putBody(unsigned char *buf)
00283 {
00284 int qq = htonl(getQQ());
00285 memcpy(buf, &qq, 4);
00286 return 4;
00287 }
00288
00289
00290
00291 int KeepAliveReplyPacket::onlineUsers=0;
00292
00293 KeepAliveReplyPacket::KeepAliveReplyPacket(unsigned char *buf, int len)
00294 : InPacket(buf, len)
00295 {
00296 }
00297
00298 KeepAliveReplyPacket::KeepAliveReplyPacket(const KeepAliveReplyPacket &rhs)
00299 : InPacket(rhs)
00300 {
00301 onlineUsers = rhs.numOnlineUsers();
00302 myIP = rhs.getMyIP();
00303 myPort = rhs.getMyPort();
00304 }
00305
00306 KeepAliveReplyPacket &KeepAliveReplyPacket::operator=(const KeepAliveReplyPacket &rhs)
00307 {
00308 *((InPacket *)this) = (InPacket)rhs;
00309 onlineUsers = rhs.numOnlineUsers();
00310 myIP = rhs.getMyIP();
00311 myPort = rhs.getMyPort();
00312 return *this;
00313 }
00314
00315 void KeepAliveReplyPacket::parseBody()
00316 {
00317 int sec = 0, offset = 0;
00318 char section[10][256];
00319 for(int i=0; i<bodyLength; i++){
00320 if(sec>5) printf("Keep Alive -- number of fields greater than 5\n");
00321 if(decryptedBuf[i]==KA_DIVIDER){
00322 section[sec][offset] = 0;
00323 sec++;
00324 offset=0;
00325 continue;
00326 }
00327 section[sec][offset++]=decryptedBuf[i];
00328 }
00329 section[sec][offset]=0;
00330
00331 if(sec != 5){
00332 printf("Keep Alive -- number of fields wrong!\n");
00333 return;
00334 }
00335
00336 onlineUsers = atoi(section[2]);
00337 if(onlineUsers == 0 ){
00338 printf("KeepAliveReplyPacket -- parse online users error!\n");
00339 return;
00340 }
00341
00342 myIP.assign( section[3]);
00343 myPort = atoi(section[4]);
00344 }
00345
00346