00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "evapacket.h"
00022 #ifdef _WIN32
00023 #include <winsock.h>
00024 #else
00025 #include <arpa/inet.h>
00026 #endif
00027 #include <string.h>
00028 #include <stdlib.h>
00029 #include <stdio.h>
00030 #include "evacrypt.h"
00031
00032 unsigned char Packet::iniKey[16] = {
00033 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
00034 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
00035 };
00036
00037 int Packet::qqNum = -1;
00038 bool Packet::mIsUDP = true;
00039 unsigned char *Packet::sessionKey = NULL;
00040 unsigned char *Packet::passwordKey = NULL;
00041 unsigned char *Packet::fileSessionKey = NULL;
00042 unsigned char *Packet::loginToken= NULL;
00043 int Packet::loginTokenLength = 0;
00044 unsigned char *Packet::clientKey= NULL;
00045 int Packet::clientKeyLength = 0;
00046
00047 unsigned char *Packet::fileAgentKey = NULL;
00048 unsigned char *Packet::fileAgentToken = NULL;
00049 int Packet::fileAgentTokenLength = 0;
00050
00051 unsigned char *Packet::fileShareToken = NULL;
00052
00053 Packet::Packet(const short version, const short command, const short sequence)
00054 {
00055 this->version = version;
00056 this->command = command;
00057 this->sequence = sequence;
00058 }
00059
00060 Packet::Packet(unsigned char *buf, int *len)
00061 {
00062 int pos;
00063
00064 if(!mIsUDP)
00065 pos=3;
00066 else
00067 pos = 1;
00068
00069 short tmp;
00070
00071 memcpy(&tmp, buf+pos, 2);
00072 version = ntohs(tmp);
00073 pos+=2;
00074
00075 memcpy(&tmp, buf+pos, 2);
00076 command = ntohs(tmp);
00077 pos+=2;
00078
00079 memcpy(&tmp, buf+pos, 2);
00080 sequence = ntohs(tmp);
00081 pos+=2;
00082
00083 (*len)=(*len)-pos;
00084 memcpy(buf, buf+pos, *len);
00085 }
00086
00087 Packet::Packet(const Packet &rhs)
00088 {
00089 *this = rhs;
00090 }
00091
00092 Packet::~Packet()
00093 {
00094 }
00095
00096 bool Packet::operator ==( const Packet &rhs) const
00097 {
00098 return (command == rhs.getCommand()) && (sequence == rhs.getSequence());
00099 }
00100
00101 Packet &Packet::operator=(const Packet &rhs)
00102 {
00103 this->version = rhs.getVersion();
00104 this->command = rhs.getCommand();
00105 this->sequence = rhs.getSequence();
00106 this->mIsUDP = rhs.isUDP();
00107 return *this;
00108 }
00109
00110 const int Packet::hashCode()
00111 {
00112 return ((int)sequence << 16) | command;
00113 }
00114
00115 void Packet::setSessionKey(const unsigned char *skey)
00116 {
00117 if(!sessionKey)
00118 sessionKey = new unsigned char[QQ_KEY_LENGTH];
00119 memcpy(sessionKey, skey, QQ_KEY_LENGTH);
00120 fprintf(stderr,"session key set!\n");
00121 }
00122
00123 void Packet::setPasswordKey(const unsigned char* pkey)
00124 {
00125 if(!passwordKey)
00126 passwordKey = new unsigned char[QQ_KEY_LENGTH];
00127 memcpy(passwordKey, pkey, QQ_KEY_LENGTH);
00128 fprintf(stderr, "password key set!\n");
00129 }
00130
00131 void Packet::setFileSessionKey(const unsigned char* fskey)
00132 {
00133 if(!fileSessionKey)
00134 fileSessionKey = new unsigned char[QQ_KEY_LENGTH];
00135 memcpy(fileSessionKey, fskey, QQ_KEY_LENGTH);
00136 fprintf(stderr, "file session key set!\n");
00137 }
00138
00139 void Packet::setLoginToken(const unsigned char *token, const int length)
00140 {
00141 if(!loginToken)
00142 loginToken = new unsigned char[length];
00143 memcpy(loginToken, token, length);
00144 loginTokenLength = length;
00145 fprintf(stderr, "login token set!\n");
00146 }
00147
00148 void Packet::setClientKey(const unsigned char *ckey, const int length)
00149 {
00150 if(!clientKey)
00151 clientKey = new unsigned char[length];
00152 memcpy(clientKey, ckey, length);
00153 clientKeyLength = length;
00154 fprintf(stderr, "client key set!\n");
00155 }
00156
00157 void Packet::setFileAgentKey(const unsigned char *key)
00158 {
00159 if(!fileAgentKey)
00160 fileAgentKey = new unsigned char[QQ_KEY_LENGTH];
00161 memcpy(fileAgentKey, key, 16);
00162 fprintf(stderr, "file agent key set!\n");
00163 for(int i=0; i<16; i++){
00164
00165 char t = fileAgentKey[i];
00166 printf("%2x", (unsigned char)t);
00167 }
00168 printf("\n");
00169 }
00170
00171 void Packet::setFileAgentToken(const unsigned char *token, const int length)
00172 {
00173 if(!fileAgentToken)
00174 fileAgentToken = new unsigned char[length];
00175 memcpy(fileAgentToken, token, length);
00176 fileAgentTokenLength = length;
00177 fprintf(stderr, "file agent token set!\n");
00178 for(int i=0; i<length; i++){
00179
00180 char t = fileAgentToken[i];
00181 printf("%2x", (unsigned char)t);
00182 }
00183 printf("\n");
00184 }
00185
00186 void Packet::setFileShareToken(const unsigned char *token)
00187 {
00188 if(!fileShareToken)
00189 fileShareToken = new unsigned char[24];
00190 memcpy(fileShareToken, token, 24);
00191 fprintf(stderr, "file share token set!\n");
00192 }
00193
00194
00195 void Packet::clearAllKeys()
00196 {
00197 if(sessionKey) delete [] sessionKey;
00198 if(passwordKey) delete [] passwordKey;
00199 if(fileSessionKey) delete [] fileSessionKey;
00200 if(loginToken) delete [] loginToken;
00201 if(clientKey) delete [] clientKey;
00202 if(fileAgentKey) delete [] fileAgentKey;
00203 if(fileAgentToken) delete [] fileAgentToken;
00204 if(fileShareToken) delete [] fileShareToken;
00205
00206
00207 sessionKey = NULL;
00208 passwordKey = NULL;
00209 fileSessionKey = NULL;
00210 loginToken = NULL;
00211 loginTokenLength = 0;
00212 clientKey = NULL;
00213 clientKeyLength = 0;
00214 fileAgentKey = NULL;
00215 fileAgentToken = NULL;
00216 fileAgentTokenLength = 0;
00217 fileShareToken = NULL;
00218 }
00219
00220
00221
00222
00223 short OutPacket::startSequenceNum = 5;
00224
00225 OutPacket::OutPacket(const short command, const bool needAck) :
00226 Packet(QQ_CLIENT_VERSION, command, ((startSequenceNum++)%0xffff))
00227 {
00228 this->mNeedAck = needAck;
00229 resendCount = 5;
00230 }
00231
00232 OutPacket::OutPacket(const OutPacket &rhs)
00233 : Packet(rhs)
00234 {
00235 mNeedAck = rhs.needAck();
00236 resendCount = rhs.getResendCount();
00237 }
00238
00239 bool OutPacket::fill(unsigned char *buf, int *len)
00240 {
00241 int headerLen = 0, bodyLen=0, encryptedLen = 0;
00242 unsigned char *bodyBuf;
00243 unsigned char *encrypted;
00244 bodyBuf = (unsigned char *)malloc(MAX_PACKET_SIZE* sizeof(unsigned char));
00245 encrypted = (unsigned char *)malloc(MAX_PACKET_SIZE * sizeof(unsigned char));
00246
00247 headerLen = putHead(buf);
00248 bodyLen = putBody(bodyBuf);
00249 encryptedLen = bodyLen;
00250 encryptBody(bodyBuf, bodyLen, encrypted, &encryptedLen);
00251
00252 memcpy(buf+headerLen, encrypted, encryptedLen);
00253
00254 buf[ headerLen + encryptedLen ] = QQ_PACKET_TAIL;
00255 (*len) = headerLen + encryptedLen + 1;
00256
00257 if(!isUDP()) {
00258 short tmp2 = htons(*len);
00259 memcpy(buf, &tmp2, 2);
00260 }
00261 free(bodyBuf);
00262 free(encrypted);
00263 return true;
00264 }
00265
00266 OutPacket &OutPacket::operator=( const OutPacket &rhs)
00267 {
00268 *((Packet*)this) = (Packet)rhs;
00269 mNeedAck = rhs.needAck();
00270 resendCount = rhs.getResendCount();
00271 return *this;
00272 }
00273
00274 int OutPacket::putBody(unsigned char *buf)
00275 {
00276 fprintf(stderr, "In OutPacket\n");
00277 buf[0]=0;
00278 return 0;
00279 }
00280
00281 int OutPacket::putHead(unsigned char *buf)
00282 {
00283 int pos=0;
00284 if(!isUDP()){
00285 buf[0]=buf[1]=0;
00286 pos+=2;
00287 }
00288 buf[pos++]=(unsigned char)QQ_PACKET_TAG;
00289
00290 short tmp = htons(version);
00291 memcpy(buf+pos, &tmp, 2);
00292 pos+=2;
00293
00294 tmp = htons(command);
00295 memcpy(buf+pos, &tmp, 2);
00296 pos+=2;
00297
00298 tmp = htons(sequence);
00299 memcpy(buf+pos, &tmp, 2);
00300 pos+=2;
00301
00302 int id = htonl(getQQ());
00303 memcpy(buf+pos, &id, 4);
00304 pos+=4;
00305
00306 return pos;
00307 }
00308
00309 void OutPacket::encryptBody(unsigned char *b, int length,
00310 unsigned char *body, int *bodyLen)
00311 {
00312 switch(command){
00313 case QQ_CMD_REQUEST_LOGIN_TOKEN:
00314 case QQ_CMD_LOGIN:
00315 *bodyLen = length;
00316 memcpy(body, b, length);
00317 break;
00318 default:{
00319 unsigned char * sessionKey = getSessionKey();
00320 if(sessionKey == NULL) {
00321 fprintf(stderr, "OutPacket->encryptBody: sessionkey not set yet, set encrypted length to 0\n");
00322 *bodyLen = 0;
00323 return;
00324 }
00325 EvaCrypt::encrypt(b, length, sessionKey, body, bodyLen);
00326 }
00327 }
00328 }
00329
00330
00331
00332
00333
00334 InPacket::InPacket( )
00335 : decryptedBuf(NULL)
00336 {
00337 }
00338
00339 InPacket::InPacket( unsigned char *buf, int len)
00340 : Packet(buf, &len),
00341 bodyLength(0)
00342 {
00343 decryptedBuf = (unsigned char*)malloc(MAX_PACKET_SIZE * sizeof(unsigned char));
00344 decryptBody(buf, len - QQ_TAIL_LENGTH);
00345 }
00346
00347 InPacket::InPacket(const InPacket &rhs)
00348 : Packet(rhs)
00349 {
00350 bodyLength = rhs.getLength();
00351 decryptedBuf = (unsigned char*)malloc(bodyLength * sizeof(unsigned char));
00352 memcpy(decryptedBuf, rhs.getBody(), bodyLength);
00353 }
00354
00355 InPacket::~InPacket()
00356 {
00357 delete decryptedBuf;
00358 }
00359
00360 InPacket &InPacket::operator=( const InPacket &rhs)
00361 {
00362 *((Packet*)this) = (Packet)rhs;
00363 bodyLength = rhs.getLength();
00364 if(!decryptedBuf){
00365 delete decryptedBuf;
00366 decryptedBuf = new unsigned char[bodyLength];
00367 }
00368 memcpy(decryptedBuf, rhs.getBody(), bodyLength);
00369 return *this;
00370 }
00371
00372 void InPacket::decryptBody(unsigned char * buf, int len)
00373 {
00374 int ret;
00375 bodyLength = MAX_PACKET_SIZE;
00376
00377 unsigned char * passwordKey = getPasswordKey();
00378 unsigned char * sessionKey = getSessionKey();
00379
00380 if(command == QQ_CMD_REQUEST_LOGIN_TOKEN ){
00381 memcpy(decryptedBuf, buf, len);
00382 bodyLength = len;
00383 return;
00384 }
00385
00386 if(passwordKey == NULL) {
00387 fprintf(stderr, "InPacket->decryptBody: password key not set yet, set decrypted length to 0\n");
00388 bodyLength = 0;
00389 return;
00390 }
00391 if((command != QQ_CMD_LOGIN) && (sessionKey == NULL)) {
00392 fprintf(stderr, "InPacket->decryptBody: session key not set yet, set decrypted length to 0\n");
00393 command = -1;
00394 bodyLength = 0;
00395 return;
00396 }
00397 if(command == QQ_CMD_LOGIN) {
00398 ret = EvaCrypt::decrypt(buf, len, passwordKey, decryptedBuf, &bodyLength);
00399 if(ret == 0){
00400 bodyLength = MAX_PACKET_SIZE;
00401 ret = EvaCrypt::decrypt(buf, len, iniKey, decryptedBuf, &bodyLength);
00402 if(ret == 0){
00403 printf("CANNOT DECRYPT! ----- login reply data(len:%d):\n", len);
00404 for(int i=0; i<len; i++){
00405 if(!(i%8)) printf("\n%d: ",i);
00406 char t = buf[i];
00407 printf("%2x ", (unsigned char)t);
00408 }
00409 printf("\n");
00410 }
00411 }
00412 } else {
00413 ret = EvaCrypt::decrypt(buf, len, sessionKey, decryptedBuf, &bodyLength);
00414 if(ret == 0){
00415 bodyLength = MAX_PACKET_SIZE;
00416 ret = EvaCrypt::decrypt(buf, len, passwordKey, decryptedBuf, &bodyLength);
00417 }
00418 }
00419 if(ret == 0)
00420 bodyLength = 0;
00421 }
00422
00423 void InPacket::setInPacket( const InPacket * packet )
00424 {
00425 version = packet->getVersion();
00426 command = packet->getCommand();
00427 sequence = packet->getSequence();
00428 bodyLength = packet->getLength();
00429 if(!decryptedBuf){
00430 delete decryptedBuf;
00431 decryptedBuf = new unsigned char[bodyLength];
00432 }
00433 memcpy(decryptedBuf, packet->getBody(), bodyLength);
00434 }
00435
00436 const bool InPacket::parse( )
00437 {
00438 if(bodyLength){
00439 parseBody();
00440 return true;
00441 }else
00442 return false;
00443 }
00444