|
Mixe for Privacy and Anonymity in the Internet
|
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
1.7.6.1