Mixe for Privacy and Anonymity in the Internet
CALocalProxy.cpp
Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2000, The JAP-Team
00003 All rights reserved.
00004 Redistribution and use in source and binary forms, with or without modification,
00005 are permitted provided that the following conditions are met:
00006 
00007   - Redistributions of source code must retain the above copyright notice,
00008     this list of conditions and the following disclaimer.
00009 
00010   - Redistributions in binary form must reproduce the above copyright notice,
00011     this list of conditions and the following disclaimer in the documentation and/or
00012     other materials provided with the distribution.
00013 
00014   - Neither the name of the University of Technology Dresden, Germany nor the names of its contributors
00015     may be used to endorse or promote products derived from this software without specific
00016     prior written permission.
00017 
00018 
00019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
00020 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
00021 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS
00022 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00023 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00024 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
00025 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00026 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00027 */
00028 #include "StdAfx.h"
00029 #include "CALocalProxy.hpp"
00030 #include "CASocketList.hpp"
00031 #include "CASocketGroup.hpp"
00032 #include "CAMsg.hpp"
00033 #include "CACmdLnOptions.hpp"
00034 #include "CAUtil.hpp"
00035 #include "CASocketAddrINet.hpp"
00036 #include "CABase64.hpp"
00037 #include "CALibProxytest.hpp"
00038 #include "xml/DOM_Output.hpp"
00039 #ifndef NEW_MIX_TYPE
00040 
00041 // signals the main loop whether to capture or replay packets
00042 bool CALocalProxy::bCapturePackets;
00043 bool CALocalProxy::bReplayPackets;
00044 int CALocalProxy::iCapturedPackets;
00045 
00046 // Signal handler for SIGUSR1.
00047 // This starts the capture with the next channel-open message.
00048 void SIGUSR1_handler(int signum)
00049   {
00050     CAMsg::printMsg(LOG_DEBUG,"Starting to capture packets for replay attack.\n");
00051     CALocalProxy::bCapturePackets = true;
00052     CALocalProxy::iCapturedPackets = 0;
00053   }
00054 
00055 // Signal handler for SIGUSR2.
00056 // This replays the currently captured packets.
00057 void SIGUSR2_handler(int signum)
00058   {
00059     CAMsg::printMsg(LOG_DEBUG,"Starting replay of packets.\n");
00060     CALocalProxy::bReplayPackets = true;
00061   }
00062 
00063 
00064 SINT32 CALocalProxy::start()
00065   {
00066     if(initOnce()!=E_SUCCESS)
00067       return E_UNKNOWN;
00068     for(;;)
00069     {
00070         CAMsg::printMsg(LOG_DEBUG, "CALocalProxy main: before init()\n");
00071         if(init() == E_SUCCESS)
00072         {
00073           CAMsg::printMsg(LOG_DEBUG, "CALocalProxy main: init() returned success\n");
00074           CAMsg::printMsg(LOG_INFO, "The local proxy is now on-line.\n");
00075           loop();
00076           CAMsg::printMsg(LOG_DEBUG, "CAMix local proxy: loop() returned, maybe connection lost.\n");
00077         }
00078         else
00079         {
00080             CAMsg::printMsg(LOG_DEBUG, "init() failed, maybe no connection.\n");
00081         }
00082 
00083         CAMsg::printMsg(LOG_DEBUG, "CALocalProxy main: before clean()\n");
00084         clean();
00085         CAMsg::printMsg(LOG_DEBUG, "CAMix LocalProxy: after clean()\n");
00086         sSleep(20);
00087     }
00088 }
00089 
00090 
00091 SINT32 CALocalProxy::initOnce()
00092   {
00093     if(CALibProxytest::getOptions()->getListenerInterfaceCount()<1)
00094       {
00095         CAMsg::printMsg(LOG_CRIT,"No Listener Interface spezified!\n");
00096         return E_UNKNOWN;
00097       }
00098 
00099     bCapturePackets = bReplayPackets = false;
00100     #if defined(REPLAY_DETECTION)&&!defined(_WIN32)
00101       // Set up signal handling for the replay attack.
00102       signal(SIGUSR1, SIGUSR1_handler);
00103       signal(SIGUSR2, SIGUSR2_handler);
00104     #endif
00105 
00106     UINT8 strTarget[255];
00107     if(CALibProxytest::getOptions()->getMixHost(strTarget,255)!=E_SUCCESS)
00108       {
00109         CAMsg::printMsg(LOG_CRIT,"No AnonServer specified!\n");
00110         return E_UNKNOWN;
00111       }
00112     return E_SUCCESS;
00113   }
00114 
00115 SINT32 CALocalProxy::init()
00116   {
00117     CAListenerInterface* pListener;
00118     m_nFlowControlDownstreamSendMe=FLOW_CONTROL_SENDME_SOFT_LIMIT;
00119     m_bWithNewFlowControl=false;
00120     m_bWithEnhancedChannelEncryption=false;
00121     m_bWithFirstMixSymmetric=false;
00122     m_socketIn.create();
00123     m_socketIn.setReuseAddr(true);
00124     pListener=CALibProxytest::getOptions()->getListenerInterface(1);
00125     if(pListener==NULL)
00126       {
00127         CAMsg::printMsg(LOG_CRIT,"No listener specified\n");
00128         return E_UNKNOWN;
00129       }
00130     CASocketAddrINet* pSocketAddrIn=(CASocketAddrINet*)pListener->getAddr();
00131     delete pListener;
00132     pListener = NULL;
00133     if(pSocketAddrIn->isAnyIP())
00134       pSocketAddrIn->setAddr((UINT8*)"127.0.0.1",pSocketAddrIn->getPort());
00135     if(m_socketIn.listen(*pSocketAddrIn)!=E_SUCCESS)
00136       {
00137         CAMsg::printMsg(LOG_CRIT,"Cannot listen (1)\n");
00138         delete pSocketAddrIn;
00139         pSocketAddrIn = NULL;
00140         return E_UNKNOWN;
00141       }
00142     delete pSocketAddrIn;
00143     pSocketAddrIn = NULL;
00144 /*    if(CALibProxytest::getOptions()->getSOCKSServerPort()!=(UINT16)-1)
00145       {
00146         socketAddrIn.setAddr((UINT8*)"127.0.0.1",CALibProxytest::getOptions()->getSOCKSServerPort());
00147         m_socketSOCKSIn.create();
00148         m_socketSOCKSIn.setReuseAddr(true);
00149         if(m_socketSOCKSIn.listen(socketAddrIn)!=E_SUCCESS)
00150           {
00151             CAMsg::printMsg(LOG_CRIT,"Cannot listen (2)\n");
00152             return E_UNKNOWN;
00153           }
00154       }*/
00155     CASocketAddrINet addrNext;
00156     UINT8 strTarget[255];
00157     CALibProxytest::getOptions()->getMixHost(strTarget,255);
00158     addrNext.setAddr(strTarget,CALibProxytest::getOptions()->getMixPort());
00159     CAMsg::printMsg(LOG_INFO,"Try connecting to next Mix...\n");
00160 
00161     m_muxOut.getCASocket()->create();
00162     m_muxOut.getCASocket()->setSendBuff(MIXPACKET_SIZE*50);
00163     m_muxOut.getCASocket()->setRecvBuff(MIXPACKET_SIZE*50);
00164     if(m_muxOut.connect(addrNext)==E_SUCCESS)
00165       {
00166         CAMsg::printMsg(LOG_INFO," connected!\n");
00167         UINT16 size;
00168         UINT8 byte;
00169         m_muxOut.getCASocket()->receiveFully((UINT8*)&size,2);
00170         m_muxOut.getCASocket()->receiveFully((UINT8*)&byte,1);
00171         CAMsg::printMsg(LOG_INFO,"Received Key Info!\n");
00172         size=ntohs(size);
00173 #ifdef _DEBUG
00174         CAMsg::printMsg(LOG_INFO,"Key Info size is:%u\n",size);
00175 #endif
00176         if(byte=='<')//assuming XML
00177           {
00178 #ifdef _DEBUG
00179             CAMsg::printMsg(LOG_INFO,"Key Info is XML!\n");
00180 #endif
00181             UINT8* buff=new UINT8[size+1];
00182             buff[0]=byte;
00183             m_muxOut.getCASocket()->receiveFully(buff+1,size-1);
00184             buff[size]=0;
00185 #ifdef _DEBUG
00186             CAMsg::printMsg(LOG_INFO,"Key Info is:\n");
00187             CAMsg::printMsg(LOG_INFO,"%s\n",buff);
00188 #endif
00189             SINT32 ret=processKeyExchange(buff,size);
00190             delete[]  buff;
00191             buff = NULL;
00192             if(ret!=E_SUCCESS)
00193               return E_UNKNOWN;
00194           }
00195         else
00196           {
00197             return E_UNKNOWN;
00198           }
00199         return E_SUCCESS;
00200       }
00201     else
00202       {
00203         CAMsg::printMsg(LOG_CRIT,"Cannot connect to next Mix!\n");
00204         return E_UNKNOWN;
00205       }
00206   }
00207 
00208 SINT32 CALocalProxy::loop()
00209   {
00210     CASocketList  oSocketList;
00211     CASocketGroup oSocketGroup(false);
00212     oSocketGroup.add(m_socketIn);
00213     UINT16 socksPort=CALibProxytest::getOptions()->getSOCKSServerPort();
00214     bool bHaveSocks=(socksPort!=0xFFFF);
00215     if(bHaveSocks)
00216       oSocketGroup.add(m_socketSOCKSIn);
00217     oSocketGroup.add(m_muxOut);
00218     MIXPACKET* pMixPacket=new MIXPACKET;
00219 
00220     memset(pMixPacket,0,MIXPACKET_SIZE);
00221     SINT32 len,ret;
00222     CASocket* newSocket;//,*tmpSocket;
00223     CASymCipher* newCipher;
00224     int countRead;
00225     CONNECTION oConnection;
00226 
00227     // Temporary storage for packets that could be replayed.
00228     MIXPACKET* pReplayMixPackets=new MIXPACKET[REPLAY_COUNT];
00229     memset(pReplayMixPackets,0,MIXPACKET_SIZE*REPLAY_COUNT);
00230     // channel ID from which packets are captured
00231     unsigned uCapturedChannel = 0;
00232 
00233 
00234     for(;;)
00235       {
00236         // Add timeout to select to allow for a replay attack to take place.
00237         if((countRead=oSocketGroup.select(100))==SOCKET_ERROR)
00238           {
00239             sSleep(1);
00240             continue;
00241           }
00242 
00243         // Start a replay attack, if a packet is present
00244         if(bReplayPackets)
00245           {
00246             if(iCapturedPackets > 0)
00247               {
00248                 for(int i = 0; i < iCapturedPackets; i++)
00249                   {
00250                     memcpy(pMixPacket,&pReplayMixPackets[i],MIXPACKET_SIZE);
00251                     CAMsg::printMsg(LOG_DEBUG,"Replaying packet #%d: %X %X %X %X\n", (i+1), *pMixPacket->data, *(pMixPacket->data+1), *(pMixPacket->data+2), *(pMixPacket->data+3));
00252                     if(m_muxOut.send(pMixPacket)==SOCKET_ERROR)
00253                       {
00254                         CAMsg::printMsg(LOG_CRIT,"Mux-Channel Sending Data Error - Exiting!\n");
00255                         ret=E_UNKNOWN;
00256                         goto MIX_CONNECTION_ERROR;
00257                       }
00258                   }
00259                 memset(pMixPacket,0,MIXPACKET_SIZE);
00260               }
00261             else
00262               {
00263                 CAMsg::printMsg(LOG_DEBUG,"No captured packets found.\n");
00264               }
00265           CAMsg::printMsg(LOG_DEBUG,"Replay finished.\n");
00266           bReplayPackets = false;
00267         }
00268 
00269         if(oSocketGroup.isSignaled(m_socketIn))
00270           {
00271             countRead--;
00272             #ifdef _DEBUG
00273               CAMsg::printMsg(LOG_DEBUG,"New Connection from Browser!\n");
00274             #endif
00275             newSocket=new CASocket;
00276             if(m_socketIn.accept(*newSocket)!=E_SUCCESS)
00277               {
00278                 #ifdef _DEBUG
00279                   CAMsg::printMsg(LOG_DEBUG,"Accept Error - Connection from Browser!\n");
00280                 #endif
00281                 delete newSocket;
00282                 newSocket = NULL;
00283               }
00284             else
00285               {
00286                 newCipher=new CASymCipher[m_chainlen];
00287                 oSocketList.add(newSocket,newCipher);
00288                 oSocketGroup.add(*newSocket);
00289               }
00290           }
00291         if(bHaveSocks&&oSocketGroup.isSignaled(m_socketSOCKSIn))
00292           {
00293             countRead--;
00294             #ifdef _DEBUG
00295               CAMsg::printMsg(LOG_DEBUG,"New Connection from SOCKS!\n");
00296             #endif
00297             newSocket=new CASocket;
00298             if(m_socketSOCKSIn.accept(*newSocket)!=E_SUCCESS)
00299               {
00300                 #ifdef _DEBUG
00301                   CAMsg::printMsg(LOG_DEBUG,"Accept Error - Connection from SOCKS!\n");
00302                 #endif
00303                 delete newSocket;
00304                 newSocket = NULL;
00305               }
00306             else
00307               {
00308                 newCipher=new CASymCipher[m_chainlen];
00309                 oSocketList.add(newSocket,newCipher);
00310                 oSocketGroup.add(*newSocket);
00311               }
00312           }
00313         //Recevie from next Mix
00314         if(oSocketGroup.isSignaled(m_muxOut))
00315             {
00316               countRead--;
00317               ret=m_muxOut.receive(pMixPacket);
00318               if(ret==SOCKET_ERROR)
00319                 {
00320                   CAMsg::printMsg(LOG_CRIT,"Mux-Channel Receiving Data Error - Exiting!\n");
00321                   ret=E_UNKNOWN;
00322                   goto MIX_CONNECTION_ERROR;
00323                 }
00324 
00325               if(oSocketList.get(pMixPacket->channel,&oConnection)==E_SUCCESS)
00326                 {
00327                   if(pMixPacket->flags==CHANNEL_CLOSE)
00328                     {
00329                       #ifdef _DEBUG
00330                         CAMsg::printMsg(LOG_DEBUG,"Closing Channel: %u ... ",pMixPacket->channel);
00331                       #endif
00332                       /*tmpSocket=*/oSocketList.remove(pMixPacket->channel);
00333                       if(oConnection.pSocket!=NULL)
00334                         {
00335                           oSocketGroup.remove(*oConnection.pSocket);
00336                           oConnection.pSocket->close();
00337                           #ifdef _DEBUG
00338                             CAMsg::printMsg(LOG_DEBUG,"closed!\n");
00339                           #endif
00340                           delete oConnection.pSocket;
00341                           oConnection.pSocket = NULL;
00342                           delete [] oConnection.pCiphers;
00343                           oConnection.pCiphers = NULL;
00344 
00345                           // stop capturing packets when the channel is closed
00346                           if(pMixPacket->channel == uCapturedChannel)
00347                             {
00348                               CAMsg::printMsg(LOG_DEBUG,"Stopping to capture packets.\n");
00349                               bCapturePackets = false;
00350                             }
00351                         }
00352                     }
00353                   else
00354                     {
00355                       for(UINT32 c=0;c<m_chainlen;c++)
00356                         oConnection.pCiphers[c].crypt2(pMixPacket->data,pMixPacket->data,DATA_SIZE);
00357                       UINT32 truelen=ntohs(pMixPacket->payload.len);
00358                       truelen=truelen&PAYLOAD_LEN_MASK;
00359                       oConnection.pSocket->send(pMixPacket->payload.data,truelen);
00360                       #ifdef _DEBUG
00361                         CAMsg::printMsg(LOG_DEBUG,"Sending Data to Browser (%u bytes)!\n",truelen);
00362                       #endif
00363                       if(m_bWithNewFlowControl)
00364                       {
00365                         if(oConnection.currentSendMeCounter+1>=m_nFlowControlDownstreamSendMe)
00366                           {
00367                             //send a SEND_ME MixPacket
00368                             pMixPacket->flags=CHANNEL_DATA;
00369                             pMixPacket->channel=oConnection.outChannel;
00370                             getRandom(pMixPacket->data,DATA_SIZE);
00371                             pMixPacket->payload.len=htons(NEW_FLOW_CONTROL_FLAG);
00372                             pMixPacket->payload.type=MIX_PAYLOAD_HTTP;
00373                             for(UINT32 c=0;c<m_chainlen;c++)
00374                               oConnection.pCiphers[c].crypt1(pMixPacket->data,pMixPacket->data,DATA_SIZE);
00375                             m_muxOut.send(pMixPacket);
00376                             #ifdef _DEBUG
00377                               CAMsg::printMsg(LOG_DEBUG,"sent sendme!\n");
00378                             #endif
00379                             oSocketList.addSendMeCounter(oConnection.outChannel,-(m_nFlowControlDownstreamSendMe-1));
00380                           }
00381                           else
00382                           {
00383                             oSocketList.addSendMeCounter(oConnection.outChannel,1);
00384                           }
00385                       }
00386                     }
00387                 }
00388             }
00389         if(countRead>0)
00390           {
00391             CONNECTION* tmpCon;
00392             tmpCon=oSocketList.getFirst();
00393             while(tmpCon!=NULL&&countRead>0)
00394               {
00395                 if(oSocketGroup.isSignaled(*tmpCon->pSocket))
00396                   {
00397                     countRead--;
00398                     getRandom(pMixPacket->payload.data,PAYLOAD_SIZE);
00399                     if(!tmpCon->pCiphers[0].isKeyValid())
00400                       len=tmpCon->pSocket->receive(pMixPacket->payload.data,PAYLOAD_SIZE-m_chainlen*m_SymChannelEncryptedKeySize);
00401                     else
00402                       len=tmpCon->pSocket->receive(pMixPacket->payload.data,PAYLOAD_SIZE);
00403                     if(len==SOCKET_ERROR||len==0)
00404                       {
00405                         CAMsg::printMsg(LOG_DEBUG,"client side close channel - upstream sent: %u\n",tmpCon->upstreamBytes);
00406                         CASocket* tmpSocket=oSocketList.remove(tmpCon->outChannel);
00407                         if(tmpSocket!=NULL)
00408                           {
00409                             oSocketGroup.remove(*tmpSocket);
00410                             pMixPacket->flags=CHANNEL_CLOSE;
00411                             pMixPacket->channel=tmpCon->outChannel;
00412                             getRandom(pMixPacket->data,DATA_SIZE);
00413                             m_muxOut.send(pMixPacket);
00414                             tmpSocket->close();
00415                             delete tmpSocket;
00416                             tmpSocket = NULL;
00417                             delete [] tmpCon->pCiphers;
00418                             tmpCon->pCiphers = NULL;
00419                           }
00420                       }
00421                     else
00422                       {
00423                         pMixPacket->channel=tmpCon->outChannel;
00424                         tmpCon->upstreamBytes+=len;
00425                         pMixPacket->payload.len=htons((UINT16)len);
00426                         if(bHaveSocks&&tmpCon->pSocket->getLocalPort()==socksPort)
00427                           {
00428                             pMixPacket->payload.type=MIX_PAYLOAD_SOCKS;
00429                           }
00430                         else
00431                           {
00432                             pMixPacket->payload.type=MIX_PAYLOAD_HTTP;
00433                           }
00434                         if(!tmpCon->pCiphers[0].isKeyValid()) //First time --> rsa key
00435                           {
00436                             //Has to bee optimized!!!!
00437                             UINT8 buff[DATA_SIZE];
00438                             //UINT32 size=DATA_SIZE-KEY_SIZE;
00439                             //tmpCon->pCipher->generateEncryptionKey(); //generate Key
00440                             for(UINT32 c=0;c<m_chainlen;c++)
00441                               {
00442                                 getRandom(buff,m_SymChannelKeySize);
00443                                 buff[0]&=0x7F; // Hack for RSA to ensure m < n !!!!!
00444                                 tmpCon->pCiphers[c].setKeys(buff,m_SymChannelKeySize);
00445                                 /*
00446                                   PROTOCOL CHANGE:
00447                                   This is a change in the protocol between JAP and the mixes:
00448                                   In the RSA encrypted part of the channel-open packet apart
00449                                   from the symmetric key for each mix, we now include a
00450                                   TIMESTAMP_SIZE bytes wide timestamp. This reduces the storage
00451                                   space for symmetrical keys in the RSA_SIZE wide part of the
00452                                   packet (from 8 to 7).
00453                                 */
00454                                 #ifdef WITH_TIMESTAMP
00455                                   //TODO insert timesampt
00456                                   //currentTimestamp(buff+KEY_SIZE,true);
00457                                 #endif
00458                                 if(m_bWithFirstMixSymmetric&&c==m_chainlen-1)
00459                                   {
00460                                     memcpy(buff+m_SymChannelKeySize,pMixPacket->data,DATA_SIZE-m_SymChannelKeySize);
00461                                     m_pSymCipher->crypt1(buff,buff,m_SymChannelKeySize);
00462                                     UINT8 iv[16];
00463                                     memset(iv,0xFF,16);
00464                                     tmpCon->pCiphers[c].setIV2(iv);
00465                                     tmpCon->pCiphers[c].crypt1(buff+m_SymChannelKeySize,buff+m_SymChannelKeySize,DATA_SIZE-m_SymChannelKeySize);
00466                                   }
00467                                 else
00468                                   {
00469                                     memcpy(buff+m_SymChannelKeySize,pMixPacket->data,DATA_SIZE-m_SymChannelEncryptedKeySize);
00470                                     if(m_bWithEnhancedChannelEncryption)
00471                                     {
00472                                       UINT8 tmpBuff[1000];
00473                                       UINT32 lk=1000;
00474                                       m_arRSA[c].encryptOAEP(buff,128-42,tmpBuff,&lk);
00475                                       tmpCon->pCiphers[c].crypt1(buff+RSA_SIZE-42,tmpBuff+RSA_SIZE,DATA_SIZE-RSA_SIZE);
00476                                       memcpy(buff,tmpBuff,DATA_SIZE);
00477                                     }
00478                                     else
00479                                     {
00480                                       m_arRSA[c].encrypt(buff,buff);
00481                                       tmpCon->pCiphers[c].crypt1(buff+RSA_SIZE,buff+RSA_SIZE,DATA_SIZE-RSA_SIZE);
00482                                     }
00483                                     // Does RSA_SIZE need to be increased by RSA_SIZE/KEY_SIZE*TIMESTAMP_SIZE?
00484                                   }
00485                                 memcpy(pMixPacket->data,buff,DATA_SIZE);
00486                                 //size-=KEY_SIZE;
00487                                 //len+=KEY_SIZE;
00488                               }
00489                             pMixPacket->flags=CHANNEL_OPEN;
00490                           }
00491                         else //sonst
00492                           {
00493                             for(UINT32 c=0;c<m_chainlen;c++)
00494                               tmpCon->pCiphers[c].crypt1(pMixPacket->data,pMixPacket->data,DATA_SIZE);
00495                             pMixPacket->flags=CHANNEL_DATA;
00496                           }
00497 
00498                         // Capture the this packet for future replay
00499                         if(bCapturePackets)
00500                           {
00501                             if(!iCapturedPackets && (pMixPacket->flags == CHANNEL_OPEN))
00502                               {
00503                                 CAMsg::printMsg(LOG_DEBUG,"Captured channel-open packet: %X %X %X %X\n", *pMixPacket->data, *(pMixPacket->data+1), *(pMixPacket->data+2), *(pMixPacket->data+3));
00504                                 memcpy(&pReplayMixPackets[iCapturedPackets++],pMixPacket,MIXPACKET_SIZE);
00505                                 uCapturedChannel = pMixPacket->channel;
00506                               }
00507                             else if(iCapturedPackets && (uCapturedChannel == pMixPacket->channel))
00508                               {
00509                                 CAMsg::printMsg(LOG_DEBUG,"Captured data packet: %X %X %X %X\n", *pMixPacket->data, *(pMixPacket->data+1), *(pMixPacket->data+2), *(pMixPacket->data+3));
00510                                 memcpy(&pReplayMixPackets[iCapturedPackets++],pMixPacket,MIXPACKET_SIZE);
00511                               }
00512                           }
00513                         if(iCapturedPackets >= REPLAY_COUNT)
00514                           {
00515                             CAMsg::printMsg(LOG_DEBUG,"Storage full, stopping to capture packets.\n");
00516                             bCapturePackets = false;
00517                           }
00518 
00519                         if(m_muxOut.send(pMixPacket)==SOCKET_ERROR)
00520                           {
00521                             CAMsg::printMsg(LOG_CRIT,"Mux-Channel Sending Data Error - Exiting!\n");
00522                             ret=E_UNKNOWN;
00523                             goto MIX_CONNECTION_ERROR;
00524                           }
00525                       }
00526                     break;
00527                   }
00528                 tmpCon=oSocketList.getNext();
00529               }
00530           }
00531       }
00532 MIX_CONNECTION_ERROR:
00533     CONNECTION* tmpCon=oSocketList.getFirst();
00534     while(tmpCon!=NULL)
00535       {
00536         delete [] tmpCon->pCiphers;
00537         tmpCon->pCiphers = NULL;
00538         delete tmpCon->pSocket;
00539         tmpCon->pSocket = NULL;
00540         tmpCon=tmpCon->next;
00541       }
00542     delete pMixPacket;
00543     pMixPacket = NULL;
00544     if(ret==E_SUCCESS)
00545       return E_SUCCESS;
00546     if(CALibProxytest::getOptions()->getAutoReconnect())
00547       return E_UNKNOWN;
00548     else
00549       exit(-1);
00550   }
00551 
00552 SINT32 CALocalProxy::clean()
00553   {
00554     m_socketIn.close();
00555     m_socketSOCKSIn.close();
00556     m_muxOut.close();
00557 
00558     delete[] m_arRSA;
00559     m_arRSA=NULL;
00560 
00561     delete m_pSymCipher;
00562     m_pSymCipher=NULL;
00563 
00564     return E_SUCCESS;
00565   }
00566 
00567 SINT32 CALocalProxy::processKeyExchange(UINT8* buff,UINT32 len)
00568   {
00569     m_SymChannelEncryptedKeySize=16;
00570     m_SymChannelKeySize=16;
00571     CAMsg::printMsg(LOG_INFO,"Login process and key exchange started...\n");
00572     //Parsing KeyInfo received from Mix n+1
00573     XERCES_CPP_NAMESPACE::DOMDocument* doc=parseDOMDocument(buff,len);
00574     if(doc==NULL)
00575       {
00576         CAMsg::printMsg(LOG_INFO,"Error parsing Key Info from Mix!\n");
00577         return E_UNKNOWN;
00578       }
00579 
00580 
00581     DOMElement* root=doc->getDocumentElement();
00582     DOMElement* elemVersion=NULL;
00583     getDOMChildByName(root,"MixProtocolVersion",elemVersion,false);
00584     UINT8 strVersion[255];
00585     UINT32 tmpLen=255;
00586     if(getDOMElementValue(elemVersion,strVersion,&tmpLen)==E_SUCCESS)
00587       {
00588 #ifdef _DEBUG
00589         CAMsg::printMsg(LOG_INFO,"XML MixProtocolVersion value:%s\n",strVersion);
00590 #endif
00591         if(tmpLen==3&&memcmp(strVersion,"0.4",3)==0)
00592           {
00593             CAMsg::printMsg(LOG_INFO,"MixCascadeProtocolVersion: 0.4\n");
00594             m_MixCascadeProtocolVersion=MIX_CASCADE_PROTOCOL_VERSION_0_4;
00595             m_bWithFirstMixSymmetric=true;
00596           }
00597         else if(tmpLen==3&&memcmp(strVersion,"0.3",3)==0)
00598           {
00599             CAMsg::printMsg(LOG_INFO,"MixCascadeProtocolVersion: 0.3\n");
00600             m_MixCascadeProtocolVersion=MIX_CASCADE_PROTOCOL_VERSION_0_3;
00601           }
00602         else if(tmpLen==3&&memcmp(strVersion,"0.2",3)==0)
00603           {
00604             CAMsg::printMsg(LOG_INFO,"MixCascadeProtocolVersion: 0.2\n");
00605             m_MixCascadeProtocolVersion=MIX_CASCADE_PROTOCOL_VERSION_0_2;
00606           }
00607         else if(tmpLen==4&&memcmp(strVersion,"0.10",4)==0)
00608           {
00609             CAMsg::printMsg(LOG_INFO,"MixCascadeProtocolVersion: 0.10\n");
00610             m_MixCascadeProtocolVersion=MIX_CASCADE_PROTOCOL_VERSION_0_1_0;
00611             m_bWithEnhancedChannelEncryption=true;
00612             m_SymChannelKeySize=32;
00613             m_SymChannelEncryptedKeySize=m_SymChannelKeySize+42;
00614             m_bWithFirstMixSymmetric=true;
00615           }
00616         else
00617           {
00618             CAMsg::printMsg(LOG_ERR,"Unsupported MixProtocolVersion!\n");
00619             return E_UNKNOWN;
00620           }
00621       }
00622     else
00623     {
00624 #ifdef _DEBUG
00625       CAMsg::printMsg(LOG_ERR,"No MixProtocolVersion given!\n");
00626       return E_UNKNOWN;
00627 #endif
00628     }
00629     DOMElement* elemMixes=NULL;
00630     getDOMChildByName(root,"Mixes",elemMixes,false);
00631     SINT32 chainlen=-1;
00632     if(elemMixes==NULL||getDOMElementAttribute(elemMixes,"count",&chainlen)!=E_SUCCESS)
00633       {
00634 #ifdef _DEBUG
00635         CAMsg::printMsg(LOG_ERR,"No count of Mixes given!\n");
00636         return E_UNKNOWN;
00637 #endif
00638       }
00639     m_chainlen=(UINT32)chainlen;
00640 #ifdef _DEBUG
00641     CAMsg::printMsg(LOG_INFO,"Number of Mixes is: %u\n",m_chainlen);
00642 #endif
00643     if(m_chainlen==0)
00644       {
00645 #ifdef _DEBUG
00646         CAMsg::printMsg(LOG_ERR,"Number of Mixes is 0!\n");
00647         return E_UNKNOWN;
00648 #endif
00649       }
00650     UINT32 i=0;
00651     m_arRSA=new CAASymCipher[m_chainlen];
00652     DOMNode* child=elemMixes->getLastChild();
00653     bool bIsLast=true;
00654     while(child!= NULL&&chainlen>0)
00655       {
00656         if(equals(child->getNodeName(),"Mix"))
00657           {
00658             DOMNode* nodeKey=child->getFirstChild();
00659             if(m_arRSA[i++].setPublicKeyAsDOMNode(nodeKey)!=E_SUCCESS)
00660               {
00661 #ifdef _DEBUG
00662                 CAMsg::printMsg(LOG_ERR,"Error in parsing the public key of a Mix\n");
00663                 return E_UNKNOWN;
00664 #endif
00665               }
00666             if(bIsLast)
00667             {
00668               DOMNode* tmpNode=NULL;
00669               getDOMChildByName(child,"MixProtocolVersion",tmpNode);
00670               UINT8 tmpBuff[255];
00671               UINT32 tmpBuffLen=255;
00672               if(getDOMElementValue(tmpNode,tmpBuff,&tmpBuffLen)==E_SUCCESS)
00673               {
00674                 CAMsg::printMsg(LOG_DEBUG,"Last Mix Protcol Version %s\n",tmpBuff);
00675                 if(strcmp("0.6",(char*)tmpBuff)==0)
00676                 {
00677                   m_bWithNewFlowControl=true;
00678                   CAMsg::printMsg(LOG_DEBUG,"Last Mix uses new flow control\n");
00679                 }
00680               }
00681               if(m_bWithNewFlowControl)
00682               {
00683                 getDOMChildByName(child,"FlowControl",tmpNode);
00684                 DOMElement* nodeDownstreamSendMe=NULL;
00685                 getDOMChildByName(tmpNode,"DownstreamSendMe",nodeDownstreamSendMe);
00686                 getDOMElementValue(nodeDownstreamSendMe,m_nFlowControlDownstreamSendMe,m_nFlowControlDownstreamSendMe);
00687                 CAMsg::printMsg(LOG_DEBUG,"Last Mix new flow control downstream sewnd me: %u\n",m_nFlowControlDownstreamSendMe);
00688               }
00689               bIsLast=false;
00690             }
00691             chainlen--;
00692           }
00693         child=child->getPreviousSibling();
00694       }
00695     if(chainlen!=0)
00696       {
00697 #ifdef _DEBUG
00698         CAMsg::printMsg(LOG_ERR,"Expected information for %u Mixes but found only %u!\n",m_chainlen,m_chainlen-chainlen);
00699         return E_UNKNOWN;
00700 #endif
00701       }
00702     //Now sending SymKeys....
00703     if(m_MixCascadeProtocolVersion==MIX_CASCADE_PROTOCOL_VERSION_0_2)
00704       {
00705         MIXPACKET oPacket;
00706         getRandom((UINT8*)&oPacket,MIXPACKET_SIZE);
00707         oPacket.flags=0;
00708         oPacket.channel=0;
00709         UINT8 keys[32];
00710         getRandom(keys,32);
00711         m_muxOut.setReceiveKey(keys,16);
00712         m_muxOut.setSendKey(keys+16,16);
00713         memcpy(oPacket.data,"KEYPACKET",9);
00714         memcpy(oPacket.data+9,keys,32);
00715         m_arRSA[m_chainlen-1].encrypt(oPacket.data,oPacket.data);
00716         m_muxOut.send(&oPacket);
00717         m_muxOut.setCrypt(true);
00718       }
00719     else
00720       {
00721         const char* XML_HEADER="<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
00722         const UINT32 XML_HEADER_SIZE=strlen(XML_HEADER);
00723         const char* XML_JAP_KEY_TEMPLATE="<JAPKeyExchange version=\"0.1\"><LinkEncryption>%s</LinkEncryption><MixEncryption>%s</MixEncryption></JAPKeyExchange>";
00724         //DOM_Document doc=DOM_Document::createDocument();
00725         //DOM_Element e = doc.createElement("JAPKeyExchange");
00726         //doc.appendChild(e);
00727         //e.setAttribute("version", "0.1");
00728         //DOM_Element elemLinkEnc = doc.createElement("LinkEncryption");
00729         UINT8* buff=new UINT8[9000];
00730         UINT8 linkKeys[64];
00731         getRandom(linkKeys,64);
00732         UINT8 outBuffLinkKey[512];
00733         UINT32 outlenLinkKey=512;
00734         CABase64::encode(linkKeys,64,outBuffLinkKey,&outlenLinkKey);
00735         outBuffLinkKey[outlenLinkKey]=0;
00736         //setDOMElementValue(elemLinkEnc,outBuff);
00737         //e.appendChild(elemLinkEnc);
00738         //DOM_Element elemMixEnc = doc.createElement("MixEncryption");
00739         UINT8 mixKeys[32];
00740         getRandom(mixKeys,32);
00741         m_pSymCipher=new CASymCipher();
00742         m_pSymCipher->setKey(mixKeys);
00743         m_pSymCipher->setIVs(mixKeys+16);
00744         UINT8 outBuffMixKey[512];
00745         UINT32 outlenMixKey=512;
00746         CABase64::encode(mixKeys,32,outBuffMixKey,&outlenMixKey);
00747         outBuffMixKey[outlenMixKey]=0;
00748         //setDOMElementValue(elemMixEnc,outBuff);
00749         //e.appendChild(elemMixEnc);
00750         sprintf((char*)buff,XML_JAP_KEY_TEMPLATE,outBuffLinkKey,outBuffMixKey);
00751         UINT32 encbufflen;
00752         UINT8* encbuff=encryptXMLElement(buff,strlen((char*)buff),encbufflen,&m_arRSA[m_chainlen-1]);
00753         UINT16 size2=htons((UINT16)(encbufflen+XML_HEADER_SIZE));
00754         SINT32 ret=m_muxOut.getCASocket()->send((UINT8*)&size2,2);
00755         ret=m_muxOut.getCASocket()->send((UINT8*)XML_HEADER,XML_HEADER_SIZE);
00756         ret=m_muxOut.getCASocket()->send(encbuff,encbufflen);
00757         delete[] encbuff;
00758         encbuff = NULL;
00759         delete[] buff;
00760         buff = NULL;
00761         // Checking Signature send from Mix
00762         ret=m_muxOut.getCASocket()->receiveFully((UINT8*)&size2,2);
00763         size2=ntohs(size2);
00764         UINT8* xmlbuff=new UINT8[size2];
00765         ret=m_muxOut.getCASocket()->receiveFully(xmlbuff,size2);
00766         delete[] xmlbuff;
00767         xmlbuff = NULL;
00768         m_muxOut.setSendKey(linkKeys,32);
00769         m_muxOut.setReceiveKey(linkKeys+32,32);
00770         m_muxOut.setCrypt(true);
00771       }
00772     if (doc != NULL)
00773     {
00774       doc->release();
00775       doc = NULL;
00776     }
00777     CAMsg::printMsg(LOG_INFO,"Login process and key exchange finished!\n");
00778     return E_SUCCESS;
00779   }
00780 #endif //!NEW_MIX_TYPE