Mixe for Privacy and Anonymity in the Internet
CAMiddleMix.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 
00029 #include "StdAfx.h"
00030 #ifndef ONLY_LOCAL_PROXY
00031 #include "CAMiddleMix.hpp"
00032 #include "CASingleSocketGroup.hpp"
00033 #include "CAMsg.hpp"
00034 #include "CACmdLnOptions.hpp"
00035 #include "CASocketAddrINet.hpp"
00036 #ifdef HAVE_UNIX_DOMAIN_PROTOCOL
00037   #include "CASocketAddrUnix.hpp"
00038 #endif
00039 #include "CAThread.hpp"
00040 #include "CAInfoService.hpp"
00041 #include "CAUtil.hpp"
00042 #include "CABase64.hpp"
00043 #include "CAPool.hpp"
00044 #include "xml/DOM_Output.hpp"
00045 #include "CAStatusManager.hpp"
00046 #include "CALibProxytest.hpp"
00047 
00048 SINT32 CAMiddleMix::initOnce()
00049   {
00050     CAMsg::printMsg(LOG_DEBUG,"Starting MiddleMix InitOnce\n");
00051     //m_pSignature=CALibProxytest::getOptions()->getSignKey();
00052     m_pMultiSignature=CALibProxytest::getOptions()->getMultiSigner();
00053     if(m_pMultiSignature==NULL)
00054       {
00055         return E_UNKNOWN;
00056       }
00057     if(CALibProxytest::getOptions()->getListenerInterfaceCount()<1)
00058       {
00059         CAMsg::printMsg(LOG_CRIT,"No ListenerInterfaces specified!\n");
00060         return E_UNKNOWN;
00061       }
00062     return E_SUCCESS;
00063   }
00064 
00081 SINT32 CAMiddleMix::processKeyExchange()
00082   {
00083     UINT8* recvBuff=NULL;
00084     UINT32 len;
00085     SINT32 ret;
00086 
00087     if((ret = m_pMuxOut->receiveFully((UINT8*)&len, sizeof(len), TIMEOUT_MIX_CONNECTION_ESTABLISHEMENT)) != E_SUCCESS)
00088     {
00089       if (ret != E_UNKNOWN)
00090       {
00091         CAMsg::printMsg(LOG_INFO,"Error receiving Key Info length from next Mix. Reason: '%s' (%i)\n",
00092           GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR);
00093       }
00094       else
00095       {
00096         CAMsg::printMsg(LOG_INFO,"Error receiving Key Info length from next Mix.");
00097       }
00098       MONITORING_FIRE_NET_EVENT(ev_net_keyExchangeNextFailed);
00099       return E_UNKNOWN;
00100     }
00101     len=ntohl(len);   
00102     CAMsg::printMsg(LOG_INFO,"Received Key Info length %u\n",len);
00103     
00104     if (len > 100000)
00105     {
00106       CAMsg::printMsg(LOG_WARNING,"Unrealistic length for key info: %u We might not be able to get a connection.\n",len);
00107     }
00108     
00109     recvBuff=new UINT8[len+1]; //for the \0 at the end
00110     if(recvBuff==NULL)
00111       return E_UNKNOWN;
00112     if((ret = m_pMuxOut->receiveFully(recvBuff,len, TIMEOUT_MIX_CONNECTION_ESTABLISHEMENT)) != E_SUCCESS)
00113     {
00114       if (ret != E_UNKNOWN)
00115       {
00116         CAMsg::printMsg(LOG_INFO,"Error receiving Key Info from next Mix. Reason: '%s' (%i)\n",
00117           GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR);
00118       }
00119       else
00120       {
00121         CAMsg::printMsg(LOG_INFO,"Error receiving Key Info from next Mix.");
00122       }
00123       MONITORING_FIRE_NET_EVENT(ev_net_keyExchangeNextFailed);
00124       delete []recvBuff;
00125       recvBuff = NULL;
00126       return E_UNKNOWN;
00127     }
00128     recvBuff[len]=0; //make a string
00129     CAMsg::printMsg(LOG_INFO,"Received Key Info...\n");
00130     CAMsg::printMsg(LOG_INFO,"%s\n",recvBuff);
00131 
00132     //Parsing KeyInfo received from Mix n+1
00133     XERCES_CPP_NAMESPACE::DOMDocument* doc=parseDOMDocument(recvBuff,len);
00134     delete []recvBuff;
00135     recvBuff = NULL;
00136     if(doc==NULL)
00137       {
00138         CAMsg::printMsg(LOG_INFO,"Error parsing Key Info from next Mix!\n");
00139         MONITORING_FIRE_NET_EVENT(ev_net_keyExchangeNextFailed);
00140         return E_UNKNOWN;
00141       }
00142 
00143     DOMElement* root=doc->getDocumentElement();
00144 
00145     //Finding first <Mix> entry and sending symetric key...
00146     bool bFoundNextMix=false;
00147     DOMNode* child=root->getFirstChild();
00148     SINT32 result;
00149     SINT32 resultCompatibility = E_SUCCESS;
00150     while(child!=NULL)
00151       {
00152         if(equals(child->getNodeName(),"Mix"))
00153           {
00154             //verify certificate from next mix if enabled
00155             if(CALibProxytest::getOptions()->verifyMixCertificates())
00156             {
00157               CACertificate* nextMixCert = CALibProxytest::getOptions()->getTrustedCertificateStore()->verifyMixCert(child);
00158               if(nextMixCert != NULL)
00159               {
00160                 CAMsg::printMsg(LOG_DEBUG, "Next mix certificate was verified by a trusted root CA.\n");
00161                 CALibProxytest::getOptions()->setNextMixTestCertificate(nextMixCert);
00162               }
00163               else
00164               {
00165                 CAMsg::printMsg(LOG_ERR, "Could not verify certificate received from next mix!\n");
00166                 return E_UNKNOWN;
00167               }
00168             }
00169             //check Signature....
00170             //CASignature oSig;
00171             CACertificate* nextCert=CALibProxytest::getOptions()->getNextMixTestCertificate();
00172             //oSig.setVerifyKey(nextCert);
00173             ret = CAMultiSignature::verifyXML(child, nextCert);
00174             //ret=oSig.verifyXML(child,NULL);
00175             delete nextCert;
00176             nextCert = NULL;
00177             if(ret!=E_SUCCESS)
00178               {
00179                 MONITORING_FIRE_NET_EVENT(ev_net_keyExchangeNextFailed);
00180                 //CAMsg::printMsg(LOG_CRIT,"Could not verify the symmetric key from next mix! The operator of the next mix has to send you his current mix certificate, and you will have to import it in your configuration. Alternatively, you might import the proper root certification authority for verifying the certificate.\n");
00181                 CAMsg::printMsg(LOG_CRIT,"Could not verify the symmetric key from next mix! The operator of the next mix has to send you his current mix certificate, and you will have to import it in your configuration.\n");
00182                 return E_UNKNOWN;
00183               }
00184             
00185             if (resultCompatibility == E_SUCCESS)
00186             {
00187               resultCompatibility = checkCompatibility(child, "next");
00188             }
00189 
00190             //extracting Nonce and computing Hash of them
00191             DOMElement* elemNonce;
00192             getDOMChildByName(child,"Nonce",elemNonce,false);
00193             UINT32 lenNonce=1024;
00194             UINT8 arNonce[1024];
00195             UINT32 tmpLen=1024;
00196             if(elemNonce==NULL)
00197               {
00198                 MONITORING_FIRE_NET_EVENT(ev_net_keyExchangeNextFailed);
00199                 CAMsg::printMsg(LOG_INFO,"No nonce found in Key Info from next Mix!\n");
00200                 if (doc != NULL)
00201                 {
00202                   doc->release();
00203                   doc = NULL;
00204                 }
00205                 return E_UNKNOWN;
00206               }
00207             getDOMElementValue(elemNonce,arNonce,&lenNonce);
00208             CABase64::decode(arNonce,lenNonce,arNonce,&tmpLen);
00209             lenNonce=tmpLen;
00210             tmpLen=1024;
00211             CABase64::encode(SHA1(arNonce,lenNonce,NULL),SHA_DIGEST_LENGTH,
00212                                   arNonce,&tmpLen);
00213             arNonce[tmpLen]=0;
00214 
00215             //Extracting PubKey of Mix n+1, generating SymKey for link encryption
00216             //with Mix n+1, encrypt and send them
00217             DOMNode* rsaKey=child->getFirstChild();
00218             CAASymCipher oRSA;
00219             oRSA.setPublicKeyAsDOMNode(rsaKey);
00220             UINT8 key[64];
00221             getRandom(key,64);
00222             XERCES_CPP_NAMESPACE::DOMDocument* docSymKey=createDOMDocument();
00223             DOMElement* elemRoot=NULL;
00224             encodeXMLEncryptedKey(key,64,elemRoot,docSymKey,&oRSA);
00225             docSymKey->appendChild(elemRoot);
00226 
00227             appendCompatibilityInfo(elemRoot);
00228 
00229             DOMElement* elemNonceHash=createDOMElement(docSymKey,"Nonce");
00230             setDOMElementValue(elemNonceHash,arNonce);
00231             elemRoot->appendChild(elemNonceHash);
00232 
00234             DOMElement *elemKeepAlive;
00235             DOMElement *elemKeepAliveSendInterval;
00236             DOMElement *elemKeepAliveRecvInterval;
00237             getDOMChildByName(child,"KeepAlive",elemKeepAlive,false);
00238             getDOMChildByName(elemKeepAlive,"SendInterval",elemKeepAliveSendInterval,false);
00239             getDOMChildByName(elemKeepAlive,"ReceiveInterval",elemKeepAliveRecvInterval,false);
00240             UINT32 tmpSendInterval,tmpRecvInterval;
00241             getDOMElementValue(elemKeepAliveSendInterval,tmpSendInterval,0xFFFFFFFF); //if now send interval was given set it to "infinite"
00242             getDOMElementValue(elemKeepAliveRecvInterval,tmpRecvInterval,0xFFFFFFFF); //if no recv interval was given --> set it to "infinite"
00243             CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Getting offer -- SendInterval %u -- ReceiveInterval %u\n",tmpSendInterval,tmpRecvInterval);
00244             // Add Info about KeepAlive traffic
00245             UINT32 u32KeepAliveSendInterval=CALibProxytest::getOptions()->getKeepAliveSendInterval();
00246             UINT32 u32KeepAliveRecvInterval=CALibProxytest::getOptions()->getKeepAliveRecvInterval();
00247             elemKeepAlive=createDOMElement(docSymKey,"KeepAlive");
00248             elemKeepAliveSendInterval=createDOMElement(docSymKey,"SendInterval");
00249             elemKeepAliveRecvInterval=createDOMElement(docSymKey,"ReceiveInterval");
00250             elemKeepAlive->appendChild(elemKeepAliveSendInterval);
00251             elemKeepAlive->appendChild(elemKeepAliveRecvInterval);
00252             setDOMElementValue(elemKeepAliveSendInterval,u32KeepAliveSendInterval);
00253             setDOMElementValue(elemKeepAliveRecvInterval,u32KeepAliveRecvInterval);
00254             elemRoot->appendChild(elemKeepAlive);
00255             CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Offering -- SendInterval %u -- Receive Interval %u\n",u32KeepAliveSendInterval,u32KeepAliveRecvInterval);
00256             m_u32KeepAliveSendInterval2=max(u32KeepAliveSendInterval,tmpRecvInterval);
00257             if(m_u32KeepAliveSendInterval>10000)
00258               m_u32KeepAliveSendInterval2-=10000; //make the send interval a little bit smaller than the related receive intervall
00259             m_u32KeepAliveRecvInterval2=max(u32KeepAliveRecvInterval,tmpSendInterval);
00260             
00261             m_u32KeepAliveSendInterval2 = u32KeepAliveSendInterval;
00262             if (m_u32KeepAliveSendInterval2 > tmpRecvInterval - 10000)
00263               m_u32KeepAliveSendInterval2-=10000; //make the send interval a little bit smaller than the related receive interval
00264             m_u32KeepAliveRecvInterval2=max(u32KeepAliveRecvInterval,tmpSendInterval);
00265             if (m_u32KeepAliveRecvInterval2 - 10000 < tmpSendInterval)
00266             {
00267               m_u32KeepAliveRecvInterval2 += 10000;
00268             }
00269             
00270             CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Calculated -- SendInterval %u -- Receive Interval %u\n",m_u32KeepAliveSendInterval2,m_u32KeepAliveRecvInterval2);
00271 
00272             //m_pSignature->signXML(elemRoot);
00273             m_pMultiSignature->signXML(elemRoot, true);
00274             m_pMuxOut->setSendKey(key,32);
00275             m_pMuxOut->setReceiveKey(key+32,32);
00276             UINT32 outlen=0;
00277             UINT8* out=DOM_Output::dumpToMem(docSymKey,&outlen);
00278             CAMsg::printMsg(LOG_DEBUG,"send length %u\n", outlen);
00279             UINT32 size=htonl(outlen);
00280             m_pMuxOut->getCASocket()->send((UINT8*)&size, sizeof(size));
00281             m_pMuxOut->getCASocket()->send(out, outlen);
00282             if (docSymKey != NULL)
00283             {
00284               docSymKey->release();
00285               docSymKey = NULL;
00286             }
00287             delete[] out;
00288             out = NULL;
00289             bFoundNextMix=true;
00290             break;
00291           }
00292         child=child->getNextSibling();
00293       }
00294       
00295       
00296     if(!bFoundNextMix)
00297       {
00298         CAMsg::printMsg(LOG_INFO,"Error -- no Key Info found for next Mix!\n");
00299         MONITORING_FIRE_NET_EVENT(ev_net_keyExchangeNextFailed);
00300         if (doc != NULL)
00301         {
00302           doc->release();
00303           doc = NULL;
00304         }
00305         return E_UNKNOWN;
00306       }
00307     // -----------------------------------------
00308     // ---- Start exchange with Mix n-1 --------
00309     // -----------------------------------------
00310     //Inserting own (key) info
00311     UINT32 count=0;
00312     if(getDOMElementAttribute(root,"count",count)!=E_SUCCESS)
00313       {
00314         MONITORING_FIRE_NET_EVENT(ev_net_keyExchangeNextFailed);
00315         if (doc != NULL)
00316         {
00317           doc->release();
00318           doc = NULL;
00319         }
00320         return E_UNKNOWN;
00321       }
00322     count++;
00323     setDOMElementAttribute(root,"count",count);
00324 
00325     addMixInfo(root, true);
00326     DOMElement* mixNode;
00327     getDOMChildByName(root, "Mix", mixNode, false);
00328 
00329 
00330     UINT8 tmpBuff[50];
00331     CALibProxytest::getOptions()->getMixId(tmpBuff,50); //the mix id...
00332     setDOMElementAttribute(mixNode,"id",tmpBuff);
00333     //Supported Mix Protocol -->currently "0.3"
00334     DOMElement* elemMixProtocolVersion=createDOMElement(doc,"MixProtocolVersion");
00335     mixNode->appendChild(elemMixProtocolVersion);
00336     setDOMElementValue(elemMixProtocolVersion,(UINT8*)"0.3");
00337 
00338     DOMElement* elemKey=NULL;
00339     m_pRSA->getPublicKeyAsDOMElement(elemKey,doc); //the key
00340     mixNode->appendChild(elemKey);
00341 
00342     appendCompatibilityInfo(mixNode);
00343 
00344     //inserting Nonce
00345     DOMElement* elemNonce=createDOMElement(doc,"Nonce");
00346     UINT8 arNonce[16];
00347     getRandom(arNonce,16);
00348     UINT32 tmpLen=50;
00349     CABase64::encode(arNonce,16,tmpBuff,&tmpLen);
00350     tmpBuff[tmpLen]=0;
00351     setDOMElementValue(elemNonce,tmpBuff);
00352     mixNode->appendChild(elemNonce);
00353 
00354 // Add Info about KeepAlive traffic
00355     DOMElement* elemKeepAlive;
00356     UINT32 u32KeepAliveSendInterval=CALibProxytest::getOptions()->getKeepAliveSendInterval();
00357     UINT32 u32KeepAliveRecvInterval=CALibProxytest::getOptions()->getKeepAliveRecvInterval();
00358     elemKeepAlive=createDOMElement(doc,"KeepAlive");
00359     DOMElement* elemKeepAliveSendInterval;
00360     DOMElement* elemKeepAliveRecvInterval;
00361     elemKeepAliveSendInterval=createDOMElement(doc,"SendInterval");
00362     elemKeepAliveRecvInterval=createDOMElement(doc,"ReceiveInterval");
00363     elemKeepAlive->appendChild(elemKeepAliveSendInterval);
00364     elemKeepAlive->appendChild(elemKeepAliveRecvInterval);
00365     setDOMElementValue(elemKeepAliveSendInterval,u32KeepAliveSendInterval);
00366     setDOMElementValue(elemKeepAliveRecvInterval,u32KeepAliveRecvInterval);
00367     mixNode->appendChild(elemKeepAlive);
00368     CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Offering -- SendInterval %u -- Receive Interval %u\n",u32KeepAliveSendInterval,u32KeepAliveRecvInterval);
00369 
00370     /* append the terms and conditions, if there are any, to the KeyInfo
00371      * Extensions, (nodes that can be removed from the KeyInfo without
00372      * destroying the signature of the "Mix"-node).
00373      */
00374     if(CALibProxytest::getOptions()->getTermsAndConditions() != NULL)
00375     {
00376       appendTermsAndConditionsExtension(doc, root);
00377       mixNode->appendChild(termsAndConditionsInfoNode(doc));
00378     }
00379 
00380     // create signature
00381     if(signXML(mixNode)!=E_SUCCESS)
00382     {
00383       CAMsg::printMsg(LOG_DEBUG,"Could not sign KeyInfo send to users...\n");
00384     }
00385 
00386 
00387 
00388     //UINT8* out=new UINT8[0xFFFF];
00389     //memset(out, 0, (sizeof(UINT8)*0xFFFF));
00390     UINT32 outlen = 0;
00391     UINT8* out = DOM_Output::dumpToMem(doc, &outlen);
00392 #ifdef _DEBUG
00393     CAMsg::printMsg(LOG_DEBUG,"New Key Info size: %u\n", outlen);
00394 #endif
00395     len = htonl(outlen);
00396     //memcpy(out,&len, sizeof(len));
00397 
00398     m_pMuxIn->getCASocket()->send((UINT8*) &len, sizeof(len));
00399 
00400     ret=m_pMuxIn->getCASocket()->send(out, outlen);
00401     delete[] out;
00402     out = NULL;
00403     if( (ret < 0) || (ret != (SINT32)outlen) )
00404     {
00405       CAMsg::printMsg(LOG_DEBUG,"Error sending new New Key Info\n");
00406       MONITORING_FIRE_NET_EVENT(ev_net_keyExchangeNextFailed);
00407       if (doc != NULL)
00408       {
00409         doc->release();
00410         doc = NULL;
00411       }
00412       return E_UNKNOWN;
00413     }
00414     MONITORING_FIRE_NET_EVENT(ev_net_keyExchangeNextSuccessful);
00415     CAMsg::printMsg(LOG_DEBUG,"Sending new key info succeeded\n");
00416     
00417     CAMsg::printMsg(LOG_INFO,"Waiting for length of symmetric key from previous Mix...\n");
00418     //Now receiving the symmetric key form Mix n-1
00419     if((ret = m_pMuxIn->receiveFully((UINT8*) &len, sizeof(len), TIMEOUT_MIX_CONNECTION_ESTABLISHEMENT)) != E_SUCCESS)
00420     {
00421       if (ret != E_UNKNOWN)
00422       {
00423         CAMsg::printMsg(LOG_CRIT,"Error receiving symmetric key info length from the previous mix! Reason: '%s' (%i)\n",
00424           GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR);
00425       }
00426       else
00427       {
00428         CAMsg::printMsg(LOG_CRIT,"Error receiving symmetric key info length from the previous mix!");
00429       }
00430       return E_UNKNOWN;
00431     }
00432     
00433     len = ntohl(len);
00434     
00435     if (len > 100000)
00436     {
00437       CAMsg::printMsg(LOG_WARNING,"Unrealistic length for key info: %u We might not be able to get a connection.\n",len);
00438     }
00439     
00440     
00441     recvBuff = new UINT8[len+1]; //for \0 at the end
00442     
00443     if((ret = m_pMuxIn->receiveFully(recvBuff, len, TIMEOUT_MIX_CONNECTION_ESTABLISHEMENT)) != E_SUCCESS)
00444     //if((recLen = m_pMuxIn->getCASocket()->receive(recvBuff, len)) != len)
00445     {   
00446       MONITORING_FIRE_NET_EVENT(ev_net_keyExchangePrevFailed);
00447       if (ret != E_UNKNOWN)
00448       {
00449         CAMsg::printMsg(LOG_ERR,"Socket error occurred while receiving the symmetric key from the previous mix! Reason: '%s' (%i) The previous mix might be unable to verify our Mix certificate(s) and therefore closed the connection. Please ask the operator for the log, and exchange your certificates if necessary.\n",
00450             GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR);
00451       }
00452       else
00453       {
00454         CAMsg::printMsg(LOG_ERR,"Socket error occurred while receiving the symmetric key from the previous mix! The previous mix might be unable to verify our Mix certificate(s) and therefore closed the connection. Please ask the operator for the log, and exchange your certificates if necessary.\n");
00455       }
00456       delete []recvBuff;
00457       recvBuff = NULL;
00458       if (doc != NULL)
00459       {
00460         doc->release();
00461         doc = NULL;
00462       }
00463       return E_UNKNOWN;
00464     }
00465     recvBuff[len]=0;
00466     CAMsg::printMsg(LOG_INFO,"Symmetric Key Info received is:\n");
00467     CAMsg::printMsg(LOG_INFO,"%s\n",(char*)recvBuff);
00468     //Parsing doc received
00469     doc=parseDOMDocument(recvBuff, len);
00470     delete[] recvBuff;
00471     recvBuff = NULL;
00472     if(doc==NULL)
00473     {
00474       MONITORING_FIRE_NET_EVENT(ev_net_keyExchangePrevFailed);
00475       CAMsg::printMsg(LOG_INFO,"Error parsing Key Info from previous Mix!\n");
00476       return E_UNKNOWN;
00477     }
00478     DOMElement* elemRoot=doc->getDocumentElement();
00479     //verify certificate from previous mix if enabled
00480     if(CALibProxytest::getOptions()->verifyMixCertificates())
00481     {
00482       CACertificate* prevMixCert = CALibProxytest::getOptions()->getTrustedCertificateStore()->verifyMixCert(elemRoot);
00483       if(prevMixCert != NULL)
00484       {
00485         CAMsg::printMsg(LOG_DEBUG, "Previous mix certificate was verified by a trusted root CA.\n");
00486         CALibProxytest::getOptions()->setPrevMixTestCertificate(prevMixCert);
00487       }
00488       else
00489       {
00490         CAMsg::printMsg(LOG_ERR, "Could not verify certificate received from previous mix!\n");
00491         return E_UNKNOWN;
00492       }
00493     }
00494     //verify signature
00495     //CASignature oSig;
00496     CACertificate* pCert=CALibProxytest::getOptions()->getPrevMixTestCertificate();
00497     //oSig.setVerifyKey(pCert);
00498     result = CAMultiSignature::verifyXML(elemRoot, pCert);
00499     delete pCert;
00500     pCert = NULL;
00501     //if(oSig.verifyXML(elemRoot)!=E_SUCCESS)
00502     if(result != E_SUCCESS)
00503     {
00504       MONITORING_FIRE_NET_EVENT(ev_net_keyExchangePrevFailed);
00505       //CAMsg::printMsg(LOG_CRIT,"Could not verify the symmetric key from previous mix! The operator of the previous mix has to send you his current mix certificate, and you will have to import it in your configuration. Alternatively, you might import the proper root certification authority for verifying the certificate.\n");
00506       CAMsg::printMsg(LOG_CRIT,"Could not verify the symmetric key from previous mix! The operator of the previous mix has to send you his current mix certificate, and you will have to import it in your configuration.\n");
00507       if (doc != NULL)
00508       {
00509         doc->release();
00510         doc = NULL;
00511       }
00512       return E_UNKNOWN;
00513     }
00514 
00515       
00516       
00517      if (resultCompatibility != E_SUCCESS ||
00518       (resultCompatibility = checkCompatibility(elemRoot, "previous")) != E_SUCCESS)
00519      {
00520         if (doc != NULL)
00521         {
00522           doc->release();
00523           doc = NULL;
00524         }
00525         return resultCompatibility;
00526       }
00527 
00528     //Verifying nonce
00529     elemNonce=NULL;
00530     getDOMChildByName(elemRoot,"Nonce",elemNonce,false);
00531     tmpLen=50;
00532     memset(tmpBuff,0,tmpLen);
00533     if(elemNonce==NULL||getDOMElementValue(elemNonce,tmpBuff,&tmpLen)!=E_SUCCESS||
00534       CABase64::decode(tmpBuff,tmpLen,tmpBuff,&tmpLen)!=E_SUCCESS||
00535       tmpLen!=SHA_DIGEST_LENGTH ||
00536       memcmp(SHA1(arNonce,16,NULL),tmpBuff,SHA_DIGEST_LENGTH)!=0
00537       )
00538     {
00539       MONITORING_FIRE_NET_EVENT(ev_net_keyExchangePrevFailed);
00540       CAMsg::printMsg(LOG_CRIT,"Could not verify the Nonce from previous mix!\n");
00541       if (doc != NULL)
00542       {
00543         doc->release();
00544         doc = NULL;
00545       }
00546       return E_UNKNOWN;
00547     }
00548     CAMsg::printMsg(LOG_INFO,"Verified the symmetric key of the previous mix!\n");
00549 
00550     UINT8 key[150];
00551     UINT32 keySize=150;
00552 
00553     ret=decodeXMLEncryptedKey(key,&keySize,elemRoot,m_pRSA);
00554     if(ret!=E_SUCCESS||keySize!=64)
00555     {
00556       MONITORING_FIRE_NET_EVENT(ev_net_keyExchangePrevFailed);
00557       CAMsg::printMsg(LOG_CRIT,"Could not set the symmetric key from previous mix to be used by the MuxSocket!\n");
00558       if (doc != NULL)
00559       {
00560         doc->release();
00561         doc = NULL;
00562       }
00563       return E_UNKNOWN;
00564     }
00565     MONITORING_FIRE_NET_EVENT(ev_net_keyExchangePrevSuccessful);
00566     m_pMuxIn->setReceiveKey(key,32);
00567     m_pMuxIn->setSendKey(key+32,32);
00568 
00570     elemKeepAlive=NULL;
00571     elemKeepAliveSendInterval=NULL;
00572     elemKeepAliveRecvInterval=NULL;
00573     getDOMChildByName(elemRoot,"KeepAlive",elemKeepAlive);
00574     getDOMChildByName(elemKeepAlive,"SendInterval",elemKeepAliveSendInterval);
00575     getDOMChildByName(elemKeepAlive,"ReceiveInterval",elemKeepAliveRecvInterval);
00576     UINT32 tmpSendInterval,tmpRecvInterval;
00577     getDOMElementValue(elemKeepAliveSendInterval,tmpSendInterval,0xFFFFFFFF); //if no send interval was given set it to "infinite"
00578     getDOMElementValue(elemKeepAliveRecvInterval,tmpRecvInterval,0xFFFFFFFF); //if no recv interval was given --> set it to "infinite"
00579     CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Getting offer -- SendInterval %u -- Receive Interval %u\n",tmpSendInterval,tmpRecvInterval);
00580     m_u32KeepAliveSendInterval = u32KeepAliveSendInterval;
00581     if (m_u32KeepAliveSendInterval > tmpRecvInterval - 10000)
00582       m_u32KeepAliveSendInterval-=10000; //make the send interval a little bit smaller than the related receive interval
00583     m_u32KeepAliveRecvInterval=max(u32KeepAliveRecvInterval,tmpSendInterval);
00584     if (m_u32KeepAliveRecvInterval - 10000 < tmpSendInterval)
00585     {
00586       m_u32KeepAliveRecvInterval += 10000;
00587     }
00588     CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Calculated -- SendInterval %u -- Receive Interval %u\n",m_u32KeepAliveSendInterval,m_u32KeepAliveRecvInterval);
00589 
00590     if (doc != NULL)
00591     {
00592       doc->release();
00593       doc = NULL;
00594     }
00595 
00596     return E_SUCCESS;
00597   }
00598 
00599 SINT32 CAMiddleMix::init()
00600   {
00601 #ifdef DYNAMIC_MIX
00602     m_bBreakNeeded = m_bReconfigured;
00603 #endif
00604 
00605     CAMsg::printMsg(LOG_INFO,"Creating Key...\n");
00606     m_pRSA=new CAASymCipher();
00607 #ifdef EXPORT_ASYM_PRIVATE_KEY
00608     if(CALibProxytest::getOptions()->isImportKey())
00609       {
00610         UINT32 keyFileBuffLen=8096;
00611         UINT8* keyFileBuff=new UINT8[keyFileBuffLen];
00612         CALibProxytest::getOptions()->getEncryptionKeyImportFile(keyFileBuff,keyFileBuffLen);
00613         UINT8* keyBuff=readFile(keyFileBuff,&keyFileBuffLen);
00614         m_pRSA->setPrivateKeyAsXML(keyBuff,keyFileBuffLen);
00615         delete[] keyFileBuff;
00616         delete[] keyBuff;
00617       }
00618     else
00619 #endif
00620       {
00621         if(m_pRSA->generateKeyPair(1024)!=E_SUCCESS)
00622           {
00623             CAMsg::printMsg(LOG_CRIT,"Could not generate a valid key pair\n");
00624             return E_UNKNOWN;
00625           }
00626       }
00627 #ifdef EXPORT_ASYM_PRIVATE_KEY
00628     if(CALibProxytest::getOptions()->isExportKey())
00629       {
00630         UINT32 keyFileBuffLen=8096;
00631         UINT8* keyFileBuff=new UINT8[keyFileBuffLen];
00632         UINT8* keyBuff=new UINT8[keyFileBuffLen];
00633         CALibProxytest::getOptions()->getEncryptionKeyExportFile(keyFileBuff,keyFileBuffLen);
00634         m_pRSA->getPrivateKeyAsXML(keyBuff,&keyFileBuffLen);
00635         saveFile(keyFileBuff,keyBuff,keyFileBuffLen);
00636         delete[] keyFileBuff;
00637         delete[] keyBuff;
00638       }
00639 #endif
00640 
00641     // connect to next mix
00642     CASocketAddr* pAddrNext=NULL;
00643     for(UINT32 i=0;i<CALibProxytest::getOptions()->getTargetInterfaceCount();i++)
00644       {
00645         CATargetInterface oNextMix;
00646         CALibProxytest::getOptions()->getTargetInterface(oNextMix,i+1);
00647         if(oNextMix.getTargetType()==TARGET_MIX)
00648           {
00649             pAddrNext=oNextMix.getAddr();
00650             break;
00651           }
00652         oNextMix.cleanAddr();
00653       }
00654     if(pAddrNext==NULL)
00655       {
00656         CAMsg::printMsg(LOG_CRIT,"No next Mix specified!\n");
00657         return E_UNKNOWN;
00658       }
00659 
00660     m_pMuxOut=new CAMuxSocket();
00661 
00662     if(m_pMuxOut->getCASocket()->create(pAddrNext->getType())!=E_SUCCESS)
00663       {
00664         CAMsg::printMsg(LOG_CRIT,"Init: Cannot create SOCKET for outgoing connection...\n");
00665         return E_UNKNOWN;
00666       }
00667     m_pMuxOut->getCASocket()->setRecvBuff(50*MIXPACKET_SIZE);
00668     m_pMuxOut->getCASocket()->setSendBuff(50*MIXPACKET_SIZE);
00669 
00670 
00671     CAListenerInterface* pListener=NULL;
00672     UINT32 interfaces=CALibProxytest::getOptions()->getListenerInterfaceCount();
00673     for(UINT32 i=1;i<=interfaces;i++)
00674       {
00675         pListener=CALibProxytest::getOptions()->getListenerInterface(i);
00676         if(!pListener->isVirtual())
00677           break;
00678         delete pListener;
00679         pListener=NULL;
00680       }
00681     if(pListener==NULL)
00682       {
00683         CAMsg::printMsg(LOG_CRIT,"Failed to initialize socket for previous mix! Reason: no usable (non virtual) listener interface found!\n");
00684         return E_UNKNOWN;
00685       }
00686     const CASocketAddr* pAddr=NULL;
00687     pAddr=pListener->getAddr();
00688     delete pListener;
00689     pListener = NULL;
00690 
00691     UINT8 buff[255];
00692     pAddr->toString(buff,255);
00693     CAMsg::printMsg(LOG_INFO,"Waiting for connection from previous Mix on %s...\n", buff);
00694 
00695     m_pMuxIn=new CAMuxSocket();
00696 #ifdef DYNAMIC_MIX
00697     // LERNGRUPPE Do not block if we are currently reconfiguring
00698     if(m_bBreakNeeded != m_bReconfigured)
00699     {
00700       return E_UNKNOWN;
00701     }
00702 #endif
00703     SINT32 ret=m_pMuxIn->accept(*pAddr);
00704     delete pAddr;
00705     pAddr = NULL;
00706     if(ret!=E_SUCCESS)
00707       {
00708         CAMsg::printMsg(LOG_CRIT,"Error waiting for previous Mix... -- restart!\n");
00709         return E_UNKNOWN;
00710       }
00711     CAMsg::printMsg(LOG_INFO," connected!\n");
00712     MONITORING_FIRE_NET_EVENT(ev_net_prevConnected);
00713 
00714     m_pMuxIn->getCASocket()->setRecvBuff(50*MIXPACKET_SIZE);
00715     m_pMuxIn->getCASocket()->setSendBuff(50*MIXPACKET_SIZE);
00716     m_pMuxIn->getCASocket()->setKeepAlive((UINT32)1800);
00717 
00718 
00719     //pAddrNext->toString(buff,255);
00720     //CAMsg::printMsg(LOG_INFO,"Connecting to next Mix on %s...\n", buff);
00721 
00723     if(connectToNextMix(pAddrNext) != E_SUCCESS)
00724     {
00725       delete pAddrNext;
00726       pAddrNext = NULL;
00727       MONITORING_FIRE_NET_EVENT(ev_net_prevConnectionClosed);
00728       CAMsg::printMsg(LOG_DEBUG, "CAMiddleMix::init - Unable to connect to next mix\n");
00729       return E_UNKNOWN;
00730     }
00731     delete pAddrNext;
00732     pAddrNext = NULL;
00733 
00734 //    mSocketGroup.add(muxOut);
00735     MONITORING_FIRE_NET_EVENT(ev_net_nextConnected);
00736     CAMsg::printMsg(LOG_INFO," connected!\n");
00737 
00738     m_pMuxOut->getCASocket()->setKeepAlive((UINT32)1800);
00739 
00740 
00741       if((ret = processKeyExchange())!=E_SUCCESS)
00742     {
00743       CAMsg::printMsg(LOG_CRIT,"Error in proccessKeyExchange()!\n");
00744         return ret;
00745     }
00746 
00747     m_pQueueSendToMixBefore=new CAQueue(sizeof(tQueueEntry));
00748     m_pQueueSendToMixAfter=new CAQueue(sizeof(tQueueEntry));
00749 
00750     m_pMuxInControlChannelDispatcher=new CAControlChannelDispatcher(m_pQueueSendToMixBefore,NULL,0);
00751 
00752 #ifdef REPLAY_DETECTION
00753     m_pReplayDB=new CADatabase();
00754     m_pReplayDB->start();
00755     m_pReplayMsgProc=new CAReplayCtrlChannelMsgProc(this);
00756     m_pReplayMsgProc->startTimeStampPorpagation(REPLAY_TIMESTAMP_PROPAGATION_INTERVALL);
00757     m_u64ReferenceTime=time(NULL);
00758 #endif
00759     m_pMiddleMixChannelList=new CAMiddleMixChannelList();
00760 
00761     return E_SUCCESS;
00762   }
00763 
00765 THREAD_RETURN mm_loopSendToMixAfter(void* param)
00766   {
00767     INIT_STACK;
00768     BEGIN_STACK("CAFirstMix::fm_loopSendToMixAfter");
00769 
00770     CAMiddleMix* pMiddleMix=(CAMiddleMix*)param;
00771     CAQueue* pQueue=((CAMiddleMix*)param)->m_pQueueSendToMixAfter;
00772     CAMuxSocket* pMuxSocket=pMiddleMix->m_pMuxOut;
00773 
00774     UINT32 len;
00775     SINT32 ret;
00776     tPoolEntry* pPoolEntry=new tPoolEntry;
00777     MIXPACKET* pMixPacket=&pPoolEntry->packet;
00778     UINT32 u32KeepAliveSendInterval=pMiddleMix->m_u32KeepAliveSendInterval2;
00779     while(pMiddleMix->m_bRun)
00780       {
00781         len=sizeof(tPoolEntry);
00782         ret=pQueue->getOrWait((UINT8*)pPoolEntry,&len,u32KeepAliveSendInterval);
00783         if(!(pMiddleMix->m_bRun))
00784         {
00785           CAMsg::printMsg(LOG_INFO,"SendToMixAfter thread: was interrupted.\n");
00786           MONITORING_FIRE_NET_EVENT(ev_net_nextConnectionClosed);
00787           break;
00788         }
00789         if(ret==E_TIMEDOUT)
00790           {//send a dummy as keep-alive-traffic
00791             pMixPacket->flags=CHANNEL_DUMMY;
00792             pMixPacket->channel=DUMMY_CHANNEL;
00793             getRandom(pMixPacket->data,DATA_SIZE);
00794           }
00795         else if(ret!=E_SUCCESS||len!=sizeof(tQueueEntry))
00796           {
00797             MONITORING_FIRE_NET_EVENT(ev_net_nextConnectionClosed);
00798             CAMsg::printMsg(LOG_ERR,"CAFirstMix::lm_loopSendToMixAfter - Error in dequeueing MixPaket\n");
00799             CAMsg::printMsg(LOG_ERR,"ret=%i len=%i\n",ret,len);
00800             break;
00801           }
00802         if((pMuxSocket->send(pMixPacket)!=MIXPACKET_SIZE))
00803           {
00804             MONITORING_FIRE_NET_EVENT(ev_net_nextConnectionClosed);
00805             CAMsg::printMsg(LOG_ERR,"CAFirstMix::lm_loopSendToMixAfter - Error in sending MixPaket\n");
00806             break;
00807           }
00808 #ifdef LOG_PACKET_TIMES
00809         if(!isZero64(pPoolEntry->timestamp_proccessing_start))
00810           {
00811             getcurrentTimeMicros(pPoolEntry->timestamp_proccessing_end);
00812             pFirstMix->m_pLogPacketStats->addToTimeingStats(*pPoolEntry,pMixPacket->flags,true);
00813           }
00814 #endif
00815       }
00816     pMiddleMix->m_bRun = false;
00817     delete pPoolEntry;
00818     pPoolEntry = NULL;
00819     FINISH_STACK("CAFirstMix::fm_loopSendToMixAfter");
00820 
00821     CAMsg::printMsg(LOG_DEBUG,"Exiting Thread SendToMixAfter\n");
00822     THREAD_RETURN_SUCCESS;
00823   }
00824 
00826 THREAD_RETURN mm_loopSendToMixBefore(void* param)
00827   {
00828     INIT_STACK;
00829     BEGIN_STACK("CAFirstMix::fm_loopSendToMixBefore");
00830 
00831     CAMiddleMix* pMiddleMix=(CAMiddleMix*)param;
00832     CAQueue* pQueue=((CAMiddleMix*)param)->m_pQueueSendToMixBefore;
00833     CAMuxSocket* pMuxSocket=pMiddleMix->m_pMuxIn;
00834 
00835     UINT32 len;
00836     SINT32 ret;
00837     tPoolEntry* pPoolEntry=new tPoolEntry;
00838     MIXPACKET* pMixPacket=&pPoolEntry->packet;
00839     UINT32 u32KeepAliveSendInterval=pMiddleMix->m_u32KeepAliveSendInterval;
00840     while(pMiddleMix->m_bRun)
00841       {
00842         len=sizeof(tPoolEntry);
00843         ret=pQueue->getOrWait((UINT8*)pPoolEntry,&len,u32KeepAliveSendInterval);
00844         if(!(pMiddleMix->m_bRun))
00845         {
00846           CAMsg::printMsg(LOG_INFO,"SendToMixBefore thread: was interrupted.\n");
00847           break;
00848         }
00849         if(ret==E_TIMEDOUT)
00850           {//send a dummy as keep-alive-traffic
00851             pMixPacket->flags=CHANNEL_DUMMY;
00852             pMixPacket->channel=DUMMY_CHANNEL;
00853             getRandom(pMixPacket->data,DATA_SIZE);
00854           }
00855         else if(ret!=E_SUCCESS||len!=sizeof(tQueueEntry))
00856           {
00857             MONITORING_FIRE_NET_EVENT(ev_net_prevConnectionClosed);
00858             CAMsg::printMsg(LOG_ERR,"CAFirstMix::lm_loopSendToMixBefore - Error in dequeueing MixPaket\n");
00859             CAMsg::printMsg(LOG_ERR,"ret=%i len=%i\n",ret,len);
00860             break;
00861           }
00862         if((pMuxSocket->send(pMixPacket)!=MIXPACKET_SIZE))
00863           {
00864             MONITORING_FIRE_NET_EVENT(ev_net_prevConnectionClosed);
00865             CAMsg::printMsg(LOG_ERR,"CAFirstMix::lm_loopSendToMixBefore - Error in sending MixPaket\n");
00866             break;
00867           }
00868 #ifdef LOG_PACKET_TIMES
00869         if(!isZero64(pPoolEntry->timestamp_proccessing_start))
00870           {
00871             getcurrentTimeMicros(pPoolEntry->timestamp_proccessing_end);
00872             pFirstMix->m_pLogPacketStats->addToTimeingStats(*pPoolEntry,pMixPacket->flags,true);
00873           }
00874 #endif
00875       }
00876     pMiddleMix->m_bRun = false;
00877     delete pPoolEntry;
00878     pPoolEntry = NULL;
00879     FINISH_STACK("CAFirstMix::fm_loopSendToMixBefore");
00880 
00881     CAMsg::printMsg(LOG_DEBUG,"Exiting Thread SendToMixBefore\n");
00882     THREAD_RETURN_SUCCESS;
00883   }
00884 
00885 #define MIDDLE_MIX_SIZE_OF_SYMMETRIC_KEYS 2*KEY_SIZE
00886 #define MIDDLE_MIX_ASYM_PADDING_SIZE 42
00887 
00888 THREAD_RETURN mm_loopReadFromMixBefore(void* param)
00889   {
00890     CAMiddleMix* pMix=(CAMiddleMix*)param;
00891     HCHANNEL channelOut = 0, channelIn = 0;
00892     tPoolEntry* pPoolEntry=new tPoolEntry;
00893     MIXPACKET* pMixPacket=&pPoolEntry->packet;
00894 
00895     CAQueue* pQueue=pMix->m_pQueueSendToMixAfter;
00896 
00897     CASymCipher* pCipher;
00898     SINT32 ret;
00899     UINT8* tmpRSABuff=new UINT8[RSA_SIZE];
00900     UINT32 rsaOutLen=RSA_SIZE;
00901     CASingleSocketGroup oSocketGroup(false);
00902     oSocketGroup.add(*(pMix->m_pMuxIn));
00903 
00904     #ifdef USE_POOL
00905       CAPool* pPool=new CAPool(MIX_POOL_SIZE);
00906     #endif
00907 
00908     while(pMix->m_bRun)
00909       {
00910         if(pQueue->getSize()>MAX_READ_FROM_PREV_MIX_QUEUE_SIZE)
00911         {
00912 #ifdef DEBUG
00913           CAMsg::printMsg(LOG_DEBUG,"CAFirstMix::Queue prev is full!\n");
00914 #endif
00915           msSleep(200);
00916           continue;
00917         }
00918         #ifndef USE_POOL
00919           ret=oSocketGroup.select(1000);
00920         #else
00921           ret=oSocketGroup.select(MIX_POOL_TIMEOUT);
00922         #endif
00923         if(ret!=1)
00924           {
00925             if(ret==E_TIMEDOUT)
00926               {
00927                 #ifndef USE_POOL
00928                   continue;
00929                 #else
00930                   pMixPacket->channel=DUMMY_CHANNEL;
00931                   pMixPacket->flags=CHANNEL_DUMMY;
00932                   getRandom(pMixPacket->data,DATA_SIZE);
00933                   pPool->pool(pPoolEntry);
00934                   if(m_pMuxOut->send(pMixPacket)==SOCKET_ERROR)
00935                     pMix->m_bRun=false;
00936                 #endif
00937               }
00938             else
00939               {
00940                 CAMsg::printMsg(LOG_CRIT,"loopUpStream -- Fehler bei select() -- goto ERR!\n");
00941                 pMix->m_bRun=false;
00942                 MONITORING_FIRE_NET_EVENT(ev_net_prevConnectionClosed);
00943               }
00944           }
00945         else
00946           {
00947             ret=pMix->m_pMuxIn->receive(pMixPacket);
00948 
00949             if ((ret!=SOCKET_ERROR)&&(pMixPacket->flags & ~CHANNEL_ALLOWED_FLAGS))
00950             {
00951               CAMsg::printMsg(LOG_INFO,"loopUpStream received a packet with invalid flags: %0X .  Removing them.\n",(pMixPacket->flags & ~CHANNEL_ALLOWED_FLAGS));
00952               pMixPacket->flags&=CHANNEL_ALLOWED_FLAGS;
00953             }
00954 
00955             if(ret==SOCKET_ERROR)
00956             {
00957 
00958               CAMsg::printMsg(LOG_CRIT,"Fehler beim Empfangen -- Exiting!\n");
00959               pMix->m_bRun=false;
00960               MONITORING_FIRE_NET_EVENT(ev_net_prevConnectionClosed);
00961             }
00962             #ifdef USE_POOL
00963             else if(pMixPacket->channel==DUMMY_CHANNEL)
00964             {
00965               pMixPacket->flags=CHANNEL_DUMMY;
00966               getRandom(pMixPacket->data,DATA_SIZE);
00967               pPool->pool(pPoolEntry);
00968               if(pMix->m_pMuxOut->send(pMixPacket)==SOCKET_ERROR)
00969                 pMix->m_bRun=false;
00970             }
00971             #endif
00972 
00973             else //receive successful
00974             {
00975               channelIn = pMixPacket->channel;
00976               if(pMix->m_pMiddleMixChannelList->getInToOut(pMixPacket->channel,&channelOut,&pCipher)!=E_SUCCESS)
00977               {//new connection ?
00978                 if(pMixPacket->flags & CHANNEL_OPEN) //if not channel-open flag set -->drop this packet
00979                 {
00980                   #ifdef _DEBUG
00981                     CAMsg::printMsg(LOG_DEBUG,"New Connection from previous Mix!\n");
00982                   #endif
00983                   pMix->m_pRSA->decryptOAEP(pMixPacket->data,tmpRSABuff,&rsaOutLen);
00984                   #ifdef REPLAY_DETECTION
00985                     // replace time(NULL) with the real timestamp ()
00986                     // packet-timestamp + m_u64ReferenceTime
00987                     UINT32 stamp=((UINT32)(tmpRSABuff[13]<<16)+(UINT32)(tmpRSABuff[14]<<8)+(UINT32)(tmpRSABuff[15]))*REPLAY_BASE;
00988                     if(pMix->m_pReplayDB->insert(tmpRSABuff,stamp+pMix->m_u64ReferenceTime)!=E_SUCCESS)
00989 //                      if(pMix->m_pReplayDB->insert(tmpRSABuff,time(NULL))!=E_SUCCESS)
00990                       {
00991                         CAMsg::printMsg(LOG_INFO,"Replay: Duplicate packet ignored.\n");
00992                         continue;
00993                       }
00994                   #endif
00995 
00996                   pCipher=new CASymCipher();
00997                   pCipher->setKeys(tmpRSABuff,MIDDLE_MIX_SIZE_OF_SYMMETRIC_KEYS);
00998                   pCipher->crypt1(pMixPacket->data+RSA_SIZE,
00999                         pMixPacket->data+rsaOutLen-MIDDLE_MIX_SIZE_OF_SYMMETRIC_KEYS,
01000                         DATA_SIZE-RSA_SIZE);
01001                   memcpy(pMixPacket->data,tmpRSABuff+MIDDLE_MIX_SIZE_OF_SYMMETRIC_KEYS,rsaOutLen-MIDDLE_MIX_SIZE_OF_SYMMETRIC_KEYS);
01002                   getRandom(pMixPacket->data+DATA_SIZE-MIDDLE_MIX_SIZE_OF_SYMMETRIC_KEYS-MIDDLE_MIX_ASYM_PADDING_SIZE,MIDDLE_MIX_SIZE_OF_SYMMETRIC_KEYS+MIDDLE_MIX_ASYM_PADDING_SIZE);
01003                   pMix->m_pMiddleMixChannelList->add(pMixPacket->channel,pCipher,&channelOut);
01004                   pMixPacket->channel=channelOut;
01005                   #ifdef USE_POOL
01006                     pPool->pool(pPoolEntry);
01007                   #endif
01008                   #ifdef LOG_CRIME
01009                   crimeSurveillanceUpstream(pMixPacket, channelIn);
01010                   #endif
01011                   pQueue->add(pPoolEntry,sizeof(tPoolEntry));
01012                 }
01013               }
01014               else
01015               {//established connection
01016                 pCipher->crypt1(pMixPacket->data,pMixPacket->data,DATA_SIZE);
01017                 pCipher->unlock();
01018                 #ifdef USE_POOL
01019                   pPool->pool(pPoolEntry);
01020                 #endif
01021                 if((pMixPacket->flags&CHANNEL_CLOSE)!=0)
01022                 {//Channel close received -->remove channel form channellist
01023                   pMix->m_pMiddleMixChannelList->remove(pMixPacket->channel);
01024                 }
01025                 pMixPacket->channel=channelOut;
01026                 #ifdef LOG_CRIME
01027                 crimeSurveillanceUpstream(pMixPacket, channelIn);
01028                 #endif
01029                 pQueue->add(pPoolEntry,sizeof(tPoolEntry));
01030               }
01031             }
01032           }
01033       }
01034 
01035     CAMsg::printMsg(LOG_CRIT,"loopReadFromMixBefore -- Exiting clean ups...\n");
01036     pMix->m_bRun=false;
01037     UINT8 b[sizeof(tQueueEntry)+1];
01038     /* write bytes to the send queues to accelerate loop()-joins for the send threads*/
01039     if(pMix->m_pQueueSendToMixBefore!=NULL)
01040     {
01041       pMix->m_pQueueSendToMixBefore->add(b,sizeof(tQueueEntry)+1);
01042     }
01043     if(pMix->m_pQueueSendToMixAfter!=NULL)
01044     {
01045       pMix->m_pQueueSendToMixAfter->add(b,sizeof(tQueueEntry)+1);
01046     }
01047     delete tmpRSABuff;
01048     tmpRSABuff = NULL;
01049     delete pPoolEntry;
01050     pPoolEntry = NULL;
01051     #ifdef USE_POOL
01052       delete pPool;
01053       pPool = NULL;
01054     #endif
01055     CAMsg::printMsg(LOG_CRIT,"loopReadFromMixBefore -- Now Exiting!\n");
01056     THREAD_RETURN_SUCCESS;
01057   }
01058 
01059 THREAD_RETURN mm_loopReadFromMixAfter(void* param)
01060   {
01061     CAMiddleMix* pMix=(CAMiddleMix*)param;
01062     HCHANNEL channelIn;
01063     CASymCipher* pCipher;
01064 
01065     tPoolEntry* pPoolEntry=new tPoolEntry;
01066     MIXPACKET* pMixPacket=&pPoolEntry->packet;
01067 
01068     SINT32 ret;
01069     CASingleSocketGroup oSocketGroup(false);
01070     oSocketGroup.add(*(pMix->m_pMuxOut));
01071 
01072     CAQueue* pQueue=pMix->m_pQueueSendToMixBefore;
01073 
01074 #ifdef USE_POOL
01075     CAPool* pPool=new CAPool(MIX_POOL_SIZE);
01076 #endif
01077     while(pMix->m_bRun)
01078       {
01079         if(pQueue->getSize()>MAX_READ_FROM_NEXT_MIX_QUEUE_SIZE)
01080         {
01081 #ifdef DEBUG
01082           CAMsg::printMsg(LOG_DEBUG,"CAMiddleMix::Queue next is full!\n");
01083 #endif
01084           msSleep(200);
01085           continue;
01086         }
01087         #ifndef USE_POOL
01088           ret=oSocketGroup.select(1000);
01089         #else
01090           ret=oSocketGroup.select(MIX_POOL_TIMEOUT);
01091         #endif
01092         if(ret!=1)
01093           {
01094             if(ret==E_TIMEDOUT)
01095               {
01096                 #ifndef USE_POOL
01097                   continue;
01098                 #else
01099                   pMixPacket->channel=DUMMY_CHANNEL;
01100                   pMixPacket->flags=CHANNEL_DUMMY;
01101                   getRandom(pMixPacket->data,DATA_SIZE);
01102                   pPool->pool(pPoolEntry);
01103                   if(pMix->m_pMuxIn->send(pMixPacket)==SOCKET_ERROR)
01104                     pMix->m_bRun=false;
01105                 #endif
01106               }
01107             else
01108             {
01109               CAMsg::printMsg(LOG_CRIT,"loopReadFromMixAfter -- Error on select() while waiting for data from next mix -- goto ERR!\n");
01110               pMix->m_bRun=false;
01111               MONITORING_FIRE_NET_EVENT(ev_net_nextConnectionClosed);
01112             }
01113           }
01114         else
01115           {
01116 
01117             ret=pMix->m_pMuxOut->receive(pMixPacket);
01118             if ((ret!=SOCKET_ERROR)&&(pMixPacket->flags & ~CHANNEL_ALLOWED_FLAGS))
01119               {
01120                 CAMsg::printMsg(LOG_INFO,"loopReadFromMixAfter -- received a packet with invalid flags: %0X .  Removing them.\n",(pMixPacket->flags & ~CHANNEL_ALLOWED_FLAGS));
01121                 pMixPacket->flags&=CHANNEL_ALLOWED_FLAGS;
01122               }
01123             if(ret==SOCKET_ERROR)
01124               {
01125                 CAMsg::printMsg(LOG_CRIT,"loopReadFromMixAfter -- Error while receiving data from next mix. Reason: %s (%i)\n",
01126                   GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR);
01127                 pMix->m_bRun=false;
01128                 MONITORING_FIRE_NET_EVENT(ev_net_nextConnectionClosed);
01129               }
01130             #ifdef USE_POOL
01131             else if(pMixPacket->channel==DUMMY_CHANNEL)
01132               {
01133                 pMixPacket->flags=CHANNEL_DUMMY;
01134                 getRandom(pMixPacket->data,DATA_SIZE);
01135                 pPool->pool(pPoolEntry);
01136                 if(pMix->m_pMuxIn->send(pMixPacket)==SOCKET_ERROR)
01137                   pMix->m_bRun=false;
01138               }
01139             #endif
01140             #ifdef REPLAY_DETECTION
01141             else if(pMixPacket->channel==REPLAY_CONTROL_CHANNEL_ID)
01142               {
01143                 pQueue->add(pPoolEntry,sizeof(tPoolEntry));
01144               }
01145             #endif
01146             else if(pMix->m_pMiddleMixChannelList->getOutToIn(&channelIn,pMixPacket->channel,&pCipher)==E_SUCCESS)
01147               {//connection found
01148 #ifdef LOG_CRIME
01149                 HCHANNEL channelOut = pMixPacket->channel;
01150 #endif
01151                 pMixPacket->channel=channelIn;
01152 #ifdef LOG_CRIME
01153                 if((pMixPacket->flags&CHANNEL_SIG_CRIME)==CHANNEL_SIG_CRIME)
01154                   {
01155                     getRandom(pMixPacket->data,DATA_SIZE);
01156                     //Log in and out channel number, to allow
01157                     CAMsg::printMsg(LOG_CRIT,"Detecting crime activity - previous mix channel: %u, "
01158                         "next mix channel: %u\n", channelIn, channelOut);
01159                   }
01160                 else
01161 #endif
01162                 pCipher->crypt2(pMixPacket->data,pMixPacket->data,DATA_SIZE);
01163                 pCipher->unlock();
01164                 #ifdef USE_POOL
01165                   pPool->pool(pPoolEntry);
01166                 #endif
01167                 if((pMixPacket->flags&CHANNEL_CLOSE)!=0)
01168                   {//Channel close received -->remove channel form channellist
01169                     pMix->m_pMiddleMixChannelList->remove(channelIn);
01170                   }
01171                 pQueue->add(pPoolEntry,sizeof(tPoolEntry));
01172               }
01173           }
01174       }
01175 
01176     CAMsg::printMsg(LOG_CRIT,"loopReadFromMixAfter -- Exiting clean ups...\n");
01177     pMix->m_bRun=false;
01178     UINT8 b[sizeof(tQueueEntry)+1];
01179     /* write bytes to the send queues to accelerate loop()-joins for the send threads*/
01180     if(pMix->m_pQueueSendToMixBefore!=NULL)
01181     {
01182       pMix->m_pQueueSendToMixBefore->add(b,sizeof(tQueueEntry)+1);
01183     }
01184     if(pMix->m_pQueueSendToMixAfter!=NULL)
01185     {
01186       pMix->m_pQueueSendToMixAfter->add(b,sizeof(tQueueEntry)+1);
01187     }
01188     delete pPoolEntry;
01189     pPoolEntry = NULL;
01190     #ifdef USE_POOL
01191       delete pPool;
01192       pPool = NULL;
01193     #endif
01194     CAMsg::printMsg(LOG_CRIT,"loopReadFromMixAfter -- Now Exiting!\n");
01195     THREAD_RETURN_SUCCESS;
01196   }
01197 
01198 SINT32 CAMiddleMix::connectToNextMix(CASocketAddr* a_pAddrNext)
01199 {
01200 #define RETRIES 100
01201 #define RETRYTIME 10
01202     UINT8 buff[255];
01203     a_pAddrNext->toString(buff,255);
01204     CAMsg::printMsg(LOG_INFO,"Try to connect to next Mix on %s ...\n",buff);
01205     UINT32 i = 0;
01206     SINT32 err = E_UNKNOWN;
01207     SINT32 errLast = E_SUCCESS;
01208     for(i=0; i < RETRIES; i++)
01209     {
01210 #ifdef DYNAMIC_MIX
01211 
01212       if(m_bBreakNeeded != m_bReconfigured)
01213       {
01214         CAMsg::printMsg(LOG_DEBUG, "CAMiddleMix::connectToNextMix - Broken the connect loop!\n");
01215         break;
01216       }
01217 #endif
01218       err = m_pMuxOut->connect(*a_pAddrNext);
01219       if(err != E_SUCCESS)
01220       {
01221         err=GET_NET_ERROR;
01222 #ifdef _DEBUG
01223         CAMsg::printMsg(LOG_DEBUG,"Con-Error: %i\n",err);
01224 #endif
01225         if(err!=ERR_INTERN_TIMEDOUT&&err!=ERR_INTERN_CONNREFUSED)
01226         {
01227           CAMsg::printMsg(LOG_ERR, "Cannot connect to next Mix on %s. Reason: %s (%i)\n",
01228             buff, GET_NET_ERROR_STR(err), err);
01229           break;
01230         }
01231           
01232         if (errLast != err || i % 10 == 0)
01233         {
01234           CAMsg::printMsg(LOG_ERR, "Cannot connect to next Mix on %s. Reason: %s (%i). Retrying...\n",
01235             buff, GET_NET_ERROR_STR(err), err);
01236           errLast = err;
01237         }
01238         else
01239         {
01240   #ifdef _DEBUG
01241           CAMsg::printMsg(LOG_DEBUG,"Cannot connect... retrying\n");
01242   #endif
01243         }         
01244         sSleep(RETRYTIME);
01245       }
01246       else
01247       {
01248         break;
01249       }
01250     }
01251     return err;
01252 }
01253 
01255 SINT32 CAMiddleMix::loop()
01256   {
01257 
01258     CASingleSocketGroup oSocketGroup(false);
01259     oSocketGroup.add(*m_pMuxIn);
01260     m_pMuxIn->setCrypt(true);
01261     m_pMuxOut->setCrypt(true);
01262 
01263     m_bRun=true;
01264 
01265     CAThread oThread;
01266     oThread.setMainLoop(mm_loopReadFromMixAfter);
01267     oThread.start(this);
01268 
01269     CAThread bThread;
01270     bThread.setMainLoop(mm_loopSendToMixBefore);
01271     bThread.start(this);
01272 
01273     CAThread cThread;
01274     cThread.setMainLoop(mm_loopReadFromMixBefore);
01275     cThread.start(this);
01276 
01277     CAThread dThread;
01278     dThread.setMainLoop(mm_loopSendToMixAfter);
01279     dThread.start(this);
01280 
01281     cThread.join();
01282 
01283     CAMsg::printMsg(LOG_CRIT,"loop(): Preparing for restart...\n");
01284     m_bRun=false;
01285 
01286     oThread.join();
01287     bThread.join();
01288     dThread.join();
01289 
01290     m_pMuxIn->close();
01291     m_pMuxOut->close();
01292 
01293     CAMsg::printMsg(LOG_CRIT,"loop(): Seems that we are restarting now!!\n");
01294     return E_UNKNOWN;
01295   }
01296 SINT32 CAMiddleMix::clean()
01297 {
01298     delete m_pQueueSendToMixBefore;
01299     m_pQueueSendToMixBefore=NULL;
01300 
01301     delete m_pQueueSendToMixAfter;
01302     m_pQueueSendToMixAfter=NULL;
01303 
01304 #ifdef REPLAY_DETECTION
01305     delete m_pReplayMsgProc;
01306     m_pReplayMsgProc=NULL;
01307 #endif
01308     if(m_pMuxIn!=NULL)
01309     {
01310       m_pMuxIn->close();
01311       delete m_pMuxIn;
01312       m_pMuxIn=NULL;
01313     }
01314 
01315     if(m_pMuxOut!=NULL)
01316     {
01317       m_pMuxOut->close();
01318       delete m_pMuxOut;
01319       m_pMuxOut=NULL;
01320     }
01321 
01322     delete m_pRSA;
01323     m_pRSA=NULL;
01324 
01325     delete m_pMiddleMixChannelList;
01326     m_pMiddleMixChannelList=NULL;
01327     return E_SUCCESS;
01328   }
01329 #endif //ONLY_LOCAL_PROXY
01330 
01331 #ifdef LOG_CRIME
01332   static void crimeSurveillanceUpstream(MIXPACKET *pMixPacket, HCHANNEL prevMixChannel)
01333   {
01334     if(pMixPacket->flags & CHANNEL_SIG_CRIME)
01335     {
01336       CAMsg::printMsg(LOG_CRIT,"Crime detection: User surveillance, previous mix channel: %u, "
01337           "next mix channel %u\n", prevMixChannel, pMixPacket->channel);
01338     }
01339   }
01340 #endif