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

evapicpacket.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 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 #include "evapicpacket.h"
00021 #include "../evacrypt.h"
00022 #include <string.h>
00023 #include <stdio.h>
00024 #ifdef _WIN32
00025 #include <winsock.h>
00026 #else
00027 #include <arpa/inet.h>
00028 #endif
00029 
00030 unsigned int EvaPicPacket::myQQ = 0;
00031 unsigned char *EvaPicPacket::fileAgentKey = NULL;
00032 
00033 EvaPicPacket::EvaPicPacket( unsigned char *buf, int len)
00034         : key(NULL)
00035 {
00036         parseHeader(buf);
00037         tail = buf[len-1];
00038 }
00039 
00040 EvaPicPacket::EvaPicPacket( const unsigned short src, const unsigned short cmd, const unsigned short seq )
00041         : source(src), command(cmd), sequence(seq), key(NULL), cryptPosition(NO_CRYPTOGRAPH)
00042 {
00043 }
00044 
00045 EvaPicPacket::EvaPicPacket( unsigned char *buf, int *len, const int cryptStart)
00046         : key(NULL), cryptPosition(cryptStart)
00047 {
00048         int pos = parseHeader(buf);
00049         tail = buf[(*len)-1];
00050         (*len)=(*len) - pos - ((tail==FAMILY_05_TAIL)?1:0);
00051         memcpy(buf, buf+pos, *len);
00052 
00053 }
00054 
00055 EvaPicPacket::EvaPicPacket(const EvaPicPacket &rhs)
00056 {
00057         *this = rhs;
00058 }
00059 
00060 EvaPicPacket::~EvaPicPacket()
00061 {
00062         if(key)
00063                 delete key;
00064 }
00065 
00066 const int EvaPicPacket::hashCode()
00067 {
00068         return ((int)sequence << 16) | command;
00069 }
00070 
00071 const int EvaPicPacket::parseHeader(unsigned char *buf)
00072 {
00073         int pos=0;
00074         
00075         unsigned short tmp;
00076         
00077         header = buf[pos++];  // should be always 0x05
00078         
00079         memcpy(&tmp, buf+pos, 2);
00080         source = ntohs(tmp);
00081         pos+=2;
00082         
00083         memcpy(&tmp, buf+pos, 2);
00084         packetLength = ntohs(tmp);
00085         pos+=2; 
00086         
00087         memcpy(&tmp, buf+pos, 2);
00088         command = ntohs(tmp);
00089         pos+=2;
00090         
00091         memcpy(&tmp, buf+pos, 2);
00092         sequence = ntohs(tmp);
00093         pos+=2;
00094         
00095         unsigned int tmp4;
00096         memcpy(&tmp4, buf+pos, 4);
00097         myQQ = ntohl(tmp4);
00098         pos+=4;
00099         return pos;
00100 }
00101 
00102 EvaPicPacket &EvaPicPacket::operator=(const EvaPicPacket &rhs)
00103 {
00104         header = rhs.getHeader();
00105         tail = rhs.getTail();
00106         source = rhs.getSource();
00107         command = rhs.getCommand();
00108         sequence = rhs.getSequence();
00109         myQQ = rhs.getQQ();
00110         cryptPosition = rhs.getCryptPosition();
00111         return *this;
00112 }
00113 
00114 void EvaPicPacket::setFileAgentKey(const unsigned char *key)
00115 {
00116         if(!fileAgentKey)
00117                 fileAgentKey = new unsigned char[16];
00118         memcpy(fileAgentKey, key, 16);
00119 }
00120 
00121 void EvaPicPacket::setKey(const unsigned char *k)
00122 {
00123         key = new unsigned char[16];
00124         memcpy(key, k, 16);
00125 }
00126 
00127 void EvaPicPacket::clearKey()
00128 {
00129         if(fileAgentKey)
00130                 delete fileAgentKey;
00131         fileAgentKey = NULL;
00132 }
00133 
00134 /* =========================================================== */
00135 
00136 // EvaPicOutPacket starts here
00137 short EvaPicOutPacket::sequenceStart = 5;   // could be any random number
00138 
00139 EvaPicOutPacket::EvaPicOutPacket(const unsigned short command, const bool ack)
00140         : EvaPicPacket(QQ_CLIENT_VERSION, command, ((sequenceStart++)%0xffff))
00141 {
00142         mNeedAck = ack;
00143         resendCount = 5;
00144 }
00145 
00146 EvaPicOutPacket::EvaPicOutPacket(const EvaPicOutPacket &rhs) 
00147         : EvaPicPacket(rhs)
00148 {
00149         *this = rhs;
00150 }
00151 
00152 const bool EvaPicOutPacket::fill(unsigned char *buf, int *len) 
00153 {
00154         int headerLen = 0, bodyLen=0, encryptedLen = 0;
00155         unsigned char *bodyBuf = new unsigned char[MAX_PACKET_SIZE];
00156         unsigned char *encrypted = new unsigned char[MAX_PACKET_SIZE];
00157         
00158         headerLen = putHead(buf);
00159         bodyLen   = putBody(bodyBuf);
00160         encryptedLen = bodyLen;
00161         
00162         int start = getCryptPosition();
00163         if(start == -1){
00164                 memcpy(buf + headerLen, bodyBuf, bodyLen);
00165                 buf[headerLen + bodyLen] = FAMILY_05_TAIL;
00166                 *len = headerLen + bodyLen + 1;
00167                 short tmp2 = htons(*len);
00168                 memcpy(buf+3, &tmp2, 2);
00169                 delete bodyBuf;
00170                 delete encrypted;
00171                 return true;
00172         }
00173         
00174         encryptBody(bodyBuf + start, bodyLen - start, encrypted, &encryptedLen); // encrypt
00175         
00176         memcpy(buf + headerLen, bodyBuf, start);                               // copy un-encrypted body
00177         memcpy(buf + headerLen + start, encrypted, encryptedLen);             // copy encrypted body
00178         buf[headerLen + start + encryptedLen] = FAMILY_05_TAIL;                // the last byte
00179         *len = headerLen + start + encryptedLen + 1;
00180         
00181         short tmp2 = htons(*len);
00182         memcpy(buf+3, &tmp2, 2);
00183         
00184         delete bodyBuf;
00185         delete encrypted;
00186         return true;
00187 }
00188 
00189 EvaPicOutPacket &EvaPicOutPacket::operator=( const EvaPicOutPacket &rhs)
00190 {
00191         *((EvaPicPacket*)this) = (EvaPicPacket)rhs;
00192         mNeedAck = rhs.needAck();
00193         resendCount = rhs.getResendCount();
00194         return *this;
00195 }
00196 
00197 int EvaPicOutPacket::putBody(unsigned char *buf)
00198 {
00199         fprintf(stderr, "In EvaPicOutPacket\n"); 
00200         buf[0]=0; 
00201         return 0;
00202 }
00203 
00204 int EvaPicOutPacket::putHead(unsigned char *buf) 
00205 {
00206         int pos=0;
00207         
00208         buf[pos++] = FAMILY_05_TAG;
00209         
00210         short tmp = htons(getSource());
00211         memcpy(buf+pos, &tmp, 2);
00212         pos+=2; 
00213 
00214         memset(buf+pos, 0, 2); // 2 unknown bytes, all 0
00215         pos+=2;
00216                 
00217         tmp = htons(getCommand());
00218         memcpy(buf+pos, &tmp, 2);
00219         pos+=2; 
00220         
00221         tmp = htons(getSequence());
00222         memcpy(buf+pos, &tmp, 2);
00223         pos+=2; 
00224         
00225         int id = htonl(getQQ());
00226         memcpy(buf+pos, &id, 4);
00227         pos+=4;
00228                 
00229         return pos;
00230 }
00231 
00232 void EvaPicOutPacket::encryptBody(unsigned char *b, int length, 
00233                             unsigned char *body, int *bodyLen) 
00234 {
00235         if(fileAgentKey == NULL) {     
00236                 fprintf(stderr, "EvaPicOutPacket->encryptBody: file agent key not set yet, set encrypted length to 0\n");
00237                 *bodyLen = 0;
00238                 return;
00239         } 
00240         EvaCrypt::encrypt(b, length, key?key:fileAgentKey, body, bodyLen); 
00241                 
00242 }
00243 
00244 
00245 
00246 /* =========================================================== */
00247 
00248 
00249 EvaPicInPacket::EvaPicInPacket( unsigned char *buf, int len)
00250         : EvaPicPacket(buf, len),decryptedBuf(NULL)
00251 {
00252         rawBody = new unsigned char [len];
00253         rawLength = len;
00254         memcpy(rawBody, buf, rawLength);
00255 }
00256 
00257 EvaPicInPacket::EvaPicInPacket( unsigned char *buf, int len, const unsigned int cryptStart)
00258         : EvaPicPacket(buf, &len, cryptStart),
00259         bodyLength(0), rawBody(NULL)
00260 {
00261         decryptedBuf = new unsigned char [MAX_PACKET_SIZE];
00262         decryptBody(buf, len);
00263 }
00264 
00265 EvaPicInPacket::EvaPicInPacket(const EvaPicInPacket &rhs)
00266         : EvaPicPacket(rhs)
00267 {
00268         *this = rhs;
00269 }
00270 
00271 EvaPicInPacket::~EvaPicInPacket()
00272 {
00273         if(decryptedBuf) delete decryptedBuf;
00274         decryptedBuf = NULL;
00275         if(rawBody)
00276                 delete rawBody;
00277         rawBody = NULL;
00278 }
00279 
00280 void EvaPicInPacket::cutOffPacketData()
00281 {
00282         rawLength = getPacketLength();
00283 }
00284 
00285 EvaPicInPacket &EvaPicInPacket::operator=( const EvaPicInPacket &rhs)
00286 {
00287         *((EvaPicPacket*)this) = (EvaPicPacket)rhs;
00288         bodyLength = rhs.getLength();
00289         if(decryptedBuf) delete decryptedBuf;
00290         decryptedBuf = new unsigned char [bodyLength];
00291         memcpy(decryptedBuf, rhs.getBody(), bodyLength);
00292         return *this;
00293 }
00294 
00295 void EvaPicInPacket::decryptBody(unsigned char * buf, int len)
00296 {
00297         bodyLength = 0;
00298         int start = getCryptPosition();
00299         if(start == -1){
00300                 bodyLength = len;
00301                 memcpy(decryptedBuf, buf, bodyLength);
00302                 return;
00303         }
00304         
00305         if(fileAgentKey == NULL) {     
00306                 fprintf(stderr, "EvaPicOutPacket->decryptBody: file agent key not set yet, set decrypted length to 0\n");
00307                 bodyLength = 0;
00308                 return;
00309         }
00310 
00311         unsigned char *bodyBuf = new unsigned char[MAX_PACKET_SIZE];
00312         int bodyLen=MAX_PACKET_SIZE;    
00313         int ret = EvaCrypt::decrypt(buf + start, len - start, fileAgentKey, bodyBuf, &bodyLen); 
00314         if(ret == 0) {
00315                 bodyLength = 0;
00316                 fprintf(stderr, "EvaPicInPacket->decryptBody: failed\n");
00317                 delete bodyBuf;
00318                 return;
00319         }
00320         
00321         memcpy(decryptedBuf, buf, start);                               // copy un-encrypted body
00322         memcpy(decryptedBuf + start, bodyBuf, bodyLen);                // copy encrypted body
00323         bodyLength = start + bodyLen;
00324         
00325         delete bodyBuf;
00326 }
00327 
00328 void EvaPicInPacket::setInPacket( const EvaPicInPacket * packet )
00329 {
00330         header = packet->getHeader();
00331         source = packet->getSource();
00332         command = packet->getCommand();
00333         sequence = packet->getSequence();
00334         bodyLength = packet->getLength();
00335         if(decryptedBuf) delete decryptedBuf;
00336         decryptedBuf = new  unsigned char[bodyLength];
00337         memcpy(decryptedBuf, packet->getBody(), bodyLength);        
00338 }
00339 
00340 void EvaPicInPacket::printRawData()
00341 {
00342         if(!decryptedBuf) return;
00343         printf("packet length:%d\n", bodyLength);
00344         for(int i=0; i<bodyLength; i++){
00345                 if(!(i%8)) printf("\n%d: ",i);
00346                 unsigned char t = decryptedBuf[i];
00347                 printf("%2x ", (unsigned char)t);
00348         }
00349         printf("\n");
00350 }

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