|
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 #include "StdAfx.h" 00029 #ifndef ONLY_LOCAL_PROXY 00030 #include "CAFirstMix.hpp" 00031 #include "CASocketGroup.hpp" 00032 #include "CASingleSocketGroup.hpp" 00033 #include "CAMsg.hpp" 00034 #include "CACmdLnOptions.hpp" 00035 #include "CAFirstMixChannelList.hpp" 00036 #include "CAListenerInterface.hpp" 00037 #include "CAASymCipher.hpp" 00038 #include "CAInfoService.hpp" 00039 #include "CASocketAddrINet.hpp" 00040 #include "CATempIPBlockList.hpp" 00041 #ifdef HAVE_UNIX_DOMAIN_PROTOCOL 00042 #include "CASocketAddrUnix.hpp" 00043 #endif 00044 #include "CAThread.hpp" 00045 #include "CAUtil.hpp" 00046 #include "CASignature.hpp" 00047 #include "CABase64.hpp" 00048 #include "xml/DOM_Output.hpp" 00049 #include "CAPool.hpp" 00050 #ifdef WITH_CONTROL_CHANNELS_TEST 00051 #include "CAControlChannelTest.hpp" 00052 #endif 00053 #ifdef PAYMENT 00054 #include "CAAccountingControlChannel.hpp" 00055 #include "CAAccountingInstance.hpp" 00056 #include "CAAccountingDBInterface.hpp" 00057 #endif 00058 #include "CAReplayControlChannel.hpp" 00059 #include "CAStatusManager.hpp" 00060 #include "CALibProxytest.hpp" 00061 const UINT32 CAFirstMix::MAX_CONCURRENT_NEW_CONNECTIONS = NUM_LOGIN_WORKER_TRHEADS * 2; 00062 00063 bool CAFirstMix::isShuttingDown() 00064 { 00065 return m_bIsShuttingDown; 00066 } 00067 00068 SINT32 CAFirstMix::initOnce() 00069 { 00070 SINT32 ret=CAMix::initOnce(); 00071 if(ret!=E_SUCCESS) 00072 return ret; 00073 CAMsg::printMsg(LOG_DEBUG,"Starting FirstMix InitOnce\n"); 00074 /*m_pSignature=CALibProxytest::getOptions()->getSignKey(); 00075 if(m_pSignature==NULL)*/ 00076 m_pMultiSignature = CALibProxytest::getOptions()->getMultiSigner(); 00077 if(m_pMultiSignature == NULL) 00078 return E_UNKNOWN; 00079 //Try to find out how many (real) ListenerInterfaces are specified 00080 UINT32 tmpSocketsIn=CALibProxytest::getOptions()->getListenerInterfaceCount(); 00081 m_nSocketsIn=0; 00082 for(UINT32 i=1;i<=tmpSocketsIn;i++) 00083 { 00084 CAListenerInterface* pListener=NULL; 00085 pListener=CALibProxytest::getOptions()->getListenerInterface(i); 00086 if(pListener==NULL) 00087 continue; 00088 if(!pListener->isVirtual()) 00089 { 00090 m_nSocketsIn++; 00091 } 00092 delete pListener; 00093 pListener = NULL; 00094 } 00095 if(m_nSocketsIn<1) 00096 { 00097 CAMsg::printMsg(LOG_CRIT,"No usable ListenerInterfaces specified (maybe wrong values or all are 'virtual'!\n"); 00098 return E_UNKNOWN; 00099 } 00100 00101 CAMsg::printMsg(LOG_DEBUG,"Starting FirstMix InitOnce - finished\n"); 00102 return E_SUCCESS; 00103 } 00104 00105 00106 00107 SINT32 CAFirstMix::init() 00108 { 00109 if (isShuttingDown()) 00110 { 00111 return E_SHUTDOWN; 00112 } 00113 00114 #ifdef DYNAMIC_MIX 00115 m_bBreakNeeded = m_bReconfigured; 00116 #endif 00117 00118 CAMsg::printMsg(LOG_DEBUG,"Starting FirstMix Init\n"); 00119 m_nMixedPackets=0; //reset to zero after each restart (at the moment neccessary for infoservice) 00120 m_bRestart=false; 00121 //Establishing all Listeners 00122 UINT32 i; 00123 m_arrSocketsIn=new CASocket*[m_nSocketsIn]; 00124 for (i = 0; i < m_nSocketsIn; i++) 00125 { 00126 m_arrSocketsIn[i] = NULL; 00127 } 00128 //initiate ownerDocument for tc templates 00129 m_templatesOwner = createDOMDocument(); 00130 00131 SINT32 retSockets = CALibProxytest::getOptions()->createSockets(true, m_arrSocketsIn, m_nSocketsIn); 00132 00133 00134 if (retSockets != E_SUCCESS) 00135 { 00136 return retSockets; 00137 } 00138 00139 CASocketAddr* pAddrNext=NULL; 00140 for(i=0;i<CALibProxytest::getOptions()->getTargetInterfaceCount();i++) 00141 { 00142 CATargetInterface oNextMix; 00143 CALibProxytest::getOptions()->getTargetInterface(oNextMix,i+1); 00144 if(oNextMix.getTargetType()==TARGET_MIX) 00145 { 00146 pAddrNext=oNextMix.getAddr(); 00147 break; 00148 } 00149 oNextMix.cleanAddr(); 00150 } 00151 if(pAddrNext==NULL) 00152 { 00153 CAMsg::printMsg(LOG_CRIT,"No next Mix specified! Please insert the address of a next mix into your configuration.\n"); 00154 return E_UNKNOWN; 00155 } 00156 m_pMuxOut=new CAMuxSocket(); 00157 if(m_pMuxOut->getCASocket()->create(pAddrNext->getType())!=E_SUCCESS) 00158 { 00159 CAMsg::printMsg(LOG_CRIT, 00160 "Cannot create SOCKET for connection to next Mix! Please check if the network and socket settings in your system are correct.\n"); 00161 return E_UNKNOWN; 00162 } 00163 m_pMuxOut->getCASocket()->setSendBuff(500*MIXPACKET_SIZE); 00164 m_pMuxOut->getCASocket()->setRecvBuff(500*MIXPACKET_SIZE); 00165 //if(((*m_pMuxOut))->setSendLowWat(MIXPACKET_SIZE)!=E_SUCCESS) 00166 // CAMsg::printMsg(LOG_INFO,"SOCKET Option SENDLOWWAT not set!\n"); 00167 CAMsg::printMsg(LOG_INFO,"MUXOUT-SOCKET RecvBuffSize: %i\n",m_pMuxOut->getCASocket()->getRecvBuff()); 00168 CAMsg::printMsg(LOG_INFO,"MUXOUT-SOCKET SendBuffSize: %i\n",m_pMuxOut->getCASocket()->getSendBuff()); 00169 //CAMsg::printMsg(LOG_INFO,"MUXOUT-SOCKET SendLowWatSize: %i\n",((*m_pMuxOut))->getSendLowWat()); 00170 00172 if((retSockets = connectToNextMix(pAddrNext)) != E_SUCCESS) 00173 { 00174 delete pAddrNext; 00175 pAddrNext = NULL; 00176 CAMsg::printMsg(LOG_DEBUG, "CAFirstMix::init - Unable to connect to next mix. Reason: %s (%i)\n", GET_NET_ERROR_STR(retSockets), retSockets); 00177 return E_UNKNOWN; 00178 } 00179 delete pAddrNext; 00180 pAddrNext = NULL; 00181 MONITORING_FIRE_NET_EVENT(ev_net_nextConnected); 00182 CAMsg::printMsg(LOG_INFO,"Established socket connection to next mix. Starting key exchange...\n"); 00183 m_pMuxOut->getCASocket()->setKeepAlive((UINT32)1800); 00184 00185 00186 if(processKeyExchange()!=E_SUCCESS) 00187 { 00188 MONITORING_FIRE_NET_EVENT(ev_net_nextConnectionClosed); 00189 CAMsg::printMsg(LOG_CRIT,"Error in establishing secure communication with next Mix. Disconnecting...\n"); 00190 return E_UNKNOWN; 00191 } 00192 else 00193 { 00194 CAMsg::printMsg(LOG_INFO,"Secure connection to next Mix was established successfully.\n"); 00195 } 00196 m_pIPList=new CAIPList(); 00197 m_pIPBlockList = new CATempIPBlockList(1000 * 60 * 2); 00198 #ifdef COUNTRY_STATS 00199 char* db_host; 00200 char* db_user; 00201 char* db_passwd; 00202 CALibProxytest::getOptions()->getCountryStatsDBConnectionLoginData(&db_host,&db_user,&db_passwd); 00203 SINT32 retcountrydb=initCountryStats(db_host,db_user,db_passwd); 00204 delete[] db_host; 00205 db_host = NULL; 00206 delete[] db_user; 00207 db_user = NULL; 00208 delete[] db_passwd; 00209 db_passwd = NULL; 00210 if(retcountrydb!=E_SUCCESS) 00211 return E_UNKNOWN; 00212 #endif 00213 m_pQueueSendToMix=new CAQueue(sizeof(tQueueEntry)); 00214 m_pQueueReadFromMix=new CAQueue(sizeof(tQueueEntry)); 00215 m_pChannelList=new CAFirstMixChannelList(); 00216 #ifdef HAVE_EPOLL 00217 m_psocketgroupUsersRead=new CASocketGroupEpoll(false); 00218 m_psocketgroupUsersWrite=new CASocketGroupEpoll(true); 00219 #else 00220 m_psocketgroupUsersRead=new CASocketGroup(false); 00221 m_psocketgroupUsersWrite=new CASocketGroup(true); 00222 #endif 00223 00224 m_pMuxOutControlChannelDispatcher=new CAControlChannelDispatcher(m_pQueueSendToMix,NULL,NULL); 00225 #ifdef REPLAY_DETECTION 00226 m_pReplayDB=new CADatabase(); 00227 m_pReplayDB->start(); 00228 m_pReplayMsgProc=new CAReplayCtrlChannelMsgProc(this); 00229 m_u64ReferenceTime=time(NULL); 00230 m_u64LastTimestampReceived=time(NULL); 00231 #endif 00232 00233 #ifdef PAYMENT 00234 if (CAAccountingDBInterface::init() != E_SUCCESS) 00235 { 00236 return E_UNKNOWN; 00237 } 00238 CAAccountingInstance::init(this); 00239 #endif 00240 00241 m_pthreadsLogin=new CAThreadPool(NUM_LOGIN_WORKER_TRHEADS,MAX_LOGIN_QUEUE,false); 00242 00243 //Starting thread for Step 1 00244 m_pthreadAcceptUsers=new CAThread((UINT8*)"CAFirstMix - AcceptUsers"); 00245 m_pthreadAcceptUsers->setMainLoop(fm_loopAcceptUsers); 00246 m_pthreadAcceptUsers->start(this); 00247 00248 //Starting thread for Step 3 00249 m_pthreadSendToMix=new CAThread((UINT8*)"CAFirstMix - SendToMix"); 00250 m_pthreadSendToMix->setMainLoop(fm_loopSendToMix); 00251 m_pthreadSendToMix->start(this); 00252 00253 //Startting thread for Step 4a 00254 m_pthreadReadFromMix=new CAThread((UINT8*)"CAFirstMix - ReadFromMix"); 00255 m_pthreadReadFromMix->setMainLoop(fm_loopReadFromMix); 00256 m_pthreadReadFromMix->start(this); 00257 #ifdef CH_LOG_STUDY 00258 nrOfChThread = new CAThread((UINT8*)"CAFirstMix - Channel open logging thread"); 00259 nrOfChThread->setMainLoop(fm_loopLogChannelsOpened); 00260 nrOfChThread->start(this); 00261 currentOpenedChannels = 0; 00262 #endif //CH_LOG_STUDY 00263 //Starting thread for logging 00264 #ifdef LOG_PACKET_TIMES 00265 m_pLogPacketStats=new CALogPacketStats(); 00266 m_pLogPacketStats->setLogIntervallInMinutes(FM_PACKET_STATS_LOG_INTERVALL); 00267 m_pLogPacketStats->start(); 00268 #endif 00269 #ifdef REPLAY_DETECTION 00270 // sendReplayTimestampRequestsToAllMixes(); 00271 #endif 00272 CAMsg::printMsg(LOG_DEBUG,"CAFirstMix init() succeeded\n"); 00273 MONITORING_FIRE_NET_EVENT(ev_net_keyExchangeNextSuccessful); 00274 return E_SUCCESS; 00275 } 00276 00277 SINT32 CAFirstMix::connectToNextMix(CASocketAddr* a_pAddrNext) 00278 { 00279 UINT8 buff[255]; 00280 a_pAddrNext->toString(buff,255); 00281 CAMsg::printMsg(LOG_INFO,"Try to connect to next Mix on %s ...\n",buff); 00282 SINT32 err = E_UNKNOWN; 00283 SINT32 errLast = E_SUCCESS; 00284 00285 for(UINT32 i=0; i < 100; i++) 00286 { 00287 #ifdef DYNAMIC_MIX 00288 00289 if(m_bBreakNeeded != m_bReconfigured) 00290 { 00291 CAMsg::printMsg(LOG_DEBUG, "CAFirstMix::connectToNextMix - Broken the connect loop!\n"); 00292 break; 00293 } 00294 #endif 00295 err = m_pMuxOut->connect(*a_pAddrNext); 00296 if(err != E_SUCCESS) 00297 { 00298 err=GET_NET_ERROR; 00299 00300 if(err!=ERR_INTERN_TIMEDOUT&&err!=ERR_INTERN_CONNREFUSED) 00301 { 00302 CAMsg::printMsg(LOG_ERR, "Cannot connect to next Mix on %s. Reason: %s (%i)\n", 00303 buff, GET_NET_ERROR_STR(err), err); 00304 break; 00305 } 00306 00307 if (errLast != err || i % 10 == 0) 00308 { 00309 CAMsg::printMsg(LOG_ERR, "Cannot connect to next Mix on %s. Reason: %s (%i). Retrying...\n", 00310 buff, GET_NET_ERROR_STR(err), err); 00311 errLast = err; 00312 } 00313 else 00314 { 00315 #ifdef _DEBUG 00316 CAMsg::printMsg(LOG_DEBUG,"Cannot connect... retrying\n"); 00317 #endif 00318 } 00319 sSleep(10); 00320 } 00321 else 00322 { 00323 break; 00324 } 00325 } 00326 return err; 00327 } 00328 00329 /* 00330 *@DOCME 00331 */ 00332 SINT32 CAFirstMix::processKeyExchange() 00333 { 00334 UINT8* recvBuff=NULL; 00335 UINT32 len; 00336 SINT32 ret; 00337 CAMsg::printMsg(LOG_INFO, "Try to read the Key Info length from next Mix...\n"); 00338 if((ret = m_pMuxOut->receiveFully((UINT8*) &len, sizeof(len), TIMEOUT_MIX_CONNECTION_ESTABLISHEMENT)) != E_SUCCESS) 00339 { 00340 if (ret != E_UNKNOWN) 00341 { 00342 CAMsg::printMsg(LOG_CRIT,"Error receiving Key Info length from next mix! Reason: '%s' (%i)\n",GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR); 00343 } 00344 else 00345 { 00346 CAMsg::printMsg(LOG_CRIT,"Error receiving Key Info length from next mix!\n"); 00347 } 00348 return ret; 00349 } 00350 len=ntohl(len); 00351 CAMsg::printMsg(LOG_INFO, "Received next mix Key Info length %u\n",len); 00352 00353 if (len > 100000) 00354 { 00355 CAMsg::printMsg(LOG_WARNING,"Unrealistic length for key info: %u We might not be able to get a connection.\n",len); 00356 } 00357 00358 recvBuff=new UINT8[len+1]; 00359 00360 if ((ret =m_pMuxOut->receiveFully(recvBuff, len, TIMEOUT_MIX_CONNECTION_ESTABLISHEMENT)) != E_SUCCESS) 00361 { 00362 if (ret != E_UNKNOWN) 00363 { 00364 CAMsg::printMsg(LOG_CRIT,"Error receiving Key Info from next mix! Reason: '%s' (%i)\n",GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR); 00365 } 00366 else 00367 { 00368 CAMsg::printMsg(LOG_CRIT,"Error receiving Key Info from next mix!\n"); 00369 } 00370 delete []recvBuff; 00371 recvBuff = NULL; 00372 return E_UNKNOWN; 00373 } 00374 recvBuff[len]=0; 00375 //get the Keys from the other mixes (and the Mix-Id's...!) 00376 CAMsg::printMsg(LOG_INFO,"Received Key Info from next mix...\n"); 00377 CAMsg::printMsg(LOG_DEBUG,"%s\n",recvBuff); 00378 00379 XERCES_CPP_NAMESPACE::DOMDocument* doc=parseDOMDocument(recvBuff, len); 00380 delete []recvBuff; 00381 recvBuff = NULL; 00382 DOMElement* elemMixes=doc->getDocumentElement(); 00383 if(elemMixes == NULL) 00384 { 00385 if(doc != NULL) 00386 { 00387 doc->release(); 00388 doc = NULL; 00389 } 00390 CAMsg::printMsg(LOG_INFO,"before returning...\n"); 00391 return E_UNKNOWN; 00392 } 00393 SINT32 count=0; 00394 if(getDOMElementAttribute(elemMixes,"count",&count)!=E_SUCCESS) 00395 { 00396 if(doc != NULL) 00397 { 00398 doc->release(); 00399 doc = NULL; 00400 } 00401 return E_UNKNOWN; 00402 } 00403 /* 00404 @todo Do not know why we do this here - probably it has something todo with the 00405 dynamic mix config, but makes not sense at all for me... 00406 00407 getDOMElementAttribute(elemMixescascadeNaem 00408 char *cascadeName; 00409 cascadeName = elemMixes.getAttribute("cascadeName").transcode(); 00410 if(cascadeName == NULL) 00411 return E_UNKNOWN; 00412 CALibProxytest::getOptions()->setCascadeName(cascadeName); 00413 */ 00414 if(CALibProxytest::getOptions()->getTermsAndConditions() != NULL) 00415 { 00416 appendTermsAndConditionsExtension(doc, elemMixes); 00417 } 00418 00419 SINT32 extRet = handleKeyInfoExtensions(elemMixes); 00420 if(extRet != E_SUCCESS) 00421 { 00422 if(doc != NULL) 00423 { 00424 doc->release(); 00425 doc = NULL; 00426 } 00427 return E_UNKNOWN; 00428 } 00429 m_pRSA=new CAASymCipher; 00430 00431 #ifdef EXPORT_ASYM_PRIVATE_KEY 00432 if(CALibProxytest::getOptions()->isImportKey()) 00433 { 00434 UINT32 keyFileBuffLen=8096; 00435 UINT8* keyFileBuff=new UINT8[keyFileBuffLen]; 00436 CALibProxytest::getOptions()->getEncryptionKeyImportFile(keyFileBuff,keyFileBuffLen); 00437 UINT8* keyBuff=readFile(keyFileBuff,&keyFileBuffLen); 00438 m_pRSA->setPrivateKeyAsXML(keyBuff,keyFileBuffLen); 00439 delete[] keyFileBuff; 00440 delete[] keyBuff; 00441 } 00442 else 00443 #endif 00444 { 00445 m_pRSA->generateKeyPair(1024); 00446 } 00447 #ifdef EXPORT_ASYM_PRIVATE_KEY 00448 if(CALibProxytest::getOptions()->isExportKey()) 00449 { 00450 UINT32 keyFileBuffLen=8096; 00451 UINT8* keyFileBuff=new UINT8[keyFileBuffLen]; 00452 UINT8* keyBuff=new UINT8[keyFileBuffLen]; 00453 CALibProxytest::getOptions()->getEncryptionKeyExportFile(keyFileBuff,keyFileBuffLen); 00454 m_pRSA->getPrivateKeyAsXML(keyBuff,&keyFileBuffLen); 00455 saveFile(keyFileBuff,keyBuff,keyFileBuffLen); 00456 delete[] keyFileBuff; 00457 delete[] keyBuff; 00458 } 00459 #endif 00460 DOMNode* child=elemMixes->getLastChild(); 00461 00462 //tmp XML-Structure for constructing the XML which is sent to each user 00463 XERCES_CPP_NAMESPACE::DOMDocument* docXmlKeyInfo=createDOMDocument(); 00464 DOMElement* elemRootKey=createDOMElement(docXmlKeyInfo,"MixCascade"); 00465 setDOMElementAttribute(elemRootKey,"version",(UINT8*)"0.2"); //set the Version of the XML to 0.2 00466 #ifdef LOG_DIALOG 00467 setDOMElementAttribute(elemRootKey,"study",(UINT8*)"true"); 00468 #endif 00469 docXmlKeyInfo->appendChild(elemRootKey); 00470 DOMElement* elemMixProtocolVersion=createDOMElement(docXmlKeyInfo,"MixProtocolVersion"); 00471 setDOMElementValue(elemMixProtocolVersion,(UINT8*)MIX_CASCADE_PROTOCOL_VERSION); 00472 elemRootKey->appendChild(elemMixProtocolVersion); 00473 DOMNode* elemMixesKey=docXmlKeyInfo->importNode(elemMixes,true); 00474 elemRootKey->appendChild(elemMixesKey); 00475 00476 //UINT32 tlen; 00477 /* //remove because it seems to be useless... 00478 while(child!=NULL) 00479 { 00480 if(child.getNodeName().equals("Mix")) 00481 { 00482 DOM_Node rsaKey=child.getFirstChild(); 00483 CAASymCipher oRSA; 00484 oRSA.setPublicKeyAsDOMNode(rsaKey); 00485 tlen=256; 00486 } 00487 child=child.getPreviousSibling(); 00488 }*/ 00489 //tlen=256; 00490 00491 //Inserting own Key in XML-Key struct 00492 DOMElement* elemKey=NULL; 00493 m_pRSA->getPublicKeyAsDOMElement(elemKey,docXmlKeyInfo); 00494 addMixInfo(elemMixesKey, true); 00495 DOMElement* elemOwnMix=NULL; 00496 getDOMChildByName(elemMixesKey, "Mix", elemOwnMix, false); 00497 elemOwnMix->appendChild(elemKey); 00498 CAMsg::printMsg(LOG_INFO,"before T&Cs1...\n"); 00499 if(CALibProxytest::getOptions()->getTermsAndConditions() != NULL) 00500 { 00501 elemOwnMix->appendChild(termsAndConditionsInfoNode(docXmlKeyInfo)); 00502 } 00503 CAMsg::printMsg(LOG_INFO,"after T&Cs1...\n"); 00504 elemOwnMix->appendChild(createDOMElement(docXmlKeyInfo,"SupportsEncrypedControlChannels")); 00505 CAMsg::printMsg(LOG_INFO,"after SupportEncChannels...\n"); 00506 if (signXML(elemOwnMix) != E_SUCCESS) 00507 { 00508 CAMsg::printMsg(LOG_DEBUG,"Could not sign MixInfo sent to users...\n"); 00509 } 00510 00511 setDOMElementAttribute(elemMixesKey,"count",count+1); 00512 00513 00514 DOMNode* elemPayment=createDOMElement(docXmlKeyInfo,"Payment"); 00515 elemRootKey->appendChild(elemPayment); 00516 #ifdef PAYMENT 00517 setDOMElementAttribute(elemPayment,"required",(UINT8*)"true"); 00518 setDOMElementAttribute(elemPayment,"version",(UINT8*)PAYMENT_VERSION); 00519 setDOMElementAttribute(elemPayment,"prepaidInterval", CALibProxytest::getOptions()->getPrepaidInterval()); 00520 setDOMElementAttribute(elemPayment,"piid", CALibProxytest::getOptions()->getBI()->getID()); 00521 00522 #else 00523 setDOMElementAttribute(elemPayment,"required",(UINT8*)"false"); 00524 #endif 00525 00526 // create signature 00527 if (signXML(elemRootKey) != E_SUCCESS) 00528 { 00529 CAMsg::printMsg(LOG_DEBUG,"Could not sign KeyInfo sent to users...\n"); 00530 } 00531 00532 00533 UINT32 tmp32Len = 0; 00534 UINT8* tmpB=DOM_Output::dumpToMem(docXmlKeyInfo, &tmp32Len); 00535 if (docXmlKeyInfo != NULL) 00536 { 00537 docXmlKeyInfo->release(); 00538 docXmlKeyInfo = NULL; 00539 } 00540 00541 if(tmp32Len > 0xFFFD) //too bytes are reserved for the length 00542 { 00543 CAMsg::printMsg(LOG_CRIT, "The key info size of %u bytes is too large for the clients. (maximum is %u)\n", 0xFFFD); 00544 if (doc != NULL) 00545 { 00546 doc->release(); 00547 doc = NULL; 00548 } 00549 return E_UNKNOWN; 00550 } 00551 00552 UINT16 tlen = (UINT16) tmp32Len; 00553 m_xmlKeyInfoBuff = new UINT8[tlen+sizeof(tlen)]; 00554 memcpy(m_xmlKeyInfoBuff+sizeof(tlen), tmpB, tlen); 00555 UINT16 s = htons(tlen); 00556 memcpy(m_xmlKeyInfoBuff, &s, sizeof(s)); 00557 m_xmlKeyInfoSize=tlen + sizeof(tlen); 00558 delete []tmpB; 00559 tmpB = NULL; 00560 SINT32 result=E_UNKNOWN; 00561 00562 //Sending symmetric key... 00563 child=elemMixes->getFirstChild(); 00564 while(child!=NULL) 00565 { 00566 if(equals(child->getNodeName(),"Mix")) 00567 { 00568 //verify certificate from next mix if enabled 00569 if(CALibProxytest::getOptions()->verifyMixCertificates()) 00570 { 00571 CACertificate* nextMixCert = CALibProxytest::getOptions()->getTrustedCertificateStore()->verifyMixCert(child); 00572 if(nextMixCert != NULL) 00573 { 00574 CAMsg::printMsg(LOG_DEBUG, "Next mix certificate was verified by a trusted root CA.\n"); 00575 CALibProxytest::getOptions()->setNextMixTestCertificate(nextMixCert); 00576 } 00577 else 00578 { 00579 CAMsg::printMsg(LOG_ERR, "Could not verify certificate received from next mix!\n"); 00580 return E_UNKNOWN; 00581 } 00582 } 00583 //check Signature.... 00584 CAMsg::printMsg(LOG_DEBUG,"Try to verify next mix signature...\n"); 00585 //CASignature oSig; 00586 CACertificate* nextCert=CALibProxytest::getOptions()->getNextMixTestCertificate(); 00587 /*oSig.setVerifyKey(nextCert); 00588 SINT32 ret=oSig.verifyXML(child,NULL);*/ 00589 result = CAMultiSignature::verifyXML(child, nextCert); 00590 delete nextCert; 00591 nextCert = NULL; 00592 if(result != E_SUCCESS) 00593 { 00594 //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"); 00595 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"); 00596 if (doc != NULL) 00597 { 00598 doc->release(); 00599 doc = NULL; 00600 } 00601 return E_UNKNOWN; 00602 } 00603 CAMsg::printMsg(LOG_DEBUG,"Successfully verified XML signature of next mix!\n"); 00604 00605 result = checkCompatibility(child, "next"); 00606 00607 00608 DOMNode* rsaKey=child->getFirstChild(); 00609 CAASymCipher oRSA; 00610 oRSA.setPublicKeyAsDOMNode(rsaKey); 00611 DOMElement* elemNonce=NULL; 00612 getDOMChildByName(child,"Nonce",elemNonce,false); 00613 UINT8 arNonce[1024]; 00614 if(elemNonce!=NULL) 00615 { 00616 UINT32 lenNonce=1024; 00617 UINT32 tmpLen=1024; 00618 getDOMElementValue(elemNonce,arNonce,&lenNonce); 00619 CABase64::decode(arNonce,lenNonce,arNonce,&tmpLen); 00620 lenNonce=tmpLen; 00621 tmpLen=1024; 00622 CABase64::encode(SHA1(arNonce,lenNonce,NULL),SHA_DIGEST_LENGTH, 00623 arNonce,&tmpLen); 00624 arNonce[tmpLen]=0; 00625 } 00626 UINT8 key[64]; 00627 getRandom(key,64); 00628 //UINT8 buff[400]; 00629 //UINT32 bufflen=400; 00630 XERCES_CPP_NAMESPACE::DOMDocument* docSymKey=createDOMDocument(); 00631 DOMElement* elemRoot=NULL; 00632 encodeXMLEncryptedKey(key,64,elemRoot,docSymKey,&oRSA); 00633 docSymKey->appendChild(elemRoot); 00634 if(elemNonce!=NULL) 00635 { 00636 DOMElement* elemNonceHash=createDOMElement(docSymKey,"Nonce"); 00637 setDOMElementValue(elemNonceHash,arNonce); 00638 elemRoot->appendChild(elemNonceHash); 00639 } 00640 00641 appendCompatibilityInfo(elemRoot); 00642 00644 DOMElement* elemKeepAlive=NULL; 00645 DOMElement* elemKeepAliveSendInterval=NULL; 00646 DOMElement* elemKeepAliveRecvInterval=NULL; 00647 getDOMChildByName(child,"KeepAlive",elemKeepAlive,false); 00648 getDOMChildByName(elemKeepAlive,"SendInterval",elemKeepAliveSendInterval,false); 00649 getDOMChildByName(elemKeepAlive,"ReceiveInterval",elemKeepAliveRecvInterval,false); 00650 UINT32 tmpSendInterval,tmpRecvInterval; 00651 getDOMElementValue(elemKeepAliveSendInterval,tmpSendInterval,0xFFFFFFFF); //if no send interval was given set it to "infinite" 00652 getDOMElementValue(elemKeepAliveRecvInterval,tmpRecvInterval,0xFFFFFFFF); //if no recv interval was given --> set it to "infinite" 00653 CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Getting offer -- SendInterval %u -- ReceiveInterval %u\n",tmpSendInterval,tmpRecvInterval); 00654 // Add Info about KeepAlive traffic 00655 UINT32 u32KeepAliveSendInterval=CALibProxytest::getOptions()->getKeepAliveSendInterval(); 00656 UINT32 u32KeepAliveRecvInterval=CALibProxytest::getOptions()->getKeepAliveRecvInterval(); 00657 elemKeepAlive=createDOMElement(docSymKey,"KeepAlive"); 00658 elemKeepAliveSendInterval=createDOMElement(docSymKey,"SendInterval"); 00659 elemKeepAliveRecvInterval=createDOMElement(docSymKey,"ReceiveInterval"); 00660 elemKeepAlive->appendChild(elemKeepAliveSendInterval); 00661 elemKeepAlive->appendChild(elemKeepAliveRecvInterval); 00662 setDOMElementValue(elemKeepAliveSendInterval,u32KeepAliveSendInterval); 00663 setDOMElementValue(elemKeepAliveRecvInterval,u32KeepAliveRecvInterval); 00664 elemRoot->appendChild(elemKeepAlive); 00665 CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Offering -- SendInterval %u -- Receive Interval %u\n",u32KeepAliveSendInterval,u32KeepAliveRecvInterval); 00666 m_u32KeepAliveSendInterval = u32KeepAliveSendInterval; 00667 if (m_u32KeepAliveSendInterval > tmpRecvInterval - 10000) 00668 m_u32KeepAliveSendInterval-=10000; //make the send interval a little bit smaller than the related receive interval 00669 m_u32KeepAliveRecvInterval=max(u32KeepAliveRecvInterval,tmpSendInterval); 00670 if (m_u32KeepAliveRecvInterval - 10000 < tmpSendInterval) 00671 { 00672 m_u32KeepAliveRecvInterval += 10000; 00673 } 00674 CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Calculated -- SendInterval %u -- Receive Interval %u\n",m_u32KeepAliveSendInterval,m_u32KeepAliveRecvInterval); 00675 00676 //m_pSignature->signXML(elemRoot); 00677 m_pMultiSignature->signXML(elemRoot, true); 00678 UINT32 outlen=0; 00679 UINT8* out=DOM_Output::dumpToMem(docSymKey,&outlen); 00680 if (docSymKey != NULL) 00681 { 00682 docSymKey->release(); 00683 docSymKey = NULL; 00684 } 00685 m_pMuxOut->setSendKey(key,32); 00686 m_pMuxOut->setReceiveKey(key+32,32); 00687 UINT32 size = htonl(outlen); 00688 CAMsg::printMsg(LOG_DEBUG,"Sending symmetric key to next Mix! Size: %i\n", outlen); 00689 m_pMuxOut->getCASocket()->send((UINT8*) &size, sizeof(size)); 00690 m_pMuxOut->getCASocket()->send(out, outlen); 00691 m_pMuxOut->setCrypt(true); 00692 delete[] out; 00693 out = NULL; 00694 break; 00695 } 00696 child=child->getNextSibling(); 00697 } 00698 00699 if (result != E_SUCCESS) 00700 { 00701 if (doc != NULL) 00702 { 00703 doc->release(); 00704 doc = NULL; 00705 } 00706 return result; 00707 } 00708 00709 00711 if(initMixParameters(elemMixes)!=E_SUCCESS) 00712 { 00713 if (doc != NULL) 00714 { 00715 doc->release(); 00716 doc = NULL; 00717 } 00718 return E_UNKNOWN; 00719 } 00720 if(initMixCascadeInfo(elemMixes)!=E_SUCCESS) 00721 { 00722 if (doc != NULL) 00723 { 00724 doc->release(); 00725 doc = NULL; 00726 } 00727 CAMsg::printMsg(LOG_CRIT,"Error initializing cascade info.\n"); 00728 return E_UNKNOWN; 00729 } 00730 /* else 00731 { 00732 if(m_pInfoService != NULL) 00733 m_pInfoService->sendCascadeHelo(); 00734 }*/ 00735 CAMsg::printMsg(LOG_DEBUG,"Key exchange finished!\n"); 00736 if (doc != NULL) 00737 { 00738 doc->release(); 00739 doc = NULL; 00740 } 00741 return E_SUCCESS; 00742 } 00743 00744 00745 SINT32 CAFirstMix::setMixParameters(const tMixParameters& params) 00746 { 00747 #ifdef REPLAY_DETECTION 00748 UINT32 diff=time(NULL)-m_u64LastTimestampReceived; 00749 for(UINT32 i=0;i<m_u32MixCount-1;i++) 00750 { 00751 //@todo dangerous strcmp 00752 if(strcmp((char*)m_arMixParameters[i].m_strMixID,(char*)params.m_strMixID)==0) 00753 { 00754 m_arMixParameters[i].m_u32ReplayOffset=params.m_u32ReplayOffset; 00755 m_arMixParameters[i].m_u32ReplayBase=params.m_u32ReplayBase; 00756 } 00757 else{ 00758 if (m_arMixParameters[i].m_u32ReplayOffset!=0) m_arMixParameters[i].m_u32ReplayOffset+=diff; 00759 } 00760 } 00761 #endif 00762 return E_SUCCESS; 00763 } 00764 00765 00766 SINT32 CAFirstMix::handleKeyInfoExtensions(DOMElement *root) 00767 { 00768 if(root == NULL) 00769 { 00770 return E_UNKNOWN; 00771 } 00772 00773 SINT32 ret = E_SUCCESS; 00774 DOMElement *extensionRoot = NULL; 00775 getDOMChildByName(root, KEYINFO_NODE_EXTENSIONS, extensionRoot); 00776 00777 if(extensionRoot != NULL) 00778 { 00779 extensionRoot = (DOMElement *) root->removeChild(extensionRoot); 00780 ret = handleTermsAndConditionsExtension(extensionRoot); 00781 extensionRoot->release(); 00782 } 00783 return ret; 00784 } 00785 00786 SINT32 CAFirstMix::handleTermsAndConditionsExtension(DOMElement *extensionsRoot) 00787 { 00788 if(extensionsRoot == NULL) 00789 { 00790 return E_UNKNOWN; 00791 } 00792 00793 DOMElement *tncDefs = NULL; 00794 DOMElement *tncTemplates = NULL; 00795 getDOMChildByName(extensionsRoot, KEYINFO_NODE_TNC_EXTENSION, tncDefs); 00796 if(tncDefs == NULL) 00797 { 00798 CAMsg::printMsg(LOG_CRIT,"No TNCs in TNC extension found.\n"); 00799 return E_UNKNOWN; 00800 } 00801 getDOMChildByName(tncDefs, OPTIONS_NODE_TNCS_TEMPLATES, tncTemplates); 00802 00803 UINT8 currentTnC_id[TMP_BUFF_SIZE]; 00804 UINT32 currentTnC_id_len = TMP_BUFF_SIZE; 00805 00806 UINT8 currentTnCEntry_templateRefid[TMP_BUFF_SIZE]; 00807 UINT32 currentTnCEntry_templateRefid_len = TMP_BUFF_SIZE; 00808 00809 UINT8 currentTnCEntry_locale[TMP_LOCALE_SIZE]; 00810 UINT32 currentTnCEntry_locale_len = TMP_LOCALE_SIZE; 00811 00812 DOMElement *currentTnCList = NULL; 00813 DOMElement *currentTnCEntry = NULL; 00814 memset(currentTnC_id, 0, TMP_BUFF_SIZE); 00815 memset(currentTnCEntry_templateRefid, 0, TMP_BUFF_SIZE); 00816 00817 if(tncTemplates != NULL) 00818 { 00819 DOMNodeList *tncTemplateList = getElementsByTagName(tncDefs, TNC_TEMPLATE_ROOT_ELEMENT); 00820 m_nrOfTermsAndConditionsTemplates = tncTemplateList->getLength(); 00821 CAMsg::printMsg(LOG_INFO, "Storing %u TC Templates.\n", m_nrOfTermsAndConditionsTemplates); 00822 if(m_nrOfTermsAndConditionsTemplates > 0) 00823 { 00824 m_tcTemplates = new DOMNode *[m_nrOfTermsAndConditionsTemplates]; 00825 for (UINT32 i = 0; i < m_nrOfTermsAndConditionsTemplates; i++) 00826 { 00827 m_tcTemplates[i] = m_templatesOwner->importNode(tncTemplateList->item(i), true); 00828 } 00829 } 00830 else 00831 { 00832 CAMsg::printMsg(LOG_ERR, "Not a single TC Template specified! the Cascade is not properly configured.\n"); 00833 return E_UNKNOWN; 00834 } 00835 } 00836 else 00837 { 00838 CAMsg::printMsg(LOG_ERR, "No TC Template node found! Cascade is not properly configured.\n"); 00839 return E_UNKNOWN; 00840 } 00841 00842 DOMNodeList *tncDefList = getElementsByTagName(tncDefs, OPTIONS_NODE_TNCS); 00843 if(tncDefList->getLength() == 0) 00844 { 00845 CAMsg::printMsg(LOG_CRIT, "No TNCs definitions found.\n"); 00846 return E_UNKNOWN; 00847 } 00848 00849 m_nrOfTermsAndConditionsDefs = tncDefList->getLength(); 00850 m_tnCDefs = new TermsAndConditions *[m_nrOfTermsAndConditionsDefs]; 00851 memset(m_tnCDefs, 0, (sizeof(TermsAndConditions*)*m_nrOfTermsAndConditionsDefs) ); 00852 00853 for (XMLSize_t i = 0; i < m_nrOfTermsAndConditionsDefs; i++) 00854 { 00855 currentTnCList = (DOMElement *) tncDefList->item(i); 00856 DOMNodeList *tncDefEntryList = getElementsByTagName(currentTnCList, OPTIONS_NODE_TNCS_TRANSLATION); 00857 getDOMElementAttribute(currentTnCList, OPTIONS_ATTRIBUTE_TNC_ID, currentTnC_id, ¤tTnC_id_len); 00858 00859 m_tnCDefs[i] = new TermsAndConditions(currentTnC_id, tncDefEntryList->getLength()); 00860 00861 for (XMLSize_t j = 0; j < tncDefEntryList->getLength(); j++) 00862 { 00863 currentTnCEntry = (DOMElement *) tncDefEntryList->item(j); 00864 00865 getDOMElementAttribute(currentTnCEntry, OPTIONS_ATTRIBUTE_TNC_TEMPLATE_REFID, 00866 currentTnCEntry_templateRefid, ¤tTnCEntry_templateRefid_len); 00867 getDOMElementAttribute(currentTnCEntry, OPTIONS_ATTRIBUTE_TNC_LOCALE, 00868 currentTnCEntry_locale, ¤tTnCEntry_locale_len); 00869 00870 DOMNode *templateNode = getTermsAndConditionsTemplate(currentTnCEntry_templateRefid); 00871 if(templateNode != NULL) 00872 { 00873 //m_tnCDefs[i]->synchLock->lock(); 00874 m_tnCDefs[i]->addTranslation(currentTnCEntry_locale, currentTnCEntry, templateNode); 00875 //m_tnCDefs[i]->synchLock->unlock(); 00876 } 00877 else 00878 { 00879 CAMsg::printMsg(LOG_CRIT,"Could not find template %s for T&C %s.\n", currentTnCEntry_templateRefid, currentTnC_id); 00880 return E_UNKNOWN; 00881 } 00882 memset(currentTnCEntry_templateRefid, 0, TMP_BUFF_SIZE); 00883 currentTnCEntry_templateRefid_len = TMP_BUFF_SIZE; 00884 memset(currentTnCEntry_locale, 0, TMP_LOCALE_SIZE); 00885 currentTnCEntry_locale_len = TMP_LOCALE_SIZE; 00886 } 00887 memset(currentTnC_id, 0, TMP_BUFF_SIZE); 00888 currentTnC_id_len = TMP_BUFF_SIZE; 00889 } 00890 return E_SUCCESS; 00891 } 00892 00893 TermsAndConditions *CAFirstMix::getTermsAndConditions(const UINT8 *opSki) 00894 { 00895 if( (m_tnCDefs == NULL) || (opSki == NULL) ) 00896 { 00897 return NULL; 00898 } 00899 for(UINT32 i = 0; i < m_nrOfTermsAndConditionsDefs; i++) 00900 { 00901 if(m_tnCDefs[i] != NULL) 00902 { 00903 if(strncasecmp((char *) m_tnCDefs[i]->getID(), 00904 (const char *) opSki, 00905 strlen((char *) m_tnCDefs[i]->getID())) == 0) 00906 { 00907 return m_tnCDefs[i]; 00908 } 00909 } 00910 } 00911 return NULL; 00912 } 00913 00914 DOMNode *CAFirstMix::getTermsAndConditionsTemplate(UINT8 *templateRefID) 00915 { 00916 UINT8 *currentRefId = NULL; 00917 bool match = false; 00918 00919 for (UINT32 i = 0; i < m_nrOfTermsAndConditionsTemplates; i++) 00920 { 00921 currentRefId = getTermsAndConditionsTemplateRefId(m_tcTemplates[i]); 00922 match = (currentRefId != NULL) && 00923 (strncmp((char *)templateRefID, (char *)currentRefId, TEMPLATE_REFID_MAXLEN ) == 0); 00924 delete [] currentRefId; 00925 currentRefId = NULL; 00926 if(match) 00927 { 00928 return m_tcTemplates[i]; 00929 } 00930 } 00931 return NULL; 00932 } 00933 00939 THREAD_RETURN fm_loopSendToMix(void* param) 00940 { 00941 INIT_STACK; 00942 BEGIN_STACK("CAFirstMix::fm_loopSendToMix"); 00943 00944 CAFirstMix* pFirstMix=(CAFirstMix*)param; 00945 CAQueue* pQueue=((CAFirstMix*)param)->m_pQueueSendToMix; 00946 CAMuxSocket* pMuxSocket=pFirstMix->m_pMuxOut; 00947 00948 UINT32 len; 00949 SINT32 ret; 00950 00951 /*#ifdef DATA_RETENTION_LOG 00952 t_dataretentionLogEntry* pDataRetentionLogEntry=new t_dataretentionLogEntry; 00953 #endif 00954 */ 00955 #ifndef USE_POOL 00956 tQueueEntry* pQueueEntry=new tQueueEntry; 00957 MIXPACKET* pMixPacket=&pQueueEntry->packet; 00958 UINT32 u32KeepAliveSendInterval=pFirstMix->m_u32KeepAliveSendInterval; 00959 while(!pFirstMix->m_bRestart) 00960 { 00961 len=sizeof(tQueueEntry); 00962 ret=pQueue->getOrWait((UINT8*)pQueueEntry,&len,u32KeepAliveSendInterval); 00963 if(ret==E_TIMEDOUT) 00964 {//send a dummy as keep-alvie-traffic 00965 pMixPacket->flags=CHANNEL_DUMMY; 00966 pMixPacket->channel=DUMMY_CHANNEL; 00967 getRandom(pMixPacket->data,DATA_SIZE); 00968 } 00969 else if(ret!=E_SUCCESS||len!=sizeof(tQueueEntry)) 00970 { 00971 CAMsg::printMsg(LOG_ERR,"CAFirstMix::lm_loopSendToMix - Error in dequeueing MixPaket\n"); 00972 CAMsg::printMsg(LOG_ERR,"ret=%i len=%i\n",ret,len); 00973 break; 00974 } 00975 00976 if(pMuxSocket->send(pMixPacket)!=MIXPACKET_SIZE) 00977 { 00978 CAMsg::printMsg(LOG_ERR,"CAFirstMix::lm_loopSendToMix - Error in sending MixPaket\n"); 00979 break; 00980 } 00981 #if defined (LOG_PACKET_TIMES) 00982 if(!isZero64(pQueueEntry->timestamp_proccessing_start)) 00983 { 00984 getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end); 00985 pFirstMix->m_pLogPacketStats->addToTimeingStats(*pQueueEntry,pMixPacket->flags,true); 00986 } 00987 #endif 00988 #ifdef DATA_RETENTION_LOG 00989 if((pQueueEntry->packet.flags&CHANNEL_OPEN)!=0) 00990 { 00991 pQueueEntry->dataRetentionLogEntry.t_out=htonl(time(NULL)); 00992 pFirstMix->m_pDataRetentionLog->log(&(pQueueEntry->dataRetentionLogEntry)); 00993 } 00994 #endif 00995 } 00996 delete pQueueEntry; 00997 pQueueEntry = NULL; 00998 #else 00999 CAPool* pPool=new CAPool(MIX_POOL_SIZE); 01000 tPoolEntry* pPoolEntry=new tPoolEntry; 01001 MIXPACKET* pMixPacket=&pPoolEntry->packet; 01002 while(!pFirstMix->m_bRestart) 01003 { 01004 len=sizeof(tQueueEntry); 01005 ret=pQueue->getOrWait((UINT8*)pPoolEntry,&len,MIX_POOL_TIMEOUT); 01006 if(ret==E_TIMEDOUT) 01007 { 01008 pMixPacket->flags=CHANNEL_DUMMY; 01009 pMixPacket->channel=DUMMY_CHANNEL; 01010 getRandom(pMixPacket->data,DATA_SIZE); 01011 #ifdef LOG_PACKET_TIMES 01012 setZero64(pPoolEntry->timestamp_proccessing_start); 01013 #endif 01014 } 01015 else if(ret!=E_SUCCESS||len!=sizeof(tQueueEntry)) 01016 break; 01017 #ifdef LOG_PACKET_TIMES 01018 getcurrentTimeMicros(pPoolEntry->pool_timestamp_in); 01019 #endif 01020 pPool->pool(pPoolEntry); 01021 #ifdef LOG_PACKET_TIMES 01022 getcurrentTimeMicros(pPoolEntry->pool_timestamp_out); 01023 #endif 01024 if(pMuxSocket->send(pMixPacket)!=MIXPACKET_SIZE) 01025 break; 01026 #ifdef LOG_PACKET_TIMES 01027 if(!isZero64(pPoolEntry->timestamp_proccessing_start)) 01028 { 01029 getcurrentTimeMicros(pPoolEntry->timestamp_proccessing_end); 01030 pFirstMix->m_pLogPacketStats->addToTimeingStats(*pPoolEntry,pMixPacket->flags,true); 01031 } 01032 #endif 01033 } 01034 delete pPoolEntry; 01035 pPoolEntry = NULL; 01036 delete pPool; 01037 pPool = NULL; 01038 #endif 01039 01040 /*#ifdef DATA_RETENTION_LOG 01041 delete pDataRetentionLogEntry; 01042 #endif 01043 */ 01044 FINISH_STACK("CAFirstMix::fm_loopSendToMix"); 01045 01046 CAMsg::printMsg(LOG_DEBUG,"Exiting Thread SendToMix\n"); 01047 THREAD_RETURN_SUCCESS; 01048 } 01049 01050 /* How to end this thread: 01051 0. set bRestart=true 01052 */ 01053 THREAD_RETURN fm_loopReadFromMix(void* pParam) 01054 { 01055 INIT_STACK; 01056 BEGIN_STACK("CAFirstMix::fm_loopReadFromMix"); 01057 01058 CAFirstMix* pFirstMix=(CAFirstMix*)pParam; 01059 CAMuxSocket* pMuxSocket=pFirstMix->m_pMuxOut; 01060 CAQueue* pQueue=pFirstMix->m_pQueueReadFromMix; 01061 tQueueEntry* pQueueEntry=new tQueueEntry; 01062 MIXPACKET* pMixPacket=&pQueueEntry->packet; 01063 CASingleSocketGroup* pSocketGroup=new CASingleSocketGroup(false); 01064 pSocketGroup->add(*pMuxSocket); 01065 #ifdef USE_POOL 01066 CAPool* pPool=new CAPool(MIX_POOL_SIZE); 01067 #endif 01068 UINT64 keepaliveNow,keepaliveLast; 01069 UINT32 u32KeepAliveRecvInterval=pFirstMix->m_u32KeepAliveRecvInterval; 01070 getcurrentTimeMillis(keepaliveLast); 01071 CAControlChannelDispatcher* pControlChannelDispatcher=pFirstMix->m_pMuxOutControlChannelDispatcher; 01072 while(!pFirstMix->m_bRestart) 01073 { 01074 if(pQueue->getSize()>MAX_READ_FROM_NEXT_MIX_QUEUE_SIZE) 01075 { 01076 #ifdef DEBUG 01077 CAMsg::printMsg(LOG_DEBUG,"CAFirstMix::Queue is full!\n"); 01078 #endif 01079 msSleep(200); 01080 getcurrentTimeMillis(keepaliveLast); 01081 continue; 01082 } 01083 //check if the connection is broken because we did not received a Keep_alive-Message 01084 getcurrentTimeMillis(keepaliveNow); 01085 UINT32 keepaliveDiff=diff64(keepaliveNow,keepaliveLast); 01086 if(keepaliveDiff>u32KeepAliveRecvInterval) 01087 { 01088 CAMsg::printMsg(LOG_DEBUG,"CAFirstMix::loopReadFromMix() -- restart because of KeepAlive-Traffic Timeout!\n"); 01089 pFirstMix->m_bRestart=true; 01090 MONITORING_FIRE_NET_EVENT(ev_net_nextConnectionClosed); 01091 break; 01092 } 01093 SINT32 ret=pSocketGroup->select(MIX_POOL_TIMEOUT); 01094 if(ret==E_TIMEDOUT) 01095 { 01096 #ifdef USE_POOL 01097 pMixPacket->flags=CHANNEL_DUMMY; 01098 pMixPacket->channel=DUMMY_CHANNEL; 01099 getRandom(pMixPacket->data,DATA_SIZE); 01100 #ifdef LOG_PACKET_TIMES 01101 setZero64(pQueueEntry->timestamp_proccessing_start); 01102 #endif 01103 #else 01104 continue; 01105 #endif 01106 } 01107 else if(ret>0) 01108 { 01109 ret=pMuxSocket->receive(pMixPacket); 01110 #ifdef LOG_PACKET_TIMES 01111 getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_start); 01112 #endif 01113 if(ret!=MIXPACKET_SIZE) 01114 { 01115 pFirstMix->m_bRestart=true; 01116 CAMsg::printMsg(LOG_ERR,"CAFirstMix::lm_loopReadFromMix - received returned: %i -- restarting!\n",ret); 01117 MONITORING_FIRE_NET_EVENT(ev_net_nextConnectionClosed); 01118 break; 01119 } 01120 } 01121 if(pMixPacket->channel>0&&pMixPacket->channel<256) 01122 { 01123 #ifdef DEBUG 01124 CAMsg::printMsg(LOG_DEBUG,"CAFirstMix - sent a packet from the next mix to the ControlChanelDispatcher... \n"); 01125 #endif 01126 pControlChannelDispatcher->proccessMixPacket(pMixPacket); 01127 getcurrentTimeMillis(keepaliveLast); 01128 continue; 01129 } 01130 #ifdef USE_POOL 01131 #ifdef LOG_PACKET_TIMES 01132 getcurrentTimeMicros(pQueueEntry->pool_timestamp_in); 01133 #endif 01134 pPool->pool((tPoolEntry*)pQueueEntry); 01135 #ifdef LOG_PACKET_TIMES 01136 getcurrentTimeMicros(pQueueEntry->pool_timestamp_out); 01137 #endif 01138 #endif 01139 pQueue->add(pQueueEntry, sizeof(tQueueEntry)); 01140 getcurrentTimeMillis(keepaliveLast); 01141 } 01142 delete pQueueEntry; 01143 pQueueEntry = NULL; 01144 delete pSocketGroup; 01145 pSocketGroup = NULL; 01146 #ifdef USE_POOL 01147 delete pPool; 01148 pPool = NULL; 01149 #endif 01150 01151 FINISH_STACK("CAFirstMix::fm_loopReadFromMix"); 01152 THREAD_RETURN_SUCCESS; 01153 } 01154 01155 struct T_UserLoginData 01156 { 01157 CAMuxSocket* pNewUser; 01158 CAFirstMix* pMix; 01159 UINT8 peerIP[4]; 01160 }; 01161 01162 typedef struct T_UserLoginData t_UserLoginData; 01163 01164 SINT32 isAllowedToPassRestrictions(CASocket* pNewMuxSocket) 01165 { 01166 UINT8* peerIP=new UINT8[4]; 01167 SINT32 master = pNewMuxSocket->getPeerIP(peerIP); 01168 01169 if(master == E_SUCCESS) 01170 { 01171 UINT32 size=0; 01172 UINT8 remoteIP[4]; 01173 01174 CAListenerInterface** intf = CALibProxytest::getOptions()->getInfoServices(size); 01175 01176 master = E_UNKNOWN; 01177 01178 for(UINT32 i = 0; i < size; i++) 01179 { 01180 if(intf[i]->getType() == HTTP_TCP || intf[i]->getType() == RAW_TCP) 01181 { 01182 CASocketAddrINet* addr = (CASocketAddrINet*) intf[i]->getAddr(); 01183 if(addr == NULL) 01184 { 01185 continue; 01186 } 01187 01188 addr->getIP(remoteIP); 01189 delete addr; 01190 addr = NULL; 01191 01192 if(memcmp(peerIP, remoteIP, 4) == 0) 01193 { 01194 CAMsg::printMsg(LOG_DEBUG,"Got InfoService connection: You are allowed for login...\n"); 01195 master = E_SUCCESS; 01196 break; 01197 } 01198 } 01199 } 01200 } 01201 delete[] peerIP; 01202 peerIP = NULL; 01203 01204 return master; 01205 } 01206 01207 01208 /*How to end this thread 01209 1. Set m_bRestart in firstMix to true 01210 2. close all accept sockets 01211 */ 01212 THREAD_RETURN fm_loopAcceptUsers(void* param) 01213 { 01214 INIT_STACK; 01215 BEGIN_STACK("CAFirstMix::fm_loopAcceptUsers"); 01216 01217 CAFirstMix* pFirstMix=(CAFirstMix*)param; 01218 CASocket** socketsIn=pFirstMix->m_arrSocketsIn; 01219 CAIPList* pIPList=pFirstMix->m_pIPList; 01220 CATempIPBlockList* pIPBlockList = pFirstMix->m_pIPBlockList; 01221 CAThreadPool* pthreadsLogin=pFirstMix->m_pthreadsLogin; 01222 UINT32 nSocketsIn=pFirstMix->m_nSocketsIn; 01223 CASocketGroup* psocketgroupAccept=new CASocketGroup(false); 01224 CAMuxSocket* pNewMuxSocket; 01225 UINT8* peerIP=new UINT8[4]; 01226 UINT32 i=0; 01227 SINT32 countRead; 01228 SINT32 ret; 01229 SINT32 retPeerIP = E_SUCCESS; 01230 01231 pFirstMix->m_newConnections = 0; 01232 01233 // kick out users that already have connected 01234 for(i=0;i<nSocketsIn;i++) 01235 { 01236 while (socketsIn[i]->close() != E_SUCCESS) 01237 { 01238 sSleep(1); 01239 } 01240 } 01241 if (CALibProxytest::getOptions()->createSockets(false,pFirstMix-> m_arrSocketsIn, pFirstMix->m_nSocketsIn) != E_SUCCESS) 01242 { 01243 goto END_THREAD; 01244 } 01245 for(i=0;i<nSocketsIn;i++) 01246 { 01247 psocketgroupAccept->add(*socketsIn[i]); 01248 } 01249 #ifdef REPLAY_DETECTION //before we can start to accept users we have to ensure that we received the replay timestamps form the over mixes 01250 CAMsg::printMsg(LOG_DEBUG,"Waiting for Replay Timestamp from next mixes\n"); 01251 i=0; 01252 while(!pFirstMix->m_bRestart && i < pFirstMix->m_u32MixCount-1) 01253 { 01254 if(pFirstMix->m_arMixParameters[i].m_u32ReplayOffset==0)//not set yet 01255 { 01256 msSleep(100);//wait a little bit and try again 01257 continue; 01258 } 01259 i++; 01260 } 01261 CAMsg::printMsg(LOG_DEBUG,"All Replay Timestamp received\n"); 01262 #endif 01263 while(!pFirstMix->m_bRestart) 01264 { 01265 if (pIPBlockList->count()>40) 01266 { 01267 CAMsg::printMsg(LOG_DEBUG,"UserAcceptLoop: login timeout list counts %d. We have %d users, %d open sockets and %d new connections. Restarting server sockets...\n",pIPBlockList->count(), pFirstMix->getNrOfUsers() ,CASocket::countOpenSockets(), pFirstMix->m_newConnections); 01268 for(i=0;i<nSocketsIn;i++) 01269 { 01270 psocketgroupAccept->remove(*socketsIn[i]); 01271 while (socketsIn[i]->close() != E_SUCCESS) 01272 { 01273 sSleep(1); 01274 } 01275 } 01276 01277 if (CALibProxytest::getOptions()->createSockets(false,pFirstMix-> m_arrSocketsIn, pFirstMix->m_nSocketsIn) != E_SUCCESS) 01278 { 01279 // could not listen 01280 goto END_THREAD; 01281 } 01282 for(i=0;i<nSocketsIn;i++) 01283 { 01284 psocketgroupAccept->add(*socketsIn[i]); 01285 } 01286 sSleep(1); 01287 } 01288 countRead=psocketgroupAccept->select(10000); 01289 if(countRead<0) 01290 { //check for Error - are we restarting ? 01291 if(pFirstMix->m_bRestart ||countRead!=E_TIMEDOUT) 01292 goto END_THREAD; 01293 } 01294 i=0; 01295 #ifdef _DEBUG 01296 CAMsg::printMsg(LOG_DEBUG,"UserAcceptLoop: countRead=%i\n",countRead); 01297 #endif 01298 while(countRead>0&&i<nSocketsIn) 01299 { 01300 if(psocketgroupAccept->isSignaled(*socketsIn[i])) 01301 { 01302 countRead--; 01303 #ifdef _DEBUG 01304 CAMsg::printMsg(LOG_DEBUG,"New direct Connection from Client!\n"); 01305 #endif 01306 pNewMuxSocket=new CAMuxSocket; 01307 ret=socketsIn[i]->accept(*(pNewMuxSocket->getCASocket())); 01308 pFirstMix->incNewConnections(); 01309 01310 if(ret!=E_SUCCESS) 01311 { 01312 // may return E_SOCKETCLOSED or E_SOCKET_LIMIT 01313 CAMsg::printMsg(LOG_ERR,"Accept Error %u - direct Connection from Client!\n",GET_NET_ERROR); 01314 } 01315 else if( (CALibProxytest::getOptions()->getMaxNrOfUsers() > 0 && 01316 pFirstMix->getNrOfUsers() >= CALibProxytest::getOptions()->getMaxNrOfUsers()) 01317 && (isAllowedToPassRestrictions(pNewMuxSocket->getCASocket()) != E_SUCCESS) 01318 01319 ) 01320 { 01321 CAMsg::printMsg(LOG_DEBUG,"CAFirstMix User control: Too many users (Maximum:%d)! Rejecting user...\n", pFirstMix->getNrOfUsers(),CALibProxytest::getOptions()->getMaxNrOfUsers()); 01322 ret = E_UNKNOWN; 01323 } 01324 else if ((pFirstMix->m_newConnections > CAFirstMix::MAX_CONCURRENT_NEW_CONNECTIONS) 01325 && (isAllowedToPassRestrictions(pNewMuxSocket->getCASocket()) != E_SUCCESS) 01326 ) 01327 01328 { 01329 /* This should protect the mix from flooding attacks 01330 * No more than MAX_CONCURRENT_NEW_CONNECTIONS are allowed. 01331 */ 01332 #ifdef _DEBUG 01333 CAMsg::printMsg(LOG_DEBUG,"CAFirstMix Flooding protection: Too many concurrent new connections (Maximum:%d)! Rejecting user...\n", CAFirstMix::MAX_CONCURRENT_NEW_CONNECTIONS); 01334 #endif 01335 ret = E_UNKNOWN; 01336 } 01337 //#ifndef PAYMENT 01338 else if ((ret = pNewMuxSocket->getCASocket()->getPeerIP(peerIP)) != E_SUCCESS || 01339 (retPeerIP = pIPList->insertIP(peerIP)) < 0) 01340 // || (pIPBlockList->checkIP(peerIP) == E_UNKNOWN && isAllowedToPassRestrictions(pNewMuxSocket->getCASocket()) != E_SUCCESS)) 01341 { 01342 if (ret != E_SUCCESS) 01343 { 01344 CAMsg::printMsg(LOG_DEBUG,"Could not insert IP address as IP could not be retrieved! We have %d login threads currently running.\n", pthreadsLogin->countRequests()); 01345 01346 } 01347 else if (retPeerIP < 0) 01348 { 01349 CAMsg::printMsg(LOG_DEBUG,"CAFirstMix Flooding protection: Could not insert IP address! We have %d login threads currently running.\n", pthreadsLogin->countRequests()); 01350 pIPBlockList->insertIP(peerIP); 01351 } 01352 else if (pIPBlockList->checkIP(peerIP) == E_UNKNOWN) 01353 { 01354 CAMsg::printMsg(LOG_DEBUG, "Client IP address %u.%u.x.x is temporarily blocked! User login denied. We have %d open sockets and %d new connections.\n", peerIP[0],peerIP[1], CASocket::countOpenSockets(), pFirstMix->m_newConnections); 01355 pIPList->removeIP(peerIP); 01356 } 01357 ret = E_UNKNOWN; 01358 } 01359 //#endif 01360 else 01361 { 01362 t_UserLoginData* d=new t_UserLoginData; 01363 d->pNewUser=pNewMuxSocket; 01364 d->pMix=pFirstMix; 01365 memcpy(d->peerIP,peerIP,4); 01366 #ifdef DEBUG 01367 CAMsg::printMsg(LOG_DEBUG,"%d concurrent client connections.\n", pFirstMix->m_newConnections); 01368 #endif 01369 if(pthreadsLogin->addRequest(fm_loopDoUserLogin,d)!=E_SUCCESS) 01370 { 01371 CAMsg::printMsg(LOG_ERR,"Could not add an login request to the login thread pool!\n"); 01372 ret=E_UNKNOWN; 01373 } 01374 } 01375 01376 if (ret != E_SUCCESS) 01377 { 01378 delete pNewMuxSocket; 01379 pNewMuxSocket = NULL; 01380 pFirstMix->decNewConnections(); 01381 if(ret==E_SOCKETCLOSED&&pFirstMix->m_bRestart) //Hm, should we restart ?? 01382 { 01383 goto END_THREAD; 01384 } 01385 else //if(ret==E_SOCKET_LIMIT) // Hm no free sockets - wait some time to hope to get a free one... 01386 { 01387 msSleep(400); 01388 } 01389 } 01390 } 01391 i++; 01392 } 01393 } 01394 END_THREAD: 01395 FINISH_STACK("CAFirstMix::fm_loopAcceptUsers"); 01396 01397 delete[] peerIP; 01398 peerIP = NULL; 01399 delete psocketgroupAccept; 01400 psocketgroupAccept = NULL; 01401 01402 CAMsg::printMsg(LOG_DEBUG,"Exiting Thread AcceptUser\n"); 01403 THREAD_RETURN_SUCCESS; 01404 } 01405 01406 01407 THREAD_RETURN fm_loopLog(void* param) 01408 { 01409 CAFirstMix* pFirstMix=(CAFirstMix*)param; 01410 pFirstMix->m_bRunLog=true; 01411 UINT32 countLog=0; 01412 while(pFirstMix->m_bRunLog) 01413 { 01414 if(countLog==0) 01415 { 01416 logMemoryUsage(); 01417 countLog=10; 01418 } 01419 sSleep(30); 01420 countLog--; 01421 } 01422 THREAD_RETURN_SUCCESS; 01423 } 01424 01425 #ifdef CH_LOG_STUDY 01426 THREAD_RETURN fm_loopLogChannelsOpened(void* param) 01427 { 01428 CAFirstMix* pFirstMix=(CAFirstMix*)param; 01429 pFirstMix->m_bRunLog=true; 01430 UINT32 countLog= 10; 01431 UINT32 value = 0; 01432 UINT32 total = 0; 01433 time_t newIvalTS = 0, ival = 0; 01434 01435 pFirstMix->nrOfChOpMutex->lock(); 01436 pFirstMix->lastLogTime = time(NULL); 01437 pFirstMix->nrOfChOpMutex->unlock(); 01438 01439 while(pFirstMix->m_bRunLog) 01440 { 01441 if(countLog == 0) 01442 { 01443 pFirstMix->nrOfChOpMutex->lock(); 01444 value = pFirstMix->nrOfOpenedChannels; 01445 total = pFirstMix->currentOpenedChannels; 01446 pFirstMix->nrOfOpenedChannels = 0; 01447 newIvalTS = time(NULL); 01448 ival = newIvalTS - pFirstMix->lastLogTime; 01449 pFirstMix->lastLogTime = newIvalTS; 01450 pFirstMix->nrOfChOpMutex->unlock(); 01451 CAMsg::printMsg(LOG_INFO,"Analyzing channels: Opened channels for %u JonDo connections in the last %u seconds, overall open channels: %u, users online: %u\n", 01452 value, ival, total, pFirstMix->getNrOfUsers() ); 01453 countLog = 10; 01454 } 01455 sSleep(1); 01456 countLog--; 01457 } 01458 THREAD_RETURN_SUCCESS; 01459 } 01460 #endif //CH_LOG_STUDY 01461 01462 THREAD_RETURN fm_loopDoUserLogin(void* param) 01463 { 01464 INIT_STACK; 01465 BEGIN_STACK("CAFirstMix::fm_loopDoUserLogin"); 01466 #ifdef COUNTRY_STATS 01467 my_thread_init(); 01468 #endif 01469 01470 t_UserLoginData* d=(t_UserLoginData*)param; 01471 d->pMix->doUserLogin(d->pNewUser,d->peerIP); 01472 01473 SAVE_STACK("CAFirstMix::fm_loopDoUserLogin", "after user login"); 01474 d->pMix->decNewConnections(); 01475 delete d; 01476 d = NULL; 01477 01478 #ifdef COUNTRY_STATS 01479 my_thread_end(); 01480 #endif 01481 FINISH_STACK("CAFirstMix::fm_loopDoUserLogin"); 01482 01483 THREAD_RETURN_SUCCESS; 01484 } 01485 01486 termsAndConditionMixAnswer_t *CAFirstMix::handleTermsAndConditionsLogin(XERCES_CPP_NAMESPACE::DOMDocument* request) 01487 { 01488 termsAndConditionMixAnswer_t *answer = 01489 new termsAndConditionMixAnswer_t; 01490 01491 const XMLCh* reqName = request->getDocumentElement()->getTagName(); 01492 01493 //Client requests lacking T&C resources. 01494 if(XMLString::equals(reqName, TNC_REQUEST)) 01495 { 01496 answer->result = TC_UNFINISHED; 01497 CAMsg::printMsg(LOG_DEBUG,"Handling TC request.\n"); 01498 XERCES_CPP_NAMESPACE::DOMDocument *response = createDOMDocument(); 01499 DOMElement *responseRoot = createDOMElement(response, TNC_RESPONSE); 01500 response->appendChild(responseRoot); 01501 //All elements with tag name 'Resources' (direct children of 'TermsAndConditionsRequest') 01502 DOMNodeList *requestedResources = getElementsByTagName(request->getDocumentElement(), TNC_RESOURCES); 01503 //All elements with tag name 'Translation' (direct children of 'Resources') 01504 DOMNodeList *requestedResourceItems = NULL; 01505 01506 DOMNode *currentNode = NULL; 01507 DOMNode *currentAnswerNode = NULL; 01508 DOMNode *currentAnswerResourceNode = NULL; 01509 01510 UINT32 idLen = TMP_BUFF_SIZE; 01511 UINT8 id[TMP_BUFF_SIZE]; 01512 memset(id, 0, idLen); 01513 01514 UINT32 localeLen = TMP_LOCALE_SIZE; 01515 UINT8 locale[TMP_LOCALE_SIZE]; 01516 memset(locale, 0, localeLen); 01517 01518 bool resourceError = false; 01519 01520 if(requestedResources->getLength() == 0) 01521 { 01522 response->release(); 01523 response = createDOMDocument(); 01524 response->appendChild(createDOMElement(response, TNC_RESPONSE_INVALID_REQUEST)); 01525 answer->result = TC_FAILED; 01526 } 01527 01528 for (XMLSize_t i = 0; i < requestedResources->getLength(); i++) 01529 { 01530 idLen = TMP_BUFF_SIZE; 01531 localeLen = TMP_LOCALE_SIZE; 01532 bool validResource = false; 01533 01534 currentNode = requestedResources->item(i); 01535 //check validity of the T&C resource request. attributes "id" and locale must be proper set. 01536 if( (getDOMElementAttribute(currentNode, OPTIONS_ATTRIBUTE_TNC_ID, id, &idLen) != E_SUCCESS) || 01537 (strlen((char *)id) < 1) ) 01538 { 01539 CAMsg::printMsg(LOG_DEBUG,"Error: invalid id.\n"); 01540 resourceError = true; 01541 } 01542 01543 if(!currentNode->hasChildNodes()) 01544 { 01545 //Empty Resource node is invalid! 01546 CAMsg::printMsg(LOG_DEBUG,"Error: No children.\n"); 01547 resourceError = true; 01548 } 01549 01550 if(!resourceError) 01551 { 01552 01553 TermsAndConditions *requestedTnC = getTermsAndConditions(id); 01554 if(requestedTnC != NULL) 01555 { 01556 requestedResourceItems = getElementsByTagName((DOMElement *)currentNode, TNC_REQ_TRANSLATION); 01557 for(XMLSize_t j = 0; j < requestedResourceItems->getLength(); j++) 01558 { 01559 validResource = false; 01560 localeLen = TMP_LOCALE_SIZE; 01561 if( (getDOMElementAttribute(requestedResourceItems->item(j), 01562 OPTIONS_ATTRIBUTE_TNC_LOCALE, 01563 locale, &localeLen) != E_SUCCESS) || 01564 (strlen((char *)locale) != ((TMP_LOCALE_SIZE) - 1) ) ) 01565 { 01566 CAMsg::printMsg(LOG_DEBUG,"Error: Invalid locale for tnc %s\n", id); 01567 break; 01568 } 01569 01570 const termsAndConditionsTranslation_t *requestedTranslation = 01571 requestedTnC->getTranslation(locale); 01572 //NOTE: No need to lock while working with the TC translation 01573 //because the translation containers are only modified during 01574 //inter-mix-keyexchange and cleanup. 01575 //Both must never run concurrently to this method 01576 if(requestedTranslation != NULL) 01577 { 01578 01579 currentAnswerNode = response->importNode(currentNode, false); 01580 responseRoot->appendChild(currentAnswerNode); 01581 if( getDOMChildByName(requestedResourceItems->item(j), TNC_RESOURCE_TEMPLATE, 01582 currentAnswerResourceNode, false) == E_SUCCESS) 01583 { 01584 currentAnswerResourceNode = response->importNode(currentAnswerResourceNode, true); 01585 currentAnswerResourceNode->appendChild( 01586 response->importNode(requestedTranslation->tnc_template, true)); 01587 currentAnswerNode->appendChild(currentAnswerResourceNode); 01588 validResource = true; 01589 } 01590 01591 if( getDOMChildByName(requestedResourceItems->item(j), TNC_RESOURCE_CUSTOMIZED_SECT, 01592 currentAnswerResourceNode, false) == E_SUCCESS) 01593 { 01594 currentAnswerResourceNode = response->importNode(currentAnswerResourceNode, true); 01595 currentAnswerResourceNode->appendChild( 01596 response->importNode(requestedTranslation->tnc_customized, true)); 01597 currentAnswerNode->appendChild(currentAnswerResourceNode); 01598 validResource = true; 01599 } 01600 } 01601 else 01602 { 01603 CAMsg::printMsg(LOG_DEBUG,"Error: no translation def found.\n"); 01604 break; 01605 } 01606 } 01607 } 01608 else 01609 { 01610 CAMsg::printMsg(LOG_DEBUG,"Error: no tc def found.\n"); 01611 } 01612 } 01613 01614 if(!validResource) 01615 { 01616 //only a manipulated client sends an invalid T&C resource request. 01617 //Manipulation is interpreted as a rejection of the terms & conditions, 01618 //so abort login immediately. 01619 response->release(); 01620 response = createDOMDocument(); 01621 response->appendChild(createDOMElement(response, TNC_RESPONSE_INVALID_REQUEST)); 01622 answer->result = TC_FAILED; 01623 break; 01624 } 01625 } 01626 answer->xmlAnswer = response; 01627 } 01628 //Client accepts/rejects the T&Cs. 01629 else if(XMLString::equals(reqName, TNC_CONFIRM)) 01630 { 01631 CAMsg::printMsg(LOG_DEBUG,"handling TC confirm.\n"); 01632 bool tcAccepted = false; 01633 getDOMElementAttribute(request->getDocumentElement(), "accepted", tcAccepted); 01634 CAMsg::printMsg(LOG_DEBUG,"Client has%s accepted the T&Cs.\n", (tcAccepted ? "" : " not") ); 01635 01636 answer->xmlAnswer = NULL; 01637 answer->result = tcAccepted ? TC_CONFIRMED : TC_FAILED; 01638 } 01639 //stops the message exchange (if client needs time for showing the T & Cs, etc.) 01640 else if(XMLString::equals(reqName, TNC_INTERRUPT)) 01641 { 01642 CAMsg::printMsg(LOG_DEBUG,"client requested interrupting the tc login.\n"); 01643 answer->xmlAnswer = NULL; 01644 answer->result = TC_FAILED; 01645 } 01646 //Client sends an invalid message 01647 else 01648 { 01649 answer->xmlAnswer = NULL; //TODO: set errorMessage here 01650 answer->result = TC_FAILED; 01651 } 01652 return answer; 01653 } 01654 01655 SINT32 CAFirstMix::doUserLogin(CAMuxSocket* pNewUser,UINT8 peerIP[4]) 01656 { 01657 INIT_STACK; 01658 SINT32 ret = doUserLogin_internal(pNewUser, peerIP); 01659 FINISH_STACK("CAFirstMix::doUserLogin"); 01660 return ret; 01661 } 01662 01668 SINT32 CAFirstMix::doUserLogin_internal(CAMuxSocket* pNewUser,UINT8 peerIP[4]) 01669 { 01670 SINT32 ret; 01671 01672 INIT_STACK; 01673 BEGIN_STACK("CAFirstMix::doUserLogin"); 01674 ret=pNewUser->getCASocket()->setKeepAlive(true); 01675 if(ret!=E_SUCCESS) 01676 CAMsg::printMsg(LOG_DEBUG,"Error setting KeepAlive for user login connection!"); 01677 01678 #ifdef DEBUG 01679 CAMsg::printMsg(LOG_DEBUG,"User login: start\n"); 01680 #endif 01681 01682 SAVE_STACK("CAFirstMix::doUserLogin", "after setting keep alive"); 01683 01684 // send the mix-keys to JAP 01685 if ((ret = pNewUser->getCASocket()->sendFullyTimeOut(m_xmlKeyInfoBuff,m_xmlKeyInfoSize, 40000, 10000)) != E_SUCCESS) 01686 { 01687 if (ret != E_UNKNOWN) 01688 { 01689 CAMsg::printMsg(LOG_DEBUG,"User login: Sending login data to client %u.%u.x.x has been interrupted! Reason: '%s' (%i)\n", 01690 peerIP[0],peerIP[1], GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR); 01691 } 01692 else 01693 { 01694 CAMsg::printMsg(LOG_DEBUG,"User login: Sending login data to client %u.%u.x.x has been interrupted!\n", peerIP[0],peerIP[1]); 01695 } 01696 01697 m_pIPBlockList->insertIP(peerIP); 01698 01699 delete pNewUser; 01700 pNewUser = NULL; 01701 m_pIPList->removeIP(peerIP); 01702 return E_UNKNOWN; 01703 } 01704 #ifdef DEBUG 01705 CAMsg::printMsg(LOG_DEBUG,"User login: login data sent\n"); 01706 #endif 01707 SAVE_STACK("CAFirstMix::doUserLogin", "after sending login data"); 01708 01709 //(pNewUser)->send(m_xmlKeyInfoBuff,m_xmlKeyInfoSize); 01710 // es kann nicht blockieren unter der Annahme das der TCP-Sendbuffer > m_xmlKeyInfoSize ist.... 01711 01712 //wait for keys from user 01713 UINT16 xml_len=0; 01714 if(pNewUser->getCASocket()->isClosed()) 01715 { 01716 CAMsg::printMsg(LOG_DEBUG,"User login: Socket was closed while waiting for first symmetric key from client!\n"); 01717 } 01718 else if ((ret = pNewUser->getCASocket()->receiveFullyT((UINT8*)&xml_len,2,FIRST_MIX_RECEIVE_SYM_KEY_FROM_JAP_TIME_OUT)) != E_SUCCESS) 01719 { 01720 if (ret != E_UNKNOWN) 01721 { 01722 CAMsg::printMsg(LOG_DEBUG,"User login: Waiting for first symmetric key from client %u.%u.x.x! failed for reason: '%s' (%i)\n", 01723 peerIP[0], peerIP[1], GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR); 01724 } 01725 else 01726 { 01727 CAMsg::printMsg(LOG_DEBUG,"User login: Waiting for first symmetric key from client %u.%u.x.x! failed.\n", 01728 peerIP[0], peerIP[1]); 01729 } 01730 m_pIPBlockList->insertIP(peerIP); 01731 01732 delete pNewUser; 01733 pNewUser = NULL; 01734 m_pIPList->removeIP(peerIP); 01735 return E_UNKNOWN; 01736 } 01737 #ifdef DEBUG 01738 CAMsg::printMsg(LOG_DEBUG,"User login: received first symmetric key from client\n"); 01739 #endif 01740 SAVE_STACK("CAFirstMix::doUserLogin", "received first symmetric key"); 01741 01742 xml_len=ntohs(xml_len); 01743 UINT8* xml_buff=new UINT8[xml_len+2]; //+2 for size... 01744 if(pNewUser->getCASocket()->isClosed() || 01745 (ret = pNewUser->getCASocket()->receiveFullyT(xml_buff+2,xml_len,FIRST_MIX_RECEIVE_SYM_KEY_FROM_JAP_TIME_OUT)) !=E_SUCCESS) 01746 { 01747 if (pNewUser->getCASocket()->isClosed()) 01748 { 01749 SET_NET_ERROR(E_SOCKETCLOSED); 01750 } 01751 01752 01753 if (ret != E_UNKNOWN) 01754 { 01755 CAMsg::printMsg(LOG_DEBUG,"User login: Waiting for second symmetric key from client failed for reason: '%s' (%i)\n", 01756 GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR); 01757 } 01758 else 01759 { 01760 CAMsg::printMsg(LOG_DEBUG,"User login: Waiting for second symmetric key from client failed.\n"); 01761 } 01762 01763 m_pIPBlockList->insertIP(peerIP); 01764 01765 delete pNewUser; 01766 pNewUser = NULL; 01767 delete[] xml_buff; 01768 xml_buff = NULL; 01769 m_pIPList->removeIP(peerIP); 01770 return E_UNKNOWN; 01771 } 01772 01773 #ifdef DEBUG 01774 CAMsg::printMsg(LOG_DEBUG,"User login: received second symmetric key from client\n"); 01775 #endif 01776 SAVE_STACK("CAFirstMix::doUserLogin", "received second symmetric key"); 01777 01778 XERCES_CPP_NAMESPACE::DOMDocument* doc=parseDOMDocument(xml_buff+2,xml_len); 01779 DOMElement* elemRoot=NULL; 01780 if(doc==NULL||(elemRoot=doc->getDocumentElement())==NULL|| 01781 decryptXMLElement(elemRoot,m_pRSA)!=E_SUCCESS) 01782 { 01783 delete[] xml_buff; 01784 xml_buff = NULL; 01785 delete pNewUser; 01786 pNewUser = NULL; 01787 m_pIPList->removeIP(peerIP); 01788 if(doc!=NULL) 01789 { 01790 doc->release(); 01791 doc = NULL; 01792 } 01793 return E_UNKNOWN; 01794 } 01795 elemRoot=doc->getDocumentElement(); 01796 if(!equals(elemRoot->getNodeName(),"JAPKeyExchange")) 01797 { 01798 if (doc != NULL) 01799 { 01800 doc->release(); 01801 doc = NULL; 01802 } 01803 delete[] xml_buff; 01804 xml_buff = NULL; 01805 delete pNewUser; 01806 pNewUser = NULL; 01807 m_pIPList->removeIP(peerIP); 01808 return E_UNKNOWN; 01809 } 01810 DOMElement* elemLinkEnc=NULL; 01811 DOMElement* elemMixEnc=NULL; 01812 getDOMChildByName(elemRoot,"LinkEncryption",elemLinkEnc,false); 01813 getDOMChildByName(elemRoot,"MixEncryption",elemMixEnc,false); 01814 UINT8 linkKey[255],mixKey[255]; 01815 UINT32 linkKeyLen=255,mixKeyLen=255; 01816 if( getDOMElementValue(elemLinkEnc,linkKey,&linkKeyLen)!=E_SUCCESS|| 01817 getDOMElementValue(elemMixEnc,mixKey,&mixKeyLen)!=E_SUCCESS|| 01818 CABase64::decode(linkKey,linkKeyLen,linkKey,&linkKeyLen)!=E_SUCCESS|| 01819 CABase64::decode(mixKey,mixKeyLen,mixKey,&mixKeyLen)!=E_SUCCESS|| 01820 linkKeyLen!=64||mixKeyLen!=32) 01821 { 01822 if (doc != NULL) 01823 { 01824 doc->release(); 01825 doc = NULL; 01826 } 01827 delete[] xml_buff; 01828 xml_buff = NULL; 01829 delete pNewUser; 01830 pNewUser = NULL; 01831 m_pIPList->removeIP(peerIP); 01832 return E_UNKNOWN; 01833 } 01834 //Getting control channel keys if available 01836 DOMElement* elemControlChannelEnc=NULL; 01837 getDOMChildByName(elemRoot,"ControlChannelEncryption",elemControlChannelEnc,false); 01838 UINT8 controlchannelKey[255]; 01839 UINT32 controlchannelKeyLen=255; 01840 UINT8* controlchannelRecvKey=NULL; 01841 UINT8* controlchannelSentKey=NULL; 01842 if( getDOMElementValue(elemControlChannelEnc,controlchannelKey,&controlchannelKeyLen)==E_SUCCESS&& 01843 CABase64::decode(controlchannelKey,controlchannelKeyLen,controlchannelKey,&controlchannelKeyLen)==E_SUCCESS&& 01844 controlchannelKeyLen==32) 01845 { 01846 controlchannelRecvKey=controlchannelKey; 01847 controlchannelSentKey=controlchannelKey+16; 01848 } 01849 01850 //Sending Signature.... 01851 xml_buff[0]=(UINT8)(xml_len>>8); 01852 xml_buff[1]=(UINT8)(xml_len&0xFF); 01853 UINT8* sig=new UINT8[255]; 01854 UINT32 siglen=255; 01855 //TODO change me to fully support MultiSig 01856 //m_pSignature->sign(xml_buff,xml_len+2,sig,&siglen); 01857 m_pMultiSignature->sign(xml_buff,xml_len+2,sig,&siglen); 01858 XERCES_CPP_NAMESPACE::DOMDocument* docSig=createDOMDocument(); 01859 01860 DOMElement *elemSig=NULL; 01861 01862 #ifdef LOG_DIALOG 01863 DOMElement* elemDialog=NULL; 01864 getDOMChildByName(elemRoot,"Dialog",elemDialog,false); 01865 UINT8 strDialog[255]; 01866 memset(strDialog,0,255); 01867 UINT32 dialogLen=255; 01868 getDOMElementValue(elemDialog,strDialog,&dialogLen); 01869 #endif 01870 #ifdef REPLAY_DETECTION 01871 //checking if Replay-Detection is enabled 01872 DOMElement *elemReplay=NULL; 01873 UINT8 replay[6]; 01874 UINT32 replay_len=5; 01875 if( (getDOMChildByName(elemRoot,"ReplayDetection",elemReplay,false)==E_SUCCESS)&& 01876 (getDOMElementValue(elemReplay,replay,&replay_len)==E_SUCCESS)&& 01877 (strncmp((char*)replay,"true",5)==0)){ 01878 elemRoot=createDOMElement(docSig,"MixExchange"); 01879 elemReplay=createDOMElement(docSig,"Replay"); 01880 docSig->appendChild(elemRoot); 01881 elemRoot->appendChild(elemReplay); 01882 01883 UINT32 diff=(UINT32)(time(NULL)-m_u64LastTimestampReceived); 01884 for(SINT32 i=0;i<getMixCount()-1;i++) 01885 { 01886 DOMElement* elemMix=createDOMElement(docSig,"Mix"); 01887 setDOMElementAttribute(elemMix,"id",m_arMixParameters[i].m_strMixID); 01888 DOMElement* elemReplayOffset=createDOMElement(docSig,"ReplayOffset"); 01889 setDOMElementValue(elemReplayOffset,(UINT32) (m_arMixParameters[i].m_u32ReplayOffset+diff)); 01890 elemMix->appendChild(elemReplayOffset); 01891 DOMElement* elemReplayBase=createDOMElement(docSig,"ReplayBase"); 01892 setDOMElementValue(elemReplayBase,(UINT32) (m_arMixParameters[i].m_u32ReplayBase)); 01893 elemMix->appendChild(elemReplayBase); 01894 elemReplay->appendChild(elemMix); 01895 } 01896 01897 DOMElement* elemMix=createDOMElement(docSig,"Mix"); 01898 UINT8 buff[255]; 01899 CALibProxytest::getOptions()->getMixId(buff,255); 01900 setDOMElementAttribute(elemMix,"id",buff); 01901 DOMElement* elemReplayOffset=createDOMElement(docSig,"ReplayOffset"); 01902 setDOMElementValue(elemReplayOffset,(UINT32) (time(NULL)-m_u64ReferenceTime)); 01903 elemMix->appendChild(elemReplayOffset); 01904 DOMElement* elemReplayBase=createDOMElement(docSig,"ReplayBase"); 01905 setDOMElementValue(elemReplayBase,(UINT32) (REPLAY_BASE)); 01906 elemMix->appendChild(elemReplayOffset); 01907 elemReplay->appendChild(elemMix); 01908 01909 elemSig=createDOMElement(docSig,"Signature"); 01910 elemRoot->appendChild(elemSig); 01911 01912 CAMsg::printMsg(LOG_DEBUG,"Replay Detection requested\n"); 01913 } 01914 else { 01915 elemSig=createDOMElement(docSig,"Signature"); 01916 docSig->appendChild(elemSig); 01917 } 01918 #endif 01919 #ifndef REPLAY_DETECTION 01920 elemSig=createDOMElement(docSig,"Signature"); 01921 docSig->appendChild(elemSig); 01922 #endif 01923 DOMElement* elemSigValue=createDOMElement(docSig,"SignatureValue"); 01924 elemSig->appendChild(elemSigValue); 01925 UINT32 u32=siglen; 01926 CABase64::encode(sig,u32,sig,&siglen); 01927 sig[siglen]=0; 01928 setDOMElementValue(elemSigValue,sig); 01929 delete[] sig; 01930 u32=xml_len; 01931 DOM_Output::dumpToMem(docSig,xml_buff+2,&u32); 01932 if (docSig != NULL) 01933 { 01934 docSig->release(); 01935 docSig = NULL; 01936 } 01937 xml_buff[0]=(UINT8)(u32>>8); 01938 xml_buff[1]=(UINT8)(u32&0xFF); 01939 01940 if (pNewUser->getCASocket()->isClosed() || 01941 pNewUser->getCASocket()->sendFullyTimeOut(xml_buff,u32+2, 30000, 10000) != E_SUCCESS) 01942 { 01943 if (doc != NULL) 01944 { 01945 doc->release(); 01946 doc = NULL; 01947 } 01948 CAMsg::printMsg(LOG_DEBUG,"User login: Sending key exchange signature has been interrupted!\n"); 01949 m_pIPBlockList->insertIP(peerIP); 01950 01951 delete[] xml_buff; 01952 xml_buff = NULL; 01953 delete pNewUser; 01954 pNewUser = NULL; 01955 m_pIPList->removeIP(peerIP); 01956 return E_UNKNOWN; 01957 } 01958 #ifdef DEBUG 01959 CAMsg::printMsg(LOG_DEBUG,"User login: key exchange signature sent\n"); 01960 #endif 01961 delete[] xml_buff; 01962 xml_buff = NULL; 01963 #if 0 //terms and conditions sending disabled. 01964 /* handle Terms And Conditions */ 01965 bool loginFailed = false; 01966 bool tcProcedureFinished = false; 01967 01968 while( !(tcProcedureFinished || loginFailed) ) 01969 { 01970 UINT16 tcRequestDataLen = 0; 01971 if (pNewUser->getCASocket()->isClosed() || 01972 (ret = pNewUser->getCASocket()->receiveFullyT((UINT8*)&tcRequestDataLen, 2, 10000)) != E_SUCCESS) 01973 { 01974 if (pNewUser->getCASocket()->isClosed()) 01975 { 01976 SET_NET_ERROR(E_SOCKETCLOSED); 01977 } 01978 01979 loginFailed = true; 01980 if (ret != E_UNKNOWN) 01981 { 01982 CAMsg::printMsg(LOG_ERR,"User login: Receiving t&c protocol data size has been interrupted. Reason: '%s' (%i)\n", 01983 GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR); 01984 } 01985 else 01986 { 01987 CAMsg::printMsg(LOG_ERR,"User login: Receiving t&c protocol data size has been interrupted.\n"); 01988 } 01989 break; 01990 } 01991 01992 tcRequestDataLen = ntohs(tcRequestDataLen); 01993 //CAMsg::printMsg(LOG_DEBUG,"User login: expecting %u bytes!\n", tcRequestDataLen); 01994 UINT8 tcDataBuf[tcRequestDataLen+1]; 01995 tcDataBuf[tcRequestDataLen] = 0; 01996 if (pNewUser->getCASocket()->isClosed() || 01997 (ret = pNewUser->getCASocket()->receiveFullyT(tcDataBuf, tcRequestDataLen, 10000)) != E_SUCCESS) 01998 { 01999 if (pNewUser->getCASocket()->isClosed()) 02000 { 02001 SET_NET_ERROR(E_SOCKETCLOSED); 02002 } 02003 02004 loginFailed = true; 02005 02006 if (ret != E_UNKNOWN) 02007 { 02008 CAMsg::printMsg(LOG_ERR,"User login: Receiving t&c protocol data has been interrupted. Reason: '%s' (%i)\n", 02009 GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR); 02010 } 02011 else 02012 { 02013 CAMsg::printMsg(LOG_ERR,"User login: Receiving t&c protocol data has been interrupted.\n"); 02014 } 02015 break; 02016 } 02017 02018 XERCES_CPP_NAMESPACE::DOMDocument *tcData = parseDOMDocument(tcDataBuf, tcRequestDataLen); 02019 if( (tcData == NULL) || (tcData->getDocumentElement() == NULL) ) 02020 { 02021 CAMsg::printMsg(LOG_ERR,"Could not parse t&c data!\n"); 02022 loginFailed = true; 02023 break; 02024 } 02025 02026 termsAndConditionMixAnswer_t *answer = handleTermsAndConditionsLogin(tcData); 02027 if(answer == NULL) 02028 { 02029 loginFailed = true; 02030 tcData->release(); 02031 tcData = NULL; 02032 break; 02033 } 02034 02035 if( (answer->xmlAnswer != NULL) ) 02036 { 02037 UINT32 size = 0; 02038 UINT8 *answerBuff = DOM_Output::dumpToMem(answer->xmlAnswer, &size); 02039 if(answerBuff != NULL) 02040 { 02041 //CAMsg::printMsg(LOG_DEBUG,"User login: answer %s\n", answerBuff); 02042 02043 UINT32 netSize = htonl(size); 02044 02045 if (pNewUser->getCASocket()->isClosed() || 02046 pNewUser->getCASocket()->sendFullyTimeOut((UINT8 *) &netSize, 4, 30000, 10000) != E_SUCCESS) 02047 { 02048 CAMsg::printMsg(LOG_DEBUG,"User login: sending t&c protocol data size has been interrupted!\n"); 02049 loginFailed = true; 02050 } 02051 else if (pNewUser->getCASocket()->isClosed() || 02052 pNewUser->getCASocket()->sendFullyTimeOut(answerBuff, size, 30000, 10000) != E_SUCCESS) 02053 { 02054 CAMsg::printMsg(LOG_DEBUG,"User login: Sending t&c protocol data has been interrupted!\n"); 02055 loginFailed = true; 02056 } 02057 delete [] answerBuff; 02058 } 02059 } 02060 tcProcedureFinished = (answer->result != TC_UNFINISHED); 02061 loginFailed = (answer->result == TC_FAILED); 02062 cleanupTnCMixAnswer(answer); 02063 delete answer; 02064 answer = NULL; 02065 tcData->release(); 02066 tcData = NULL; 02067 } 02068 02069 //Only if a positive confirm message was received, the client may pass! 02070 02071 if(loginFailed) 02072 { 02073 if (doc != NULL) 02074 { 02075 doc->release(); 02076 doc = NULL; 02077 } 02078 CAMsg::printMsg(LOG_DEBUG,"User login: failed!\n"); 02079 delete[] xml_buff; 02080 xml_buff = NULL; 02081 delete pNewUser; 02082 pNewUser = NULL; 02083 m_pIPList->removeIP(peerIP); 02084 return E_UNKNOWN; 02085 } 02086 /* end Terms And Conditions negotiation */ 02087 #endif 02088 SAVE_STACK("CAFirstMix::doUserLogin", "sent key exchange signature"); 02089 02090 pNewUser->getCASocket()->setNonBlocking(true); 02091 02092 SAVE_STACK("CAFirstMix::doUserLogin", "Creating CAQueue..."); 02093 CAQueue* tmpQueue=new CAQueue(sizeof(tQueueEntry)); 02094 02095 SAVE_STACK("CAFirstMix::doUserLogin", "Adding user to connection list..."); 02096 #ifdef LOG_DIALOG 02097 fmHashTableEntry* pHashEntry=m_pChannelList->add(pNewUser,peerIP,tmpQueue,strDialog); 02098 #else 02099 fmHashTableEntry* pHashEntry=m_pChannelList->add(pNewUser,peerIP,tmpQueue,controlchannelSentKey,controlchannelRecvKey); 02100 #endif 02101 if( (pHashEntry == NULL) || 02102 (pHashEntry->pControlMessageQueue == NULL) )// adding user connection to mix->JAP channel list (stefan: sollte das nicht connection list sein? --> es handelt sich um eine Datenstruktu fr Connections/Channels ). 02103 { 02104 if (doc != NULL) 02105 { 02106 doc->release(); 02107 doc = NULL; 02108 } 02109 CAMsg::printMsg(LOG_ERR,"User login: Could not add new socket to connection list!\n"); 02110 if(pHashEntry!=NULL) 02111 m_pChannelList->remove(pNewUser); 02112 m_pIPList->removeIP(peerIP); 02113 delete tmpQueue; 02114 tmpQueue = NULL; 02115 delete pNewUser; 02116 pNewUser = NULL; 02117 return E_UNKNOWN; 02118 } 02119 02120 SAVE_STACK("CAFirstMix::doUserLogin", "socket added to connection list"); 02121 #ifdef PAYMENT 02122 #ifdef DEBUG 02123 CAMsg::printMsg(LOG_DEBUG,"User login: registering payment control channel\n"); 02124 #endif 02125 pHashEntry->pControlChannelDispatcher->registerControlChannel(new CAAccountingControlChannel(pHashEntry)); 02126 SAVE_STACK("CAFirstMix::doUserLogin", "payment registered"); 02127 #endif 02128 pHashEntry->pSymCipher=new CASymCipher(); 02129 pHashEntry->pSymCipher->setKey(mixKey); 02130 pHashEntry->pSymCipher->setIVs(mixKey+16); 02131 pNewUser->setReceiveKey(linkKey,32); 02132 pNewUser->setSendKey(linkKey+32,32); 02133 pNewUser->setCrypt(true); 02134 02135 if (doc != NULL) 02136 { 02137 doc->release(); 02138 doc = NULL; 02139 } 02140 #ifdef PAYMENT 02141 02142 SAVE_STACK("CAFirstMix::doUserLogin", "Starting AI login procedure"); 02143 #ifdef DEBUG 02144 CAMsg::printMsg(LOG_DEBUG,"Starting AI login procedure for owner %x \n", pHashEntry); 02145 #endif 02146 SINT32 ai_ret; 02147 MIXPACKET *paymentLoginPacket = new MIXPACKET; 02148 tQueueEntry *aiAnswerQueueEntry=new tQueueEntry; 02149 CAQueue *controlMessages = pHashEntry->pControlMessageQueue; 02150 UINT32 qlen=sizeof(tQueueEntry); 02151 SINT32 aiLoginStatus = 0; 02152 aiLoginStatus = CAAccountingInstance::loginProcessStatus(pHashEntry); 02153 while(aiLoginStatus & AUTH_LOGIN_NOT_FINISHED) 02154 { 02155 if(pNewUser->receive(paymentLoginPacket, AI_LOGIN_SO_TIMEOUT) != MIXPACKET_SIZE) 02156 { 02157 CAMsg::printMsg(LOG_INFO,"AI login: client receive timeout.\n"); 02158 aiLoginStatus = AUTH_LOGIN_FAILED; 02159 break; 02160 } 02161 if(paymentLoginPacket->channel > 0 && paymentLoginPacket->channel < 256) 02162 { 02163 if(!pHashEntry->pControlChannelDispatcher->proccessMixPacket(paymentLoginPacket)) 02164 { 02165 aiLoginStatus = AUTH_LOGIN_FAILED; 02166 break; 02167 } 02168 02169 while(controlMessages->getSize()>0) 02170 { 02171 controlMessages->get((UINT8*)aiAnswerQueueEntry,&qlen); 02172 pNewUser->prepareForSend(&(aiAnswerQueueEntry->packet)); 02173 ai_ret = pNewUser->getCASocket()-> 02174 sendFullyTimeOut(((UINT8*)&(aiAnswerQueueEntry->packet)), MIXPACKET_SIZE, 3*(AI_LOGIN_SO_TIMEOUT), AI_LOGIN_SO_TIMEOUT); 02175 if (ai_ret != E_SUCCESS) 02176 { 02177 if(ai_ret == E_TIMEDOUT ) 02178 { 02179 CAMsg::printMsg(LOG_INFO,"timeout occurred during AI login."); 02180 } 02181 aiLoginStatus = AUTH_LOGIN_FAILED; 02182 goto loop_break; 02183 } 02184 } 02185 if(aiLoginStatus == AUTH_LOGIN_FAILED) 02186 { 02187 break; 02188 } 02189 } 02190 aiLoginStatus = CAAccountingInstance::loginProcessStatus(pHashEntry); 02191 } 02192 loop_break: 02193 SAVE_STACK("CAFirstMix::doUserLogin", "AI login packages exchanged."); 02194 /* We have exchanged all AI login packets: 02195 * 1. AccountCert 02196 * 2. ChallengeResponse 02197 * 3. Cost confirmation. 02198 * Now start settlement to ensure that the clients account is balanced 02199 */ 02200 if(!(aiLoginStatus & AUTH_LOGIN_FAILED)) 02201 { 02202 if(!(aiLoginStatus & (AUTH_LOGIN_SKIP_SETTLEMENT )) || (aiLoginStatus & (AUTH_WAITING_FOR_FIRST_SETTLED_CC)) ) 02203 { 02204 //#ifdef DEBUG 02205 CAMsg::printMsg(LOG_DEBUG,"AI login messages successfully exchanged: now starting settlement for user account balancing check\n"); 02206 //#endif 02207 if(CAAccountingInstance::newSettlementTransaction() != E_SUCCESS) 02208 { 02209 aiLoginStatus |= AUTH_LOGIN_FAILED; 02210 } 02211 } 02212 //#ifdef DEBUG 02213 else 02214 { 02215 CAMsg::printMsg(LOG_DEBUG,"AI login messages successfully exchanged: skipping settlement, user has valid prepaid amount\n"); 02216 } 02217 //#endif 02218 } 02219 02220 if(!(aiLoginStatus & AUTH_LOGIN_FAILED)) 02221 { 02222 aiLoginStatus = CAAccountingInstance::finishLoginProcess(pHashEntry); 02223 if(pNewUser != NULL) 02224 { 02225 while(controlMessages->getSize()>0) 02226 { 02227 controlMessages->get((UINT8*)aiAnswerQueueEntry,&qlen); 02228 pNewUser->prepareForSend(&(aiAnswerQueueEntry->packet)); 02229 02230 //not really elegant but works: if the client closed the socket during the settlement 02231 //the first send will succeed but the second one will fail. 02232 ai_ret = pNewUser->getCASocket()-> 02233 sendFullyTimeOut(((UINT8*)&(aiAnswerQueueEntry->packet)), 499, 3*(AI_LOGIN_SO_TIMEOUT), AI_LOGIN_SO_TIMEOUT); 02234 02235 ai_ret = pNewUser->getCASocket()-> 02236 sendFullyTimeOut(((UINT8*)&(aiAnswerQueueEntry->packet)+499), 499, 3*(AI_LOGIN_SO_TIMEOUT), AI_LOGIN_SO_TIMEOUT); 02237 if (ai_ret != E_SUCCESS) 02238 { 02239 int errnum = errno; 02240 CAMsg::printMsg(LOG_INFO,"AI login: net error occured after settling: %s\n", strerror(errnum)); 02241 aiLoginStatus |= AUTH_LOGIN_FAILED; 02242 break; 02243 } 02244 } 02245 } 02246 else 02247 { 02248 CAMsg::printMsg(LOG_DEBUG,"Socket was disposed.\n"); 02249 aiLoginStatus |= AUTH_LOGIN_FAILED; 02250 } 02251 } 02252 02253 delete paymentLoginPacket; 02254 paymentLoginPacket = NULL; 02255 delete aiAnswerQueueEntry; 02256 aiAnswerQueueEntry = NULL; 02257 02258 SAVE_STACK("CAFirstMix::doUserLogin", "AI login procedure finished."); 02259 02260 if((aiLoginStatus & AUTH_LOGIN_FAILED)) 02261 { 02262 #ifdef DEBUG 02263 CAMsg::printMsg(LOG_INFO,"User AI login failed: deleting socket %x\n", pHashEntry); 02264 #endif 02265 CAAccountingInstance::unlockLogin(pHashEntry); 02266 m_pChannelList->remove(pNewUser); 02267 delete pNewUser; 02268 pNewUser = NULL; 02269 m_pIPList->removeIP(peerIP); 02270 return E_UNKNOWN; 02271 } 02272 /* Hot fix: push timeout entry only if login was succesful, otherwise 02273 * socket may be deleted due to timeout, login fails and the socket will be deleted 02274 * for second time causing a segfault. 02275 */ 02276 m_pChannelList->pushTimeoutEntry(pHashEntry); 02277 02278 02279 #ifdef LOG_CRIME 02280 UINT64 accountNumber = CAAccountingInstance::unlockLogin(pHashEntry); 02281 UINT64* surveillanceAccounts = CALibProxytest::getOptions()->getCrimeSurveillanceAccounts(); 02282 UINT32 nrOfSurveillanceAccounts = CALibProxytest::getOptions()->getNrOfCrimeSurveillanceAccounts(); 02283 02284 for (UINT32 iAccount = 0; iAccount < nrOfSurveillanceAccounts; iAccount++) 02285 { 02286 if (accountNumber == surveillanceAccounts[iAccount]) 02287 { 02288 CAMsg::printMsg(LOG_CRIT,"Crime detection: User logged in with account %llu has IP %u.%u.%u.%u\n",accountNumber, peerIP[0], peerIP[1], peerIP[2], peerIP[3]); 02289 break; 02290 } 02291 } 02292 #else 02293 CAAccountingInstance::unlockLogin(pHashEntry); 02294 #endif 02295 02296 #ifdef DEBUG 02297 CAMsg::printMsg(LOG_INFO,"User AI login successful for owner %x\n", pHashEntry); 02298 #endif 02299 #endif 02300 02301 #ifdef WITH_CONTROL_CHANNELS_TEST 02302 pHashEntry->pControlChannelDispatcher->registerControlChannel(new CAControlChannelTest()); 02303 #endif 02304 #ifdef REPLAY_DETECTION 02305 pHashEntry->pControlChannelDispatcher->registerControlChannel(new CAReplayControlChannel(m_pReplayMsgProc)); 02306 #endif 02307 #ifdef COUNTRY_STATS 02308 incUsers(pHashEntry); 02309 #else 02310 incUsers(); 02311 #endif 02312 #ifdef HAVE_EPOLL 02313 m_psocketgroupUsersRead->add(*pNewUser,m_pChannelList->get(pNewUser)); // add user socket to the established ones that we read data from. 02314 m_psocketgroupUsersWrite->add(*pNewUser,m_pChannelList->get(pNewUser)); 02315 #else 02316 if(m_psocketgroupUsersRead->add(*pNewUser)!=E_SUCCESS)// add user socket to the established ones that we read data from. 02317 { 02318 CAMsg::printMsg(LOG_DEBUG,"User login: Adding to m_psocketgroupUsersRead failed!\n"); 02319 } 02320 if( m_psocketgroupUsersWrite->add(*pNewUser)!=E_SUCCESS) 02321 { 02322 CAMsg::printMsg(LOG_DEBUG,"User login: Adding to m_psocketgroupUsersWrite failed!\n"); 02323 } 02324 #endif 02325 02326 #ifndef LOG_DIALOG 02327 CAMsg::printMsg(LOG_INFO,"User login: finished\n"); 02328 #else 02329 CAMsg::printMsg(LOG_INFO,"User login: finished -- connection-ID: %Lu -- country-id: %u -- dialog: %s\n",pHashEntry->id,pHashEntry->countryID,pHashEntry->strDialog); 02330 #endif 02331 return E_SUCCESS; 02332 } 02333 02334 #ifdef PAYMENT 02335 bool CAFirstMix::forceKickout(fmHashTableEntry* pHashTableEntry, const XERCES_CPP_NAMESPACE::DOMDocument *pErrDoc) 02336 { 02337 return m_pChannelList->forceKickout(pHashTableEntry, pErrDoc); 02338 } 02339 #endif 02340 //NEVER EVER DELETE THIS! 02341 /* 02342 THREAD_RETURN loopReadFromUsers(void* param) 02343 { 02344 CAFirstMix* pFirstMix=(CAFirstMix*)param; 02345 CAFirstMixChannelList* pChannelList=pFirstMix->m_pChannelList; 02346 CASocketGroup* psocketgroupUsersRead=pFirstMix->m_psocketgroupUsersRead; 02347 CASocketGroup* psocketgroupUsersWrite=pFirstMix->m_psocketgroupUsersWrite; 02348 CAQueue* pQueueSendToMix=pFirstMix->m_pQueueSendToMix; 02349 // CAInfoService* pInfoService=pFirstMix->m_pInfoService; 02350 CAASymCipher* pRSA=pFirstMix->m_pRSA; 02351 CAIPList* pIPList=pFirstMix->m_pIPList; 02352 CAMuxSocket* pNextMix=pFirstMix->m_pMuxOut; 02353 02354 CAMuxSocket* pMuxSocket; 02355 02356 SINT32 countRead; 02357 SINT32 ret; 02358 UINT8* ip=new UINT8[4]; 02359 UINT8* tmpBuff=new UINT8[MIXPACKET_SIZE]; 02360 MIXPACKET* pMixPacket=new MIXPACKET; 02361 UINT8* rsaBuff=new UINT8[RSA_SIZE]; 02362 02363 fmHashTableEntry* pHashEntry; 02364 fmChannelListEntry* pEntry; 02365 CASymCipher* pCipher=NULL; 02366 02367 for(;;) 02368 { 02369 countRead=psocketgroupUsersRead->select(false,1000); //if we sleep here forever, we will not notice new sockets... 02370 if(countRead<0) 02371 { //check for error 02372 if(pFirstMix->m_bRestart ||countRead!=E_TIMEDOUT) 02373 goto END_THREAD; 02374 } 02375 pHashEntry=pChannelList->getFirst(); 02376 while(pHashEntry!=NULL&&countRead>0) 02377 { 02378 pMuxSocket=pHashEntry->pMuxSocket; 02379 if(psocketgroupUsersRead->isSignaled(*pMuxSocket)) 02380 { 02381 countRead--; 02382 ret=pMuxSocket->receive(pMixPacket,0); 02383 if(ret==SOCKET_ERROR) 02384 { 02385 pMuxSocket->getPeerIP(ip); 02386 pIPList->removeIP(ip); 02387 psocketgroupUsersRead->remove(pMuxSocket); 02388 psocketgroupUsersWrite->remove(pMuxSocket); 02389 pEntry=pChannelList->getFirstChannelForSocket(pMuxSocket); 02390 while(pEntry!=NULL) 02391 { 02392 pNextMix->close(pEntry->channelOut,tmpBuff); 02393 pQueueSendToMix->add(tmpBuff,MIXPACKET_SIZE); 02394 delete pEntry->pCipher; 02395 pEntry=pChannelList->getNextChannel(pEntry); 02396 } 02397 ASSERT(pHashEntry->pQueueSend!=NULL,"Send queue is NULL"); 02398 delete pHashEntry->pQueueSend; 02399 pChannelList->remove(pMuxSocket); 02400 pMuxSocket->close(); 02401 delete pMuxSocket; 02402 pFirstMix->decUsers(); 02403 } 02404 else if(ret==MIXPACKET_SIZE) 02405 { 02406 if(pMixPacket->flags==CHANNEL_CLOSE) 02407 { 02408 pEntry=pChannelList->get(pMuxSocket,pMixPacket->channel); 02409 if(pEntry!=NULL) 02410 { 02411 pNextMix->close(pEntry->channelOut,tmpBuff); 02412 pQueueSendToMix->add(tmpBuff,MIXPACKET_SIZE); 02413 delete pEntry->pCipher; 02414 pChannelList->removeChannel(pMuxSocket,pMixPacket->channel); 02415 } 02416 else 02417 { 02418 #if defined(_DEBUG) && ! defined(__MIX_TEST) 02419 CAMsg::printMsg(LOG_DEBUG,"Invalid ID to close from Browser!\n"); 02420 #endif 02421 } 02422 } 02423 else 02424 { 02425 pEntry=pChannelList->get(pMuxSocket,pMixPacket->channel); 02426 if(pEntry!=NULL&&pMixPacket->flags==CHANNEL_DATA) 02427 { 02428 pMixPacket->channel=pEntry->channelOut; 02429 pCipher=pEntry->pCipher; 02430 pCipher->decryptAES(pMixPacket->data,pMixPacket->data,DATA_SIZE); 02431 pNextMix->send(pMixPacket,tmpBuff); 02432 pQueueSendToMix->add(tmpBuff,MIXPACKET_SIZE); 02433 pFirstMix->incMixedPackets(); 02434 } 02435 else if(pEntry==NULL&&(pMixPacket->flags==CHANNEL_OPEN_OLD||pMixPacket->flags==CHANNEL_OPEN_NEW)) 02436 { 02437 pCipher= new CASymCipher(); 02438 pRSA->decrypt(pMixPacket->data,rsaBuff); 02439 pCipher->setKeyAES(rsaBuff); 02440 pCipher->decryptAES(pMixPacket->data+RSA_SIZE, 02441 pMixPacket->data+RSA_SIZE-KEY_SIZE, 02442 DATA_SIZE-RSA_SIZE); 02443 memcpy(pMixPacket->data,rsaBuff+KEY_SIZE,RSA_SIZE-KEY_SIZE); 02444 02445 if(pChannelList->addChannel(pMuxSocket,pMixPacket->channel,pCipher,&pMixPacket->channel)!=E_SUCCESS) 02446 {//todo --> maybe move up to not make decryption!! 02447 delete pCipher; 02448 } 02449 else 02450 { 02451 #if defined(_DEBUG) && !defined(__MIX_TEST) 02452 CAMsg::printMsg(LOG_DEBUG,"Added out channel: %u\n",pMixPacket->channel); 02453 #endif 02454 pNextMix->send(pMixPacket,tmpBuff); 02455 pQueueSendToMix->add(tmpBuff,MIXPACKET_SIZE); 02456 pFirstMix->incMixedPackets(); 02457 } 02458 } 02459 } 02460 } 02461 } 02462 pHashEntry=pChannelList->getNext(); 02463 } 02464 } 02465 END_THREAD: 02466 delete ip; 02467 delete tmpBuff; 02468 delete pMixPacket; 02469 delete rsaBuff; 02470 CAMsg::printMsg(LOG_DEBUG,"Exiting Thread ReadFromUser\n"); 02471 THREAD_RETURN_SUCCESS; 02472 } 02473 */ 02474 02475 SINT32 CAFirstMix::clean() 02476 { 02477 //#ifdef _DEBUG 02478 CAMsg::printMsg(LOG_DEBUG,"CAFirstMix::clean() start\n"); 02479 //#endif 02480 m_bRunLog=false; 02481 m_bRestart=true; 02482 if(m_pMuxOut!=NULL) 02483 { 02484 m_pMuxOut->close(); 02485 } 02486 02487 //writing some bytes to the queue... 02488 if(m_pQueueSendToMix!=NULL) 02489 { 02490 UINT8 b[sizeof(tQueueEntry)+1]; 02491 m_pQueueSendToMix->add(b,sizeof(tQueueEntry)+1); 02492 } 02493 02494 if(m_pthreadAcceptUsers!=NULL) 02495 { 02496 CAMsg::printMsg(LOG_CRIT,"Wait for LoopAcceptUsers!\n"); 02497 m_pthreadAcceptUsers->join(); 02498 delete m_pthreadAcceptUsers; 02499 } 02500 m_pthreadAcceptUsers=NULL; 02501 if(m_pthreadsLogin!=NULL) 02502 delete m_pthreadsLogin; 02503 m_pthreadsLogin=NULL; 02504 // if(m_pInfoService!=NULL) 02505 // { 02506 // CAMsg::printMsg(LOG_CRIT,"Stopping InfoService....\n"); 02507 // CAMsg::printMsg (LOG_CRIT,"Memory usage before: %u\n",getMemoryUsage()); 02508 // m_pInfoService->stop(); 02509 // CAMsg::printMsg (LOG_CRIT,"Memory usage after: %u\n",getMemoryUsage()); 02510 // CAMsg::printMsg(LOG_CRIT,"Stopped InfoService!\n"); 02511 // delete m_pInfoService; 02512 // } 02513 // m_pInfoService=NULL; 02514 02515 if(m_pthreadSendToMix!=NULL) 02516 { 02517 CAMsg::printMsg(LOG_CRIT,"Wait for LoopSendToMix!\n"); 02518 m_pthreadSendToMix->join(); 02519 delete m_pthreadSendToMix; 02520 } 02521 m_pthreadSendToMix=NULL; 02522 if(m_pthreadReadFromMix!=NULL) 02523 { 02524 CAMsg::printMsg(LOG_CRIT,"Wait for LoopReadFromMix!\n"); 02525 m_pthreadReadFromMix->join(); 02526 delete m_pthreadReadFromMix; 02527 } 02528 m_pthreadReadFromMix=NULL; 02529 02530 #ifdef CH_LOG_STUDY 02531 if(nrOfChThread != NULL) 02532 { 02533 nrOfChThread->join(); 02534 delete nrOfChThread; 02535 nrOfChThread = NULL; 02536 } 02537 #endif 02538 02539 #ifdef LOG_PACKET_TIMES 02540 if(m_pLogPacketStats!=NULL) 02541 { 02542 CAMsg::printMsg(LOG_CRIT,"Wait for LoopLogPacketStats to terminate!\n"); 02543 m_pLogPacketStats->stop(); 02544 delete m_pLogPacketStats; 02545 } 02546 m_pLogPacketStats=NULL; 02547 #endif 02548 if(m_arrSocketsIn!=NULL) 02549 { 02550 for(UINT32 i=0;i<m_nSocketsIn;i++) 02551 { 02552 if (m_arrSocketsIn[i] != NULL) 02553 { 02554 m_arrSocketsIn[i]->close(); 02555 delete m_arrSocketsIn[i]; 02556 m_arrSocketsIn[i] = NULL; 02557 } 02558 } 02559 delete[] m_arrSocketsIn; 02560 } 02561 m_arrSocketsIn=NULL; 02562 #ifdef REPLAY_DETECTION 02563 if(m_pReplayMsgProc!=NULL) 02564 { 02565 delete m_pReplayMsgProc; 02566 } 02567 m_pReplayMsgProc=NULL; 02568 #endif 02569 02570 if(m_pMuxOutControlChannelDispatcher!=NULL) 02571 { 02572 delete m_pMuxOutControlChannelDispatcher; 02573 } 02574 m_pMuxOutControlChannelDispatcher=NULL; 02575 02576 if(m_pMuxOut!=NULL) 02577 { 02578 m_pMuxOut->close(); 02579 delete m_pMuxOut; 02580 } 02581 m_pMuxOut=NULL; 02582 #ifdef COUNTRY_STATS 02583 deleteCountryStats(); 02584 #endif 02585 if(m_pIPList!=NULL) 02586 delete m_pIPList; 02587 m_pIPList=NULL; 02588 if(m_pQueueSendToMix!=NULL) 02589 delete m_pQueueSendToMix; 02590 m_pQueueSendToMix=NULL; 02591 if(m_pQueueReadFromMix!=NULL) 02592 delete m_pQueueReadFromMix; 02593 m_pQueueReadFromMix=NULL; 02594 02595 if(m_pChannelList!=NULL) 02596 { 02597 CAMsg::printMsg(LOG_CRIT,"Before deleting CAFirstMixChannelList()!\n"); 02598 CAMsg::printMsg (LOG_CRIT,"Memory usage before: %u\n",getMemoryUsage()); 02599 fmHashTableEntry* pHashEntry=m_pChannelList->getFirst(); 02600 while(pHashEntry!=NULL) 02601 { 02602 CAMuxSocket * pMuxSocket=pHashEntry->pMuxSocket; 02603 delete pHashEntry->pQueueSend; 02604 pHashEntry->pQueueSend = NULL; 02605 delete pHashEntry->pSymCipher; 02606 pHashEntry->pSymCipher = NULL; 02607 02608 fmChannelListEntry* pEntry=m_pChannelList->getFirstChannelForSocket(pHashEntry->pMuxSocket); 02609 while(pEntry!=NULL) 02610 { 02611 delete pEntry->pCipher; 02612 pEntry->pCipher = NULL; 02613 pEntry=m_pChannelList->getNextChannel(pEntry); 02614 } 02615 m_pChannelList->remove(pHashEntry->pMuxSocket); 02616 pMuxSocket->close(); 02617 delete pMuxSocket; 02618 pMuxSocket = NULL; 02619 pHashEntry=m_pChannelList->getNext(); 02620 } 02621 } 02622 02623 if(m_pChannelList!=NULL) 02624 delete m_pChannelList; 02625 m_pChannelList=NULL; 02626 CAMsg::printMsg (LOG_CRIT,"Memory usage after: %u\n",getMemoryUsage()); 02627 #ifdef PAYMENT 02628 CAAccountingInstance::clean(); 02629 CAAccountingDBInterface::cleanup(); 02630 #endif 02631 if(m_psocketgroupUsersRead!=NULL) 02632 delete m_psocketgroupUsersRead; 02633 m_psocketgroupUsersRead=NULL; 02634 if(m_psocketgroupUsersWrite!=NULL) 02635 delete m_psocketgroupUsersWrite; 02636 m_psocketgroupUsersWrite=NULL; 02637 if(m_pRSA!=NULL) 02638 delete m_pRSA; 02639 m_pRSA=NULL; 02640 if(m_xmlKeyInfoBuff!=NULL) 02641 delete[] m_xmlKeyInfoBuff; 02642 m_xmlKeyInfoBuff=NULL; 02643 m_docMixCascadeInfo=NULL; 02644 if(m_arMixParameters!=NULL) 02645 { 02646 for(UINT32 i=0;i<m_u32MixCount-1;i++) 02647 { 02648 delete[] m_arMixParameters[i].m_strMixID; 02649 } 02650 delete[] m_arMixParameters; 02651 } 02652 m_arMixParameters=NULL; 02653 m_u32MixCount=0; 02654 m_nMixedPackets=0; //reset to zero after each restart (at the moment neccessary for infoservice) 02655 m_nUser=0; 02656 02657 02658 delete m_pIPBlockList; 02659 m_pIPBlockList = NULL; 02660 02661 CAMsg::printMsg (LOG_CRIT,"before tc cleanup\n"); 02662 for (UINT32 i = 0; i < m_nrOfTermsAndConditionsDefs; i++) 02663 { 02664 delete m_tnCDefs[i]; 02665 m_tnCDefs[i] = NULL; 02666 } 02667 delete [] m_tnCDefs; 02668 m_tnCDefs = NULL; 02669 m_nrOfTermsAndConditionsDefs = 0; 02670 CAMsg::printMsg (LOG_CRIT,"before template cleanup\n"); 02671 for(UINT32 i = 0; i < m_nrOfTermsAndConditionsTemplates; i++) 02672 { 02673 m_tcTemplates[i]->release(); 02674 m_tcTemplates[i] = NULL; 02675 } 02676 delete [] m_tcTemplates; 02677 m_tcTemplates = NULL; 02678 CAMsg::printMsg (LOG_CRIT,"before template owner release\n"); 02679 if(m_templatesOwner != NULL) 02680 { 02681 m_templatesOwner->release(); 02682 m_templatesOwner = NULL; 02683 } 02684 CAMsg::printMsg (LOG_CRIT,"after template owner release\n"); 02685 m_nrOfTermsAndConditionsTemplates = 0; 02686 //#ifdef _DEBUG 02687 CAMsg::printMsg(LOG_DEBUG,"CAFirstMix::clean() finished\n"); 02688 //#endif 02689 02690 return E_SUCCESS; 02691 } 02692 02693 #ifdef DELAY_USERS 02694 SINT32 CAFirstMix::reconfigure() 02695 { 02696 CAMsg::printMsg(LOG_DEBUG,"Reconfiguring First Mix\n"); 02697 #ifdef DELAY_USERS 02698 CAMsg::printMsg(LOG_DEBUG,"Set new ressources limitation parameters\n"); 02699 if(m_pChannelList!=NULL) 02700 m_pChannelList->setDelayParameters( CALibProxytest::getOptions()->getDelayChannelUnlimitTraffic(), 02701 CALibProxytest::getOptions()->getDelayChannelBucketGrow(), 02702 CALibProxytest::getOptions()->getDelayChannelBucketGrowIntervall()); 02703 #endif 02704 return E_SUCCESS; 02705 } 02706 #endif 02707 02709 SINT32 CAFirstMix::initMixParameters(DOMElement* elemMixes) 02710 { 02711 DOMNodeList* nl=getElementsByTagName(elemMixes,"Mix"); 02712 m_u32MixCount=nl->getLength(); 02713 m_arMixParameters=new tMixParameters[m_u32MixCount]; 02714 memset(m_arMixParameters,0,sizeof(tMixParameters)*m_u32MixCount); 02715 UINT8 buff[255]; 02716 CALibProxytest::getOptions()->getMixId(buff,255); 02717 UINT32 len=strlen((char*)buff)+1; 02718 UINT32 aktMix=0; 02719 for(UINT32 i=0;i<nl->getLength();i++) 02720 { 02721 DOMNode* child=nl->item(i); 02722 len=255; 02723 getDOMElementAttribute(child,"id",buff,&len); 02724 m_arMixParameters[aktMix].m_strMixID=new UINT8[len+1]; 02725 memcpy(m_arMixParameters[aktMix].m_strMixID,buff,len); 02726 m_arMixParameters[aktMix].m_strMixID[len]=0; 02727 aktMix++; 02728 } 02729 m_u32MixCount++; 02730 return E_SUCCESS; 02731 } 02732 02733 UINT32 CAFirstMix::getNrOfUsers() 02734 { 02735 #ifdef PAYMENT 02736 return CAAccountingInstance::getNrOfUsers(); 02737 #else 02738 return m_nUser; 02739 #endif 02740 } 02741 02742 SINT32 CAFirstMix::getMixedPackets(UINT64& ppackets) 02743 { 02744 set64(ppackets,m_nMixedPackets); 02745 return E_SUCCESS; 02746 } 02747 02748 SINT32 CAFirstMix::getLevel(SINT32* puser,SINT32* prisk,SINT32* ptraffic) 02749 { 02750 *puser=(SINT32)getNrOfUsers(); 02751 *prisk=-1; 02752 *ptraffic=-1; 02753 return E_SUCCESS; 02754 } 02755 02756 #ifdef REPLAY_DETECTION 02757 SINT32 CAFirstMix::sendReplayTimestampRequestsToAllMixes() 02758 { 02759 for(UINT32 i=0;i<m_u32MixCount-1;i++) 02760 { 02761 m_pReplayMsgProc->sendGetTimestamp(m_arMixParameters[i].m_strMixID); 02762 } 02763 return E_SUCCESS; 02764 } 02765 #endif //REPLAY_DETECTION 02766 02767 #ifdef COUNTRY_STATS 02768 #define COUNTRY_STATS_DB "CountryStats" 02769 #define NR_OF_COUNTRIES 254 02770 02773 void mysqlEscapeTableName(UINT8* str) 02774 { 02775 UINT32 i=0; 02776 while(str[i]!=0) 02777 { 02778 if(str[i]=='.'||str[i]==':'||str[i]=='/'||str[i]=='\\') 02779 str[i]='_'; 02780 i++; 02781 } 02782 } 02783 02784 SINT32 CAFirstMix::initCountryStats(char* db_host,char* db_user,char* db_passwd) 02785 { 02786 m_CountryStats=NULL; 02787 m_mysqlCon=mysql_init(NULL); 02788 #ifdef HAVE_MYSQL_OPT_RECONNECT 02789 my_bool thetrue=1; 02790 mysql_options(m_mysqlCon,MYSQL_OPT_RECONNECT,&thetrue); 02791 #endif 02792 MYSQL* tmp=NULL; 02793 tmp=mysql_real_connect(m_mysqlCon,db_host,db_user,db_passwd,COUNTRY_STATS_DB,0,NULL,0); 02794 if(tmp==NULL) 02795 { 02796 CAMsg::printMsg(LOG_DEBUG,"Could not connect to CountryStats DB!\n"); 02797 mysql_thread_end(); 02798 mysql_close(m_mysqlCon); 02799 m_mysqlCon=NULL; 02800 return E_UNKNOWN; 02801 } 02802 CAMsg::printMsg(LOG_DEBUG,"Connected to CountryStats DB!\n"); 02803 char query[1024]; 02804 UINT8 buff[255]; 02805 CALibProxytest::getOptions()->getCascadeName(buff,255); 02806 mysqlEscapeTableName(buff); 02807 sprintf(query,"CREATE TABLE IF NOT EXISTS `stats_%s` (date timestamp,id int,count int,packets_in int,packets_out int)",buff); 02808 SINT32 ret=mysql_query(m_mysqlCon,query); 02809 if(ret!=0) 02810 { 02811 CAMsg::printMsg(LOG_INFO,"CountryStats DB - create table for %s failed!\n",buff); 02812 } 02813 m_CountryStats=new UINT32[NR_OF_COUNTRIES+1]; 02814 memset((void*)m_CountryStats,0,sizeof(UINT32)*(NR_OF_COUNTRIES+1)); 02815 m_PacketsPerCountryIN=new tUINT32withLock[NR_OF_COUNTRIES+1]; 02816 //memset((void*)m_PacketsPerCountryIN,0,sizeof(UINT32)*(NR_OF_COUNTRIES+1)); 02817 m_PacketsPerCountryOUT=new tUINT32withLock[NR_OF_COUNTRIES+1]; 02818 //memset((void*)m_PacketsPerCountryOUT,0,sizeof(UINT32)*(NR_OF_COUNTRIES+1)); 02819 m_threadLogLoop=new CAThread((UINT8*)"Country Logger Thread"); 02820 m_threadLogLoop->setMainLoop(iplist_loopDoLogCountries); 02821 m_bRunLogCountries=true; 02822 m_threadLogLoop->start(this,true); 02823 return E_SUCCESS; 02824 } 02825 02826 SINT32 CAFirstMix::deleteCountryStats() 02827 { 02828 m_bRunLogCountries=false; 02829 if(m_threadLogLoop!=NULL) 02830 { 02831 m_threadLogLoop->join(); 02832 delete m_threadLogLoop; 02833 m_threadLogLoop=NULL; 02834 } 02835 if(m_mysqlCon!=NULL) 02836 { 02837 mysql_thread_end(); 02838 mysql_close(m_mysqlCon); 02839 m_mysqlCon=NULL; 02840 } 02841 02842 delete[] m_CountryStats; 02843 m_CountryStats=NULL; 02844 02845 delete[] m_PacketsPerCountryIN; 02846 m_PacketsPerCountryIN=NULL; 02847 02848 delete[] m_PacketsPerCountryOUT; 02849 m_PacketsPerCountryOUT=NULL; 02850 return E_SUCCESS; 02851 } 02852 02861 SINT32 CAFirstMix::updateCountryStats(const UINT8 ip[4],UINT32 a_countryID,bool bRemove) 02862 { 02863 if(!bRemove) 02864 { 02865 UINT32 countryID=a_countryID; 02866 if(ip!=NULL) 02867 { 02868 UINT32 u32ip=ip[0]<<24|ip[1]<<16|ip[2]<<8|ip[3]; 02869 char query[1024]; 02870 sprintf(query,"SELECT id FROM ip2c WHERE ip_lo<=\"%u\" and ip_hi>=\"%u\" LIMIT 1",u32ip,u32ip); 02871 int ret=mysql_query(m_mysqlCon,query); 02872 if(ret!=0) 02873 { 02874 CAMsg::printMsg(LOG_INFO,"CountryStatsDB - updateCountryStats - error (%i) in finding countryid for ip %u\n",ret,u32ip); 02875 goto RET; 02876 } 02877 MYSQL_RES* result=mysql_store_result(m_mysqlCon); 02878 if(result==NULL) 02879 { 02880 CAMsg::printMsg(LOG_INFO,"CountryStatsDB - updateCountryStats - error in retriving results of the query\n"); 02881 goto RET; 02882 } 02883 MYSQL_ROW row=mysql_fetch_row(result); 02884 SINT32 t; 02885 if(row!=NULL&&(t=atoi(row[0]))>0&&t<=NR_OF_COUNTRIES) 02886 { 02887 countryID=t; 02888 #ifdef DEBUG 02889 CAMsg::printMsg(LOG_DEBUG,"Country ID for ip %u is %u\n",u32ip,countryID); 02890 #endif 02891 //temp hack 02892 if(countryID==99) 02893 { 02894 CAMsg::printMsg(LOG_DEBUG,"Country ID for ip %u.%u.%u.%u is %u\n",ip[0],ip[1],ip[2],ip[3],countryID); 02895 } 02896 } 02897 else 02898 { 02899 CAMsg::printMsg(LOG_DEBUG,"DO country stats query result no result for ip %u)\n",u32ip); 02900 } 02901 mysql_free_result(result); 02902 } 02903 RET: 02904 m_CountryStats[countryID]++; 02905 return countryID; 02906 } 02907 else//bRemove 02908 { 02909 m_CountryStats[a_countryID]--; 02910 } 02911 return a_countryID; 02912 } 02913 02914 THREAD_RETURN iplist_loopDoLogCountries(void* param) 02915 { 02916 mysql_thread_init(); 02917 CAMsg::printMsg(LOG_DEBUG,"Starting iplist_loopDoLogCountries\n"); 02918 CAFirstMix* pFirstMix=(CAFirstMix*)param; 02919 UINT32 s=0; 02920 UINT8 buff[255]; 02921 memset(buff,0,255); 02922 CALibProxytest::getOptions()->getCascadeName(buff,255); 02923 mysqlEscapeTableName(buff); 02924 while(pFirstMix->m_bRunLogCountries) 02925 { 02926 if(s==LOG_COUNTRIES_INTERVALL) 02927 { 02928 UINT8 aktDate[255]; 02929 time_t aktTime=time(NULL); 02930 strftime((char*)aktDate,255,"%Y%m%d%H%M%S",gmtime(&aktTime)); 02931 char query[1024]; 02932 sprintf(query,"INSERT into `stats_%s` (date,id,count,packets_in,packets_out) VALUES (\"%s\",\"%%u\",\"%%u\",\"%%u\",\"%%u\")",buff,aktDate); 02933 pFirstMix->m_pmutexUser->lock(); 02934 for(UINT32 i=0;i<NR_OF_COUNTRIES+1;i++) 02935 { 02936 if(pFirstMix->m_CountryStats[i]>0) 02937 { 02938 char aktQuery[1024]; 02939 sprintf(aktQuery,query,i,pFirstMix->m_CountryStats[i],pFirstMix->m_PacketsPerCountryIN[i].getAndzero(),pFirstMix->m_PacketsPerCountryOUT[i].getAndzero()); 02940 SINT32 ret=mysql_query(pFirstMix->m_mysqlCon,aktQuery); 02941 if(ret!=0) 02942 { 02943 CAMsg::printMsg(LOG_INFO,"CountryStats DB - failed to update CountryStats DB with new values - error %i\n",ret); 02944 } 02945 } 02946 } 02947 pFirstMix->m_pmutexUser->unlock(); 02948 s=0; 02949 } 02950 sSleep(10); 02951 s++; 02952 } 02953 CAMsg::printMsg(LOG_DEBUG,"Exiting iplist_loopDoLogCountries\n"); 02954 mysql_thread_end(); 02955 THREAD_RETURN_SUCCESS; 02956 } 02957 #endif 02958 #endif //ONLY_LOCAL_PROXY
1.7.6.1