Main Page | Class Hierarchy | Class List | Directories | File List | Class Members | File Members

evaftprotocols.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2004-2005 by yunfan                                     *
00003  *   yunfan_zg@163.com                                                     *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019  ***************************************************************************/ 
00020 
00021 #include "evaftprotocols.h"
00022 #include "../evautil.h"
00023 #include "../evacrypt.h"
00024 #include <stdio.h>
00025 #include <string.h>
00026 
00027 EvaFTAgentCreate::EvaFTAgentCreate()
00028         : EvaFTAgentPacket(QQ_FILE_AGENT_CMD_CREATE),
00029         m_Token(NULL), m_TokenLength(0), m_Id(0), m_Ip(0)
00030 {
00031 }
00032 
00033 EvaFTAgentCreate::~EvaFTAgentCreate()
00034 {
00035         if(m_Token)
00036                 delete []m_Token;
00037 }
00038 
00039 void EvaFTAgentCreate::setFileAgentToken(const unsigned char *token, const int len)
00040 {
00041         if(!token) return;
00042         if(m_Token) delete [] m_Token;
00043         m_Token = new unsigned char[len];
00044         memcpy(m_Token, token, len);
00045         m_TokenLength = len;
00046 }
00047 
00048 const int EvaFTAgentCreate::fillBody(unsigned char *buf)
00049 {
00050         if(!m_Token) return -1;
00051         int pos=0;
00052         pos += EvaUtil::write16(buf, m_TokenLength);
00053         memcpy(buf+pos, m_Token, m_TokenLength); pos+=m_TokenLength;
00054         
00055         int rawPos=0;
00056         unsigned char *raw = new unsigned char [20];
00057         rawPos += EvaUtil::write16(raw, 0x07d0);
00058         rawPos += EvaUtil::write32(raw + rawPos, m_Id);
00059         memcpy(raw+rawPos, &m_Ip, 4); rawPos+=4; // in little endian format
00060         rawPos += EvaUtil::write16(raw + rawPos, 0x0575);
00061 
00062         int outLen = 1000;
00063         EvaCrypt::encrypt(raw, rawPos, m_FileAgentKey, buf+pos, &outLen);
00064         pos += outLen;
00065         delete []raw;
00066         return pos;
00067 }
00068 
00069 
00072 EvaFTAgentCreateReply::EvaFTAgentCreateReply(const unsigned char *buf, const int len)
00073         : EvaFTAgentPacket(buf, len),
00074         m_ReplyCode(QQ_FILE_AGENT_CREATE_REDIRECT),
00075         m_Ip(0), m_Port(0)
00076 {
00077 }
00078 
00079 const bool EvaFTAgentCreateReply::parseBody( unsigned char *buf, const int len)
00080 {
00081         int rawLen = 256;
00082         unsigned char *raw = new unsigned char[256];
00083         
00084         if(!EvaCrypt::decrypt(buf, len, m_FileAgentKey, raw, &rawLen)){
00085                 fprintf(stderr, "EvaFTAgentCreateReply::parseBody -- decrypt failed\n");
00086                 delete []raw;
00087                 return false;
00088         }
00089         
00090         int pos = 0;
00091         m_ReplyCode = EvaUtil::read16(raw); pos+=2;
00092         switch(m_ReplyCode){
00093         case QQ_FILE_AGENT_CREATE_OK:
00094                 memcpy(&m_Ip, raw+pos, 4); pos+=4;   // ip in little endian format
00095                 m_Port = EvaUtil::read16(raw+pos); pos+=2;
00096                 m_Session = EvaUtil::read32(raw+pos); pos+=4;
00097                 // all following are 0x00s, 8 more bytes
00098                 break;
00099         case QQ_FILE_AGENT_CREATE_REDIRECT:
00100                 pos+=10; // 10 bytes 0x000
00101                 memcpy(&m_Ip, raw+pos, 4); pos+=4;   // ip in little endian format
00102                 m_Port = EvaUtil::read16(raw+pos); pos+=2;
00103                 // actually, there still 2 more bytes(0x0000)
00104                 break;
00105         case QQ_FILE_AGENT_CREATE_ERROR:{
00106                 pos+=2; // unknown 2 bytes
00107                 memcpy(&m_Ip, raw+pos, 4); pos+=4;   // ip in little endian format, unknown ip
00108                 pos+=10; // 10 bytes 0x000
00109                 short msgLen = EvaUtil::read16(raw+pos); pos+=2;
00110                 char *tmp = new char[msgLen+1];
00111                 memcpy(tmp, raw+pos, msgLen); pos+=msgLen;
00112                 tmp[msgLen]=0x00;
00113                 m_ErrMessage.assign(tmp);
00114                 delete []tmp;
00115                 }
00116                 break;
00117         default:
00118                 fprintf(stderr, "EvaFTAgentCreateReply::parseBody -- un-supported reply code: 0x%4x\n", 0xffff&m_ReplyCode);
00119                 delete []raw;
00120                 return false;
00121         }
00122         delete []raw;
00123         return true;
00124 }
00125 
00126 
00127 
00130 EvaFTAgentLogin::EvaFTAgentLogin()
00131         : EvaFTAgentPacket(QQ_FILE_AGENT_CMD_LOGIN),
00132         m_Token(NULL), m_TokenLength(0)
00133 {
00134 }
00135 
00136 EvaFTAgentLogin::~EvaFTAgentLogin()
00137 {
00138         if(m_Token)
00139                 delete []m_Token;
00140 }
00141 
00142 void EvaFTAgentLogin::setFileAgentToken(const unsigned char *token, const int len)
00143 {
00144         if(!token) return;
00145         if(m_Token) delete [] m_Token;
00146         m_Token = new unsigned char[len];
00147         memcpy(m_Token, token, len);
00148         m_TokenLength = len;
00149 }
00150 
00151 const int EvaFTAgentLogin::fillBody(unsigned char *buf)
00152 {
00153         if(!m_Token) return -1;
00154         int pos=0;
00155         
00156         unsigned char *raw = new unsigned char [256];
00157         pos += EvaUtil::write16(raw, m_TokenLength);
00158         memcpy(raw+pos, m_Token, m_TokenLength); pos+=m_TokenLength;
00159         
00160         
00161         int outLen = 1000;
00162         EvaCrypt::encrypt(raw, pos, m_FileAgentKey, buf, &outLen);
00163         delete []raw;
00164         return outLen;
00165 }
00166 
00167 
00168 
00172 EvaFTAgentLoginReply::EvaFTAgentLoginReply(const unsigned char *buf, const int len)
00173         : EvaFTAgentPacket(buf, len),
00174         m_ReplyCode(1)
00175 {
00176 }
00177 
00178 const bool EvaFTAgentLoginReply::parseBody(unsigned char *buf, const int len)
00179 {
00180         int rawLen = 256;
00181         unsigned char *raw = new unsigned char[256];
00182         
00183         if(!EvaCrypt::decrypt(buf, len, m_FileAgentKey, raw, &rawLen)){
00184                 fprintf(stderr, "EvaFTAgentCreateReply::parseBody -- decrypt failed\n");
00185                 delete []raw;
00186                 return false;
00187         }
00188         
00189         int pos = 0;
00190         m_ReplyCode = EvaUtil::read32(raw); pos+=4;
00191         delete []raw;
00192         return true;
00193 }
00194 
00195 
00196 
00199 EvaFTAgentTransfer::EvaFTAgentTransfer(const int type)
00200         : EvaFTAgentPacket(QQ_FILE_AGENT_CMD_TRANSFER),
00201         m_Type(type), m_FileName(""), m_FMd5(NULL),
00202         m_FileSize(0), m_Data(NULL),
00203         m_DataLength(0), m_StartOffset(0)
00204 {
00205 }
00206 
00207 EvaFTAgentTransfer::~EvaFTAgentTransfer()
00208 {       
00209         if(m_FMd5)
00210                 delete []m_FMd5;
00211         if(m_Data)
00212                 delete []m_Data;
00213 }
00214 
00215 void EvaFTAgentTransfer::setInfo(const std::string &file, const unsigned char *fileMd5, 
00216                         const unsigned int size)
00217 {
00218         if(!fileMd5)  return;
00219 
00220         m_FileName = file;
00221         if(!m_FMd5)   m_FMd5 = new unsigned char[16];
00222         memcpy(m_FMd5, fileMd5, 16);
00223 
00224         m_FileSize = size;
00225 }
00226 
00227 void EvaFTAgentTransfer::setData(const unsigned char *data, const unsigned int len)
00228 {
00229         m_DataLength = len;
00230 
00231         if(m_Data) delete []m_Data;
00232         m_Data = new unsigned char[m_DataLength];
00233         memcpy(m_Data, data, m_DataLength);
00234 }
00235 
00236 const int EvaFTAgentTransfer::fillBody(unsigned char *buf)
00237 {
00238         int pos=4; // ignore unknown 4 bytes
00239         int start = pos;
00240         pos+=2; // the following data length, set it at last
00241         
00242         switch(m_Type){
00243         case QQ_FILE_AGENT_TRANSFER_INFO:
00244                 pos+=2; // the whole part length including these 2 bytes(save as 2 bytes ahead)
00245                 memcpy(buf+pos, m_FMd5, 16); pos+=16;
00246                 memcpy(buf+pos, EvaUtil::doMd5((char *)m_FileName.c_str(), m_FileName.length()), 16); pos+=16;
00247                 pos+=EvaUtil::write32(buf+pos, m_FileSize);
00248                 pos+=EvaUtil::write16(buf+pos, 0xffff & m_FileName.length());
00249                 memcpy(buf+pos, m_FileName.c_str(), m_FileName.length());
00250                 pos += m_FileName.length();
00251                 pos+=8; // unknown 8 bytes;
00252                 EvaUtil::write16(buf+start+2, pos-start-2); // write back length of this part
00253                 break;
00254         case QQ_FILE_AGENT_TRANSFER_DATA:
00255                 memcpy(buf+pos, m_Data, m_DataLength); pos+=m_DataLength;
00256                 break;
00257         case QQ_FILE_AGENT_TRANSFER_REPLY:
00258                 buf[pos++] = 0x02; // always 0x02
00259                 break;
00260         case QQ_FILE_AGENT_TRANSFER_START:
00261                 pos+=EvaUtil::write32(buf+pos, m_StartOffset);
00262                 break;
00263         default:
00264                 fprintf(stderr, "EvaFTAgentTransfer::fillBody -- Un-supported type: %d\n", m_Type);
00265                 return -1;
00266         }
00267         EvaUtil::write16(buf+start, pos - start -2);
00268         return pos;
00269 }
00270 
00271 
00272 
00275 EvaFTAgentTransferReply::EvaFTAgentTransferReply(const int type, const unsigned char *buf, const int len)
00276         : EvaFTAgentPacket(buf, len), m_Type(type),
00277         m_ReplyCode(1), m_NextReplyCode(0xff),
00278         m_FileMd5(NULL), m_FileNameMd5(NULL),
00279         m_FileName(""), m_FileSize(0),
00280         m_Data(NULL), m_DataLength(0)
00281 {
00282 }
00283 
00284 EvaFTAgentTransferReply::~EvaFTAgentTransferReply()
00285 {
00286         if(m_FileMd5) delete []m_FileMd5;
00287         if(m_FileNameMd5) delete []m_FileNameMd5;
00288         if(m_Data) delete []m_Data;
00289 }
00290 
00291 const unsigned char * EvaFTAgentTransferReply::getFileMd5()
00292 {
00293         return m_FileMd5;
00294 }
00295 
00296 const unsigned char * EvaFTAgentTransferReply::getFileNameMd5()
00297 {
00298         return m_FileNameMd5;
00299 }
00300 
00301 
00302 const bool EvaFTAgentTransferReply::parseBody( unsigned char *buf, const int len)
00303 {
00304         int pos=4; // 4 unknown bytes
00305         int contentsLen = EvaUtil::read16(buf+pos); pos += 2;
00306         if(contentsLen != (len - 6)) return false;
00307 
00308         switch(m_Type){
00309         case QQ_FILE_AGENT_TRANSFER_INFO:{
00310                 if(EvaUtil::read16(buf+pos) != contentsLen) return false;
00311                 pos+=2;
00312                 if(!m_FileMd5) m_FileMd5 = new unsigned char[16];
00313                 memcpy(m_FileMd5, buf+pos, 16); pos+=16;
00314 
00315                 if(!m_FileNameMd5) m_FileNameMd5 = new unsigned char[16];
00316                 memcpy(m_FileNameMd5, buf+pos, 16); pos+=16;
00317 
00318                 m_FileSize = EvaUtil::read32(buf+pos); pos+=4;
00319                 
00320                 unsigned short strLen = EvaUtil::read16(buf+pos); pos+=2;
00321                 char *strFile = new char[strLen + 1];
00322                 memcpy(strFile, buf+pos, strLen);
00323                 strFile[strLen] = 0x00;
00324                 m_FileName.assign(strFile);
00325                 delete strFile;
00326                 }
00327                 break;
00328         case QQ_FILE_AGENT_TRANSFER_DATA:
00329                 m_DataLength = contentsLen;
00330                 m_Data = new unsigned char[m_DataLength];
00331                 memcpy(m_Data, buf+pos, m_DataLength); pos+=m_DataLength;
00332                 break;
00333         case QQ_FILE_AGENT_TRANSFER_REPLY:
00334                 m_NextReplyCode = buf[pos++];
00335                 break;
00336         case QQ_FILE_AGENT_TRANSFER_START:
00337                 m_ReplyCode = EvaUtil::read32(buf+pos); pos += 4;
00338                 break;
00339         default:
00340                 fprintf(stderr, "EvaFTAgentTransferReply::parseBody -- Un-supported type: %d\n", m_Type);
00341                 return false;
00342         }
00343 
00344         return true;
00345 }
00346 
00347 
00350 EvaFTAgentAckReady::EvaFTAgentAckReady()
00351         : EvaFTAgentPacket(QQ_FILE_AGENT_CMD_READY)
00352 {
00353 }
00354 
00355 EvaFTAgentAckReady::~EvaFTAgentAckReady()
00356 {
00357 }
00358 
00359 const int EvaFTAgentAckReady::fillBody(unsigned char *buf)
00360 {
00361         int pos=0;
00362         unsigned char *raw = new unsigned char [4];
00363         memset(raw, 0, 4); pos+=4;
00364         int outLen = 64;
00365         EvaCrypt::encrypt(raw, pos, m_FileAgentKey, buf, &outLen);
00366         pos = outLen;
00367         delete []raw;
00368         return pos;
00369 }
00370 
00371 
00372 
00376 EvaFTAgentAskReady::EvaFTAgentAskReady(const unsigned char *buf, const int len)
00377         : EvaFTAgentPacket(buf, len),
00378         m_ReplyCode(1)
00379 {
00380 }
00381 
00382 const bool EvaFTAgentAskReady::parseBody(unsigned char *buf, const int len)
00383 {
00384         int rawLen = 256;
00385         unsigned char *raw = new unsigned char[256];
00386         
00387         if(!EvaCrypt::decrypt(buf, len, m_FileAgentKey, raw, &rawLen)){
00388                 fprintf(stderr, "EvaFTAgentAskReady::parseBody -- decrypt failed\n");
00389                 delete []raw;
00390                 return false;
00391         }
00392         
00393         int pos = 0;
00394         m_ReplyCode = EvaUtil::read32(raw); pos+=4;
00395         delete []raw;
00396         return true;
00397 }
00398 
00399 
00400 
00403 EvaFTAgentStart::EvaFTAgentStart()
00404         : EvaFTAgentPacket(QQ_FILE_AGENT_CMD_START)
00405 {
00406 }
00407 
00408 EvaFTAgentStart::~EvaFTAgentStart()
00409 {
00410 }
00411 
00412 const int EvaFTAgentStart::fillBody(unsigned char *buf)
00413 {
00414         int pos=0;
00415         unsigned char *raw = new unsigned char [2];
00416         
00417         // unknown fixed bytes
00418         raw[pos++] = 0x07;
00419         raw[pos++] = 0xd0;
00420 
00421         int outLen = 64;
00422         EvaCrypt::encrypt(raw, pos, m_FileAgentKey, buf, &outLen);
00423         pos = outLen;
00424         delete []raw;
00425         return pos;
00426 }
00427 
00428 
00429 
00433 EvaFTAgentStartReply::EvaFTAgentStartReply(const unsigned char *buf, const int len)
00434         : EvaFTAgentPacket(buf, len)
00435 {
00436 }
00437 
00438 const bool EvaFTAgentStartReply::parseBody(unsigned char *buf, const int len)
00439 {
00440         int rawLen = 256;
00441         unsigned char *raw = new unsigned char[256];
00442         
00443         if(!EvaCrypt::decrypt(buf, len, m_FileAgentKey, raw, &rawLen)){
00444                 fprintf(stderr, "EvaFTAgentStartReply::parseBody -- decrypt failed\n");
00445                 delete []raw;
00446                 return false;
00447         }
00448         
00449         // looks like all unknown contents are fixed values
00450         int pos = 0;    
00451         unsigned int part1 = EvaUtil::read32(raw); pos+=4; // this should be 1
00452         if(part1 != 1)
00453                 fprintf(stderr, "EvaFTAgentStartReply::parseBody -- part1 is 0x%8x\n", part1);
00454         unsigned char part2 = raw[pos++];  // should be 0x90
00455         if(part2 != 0x90)
00456                 fprintf(stderr, "EvaFTAgentStartReply::parseBody -- part2 is 0x%2x\n", 0xff&part2);
00457         pos+=2; // 2 0x00s
00458         unsigned char part3 = raw[pos++]; // should be 0x2d
00459         if(part3 != 0x2d)
00460                 fprintf(stderr, "EvaFTAgentStartReply::parseBody -- part3 is 0x%2x\n", 0xff&part3);
00461         pos+=4; // all 0x00s
00462         
00463         delete []raw;
00464         return true;
00465 }
00466 
00467 
00470 EvaFTSynCreate::EvaFTSynCreate()
00471         : EvaFTSynPacket(QQ_FILE_SYN_CMD_CREATE),
00472         m_Token(NULL), m_TokenLength(0), m_BuddyId(0)
00473 {
00474 }
00475 
00476 EvaFTSynCreate::~EvaFTSynCreate()
00477 {
00478         if(m_Token)
00479                 delete []m_Token;
00480 }
00481 
00482 void EvaFTSynCreate::setFileAgentToken(const unsigned char *token, const int len)
00483 {
00484         if(!token) return;
00485         if(m_Token) delete [] m_Token;
00486         m_Token = new unsigned char[len];
00487         memcpy(m_Token, token, len);
00488         m_TokenLength = len;
00489 }
00490 
00491 const int EvaFTSynCreate::fillBody(unsigned char *buf)
00492 {
00493         if(!m_Token) return -1;
00494         int pos=0;
00495         pos += EvaUtil::write16(buf, m_TokenLength);
00496         memcpy(buf+pos, m_Token, m_TokenLength); pos+=m_TokenLength;
00497         
00498         int rawPos=0;
00499         unsigned char *raw = new unsigned char [20];
00500         memset(raw, 0, 4); rawPos+=4;
00501         rawPos += EvaUtil::write32(raw + rawPos, m_BuddyId);
00502 
00503         int outLen = 1000;
00504         EvaCrypt::encrypt(raw, rawPos, m_FileAgentKey, buf+pos, &outLen);
00505         pos += outLen;
00506         delete []raw;
00507         return pos;
00508 }
00509 
00510 
00511 
00514 EvaFTSynCreateReply::EvaFTSynCreateReply(const unsigned char *buf, const int len)
00515         : EvaFTSynPacket(buf, len),
00516         m_ReplyCode(QQ_FILE_AGENT_CREATE_REDIRECT),
00517         m_Ip(0), m_Port(0)
00518 {
00519 }
00520 
00521 const bool EvaFTSynCreateReply::parseBody( unsigned char *buf, const int len)
00522 {
00523         int rawLen = 256;
00524         unsigned char *raw = new unsigned char[256];
00525         
00526         if(!EvaCrypt::decrypt(buf, len, m_FileAgentKey, raw, &rawLen)){
00527                 fprintf(stderr, "EvaFTSynCreateReply::parseBody -- decrypt failed\n");
00528                 delete []raw;
00529                 return false;
00530         }
00531         
00532         int pos = 0;
00533         m_ReplyCode = EvaUtil::read16(raw); pos+=2;
00534         switch(m_ReplyCode){
00535         case QQ_FILE_AGENT_CREATE_OK:
00536                 m_Session = EvaUtil::read32(raw+pos); pos+=4;
00537                 m_Ip  = EvaUtil::read32(raw+pos); pos+=4;
00538                 m_Port = EvaUtil::read16(raw+pos); pos+=2;
00539                 // all following are 0x00s, 6 more bytes
00540                 break;
00541         default:
00542                 fprintf(stderr, "EvaFTSynCreateReply::parseBody -- un-supported reply code: 0x%4x\n", 0xffff&m_ReplyCode);
00543                 delete []raw;
00544                 return false;
00545         }
00546         delete []raw;
00547         return true;
00548 }
00549 
00550 
00551 
00552 
00553 
00554 
00555 
00556 
00557 
00558 
00559 

Generated on Mon May 15 20:48:42 2006 for libeva by  doxygen 1.4.4