Mixe for Privacy and Anonymity in the Internet
CAFirstMix.cpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2000, The JAP-Team
3 All rights reserved.
4 Redistribution and use in source and binary forms, with or without modification,
5 are permitted provided that the following conditions are met:
6 
7  - Redistributions of source code must retain the above copyright notice,
8  this list of conditions and the following disclaimer.
9 
10  - Redistributions in binary form must reproduce the above copyright notice,
11  this list of conditions and the following disclaimer in the documentation and/or
12  other materials provided with the distribution.
13 
14  - Neither the name of the University of Technology Dresden, Germany nor the names of its contributors
15  may be used to endorse or promote products derived from this software without specific
16  prior written permission.
17 
18 
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
20 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
21 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS
22 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
27 */
28 #include "StdAfx.h"
29 #if !defined ONLY_LOCAL_PROXY || defined INCLUDE_FIRST_MIX
30 #include "CAFirstMix.hpp"
31 #include "CASocketGroup.hpp"
32 #include "CASingleSocketGroup.hpp"
33 #include "CAMsg.hpp"
34 #include "CACmdLnOptions.hpp"
36 #include "CAListenerInterface.hpp"
37 #include "CAASymCipher.hpp"
38 #include "CAInfoService.hpp"
39 #include "CASocketAddrINet.hpp"
40 #include "CATempIPBlockList.hpp"
41 #ifdef HAVE_UNIX_DOMAIN_PROTOCOL
42  #include "CASocketAddrUnix.hpp"
43 #endif
44 #include "CAThread.hpp"
45 #include "CAUtil.hpp"
46 #include "CASignature.hpp"
47 #include "CABase64.hpp"
48 #include "xml/DOM_Output.hpp"
49 #include "CAPool.hpp"
50 #ifdef WITH_CONTROL_CHANNELS_TEST
51  #include "CAControlChannelTest.hpp"
52 #endif
53 #ifdef PAYMENT
55  #include "CAAccountingInstance.hpp"
57 #endif
59 #include "CAStatusManager.hpp"
60 #include "CALibProxytest.hpp"
63 
65 {
66  return m_bIsShuttingDown;
67 }
68 
70  {
71  SINT32 ret=CAMix::initOnce();
72  if(ret!=E_SUCCESS)
73  return ret;
74  CAMsg::printMsg(LOG_DEBUG,"Starting FirstMix InitOnce\n");
75  /*m_pSignature=CALibProxytest::getOptions()->getSignKey();
76  if(m_pSignature==NULL)*/
78  if(m_pMultiSignature == NULL)
79  return E_UNKNOWN;
80  //Try to find out how many (real) ListenerInterfaces are specified
82  m_nSocketsIn=0;
83  for(UINT32 i=1;i<=tmpSocketsIn;i++)
84  {
85  CAListenerInterface* pListener=NULL;
87  if(pListener==NULL)
88  continue;
89  if(!pListener->isVirtual())
90  {
91  m_nSocketsIn++;
92  }
93  delete pListener;
94  pListener = NULL;
95  }
96  if(m_nSocketsIn<1)
97  {
98  CAMsg::printMsg(LOG_CRIT,"No usable ListenerInterfaces specified (maybe wrong values or all are 'virtual'!\n");
99  return E_UNKNOWN;
100  }
101 
102  CAMsg::printMsg(LOG_DEBUG,"Starting FirstMix InitOnce - finished\n");
103  return E_SUCCESS;
104  }
105 
106 
107 
109  {
110  if (isShuttingDown())
111  {
112  return E_SHUTDOWN;
113  }
114 
115 #ifdef DYNAMIC_MIX
116  m_bBreakNeeded = m_bReconfigured;
117 #endif
118 
119  CAMsg::printMsg(LOG_DEBUG,"Starting FirstMix Init\n");
120  m_nMixedPackets=0; //reset to zero after each restart (at the moment neccessary for infoservice)
121  m_bRestart=false;
122  //Establishing all Listeners
123  UINT32 i;
125  for (i = 0; i < m_nSocketsIn; i++)
126  {
127  m_arrSocketsIn[i] = NULL;
128  }
129  //initiate ownerDocument for tc templates
131 
133 
134 
135  if (retSockets != E_SUCCESS)
136  {
137  return retSockets;
138  }
139 
140  CASocketAddr* pAddrNext=NULL;
142  {
143  CATargetInterface oNextMix;
145  if(oNextMix.getTargetType()==TARGET_MIX)
146  {
147  pAddrNext=oNextMix.getAddr();
148  break;
149  }
150  oNextMix.cleanAddr();
151  }
152  if(pAddrNext==NULL)
153  {
154  CAMsg::printMsg(LOG_CRIT,"No next Mix specified! Please insert the address of a next mix into your configuration.\n");
155  return E_UNKNOWN;
156  }
157  m_pMuxOut = new CAMuxSocket(OFB);
158  if(m_pMuxOut->getCASocket()->create(pAddrNext->getType())!=E_SUCCESS)
159  {
160  CAMsg::printMsg(LOG_CRIT,
161  "Cannot create SOCKET for connection to next Mix! Please check if the network and socket settings in your system are correct.\n");
162  return E_UNKNOWN;
163  }
166  //if(((*m_pMuxOut))->setSendLowWat(MIXPACKET_SIZE)!=E_SUCCESS)
167  // CAMsg::printMsg(LOG_INFO,"SOCKET Option SENDLOWWAT not set!\n");
168  CAMsg::printMsg(LOG_INFO,"MUXOUT-SOCKET RecvBuffSize: %i\n",m_pMuxOut->getCASocket()->getRecvBuff());
169  CAMsg::printMsg(LOG_INFO,"MUXOUT-SOCKET SendBuffSize: %i\n",m_pMuxOut->getCASocket()->getSendBuff());
170  //CAMsg::printMsg(LOG_INFO,"MUXOUT-SOCKET SendLowWatSize: %i\n",((*m_pMuxOut))->getSendLowWat());
171 
173  if((retSockets = connectToNextMix(pAddrNext)) != E_SUCCESS)
174  {
175  delete pAddrNext;
176  pAddrNext = NULL;
177  CAMsg::printMsg(LOG_DEBUG, "CAFirstMix::init - Unable to connect to next mix. Reason: %s (%i)\n", GET_NET_ERROR_STR(retSockets), retSockets);
178  return E_UNKNOWN;
179  }
180  delete pAddrNext;
181  pAddrNext = NULL;
183  CAMsg::printMsg(LOG_INFO,"Established socket connection to next mix. Starting key exchange...\n");
185 #ifdef __BUILD_AS_SHADOW_PLUGIN__
187 #endif
188 
189 
191  {
193  CAMsg::printMsg(LOG_CRIT,"Error in establishing secure communication with next Mix. Disconnecting...\n");
194  return E_UNKNOWN;
195  }
196  else
197  {
198  CAMsg::printMsg(LOG_INFO,"Secure connection to next Mix was established successfully.\n");
199  }
200  m_pIPList=new CAIPList();
201  m_pIPBlockList = new CATempIPBlockList(1000 * 60 * 2);
202 #ifdef COUNTRY_STATS
203  char* db_host;
204  char* db_user;
205  char* db_passwd;
206  CALibProxytest::getOptions()->getCountryStatsDBConnectionLoginData(&db_host,&db_user,&db_passwd);
207  SINT32 retcountrydb=initCountryStats(db_host,db_user,db_passwd);
208  delete[] db_host;
209  db_host = NULL;
210  delete[] db_user;
211  db_user = NULL;
212  delete[] db_passwd;
213  db_passwd = NULL;
214  if(retcountrydb!=E_SUCCESS)
215  return E_UNKNOWN;
216 #endif
219 #ifndef MULTI_THREADED_PACKET_PROCESSING
221 #ifdef HAVE_EPOLL
224 #else
227 #endif
228 #else // with MULTI_THREADED_PACKET_PROCESSING
229  m_pChannelToQueueList=new CAFirstMixChannelToQueueList() ;
230 
231  m_arpChannelList = new CAFirstMixChannelList*[m_numThreads];
232 #ifdef HAVE_EPOLL
233  m_arpsocketgroupUsersRead=new CASocketGroupEpoll*[m_numThreads];
234  m_arpsocketgroupUsersWrite=new CASocketGroupEpoll*[m_numThreads];
235 #else
236  m_arpsocketgroupUsersRead=new CASocketGroup*[m_numThreads];
237  m_arpsocketgroupUsersWrite=new CASocketGroup*[m_numThreads];
238 #endif
239  for (UINT32 i = 0; i < m_numThreads; i++)
240  {
241  m_arpChannelList[i] = new CAFirstMixChannelList();
242 #ifdef HAVE_EPOLL
243  m_arpsocketgroupUsersRead[i] = new CASocketGroupEpoll(false);
244  m_arpsocketgroupUsersWrite[i] = new CASocketGroupEpoll(true);
245 #else
246  m_arpsocketgroupUsersRead[i] = new CASocketGroup(false);
247  m_arpsocketgroupUsersWrite[i] = new CASocketGroup(true);
248 #endif
249  }
250 
251 
252 #endif //with MULTI_THREADED_PACKET_PROCESSING
253 
255 #ifdef REPLAY_DETECTION
256  m_pReplayDB=new CADatabase();
257  m_pReplayDB->start();
259  m_u64ReferenceTime=time(NULL);
260  m_u64LastTimestampReceived=time(NULL);
261 #endif
262 
263 #ifdef PAYMENT
265  {
266  return E_UNKNOWN;
267  }
269 #endif
270 
272 
273  //Starting thread for Step 1
274  m_pthreadAcceptUsers=new CAThread((UINT8*)"CAFirstMix - AcceptUsers");
277 
278  //Starting thread for Step 3
279  m_pthreadSendToMix=new CAThread((UINT8*)"CAFirstMix - SendToMix");
281  m_pthreadSendToMix->start(this);
282 
283  //Startting thread for Step 4a
284  m_pthreadReadFromMix=new CAThread((UINT8*)"CAFirstMix - ReadFromMix");
287 #ifdef CH_LOG_STUDY
288  nrOfChThread = new CAThread((UINT8*)"CAFirstMix - Channel open logging thread");
289  nrOfChThread->setMainLoop(fm_loopLogChannelsOpened);
290  nrOfChThread->start(this);
291  currentOpenedChannels = 0;
292 #endif //CH_LOG_STUDY
293  //Starting thread for logging
294 #ifdef LOG_PACKET_TIMES
295  m_pLogPacketStats=new CALogPacketStats();
296  m_pLogPacketStats->setLogIntervallInMinutes(FM_PACKET_STATS_LOG_INTERVALL);
297  m_pLogPacketStats->start();
298 #endif
299 #ifdef REPLAY_DETECTION
300 // sendReplayTimestampRequestsToAllMixes();
301 #endif
302  CAMsg::printMsg(LOG_DEBUG,"CAFirstMix init() succeeded\n");
304  return E_SUCCESS;
305 }
306 
308 {
309  UINT8 buff[255];
310  a_pAddrNext->toString(buff,255);
311  CAMsg::printMsg(LOG_INFO,"Try to connect to next Mix on %s ...\n",buff);
312  SINT32 err = E_UNKNOWN;
313  SINT32 errLast = E_SUCCESS;
314 
315  for(UINT32 i=0; i < 100; i++)
316  {
317 #ifdef DYNAMIC_MIX
319  if(m_bBreakNeeded != m_bReconfigured)
320  {
321  CAMsg::printMsg(LOG_DEBUG, "CAFirstMix::connectToNextMix - Broken the connect loop!\n");
322  break;
323  }
324 #endif
325  err = m_pMuxOut->connect(*a_pAddrNext);
326  if(err != E_SUCCESS)
327  {
328  err=GET_NET_ERROR;
329 
331  {
332  CAMsg::printMsg(LOG_ERR, "Cannot connect to next Mix on %s. Reason: %s (%i)\n",
333  buff, GET_NET_ERROR_STR(err), err);
334  break;
335  }
336 
337  if (errLast != err || i % 10 == 0)
338  {
339  CAMsg::printMsg(LOG_ERR, "Cannot connect to next Mix on %s. Reason: %s (%i). Retrying...\n",
340  buff, GET_NET_ERROR_STR(err), err);
341  errLast = err;
342  }
343  else
344  {
345 #ifdef _DEBUG
346  CAMsg::printMsg(LOG_DEBUG,"Cannot connect... retrying\n");
347 #endif
348  }
349  sSleep(10);
350  }
351  else
352  {
353  break;
354  }
355  }
356  return err;
357 }
358 
359 /*
360 *@DOCME
361 */
363  {
364  UINT8* recvBuff=NULL;
366  SINT32 ret;
367  CAMsg::printMsg(LOG_INFO, "Try to read the Key Info length from next Mix...\n");
369  {
370  if (ret != E_UNKNOWN)
371  {
372  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);
373  }
374  else
375  {
376  CAMsg::printMsg(LOG_CRIT,"Error receiving Key Info length from next mix!\n");
377  }
378  return ret;
379  }
380  len=ntohl(len);
381  CAMsg::printMsg(LOG_INFO, "Received next mix Key Info length %u\n",len);
382 
383  if (len > 100000)
384  {
385  CAMsg::printMsg(LOG_WARNING,"Unrealistic length for key info: %u We might not be able to get a connection.\n",len);
386  }
387 
388  recvBuff=new UINT8[len+1];
389 
391  {
392  if (ret != E_UNKNOWN)
393  {
394  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);
395  }
396  else
397  {
398  CAMsg::printMsg(LOG_CRIT,"Error receiving Key Info from next mix!\n");
399  }
400  delete []recvBuff;
401  recvBuff = NULL;
402  return E_UNKNOWN;
403  }
404  recvBuff[len]=0;
405  //get the Keys from the other mixes (and the Mix-Id's...!)
406  CAMsg::printMsg(LOG_INFO,"Received Key Info from next mix...\n");
407  CAMsg::printMsg(LOG_DEBUG,"%s\n",recvBuff);
408 
409  XERCES_CPP_NAMESPACE::DOMDocument* doc=parseDOMDocument(recvBuff, len);
410  delete []recvBuff;
411  recvBuff = NULL;
412  DOMElement* elemMixes=doc->getDocumentElement();
413  if(elemMixes == NULL)
414  {
415  if(doc != NULL)
416  {
417  doc->release();
418  doc = NULL;
419  }
420  CAMsg::printMsg(LOG_INFO,"before returning...\n");
421  return E_UNKNOWN;
422  }
423  SINT32 count=0;
424  if(getDOMElementAttribute(elemMixes,"count",&count)!=E_SUCCESS)
425  {
426  if(doc != NULL)
427  {
428  doc->release();
429  doc = NULL;
430  }
431  return E_UNKNOWN;
432  }
433  /*
434  @todo Do not know why we do this here - probably it has something todo with the
435  dynamic mix config, but makes not sense at all for me...
436 
437  getDOMElementAttribute(elemMixescascadeNaem
438  char *cascadeName;
439  cascadeName = elemMixes.getAttribute("cascadeName").transcode();
440  if(cascadeName == NULL)
441  return E_UNKNOWN;
442  CALibProxytest::getOptions()->setCascadeName(cascadeName);
443 */
444 #ifdef PAYMENT
446  {
447  appendTermsAndConditionsExtension(doc, elemMixes);
448  }
449 #endif
450  SINT32 extRet = handleKeyInfoExtensions(elemMixes);
451  if(extRet != E_SUCCESS)
452  {
453  if(doc != NULL)
454  {
455  doc->release();
456  doc = NULL;
457  }
458  return E_UNKNOWN;
459  }
460  m_pRSA=new CAASymCipher;
461 
462 #ifdef EXPORT_ASYM_PRIVATE_KEY
463  if(CALibProxytest::getOptions()->isImportKey())
464  {
465  UINT32 keyFileBuffLen=8096;
466  UINT8* keyFileBuff=new UINT8[keyFileBuffLen];
467  CALibProxytest::getOptions()->getEncryptionKeyImportFile(keyFileBuff,keyFileBuffLen);
468  UINT8* keyBuff=readFile(keyFileBuff,&keyFileBuffLen);
469  m_pRSA->setPrivateKeyAsXML(keyBuff,keyFileBuffLen);
470  delete[] keyFileBuff;
471  delete[] keyBuff;
472  }
473  else
474 #endif
475  {
476  m_pRSA->generateKeyPair(1024);
477  }
478 #ifdef EXPORT_ASYM_PRIVATE_KEY
479  if(CALibProxytest::getOptions()->isExportKey())
480  {
481  UINT32 keyFileBuffLen=8096;
482  UINT8* keyFileBuff=new UINT8[keyFileBuffLen];
483  UINT8* keyBuff=new UINT8[keyFileBuffLen];
484  CALibProxytest::getOptions()->getEncryptionKeyExportFile(keyFileBuff,keyFileBuffLen);
485  m_pRSA->getPrivateKeyAsXML(keyBuff,&keyFileBuffLen);
486  saveFile(keyFileBuff,keyBuff,keyFileBuffLen);
487  delete[] keyFileBuff;
488  delete[] keyBuff;
489  }
490 #endif
491  DOMNode* child=elemMixes->getLastChild();
492 
493  //tmp XML-Structure for constructing the XML which is sent to each user
494  XERCES_CPP_NAMESPACE::DOMDocument* docXmlKeyInfo=createDOMDocument();
495  DOMElement* elemRootKey=createDOMElement(docXmlKeyInfo,"MixCascade");
496  setDOMElementAttribute(elemRootKey,"version",(UINT8*)"0.2"); //set the Version of the XML to 0.2
497  setDOMElementAttribute(elemRootKey, "maxOpenChannels", CHANNELS_PER_CLIENT);
498 #ifdef LOG_DIALOG
499  setDOMElementAttribute(elemRootKey,"study",(UINT8*)"true");
500 #endif
501  docXmlKeyInfo->appendChild(elemRootKey);
502  DOMElement* elemMixProtocolVersion=createDOMElement(docXmlKeyInfo,"MixProtocolVersion");
503  setDOMElementValue(elemMixProtocolVersion,(UINT8*)MIX_CASCADE_PROTOCOL_VERSION);
504  elemRootKey->appendChild(elemMixProtocolVersion);
505  DOMNode* elemMixesKey=docXmlKeyInfo->importNode(elemMixes,true);
506  elemRootKey->appendChild(elemMixesKey);
507 
508  //UINT32 tlen;
509  /* //remove because it seems to be useless...
510  while(child!=NULL)
511  {
512  if(child.getNodeName().equals("Mix"))
513  {
514  DOM_Node rsaKey=child.getFirstChild();
515  CAASymCipher oRSA;
516  oRSA.setPublicKeyAsDOMNode(rsaKey);
517  tlen=256;
518  }
519  child=child.getPreviousSibling();
520  }*/
521  //tlen=256;
522 
523  //Inserting own Key in XML-Key struct
524  DOMElement* elemKey=NULL;
525  m_pRSA->getPublicKeyAsDOMElement(elemKey,docXmlKeyInfo);
526  addMixInfo(elemMixesKey, true);
527  DOMElement* elemOwnMix=NULL;
528  getDOMChildByName(elemMixesKey, "Mix", elemOwnMix, false);
529  elemOwnMix->appendChild(elemKey);
530 #ifdef PAYMENT
531  CAMsg::printMsg(LOG_INFO,"before T&Cs1...\n");
533  {
534  elemOwnMix->appendChild(termsAndConditionsInfoNode(docXmlKeyInfo));
535  }
536  CAMsg::printMsg(LOG_INFO,"after T&Cs1...\n");
537 #endif
538  elemOwnMix->appendChild(createDOMElement(docXmlKeyInfo,"SupportsEncrypedControlChannels"));
539  CAMsg::printMsg(LOG_INFO,"after SupportEncChannels...\n");
540  if (signXML(elemOwnMix) != E_SUCCESS)
541  {
542  CAMsg::printMsg(LOG_DEBUG,"Could not sign MixInfo sent to users...\n");
543  }
544 
545  setDOMElementAttribute(elemMixesKey,"count",count+1);
546 
547 
548  DOMNode* elemPayment=createDOMElement(docXmlKeyInfo,"Payment");
549  elemRootKey->appendChild(elemPayment);
550 #ifdef PAYMENT
551  setDOMElementAttribute(elemPayment,"required",(UINT8*)"true");
552  setDOMElementAttribute(elemPayment,"version",(UINT8*)PAYMENT_VERSION);
553  setDOMElementAttribute(elemPayment,"prepaidInterval", CALibProxytest::getOptions()->getPrepaidInterval());
554  setDOMElementAttribute(elemPayment,"piid", CALibProxytest::getOptions()->getBI()->getID());
555 
556 #else
557  setDOMElementAttribute(elemPayment,"required",(UINT8*)"false");
558 #endif
559 
560  // create signature
561  if (signXML(elemRootKey) != E_SUCCESS)
562  {
563  CAMsg::printMsg(LOG_DEBUG,"Could not sign KeyInfo sent to users...\n");
564  }
565 
566 
567  UINT32 tmp32Len = 0;
568  UINT8* tmpB=DOM_Output::dumpToMem(docXmlKeyInfo, &tmp32Len);
569  if (docXmlKeyInfo != NULL)
570  {
571  docXmlKeyInfo->release();
572  docXmlKeyInfo = NULL;
573  }
574 
575  if(tmp32Len > 0xFFFD) //too bytes are reserved for the length
576  {
577  CAMsg::printMsg(LOG_CRIT, "The key info size of %u bytes is too large for the clients. (maximum is %u)\n", 0xFFFD);
578  if (doc != NULL)
579  {
580  doc->release();
581  doc = NULL;
582  }
583  return E_UNKNOWN;
584  }
585 
586  UINT16 tlen = (UINT16) tmp32Len;
587  m_xmlKeyInfoBuff = new UINT8[tlen+sizeof(tlen)];
588  memcpy(m_xmlKeyInfoBuff+sizeof(tlen), tmpB, tlen);
589  UINT16 s = htons(tlen);
590  memcpy(m_xmlKeyInfoBuff, &s, sizeof(s));
591  m_xmlKeyInfoSize=tlen + sizeof(tlen);
592  delete []tmpB;
593  tmpB = NULL;
594  SINT32 result=E_UNKNOWN;
595 
596  //Sending symmetric key...
597  child=elemMixes->getFirstChild();
598  while(child!=NULL)
599  {
600  if(equals(child->getNodeName(),"Mix"))
601  {
602  //verify certificate from next mix if enabled
604  {
606  if(nextMixCert != NULL)
607  {
608  CAMsg::printMsg(LOG_DEBUG, "Next mix certificate was verified by a trusted root CA.\n");
610  }
611  else
612  {
613  CAMsg::printMsg(LOG_ERR, "Could not verify certificate received from next mix!\n");
614  return E_UNKNOWN;
615  }
616  }
617  //check Signature....
618  CAMsg::printMsg(LOG_DEBUG,"Try to verify next mix signature...\n");
619  //CASignature oSig;
621  /*oSig.setVerifyKey(nextCert);
622  SINT32 ret=oSig.verifyXML(child,NULL);*/
623  result = CAMultiSignature::verifyXML(child, nextCert);
624  delete nextCert;
625  nextCert = NULL;
626  if(result != E_SUCCESS)
627  {
628  //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");
629  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");
630  if (doc != NULL)
631  {
632  doc->release();
633  doc = NULL;
634  }
635  return E_UNKNOWN;
636  }
637  CAMsg::printMsg(LOG_DEBUG,"Successfully verified XML signature of next mix!\n");
638 
639  result = checkCompatibility(child, "next");
640 
641 
642  DOMNode* rsaKey=child->getFirstChild();
643  CAASymCipher oRSA;
644  oRSA.setPublicKeyAsDOMNode(rsaKey);
645  DOMElement* elemNonce=NULL;
646  getDOMChildByName(child,"Nonce",elemNonce,false);
647  UINT8 arNonce[1024];
648  if(elemNonce!=NULL)
649  {
650  UINT32 lenNonce=1024;
651  UINT32 tmpLen=1024;
652  getDOMElementValue(elemNonce,arNonce,&lenNonce);
653  CABase64::decode(arNonce,lenNonce,arNonce,&tmpLen);
654  lenNonce=tmpLen;
655  tmpLen=1024;
656  CABase64::encode(SHA1(arNonce,lenNonce,NULL),SHA_DIGEST_LENGTH,
657  arNonce,&tmpLen);
658  arNonce[tmpLen]=0;
659  }
660  UINT8 key[64];
661 #ifdef SET_STATIC_MUX_SOCKET_KEY
662  CAMsg::printMsg(LOG_CRIT, "Warning! Will use an all zero MuxSocket key - do not use this Mix in a productive environment -- only for testing!\n");
663  memset(key,0,64);
664 #else
665  getRandom(key, 64);
666 #endif
667  //UINT8 buff[400];
668  //UINT32 bufflen=400;
669  XERCES_CPP_NAMESPACE::DOMDocument* docSymKey=createDOMDocument();
670  DOMElement* elemRoot=NULL;
671  encodeXMLEncryptedKey(key,64,elemRoot,docSymKey,&oRSA);
672  docSymKey->appendChild(elemRoot);
673  if(elemNonce!=NULL)
674  {
675  DOMElement* elemNonceHash=createDOMElement(docSymKey,"Nonce");
676  setDOMElementValue(elemNonceHash,arNonce);
677  elemRoot->appendChild(elemNonceHash);
678  }
679 
680  appendCompatibilityInfo(elemRoot);
681 
683  DOMElement* elemKeepAlive=NULL;
684  DOMElement* elemKeepAliveSendInterval=NULL;
685  DOMElement* elemKeepAliveRecvInterval=NULL;
686  getDOMChildByName(child,"KeepAlive",elemKeepAlive,false);
687  getDOMChildByName(elemKeepAlive,"SendInterval",elemKeepAliveSendInterval,false);
688  getDOMChildByName(elemKeepAlive,"ReceiveInterval",elemKeepAliveRecvInterval,false);
689  UINT32 tmpSendInterval,tmpRecvInterval;
690  getDOMElementValue(elemKeepAliveSendInterval,tmpSendInterval,0xFFFFFFFF); //if no send interval was given set it to "infinite"
691  getDOMElementValue(elemKeepAliveRecvInterval,tmpRecvInterval,0xFFFFFFFF); //if no recv interval was given --> set it to "infinite"
692  CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Getting offer -- SendInterval %u -- ReceiveInterval %u\n",tmpSendInterval,tmpRecvInterval);
693  // Add Info about KeepAlive traffic
694  UINT32 u32KeepAliveSendInterval=CALibProxytest::getOptions()->getKeepAliveSendInterval();
695  UINT32 u32KeepAliveRecvInterval=CALibProxytest::getOptions()->getKeepAliveRecvInterval();
696  elemKeepAlive=createDOMElement(docSymKey,"KeepAlive");
697  elemKeepAliveSendInterval=createDOMElement(docSymKey,"SendInterval");
698  elemKeepAliveRecvInterval=createDOMElement(docSymKey,"ReceiveInterval");
699  elemKeepAlive->appendChild(elemKeepAliveSendInterval);
700  elemKeepAlive->appendChild(elemKeepAliveRecvInterval);
701  setDOMElementValue(elemKeepAliveSendInterval,u32KeepAliveSendInterval);
702  setDOMElementValue(elemKeepAliveRecvInterval,u32KeepAliveRecvInterval);
703  elemRoot->appendChild(elemKeepAlive);
704  CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Offering -- SendInterval %u -- Receive Interval %u\n",u32KeepAliveSendInterval,u32KeepAliveRecvInterval);
705  m_u32KeepAliveSendInterval = u32KeepAliveSendInterval;
706  if (m_u32KeepAliveSendInterval > tmpRecvInterval - 10000)
707  m_u32KeepAliveSendInterval-=10000; //make the send interval a little bit smaller than the related receive interval
708  m_u32KeepAliveRecvInterval=max(u32KeepAliveRecvInterval,tmpSendInterval);
709  if (m_u32KeepAliveRecvInterval - 10000 < tmpSendInterval)
710  {
712  }
713  CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Calculated -- SendInterval %u -- Receive Interval %u\n",m_u32KeepAliveSendInterval,m_u32KeepAliveRecvInterval);
714 
715  //m_pSignature->signXML(elemRoot);
716  m_pMultiSignature->signXML(elemRoot, true);
717  UINT32 outlen=0;
718  UINT8* out=DOM_Output::dumpToMem(docSymKey,&outlen);
719  if (docSymKey != NULL)
720  {
721  docSymKey->release();
722  docSymKey = NULL;
723  }
724  m_pMuxOut->setSendKey(key,32);
725  m_pMuxOut->setReceiveKey(key+32,32);
726  UINT32 size = htonl(outlen);
727  CAMsg::printMsg(LOG_DEBUG,"Sending symmetric key to next Mix! Size: %i\n", outlen);
728  m_pMuxOut->getCASocket()->send((UINT8*) &size, sizeof(size));
729  m_pMuxOut->getCASocket()->send(out, outlen);
730  m_pMuxOut->setCrypt(true);
731  delete[] out;
732  out = NULL;
733  break;
734  }
735  child=child->getNextSibling();
736  }
737 
738  if (result != E_SUCCESS)
739  {
740  if (doc != NULL)
741  {
742  doc->release();
743  doc = NULL;
744  }
745  return result;
746  }
747 
748 
750  if(initMixParameters(elemMixes)!=E_SUCCESS)
751  {
752  if (doc != NULL)
753  {
754  doc->release();
755  doc = NULL;
756  }
757  return E_UNKNOWN;
758  }
759  if(initMixCascadeInfo(elemMixes)!=E_SUCCESS)
760  {
761  if (doc != NULL)
762  {
763  doc->release();
764  doc = NULL;
765  }
766  CAMsg::printMsg(LOG_CRIT,"Error initializing cascade info.\n");
767  return E_UNKNOWN;
768  }
769 /* else
770  {
771  if(m_pInfoService != NULL)
772  m_pInfoService->sendCascadeHelo();
773  }*/
774  CAMsg::printMsg(LOG_DEBUG,"Key exchange finished!\n");
775  if (doc != NULL)
776  {
777  doc->release();
778  doc = NULL;
779  }
780  return E_SUCCESS;
781 }
782 
783 
785  {
786 #ifdef REPLAY_DETECTION
787  UINT32 diff=time(NULL)-m_u64LastTimestampReceived;
788  for(UINT32 i=0;i<m_u32MixCount-1;i++)
789  {
790 //@todo dangerous strcmp
791  if(strcmp((char*)m_arMixParameters[i].m_strMixID,(char*)params.m_strMixID)==0)
792  {
795  }
796  else{
797  if (m_arMixParameters[i].m_u32ReplayOffset!=0) m_arMixParameters[i].m_u32ReplayOffset+=diff;
798  }
799  }
800 #endif
801  return E_SUCCESS;
802  }
803 
804 
806 {
807  if(root == NULL)
808  {
809  return E_UNKNOWN;
810  }
811 
812  SINT32 ret = E_SUCCESS;
813  DOMElement *extensionRoot = NULL;
814  getDOMChildByName(root, KEYINFO_NODE_EXTENSIONS, extensionRoot);
815 
816  if(extensionRoot != NULL)
817  {
818  extensionRoot = (DOMElement *) root->removeChild(extensionRoot);
819  ret = handleTermsAndConditionsExtension(extensionRoot);
820  extensionRoot->release();
821  }
822  return ret;
823 }
824 
826 {
827  if(extensionsRoot == NULL)
828  {
829  return E_UNKNOWN;
830  }
831 
832  DOMElement *tncDefs = NULL;
833  DOMElement *tncTemplates = NULL;
834  getDOMChildByName(extensionsRoot, KEYINFO_NODE_TNC_EXTENSION, tncDefs);
835  if(tncDefs == NULL)
836  {
837  CAMsg::printMsg(LOG_CRIT,"No TNCs in TNC extension found.\n");
838  return E_UNKNOWN;
839  }
840  getDOMChildByName(tncDefs, OPTIONS_NODE_TNCS_TEMPLATES, tncTemplates);
841 
842  UINT8 currentTnC_id[TMP_BUFF_SIZE];
843  UINT32 currentTnC_id_len = TMP_BUFF_SIZE;
844 
845  UINT8 currentTnCEntry_templateRefid[TMP_BUFF_SIZE];
846  UINT32 currentTnCEntry_templateRefid_len = TMP_BUFF_SIZE;
847 
848  UINT8 currentTnCEntry_locale[TMP_LOCALE_SIZE];
849  UINT32 currentTnCEntry_locale_len = TMP_LOCALE_SIZE;
850 
851  DOMElement *currentTnCList = NULL;
852  DOMElement *currentTnCEntry = NULL;
853  memset(currentTnC_id, 0, TMP_BUFF_SIZE);
854  memset(currentTnCEntry_templateRefid, 0, TMP_BUFF_SIZE);
855 
856  if(tncTemplates != NULL)
857  {
858  DOMNodeList *tncTemplateList = getElementsByTagName(tncDefs, TNC_TEMPLATE_ROOT_ELEMENT);
859  m_nrOfTermsAndConditionsTemplates = tncTemplateList->getLength();
860  CAMsg::printMsg(LOG_INFO, "Storing %u TC Templates.\n", m_nrOfTermsAndConditionsTemplates);
862  {
864  for (UINT32 i = 0; i < m_nrOfTermsAndConditionsTemplates; i++)
865  {
866  m_tcTemplates[i] = m_templatesOwner->importNode(tncTemplateList->item(i), true);
867  }
868  }
869  else
870  {
871  CAMsg::printMsg(LOG_ERR, "Not a single TC Template specified! the Cascade is not properly configured.\n");
872  return E_UNKNOWN;
873  }
874  }
875  else
876  {
877  CAMsg::printMsg(LOG_ERR, "No TC Template node found! Cascade is not properly configured.\n");
878  return E_UNKNOWN;
879  }
880 
881  DOMNodeList *tncDefList = getElementsByTagName(tncDefs, OPTIONS_NODE_TNCS);
882  if(tncDefList->getLength() == 0)
883  {
884  CAMsg::printMsg(LOG_CRIT, "No TNCs definitions found.\n");
885  return E_UNKNOWN;
886  }
887 
888  m_nrOfTermsAndConditionsDefs = tncDefList->getLength();
891 
892  for (UINT32 i = 0; i < m_nrOfTermsAndConditionsDefs; i++)
893  {
894  currentTnCList = (DOMElement *) tncDefList->item(i);
895  DOMNodeList *tncDefEntryList = getElementsByTagName(currentTnCList, OPTIONS_NODE_TNCS_TRANSLATION);
896  getDOMElementAttribute(currentTnCList, OPTIONS_ATTRIBUTE_TNC_ID, currentTnC_id, &currentTnC_id_len);
897 
898  m_tnCDefs[i] = new TermsAndConditions(currentTnC_id, tncDefEntryList->getLength());
899 
900  for (XMLSize_t j = 0; j < tncDefEntryList->getLength(); j++)
901  {
902  currentTnCEntry = (DOMElement *) tncDefEntryList->item(j);
903 
905  currentTnCEntry_templateRefid, &currentTnCEntry_templateRefid_len);
907  currentTnCEntry_locale, &currentTnCEntry_locale_len);
908 
909  DOMNode *templateNode = getTermsAndConditionsTemplate(currentTnCEntry_templateRefid);
910  if(templateNode != NULL)
911  {
912  //m_tnCDefs[i]->synchLock->lock();
913  m_tnCDefs[i]->addTranslation(currentTnCEntry_locale, currentTnCEntry, templateNode);
914  //m_tnCDefs[i]->synchLock->unlock();
915  }
916  else
917  {
918  CAMsg::printMsg(LOG_CRIT,"Could not find template %s for T&C %s.\n", currentTnCEntry_templateRefid, currentTnC_id);
919  return E_UNKNOWN;
920  }
921  memset(currentTnCEntry_templateRefid, 0, TMP_BUFF_SIZE);
922  currentTnCEntry_templateRefid_len = TMP_BUFF_SIZE;
923  memset(currentTnCEntry_locale, 0, TMP_LOCALE_SIZE);
924  currentTnCEntry_locale_len = TMP_LOCALE_SIZE;
925  }
926  memset(currentTnC_id, 0, TMP_BUFF_SIZE);
927  currentTnC_id_len = TMP_BUFF_SIZE;
928  }
929  return E_SUCCESS;
930 }
931 
933 {
934  if( (m_tnCDefs == NULL) || (opSki == NULL) )
935  {
936  return NULL;
937  }
938  for(UINT32 i = 0; i < m_nrOfTermsAndConditionsDefs; i++)
939  {
940  if(m_tnCDefs[i] != NULL)
941  {
942  if(strncasecmp((char *) m_tnCDefs[i]->getID(),
943  (const char *) opSki,
944  strlen((char *) m_tnCDefs[i]->getID())) == 0)
945  {
946  return m_tnCDefs[i];
947  }
948  }
949  }
950  return NULL;
951 }
952 
954 {
955  UINT8 *currentRefId = NULL;
956  bool match = false;
957 
958  for (UINT32 i = 0; i < m_nrOfTermsAndConditionsTemplates; i++)
959  {
961  match = (currentRefId != NULL) &&
962  (strncmp((char *)templateRefID, (char *)currentRefId, TEMPLATE_REFID_MAXLEN ) == 0);
963  delete [] currentRefId;
964  currentRefId = NULL;
965  if(match)
966  {
967  return m_tcTemplates[i];
968  }
969  }
970  return NULL;
971 }
972 
979  {
980  INIT_STACK;
981  BEGIN_STACK("CAFirstMix::fm_loopSendToMix");
982 
983  CAFirstMix* pFirstMix=(CAFirstMix*)param;
984  CAQueue* pQueue=((CAFirstMix*)param)->m_pQueueSendToMix;
985  CAMuxSocket* pMuxSocket=pFirstMix->m_pMuxOut;
986 
987  UINT32 len;
988  SINT32 ret;
989 
990 /*#ifdef DATA_RETENTION_LOG
991  t_dataretentionLogEntry* pDataRetentionLogEntry=new t_dataretentionLogEntry;
992 #endif
993 */
994 #ifndef USE_POOL
995  tQueueEntry* pQueueEntry=new tQueueEntry;
996  MIXPACKET* pMixPacket=&pQueueEntry->packet;
997  UINT32 u32KeepAliveSendInterval=pFirstMix->m_u32KeepAliveSendInterval;
998  while(!pFirstMix->m_bRestart)
999  {
1000  len=sizeof(tQueueEntry);
1001  ret=pQueue->getOrWait((UINT8*)pQueueEntry,&len,u32KeepAliveSendInterval);
1002  if(ret==E_TIMEDOUT)
1003  {//send a dummy as keep-alvie-traffic
1004  pMixPacket->flags=CHANNEL_DUMMY;
1005  pMixPacket->channel=DUMMY_CHANNEL;
1006  getRandom(pMixPacket->data,DATA_SIZE);
1007  }
1008  else if(ret!=E_SUCCESS||len!=sizeof(tQueueEntry))
1009  {
1010  CAMsg::printMsg(LOG_ERR,"CAFirstMix::lm_loopSendToMix - Error in dequeueing MixPaket\n");
1011  CAMsg::printMsg(LOG_ERR,"ret=%i len=%i\n",ret,len);
1012  break;
1013  }
1014 
1015  if(pMuxSocket->send(pMixPacket)!=MIXPACKET_SIZE)
1016  {
1017  CAMsg::printMsg(LOG_ERR,"CAFirstMix::lm_loopSendToMix - Error in sending MixPaket\n");
1018  break;
1019  }
1020 #if defined (LOG_PACKET_TIMES)
1021  if(!isZero64(pQueueEntry->timestamp_proccessing_start))
1022  {
1023  getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end);
1024  pFirstMix->m_pLogPacketStats->addToTimeingStats(*pQueueEntry,pMixPacket->flags,true);
1025  }
1026 #endif
1027 #ifdef DATA_RETENTION_LOG
1028  if((pQueueEntry->packet.flags&CHANNEL_OPEN)!=0)
1029  {
1030  pQueueEntry->dataRetentionLogEntry.t_out=htonl(time(NULL));
1031  pFirstMix->m_pDataRetentionLog->log(&(pQueueEntry->dataRetentionLogEntry));
1032  }
1033 #endif
1034  }
1035  delete pQueueEntry;
1036  pQueueEntry = NULL;
1037 #else
1038  CAPool* pPool=new CAPool(MIX_POOL_SIZE);
1039  tPoolEntry* pPoolEntry=new tPoolEntry;
1040  MIXPACKET* pMixPacket=&pPoolEntry->packet;
1041  while(!pFirstMix->m_bRestart)
1042  {
1043  len=sizeof(tQueueEntry);
1044  ret=pQueue->getOrWait((UINT8*)pPoolEntry,&len,MIX_POOL_TIMEOUT);
1045  if(ret==E_TIMEDOUT)
1046  {
1047  pMixPacket->flags=CHANNEL_DUMMY;
1048  pMixPacket->channel=DUMMY_CHANNEL;
1049  getRandom(pMixPacket->data,DATA_SIZE);
1050  #ifdef LOG_PACKET_TIMES
1051  setZero64(pPoolEntry->timestamp_proccessing_start);
1052  #endif
1053  }
1054  else if(ret!=E_SUCCESS||len!=sizeof(tQueueEntry))
1055  break;
1056  #ifdef LOG_PACKET_TIMES
1057  getcurrentTimeMicros(pPoolEntry->pool_timestamp_in);
1058  #endif
1059  pPool->pool(pPoolEntry);
1060  #ifdef LOG_PACKET_TIMES
1061  getcurrentTimeMicros(pPoolEntry->pool_timestamp_out);
1062  #endif
1063  if(pMuxSocket->send(pMixPacket)!=MIXPACKET_SIZE)
1064  break;
1065  #ifdef LOG_PACKET_TIMES
1066  if(!isZero64(pPoolEntry->timestamp_proccessing_start))
1067  {
1068  getcurrentTimeMicros(pPoolEntry->timestamp_proccessing_end);
1069  pFirstMix->m_pLogPacketStats->addToTimeingStats(*pPoolEntry,pMixPacket->flags,true);
1070  }
1071  #endif
1072  }
1073  delete pPoolEntry;
1074  pPoolEntry = NULL;
1075  delete pPool;
1076  pPool = NULL;
1077 #endif
1078 
1079 /*#ifdef DATA_RETENTION_LOG
1080  delete pDataRetentionLogEntry;
1081 #endif
1082 */
1083  FINISH_STACK("CAFirstMix::fm_loopSendToMix");
1084 
1085  CAMsg::printMsg(LOG_DEBUG,"Exiting Thread SendToMix\n");
1087  }
1088 
1089 /* How to end this thread:
1090  0. set bRestart=true
1091 */
1093  {
1094  INIT_STACK;
1095  BEGIN_STACK("CAFirstMix::fm_loopReadFromMix");
1096 
1097  CAFirstMix* pFirstMix=(CAFirstMix*)pParam;
1098  CAMuxSocket* pMuxSocket=pFirstMix->m_pMuxOut;
1099  CAQueue* pQueue=pFirstMix->m_pQueueReadFromMix;
1100  tQueueEntry* pQueueEntry=new tQueueEntry;
1101  MIXPACKET* pMixPacket=&pQueueEntry->packet;
1102  CASingleSocketGroup* pSocketGroup=new CASingleSocketGroup(false);
1103  pSocketGroup->add(*pMuxSocket);
1104  #ifdef USE_POOL
1105  CAPool* pPool=new CAPool(MIX_POOL_SIZE);
1106  #endif
1107  UINT64 keepaliveNow,keepaliveLast;
1108  UINT32 u32KeepAliveRecvInterval=pFirstMix->m_u32KeepAliveRecvInterval;
1109  getcurrentTimeMillis(keepaliveLast);
1110  CAControlChannelDispatcher* pControlChannelDispatcher=pFirstMix->m_pMuxOutControlChannelDispatcher;
1111  while (!pFirstMix->m_bRestart)
1112  {
1114  {
1115 #ifdef DEBUG
1116  CAMsg::printMsg(LOG_DEBUG, "CAFirstMix::Queue is full!\n");
1117 #endif
1118  msSleep(200);
1119  getcurrentTimeMillis(keepaliveLast);
1120  continue;
1121  }
1122  //check if the connection is broken because we did not received a Keep_alive-Message
1123  getcurrentTimeMillis(keepaliveNow);
1124  UINT32 keepaliveDiff = diff64(keepaliveNow, keepaliveLast);
1125  if (keepaliveDiff > u32KeepAliveRecvInterval)
1126  {
1127  CAMsg::printMsg(LOG_DEBUG, "CAFirstMix::loopReadFromMix() -- restart because of KeepAlive-Traffic Timeout!\n");
1128  pFirstMix->m_bRestart = true;
1130  break;
1131  }
1132  SINT32 ret = pSocketGroup->select(MIX_POOL_TIMEOUT);
1133  if (ret < 0)
1134  {
1135  if (ret == E_TIMEDOUT)
1136  {
1137 #ifdef USE_POOL
1138  pMixPacket->flags=CHANNEL_DUMMY;
1139  pMixPacket->channel=DUMMY_CHANNEL;
1140  getRandom(pMixPacket->data,DATA_SIZE);
1141 #ifdef LOG_PACKET_TIMES
1142  setZero64(pQueueEntry->timestamp_proccessing_start);
1143 #endif
1144 #else
1145  continue;
1146 #endif
1147  }
1148  else
1149  {
1150  /* another error occured (happens sometimes while debugging because
1151  * of interruption, if a breakpoint is reached -> poll() returns
1152  * errorcode EINTR)
1153  * Note: Any Error on select() does not mean, that the underliny connections have some error state, because
1154  * in this case select() returns the socket and than this socket returns the error
1155  */
1156 #ifdef DEBUG
1157  CAMsg::printMsg(LOG_DEBUG, "CAFirstMix::loopReadFromMix() - socket select error: %i\n",ret);
1158 #endif
1159  continue;
1160  }
1161  }
1162  else if (ret > 0)
1163  {
1164  ret = pMuxSocket->receive(pMixPacket);
1165 #ifdef LOG_PACKET_TIMES
1166  getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_start);
1167 #endif
1168  if (ret != MIXPACKET_SIZE)
1169  {
1170  pFirstMix->m_bRestart = true;
1171  CAMsg::printMsg(LOG_ERR, "CAFirstMix::lm_loopReadFromMix - received returned: %i -- restarting!\n", ret);
1173  break;
1174  }
1175  if (pMixPacket->channel > 0 && pMixPacket->channel < 256)
1176  {
1177 #ifdef DEBUG
1178  CAMsg::printMsg(LOG_DEBUG, "CAFirstMix - sent a packet from the next mix to the ControlChanelDispatcher... \n");
1179 #endif
1180  pControlChannelDispatcher->proccessMixPacket(pMixPacket);
1181  getcurrentTimeMillis(keepaliveLast);
1182  continue;
1183  }
1184  }
1185 #ifdef USE_POOL
1186 #ifdef LOG_PACKET_TIMES
1187  getcurrentTimeMicros(pQueueEntry->pool_timestamp_in);
1188 #endif
1189  pPool->pool((tPoolEntry*)pQueueEntry);
1190 #ifdef LOG_PACKET_TIMES
1191  getcurrentTimeMicros(pQueueEntry->pool_timestamp_out);
1192 #endif
1193 #endif
1194 #ifdef ANON_DEBUG_MODE
1195  if (pMixPacket->flags&CHANNEL_DEBUG)
1196  {
1197  UINT8 base64Payload[DATA_SIZE << 1];
1198  EVP_EncodeBlock(base64Payload, pMixPacket->data, DATA_SIZE);//base64 encoding (without newline!)
1199  CAMsg::printMsg(LOG_DEBUG, "Received Downstream AN.ON packet from previous Mix debug: %s\n", base64Payload);
1200  }
1201 
1202 #endif
1203  pQueue->add(pQueueEntry, sizeof(tQueueEntry));
1204  getcurrentTimeMillis(keepaliveLast);
1205  }
1206  delete pQueueEntry;
1207  pQueueEntry = NULL;
1208  delete pSocketGroup;
1209  pSocketGroup = NULL;
1210  #ifdef USE_POOL
1211  delete pPool;
1212  pPool = NULL;
1213  #endif
1214 
1215  FINISH_STACK("CAFirstMix::fm_loopReadFromMix");
1217  }
1218 
1220  {
1224  };
1225 
1226 typedef struct T_UserLoginData t_UserLoginData;
1227 
1229 {
1230  UINT8* peerIP=new UINT8[4];
1231  SINT32 master = pNewMuxSocket->getPeerIP(peerIP);
1232 
1233  if(master == E_SUCCESS)
1234  {
1235  UINT32 size=0;
1236  UINT8 remoteIP[4];
1237 
1239 
1240  master = E_UNKNOWN;
1241 
1242  for(UINT32 i = 0; i < size; i++)
1243  {
1244  if(intf[i]->getType() == HTTP_TCP || intf[i]->getType() == RAW_TCP)
1245  {
1246  CASocketAddrINet* addr = (CASocketAddrINet*) intf[i]->getAddr();
1247  if(addr == NULL)
1248  {
1249  continue;
1250  }
1251 
1252  addr->getIP(remoteIP);
1253  delete addr;
1254  addr = NULL;
1255 
1256  if(memcmp(peerIP, remoteIP, 4) == 0)
1257  {
1258  CAMsg::printMsg(LOG_DEBUG,"Got InfoService connection: You are allowed for login...\n");
1259  master = E_SUCCESS;
1260  break;
1261  }
1262  }
1263  }
1264  }
1265  delete[] peerIP;
1266  peerIP = NULL;
1267 
1268  return master;
1269 }
1270 
1271 
1272 /*How to end this thread
1273 1. Set m_bRestart in firstMix to true
1274 2. close all accept sockets
1275 */
1277  {
1278  INIT_STACK;
1279  BEGIN_STACK("CAFirstMix::fm_loopAcceptUsers");
1280  CAMsg::printMsg(LOG_DEBUG, "Start acceptusers\n");
1281 
1282  CAFirstMix* pFirstMix=(CAFirstMix*)param;
1283  CASocket** socketsIn=pFirstMix->m_arrSocketsIn;
1284  CAIPList* pIPList=pFirstMix->m_pIPList;
1285  CATempIPBlockList* pIPBlockList = pFirstMix->m_pIPBlockList;
1286  CAThreadPool* pthreadsLogin=pFirstMix->m_pthreadsLogin;
1287  UINT32 nSocketsIn=pFirstMix->m_nSocketsIn;
1288 #ifdef __BUILD_AS_SHADOW_PLUGIN__
1289  CASocketGroupEpoll* psocketgroupAccept=new CASocketGroupEpoll(false);
1290 #else
1291  CASocketGroup* psocketgroupAccept = new CASocketGroup(false);
1292 #endif
1293  CAMuxSocket* pNewMuxSocket;
1294  UINT8* peerIP=new UINT8[4];
1295  UINT32 i=0;
1296  SINT32 countRead;
1297  SINT32 ret;
1298  SINT32 retPeerIP = E_SUCCESS;
1299 
1300  pFirstMix->m_newConnections = 0;
1301 
1302  // kick out users that already have connected
1303  for(i=0;i<nSocketsIn;i++)
1304  {
1305  while (socketsIn[i]->close() != E_SUCCESS)
1306  {
1307  sSleep(1);
1308  }
1309  delete socketsIn[i];
1310  }
1311  CAMsg::printMsg(LOG_DEBUG, "Creating incoming sockets\n");
1312 
1313  if (CALibProxytest::getOptions()->createSockets(false,pFirstMix-> m_arrSocketsIn, pFirstMix->m_nSocketsIn) != E_SUCCESS)
1314  {
1315  goto END_THREAD;
1316  }
1317  CAMsg::printMsg(LOG_DEBUG, "Add sockets to select group\n");
1318  for(i=0;i<nSocketsIn;i++)
1319  {
1320  psocketgroupAccept->add(*socketsIn[i]);
1321  }
1322 #ifdef REPLAY_DETECTION //before we can start to accept users we have to ensure that we received the replay timestamps form the over mixes
1323  CAMsg::printMsg(LOG_DEBUG,"Waiting for Replay Timestamp from next mixes\n");
1324  i=0;
1325  while(!pFirstMix->m_bRestart && i < pFirstMix->m_u32MixCount-1)
1326  {
1327  if(pFirstMix->m_arMixParameters[i].m_u32ReplayOffset==0)//not set yet
1328  {
1329  msSleep(100);//wait a little bit and try again
1330  continue;
1331  }
1332  i++;
1333  }
1334  CAMsg::printMsg(LOG_DEBUG,"All Replay Timestamp received\n");
1335 #endif
1336  CAMsg::printMsg(LOG_DEBUG, "Start accept users inner loop\n");
1337 
1338  while(!pFirstMix->m_bRestart)
1339  {
1340  if (pIPBlockList->count()>40)
1341  {
1342  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);
1343  for(i=0;i<nSocketsIn;i++)
1344  {
1345  psocketgroupAccept->remove(*socketsIn[i]);
1346  while (socketsIn[i]->close() != E_SUCCESS)
1347  {
1348  sSleep(1);
1349  }
1350  }
1351 
1352  if (CALibProxytest::getOptions()->createSockets(false,pFirstMix-> m_arrSocketsIn, pFirstMix->m_nSocketsIn) != E_SUCCESS)
1353  {
1354  // could not listen
1355  goto END_THREAD;
1356  }
1357  for(i=0;i<nSocketsIn;i++)
1358  {
1359  psocketgroupAccept->add(*socketsIn[i]);
1360  }
1361  sSleep(1);
1362  }
1363 #ifdef __BUILD_AS_SHADOW_PLUGIN__
1364  CAMsg::printMsg(LOG_DEBUG, "Before acceptusers->select()\n");
1365  countRead=psocketgroupAccept->select();
1366  CAMsg::printMsg(LOG_DEBUG, "after acceptusers->select()\n");
1367 #else
1368  countRead = psocketgroupAccept->select(10000);
1369 #endif
1370  if(countRead<0)
1371  { //check for Error - are we restarting ?
1372  if(pFirstMix->m_bRestart ||countRead!=E_TIMEDOUT)
1373  goto END_THREAD;
1374  }
1375  i=0;
1376 #ifdef _DEBUG
1377  CAMsg::printMsg(LOG_DEBUG,"UserAcceptLoop: countRead=%i\n",countRead);
1378 #endif
1379  while(countRead>0&&i<nSocketsIn)
1380  {
1381  if(psocketgroupAccept->isSignaled(*socketsIn[i]))
1382  {
1383  countRead--;
1384  #ifdef _DEBUG
1385  CAMsg::printMsg(LOG_DEBUG,"New direct Connection from Client!\n");
1386  #endif
1387  #ifdef SYM_CHANNEL_CIPHER_CTR
1388  pNewMuxSocket=new CAMuxSocket(CTR);
1389  #elif defined NO_ENCRYPTION
1390  pNewMuxSocket = new CAMuxSocket(NULL_CIPHER);
1391 #else
1392  pNewMuxSocket=new CAMuxSocket(OFB);
1393  #endif
1394  ret=socketsIn[i]->accept(*(pNewMuxSocket->getCASocket()));
1395  pFirstMix->incNewConnections();
1396 
1397  if(ret!=E_SUCCESS)
1398  {
1399  // may return E_SOCKETCLOSED or E_SOCKET_LIMIT
1400  CAMsg::printMsg(LOG_ERR,"Accept Error %u - direct Connection from Client!\n",GET_NET_ERROR);
1401  }
1402  else if( (CALibProxytest::getOptions()->getMaxNrOfUsers() > 0 &&
1404  && (isAllowedToPassRestrictions(pNewMuxSocket->getCASocket()) != E_SUCCESS)
1405 
1406  )
1407  {
1408  CAMsg::printMsg(LOG_DEBUG,"CAFirstMix User control: Too many users (Maximum:%d)! Rejecting user...\n", pFirstMix->getNrOfUsers(),CALibProxytest::getOptions()->getMaxNrOfUsers());
1409  ret = E_UNKNOWN;
1410  }
1412  && (isAllowedToPassRestrictions(pNewMuxSocket->getCASocket()) != E_SUCCESS)
1413  )
1414 
1415  {
1416  /* This should protect the mix from flooding attacks
1417  * No more than MAX_CONCURRENT_NEW_CONNECTIONS are allowed.
1418  */
1419 #ifdef _DEBUG
1420  CAMsg::printMsg(LOG_DEBUG,"CAFirstMix Flooding protection: Too many concurrent new connections (Maximum:%d)! Rejecting user...\n", CAFirstMix::MAX_CONCURRENT_NEW_CONNECTIONS);
1421 #endif
1422  ret = E_UNKNOWN;
1423  }
1424 //#ifndef PAYMENT
1425  else if ((ret = pNewMuxSocket->getCASocket()->getPeerIP(peerIP)) != E_SUCCESS ||
1426  (retPeerIP = pIPList->insertIP(peerIP)) < 0)
1427  // || (pIPBlockList->checkIP(peerIP) == E_UNKNOWN && isAllowedToPassRestrictions(pNewMuxSocket->getCASocket()) != E_SUCCESS))
1428  {
1429  if (ret != E_SUCCESS)
1430  {
1431  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());
1432 
1433  }
1434  else if (retPeerIP < 0)
1435  {
1436  CAMsg::printMsg(LOG_DEBUG,"CAFirstMix Flooding protection: Could not insert IP address! We have %d login threads currently running.\n", pthreadsLogin->countRequests());
1437  pIPBlockList->insertIP(peerIP);
1438  }
1439  else if (pIPBlockList->checkIP(peerIP) == E_UNKNOWN)
1440  {
1441  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);
1442  pIPList->removeIP(peerIP);
1443  }
1444  ret = E_UNKNOWN;
1445  }
1446 //#endif
1447  else
1448  {
1450  d->pNewUser=pNewMuxSocket;
1451  d->pMix=pFirstMix;
1452  memcpy(d->peerIP,peerIP,4);
1453 #ifdef DEBUG
1454  CAMsg::printMsg(LOG_DEBUG,"%d concurrent client connections.\n", pFirstMix->m_newConnections);
1455 #endif
1456  if(pthreadsLogin->addRequest(fm_loopDoUserLogin,d)!=E_SUCCESS)
1457  {
1458  CAMsg::printMsg(LOG_ERR,"Could not add an login request to the login thread pool!\n");
1459  ret=E_UNKNOWN;
1460  }
1461  }
1462 
1463  if (ret != E_SUCCESS)
1464  {
1465  delete pNewMuxSocket;
1466  pNewMuxSocket = NULL;
1467  pFirstMix->decNewConnections();
1468  if(ret==E_SOCKETCLOSED&&pFirstMix->m_bRestart) //Hm, should we restart ??
1469  {
1470  goto END_THREAD;
1471  }
1472  else //if(ret==E_SOCKET_LIMIT) // Hm no free sockets - wait some time to hope to get a free one...
1473  {
1474  msSleep(400);
1475  }
1476  }
1477  }
1478  i++;
1479  }
1480  }
1481 END_THREAD:
1482  FINISH_STACK("CAFirstMix::fm_loopAcceptUsers");
1483 
1484  delete[] peerIP;
1485  peerIP = NULL;
1486  delete psocketgroupAccept;
1487  psocketgroupAccept = NULL;
1488 
1489  CAMsg::printMsg(LOG_DEBUG,"Exiting Thread AcceptUser\n");
1491  }
1492 
1493 
1495  {
1496  CAFirstMix* pFirstMix=(CAFirstMix*)param;
1497  pFirstMix->m_bRunLog=true;
1498  UINT32 countLog=0;
1499  while(pFirstMix->m_bRunLog)
1500  {
1501  if(countLog==0)
1502  {
1503  logMemoryUsage();
1504  countLog=10;
1505  }
1506  sSleep(30);
1507  countLog--;
1508  }
1510  }
1511 
1512 #ifdef CH_LOG_STUDY
1513 THREAD_RETURN fm_loopLogChannelsOpened(void* param)
1514  {
1515  CAFirstMix* pFirstMix=(CAFirstMix*)param;
1516  pFirstMix->m_bRunLog=true;
1517  UINT32 countLog= 10;
1518  UINT32 value = 0;
1519  UINT32 total = 0;
1520  time_t newIvalTS = 0, ival = 0;
1521 
1522  pFirstMix->nrOfChOpMutex->lock();
1523  pFirstMix->lastLogTime = time(NULL);
1524  pFirstMix->nrOfChOpMutex->unlock();
1525 
1526  while(pFirstMix->m_bRunLog)
1527  {
1528  if(countLog == 0)
1529  {
1530  pFirstMix->nrOfChOpMutex->lock();
1531  value = pFirstMix->nrOfOpenedChannels;
1532  total = pFirstMix->currentOpenedChannels;
1533  pFirstMix->nrOfOpenedChannels = 0;
1534  newIvalTS = time(NULL);
1535  ival = newIvalTS - pFirstMix->lastLogTime;
1536  pFirstMix->lastLogTime = newIvalTS;
1537  pFirstMix->nrOfChOpMutex->unlock();
1538  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",
1539  value, ival, total, pFirstMix->getNrOfUsers() );
1540  countLog = 10;
1541  }
1542  sSleep(1);
1543  countLog--;
1544  }
1546  }
1547 #endif //CH_LOG_STUDY
1548 
1550  {
1551  INIT_STACK;
1552  BEGIN_STACK("CAFirstMix::fm_loopDoUserLogin");
1553 #ifdef COUNTRY_STATS
1554  my_thread_init();
1555 #endif
1556 
1557  t_UserLoginData* d=(t_UserLoginData*)param;
1558  d->pMix->doUserLogin(d->pNewUser,d->peerIP);
1559 
1560  SAVE_STACK("CAFirstMix::fm_loopDoUserLogin", "after user login");
1561  d->pMix->decNewConnections();
1562  delete d;
1563  d = NULL;
1564 
1565 #ifdef COUNTRY_STATS
1566  my_thread_end();
1567 #endif
1568  FINISH_STACK("CAFirstMix::fm_loopDoUserLogin");
1569 
1571  }
1572 
1574 {
1577 
1578  const XMLCh* reqName = request->getDocumentElement()->getTagName();
1579 
1580  //Client requests lacking T&C resources.
1581  if(XMLString::equals(reqName, TNC_REQUEST))
1582  {
1583  answer->result = TC_UNFINISHED;
1584  CAMsg::printMsg(LOG_DEBUG,"Handling TC request.\n");
1585  XERCES_CPP_NAMESPACE::DOMDocument *response = createDOMDocument();
1586  DOMElement *responseRoot = createDOMElement(response, TNC_RESPONSE);
1587  response->appendChild(responseRoot);
1588  //All elements with tag name 'Resources' (direct children of 'TermsAndConditionsRequest')
1589  DOMNodeList *requestedResources = getElementsByTagName(request->getDocumentElement(), TNC_RESOURCES);
1590  //All elements with tag name 'Translation' (direct children of 'Resources')
1591  DOMNodeList *requestedResourceItems = NULL;
1592 
1593  DOMNode *currentNode = NULL;
1594  DOMNode *currentAnswerNode = NULL;
1595  DOMNode *currentAnswerResourceNode = NULL;
1596 
1597  UINT32 idLen = TMP_BUFF_SIZE;
1598  UINT8 id[TMP_BUFF_SIZE];
1599  memset(id, 0, idLen);
1600 
1601  UINT32 localeLen = TMP_LOCALE_SIZE;
1602  UINT8 locale[TMP_LOCALE_SIZE];
1603  memset(locale, 0, localeLen);
1604 
1605  bool resourceError = false;
1606 
1607  if(requestedResources->getLength() == 0)
1608  {
1609  response->release();
1610  response = createDOMDocument();
1611  response->appendChild(createDOMElement(response, TNC_RESPONSE_INVALID_REQUEST));
1612  answer->result = TC_FAILED;
1613  }
1614 
1615  for (XMLSize_t i = 0; i < requestedResources->getLength(); i++)
1616  {
1617  idLen = TMP_BUFF_SIZE;
1618  localeLen = TMP_LOCALE_SIZE;
1619  bool validResource = false;
1620 
1621  currentNode = requestedResources->item(i);
1622  //check validity of the T&C resource request. attributes "id" and locale must be proper set.
1623  if( (getDOMElementAttribute(currentNode, OPTIONS_ATTRIBUTE_TNC_ID, id, &idLen) != E_SUCCESS) ||
1624  (strlen((char *)id) < 1) )
1625  {
1626  CAMsg::printMsg(LOG_DEBUG,"Error: invalid id.\n");
1627  resourceError = true;
1628  }
1629 
1630  if(!currentNode->hasChildNodes())
1631  {
1632  //Empty Resource node is invalid!
1633  CAMsg::printMsg(LOG_DEBUG,"Error: No children.\n");
1634  resourceError = true;
1635  }
1636 
1637  if(!resourceError)
1638  {
1639 
1640  TermsAndConditions *requestedTnC = getTermsAndConditions(id);
1641  if(requestedTnC != NULL)
1642  {
1643  requestedResourceItems = getElementsByTagName((DOMElement *)currentNode, TNC_REQ_TRANSLATION);
1644  for(XMLSize_t j = 0; j < requestedResourceItems->getLength(); j++)
1645  {
1646  validResource = false;
1647  localeLen = TMP_LOCALE_SIZE;
1648  if( (getDOMElementAttribute(requestedResourceItems->item(j),
1650  locale, &localeLen) != E_SUCCESS) ||
1651  (strlen((char *)locale) != ((TMP_LOCALE_SIZE) - 1) ) )
1652  {
1653  CAMsg::printMsg(LOG_DEBUG,"Error: Invalid locale for tnc %s\n", id);
1654  break;
1655  }
1656 
1657  const termsAndConditionsTranslation_t *requestedTranslation =
1658  requestedTnC->getTranslation(locale);
1659  //NOTE: No need to lock while working with the TC translation
1660  //because the translation containers are only modified during
1661  //inter-mix-keyexchange and cleanup.
1662  //Both must never run concurrently to this method
1663  if(requestedTranslation != NULL)
1664  {
1665 
1666  currentAnswerNode = response->importNode(currentNode, false);
1667  responseRoot->appendChild(currentAnswerNode);
1668  if( getDOMChildByName(requestedResourceItems->item(j), TNC_RESOURCE_TEMPLATE,
1669  currentAnswerResourceNode, false) == E_SUCCESS)
1670  {
1671  currentAnswerResourceNode = response->importNode(currentAnswerResourceNode, true);
1672  currentAnswerResourceNode->appendChild(
1673  response->importNode(requestedTranslation->tnc_template, true));
1674  currentAnswerNode->appendChild(currentAnswerResourceNode);
1675  validResource = true;
1676  }
1677 
1678  if( getDOMChildByName(requestedResourceItems->item(j), TNC_RESOURCE_CUSTOMIZED_SECT,
1679  currentAnswerResourceNode, false) == E_SUCCESS)
1680  {
1681  currentAnswerResourceNode = response->importNode(currentAnswerResourceNode, true);
1682  currentAnswerResourceNode->appendChild(
1683  response->importNode(requestedTranslation->tnc_customized, true));
1684  currentAnswerNode->appendChild(currentAnswerResourceNode);
1685  validResource = true;
1686  }
1687  }
1688  else
1689  {
1690  CAMsg::printMsg(LOG_DEBUG,"Error: no translation def found.\n");
1691  break;
1692  }
1693  }
1694  }
1695  else
1696  {
1697  CAMsg::printMsg(LOG_DEBUG,"Error: no tc def found.\n");
1698  }
1699  }
1700 
1701  if(!validResource)
1702  {
1703  //only a manipulated client sends an invalid T&C resource request.
1704  //Manipulation is interpreted as a rejection of the terms & conditions,
1705  //so abort login immediately.
1706  response->release();
1707  response = createDOMDocument();
1708  response->appendChild(createDOMElement(response, TNC_RESPONSE_INVALID_REQUEST));
1709  answer->result = TC_FAILED;
1710  break;
1711  }
1712  }
1713  answer->xmlAnswer = response;
1714  }
1715  //Client accepts/rejects the T&Cs.
1716  else if(XMLString::equals(reqName, TNC_CONFIRM))
1717  {
1718  CAMsg::printMsg(LOG_DEBUG,"handling TC confirm.\n");
1719  bool tcAccepted = false;
1720  getDOMElementAttribute(request->getDocumentElement(), "accepted", tcAccepted);
1721  CAMsg::printMsg(LOG_DEBUG,"Client has%s accepted the T&Cs.\n", (tcAccepted ? "" : " not") );
1722 
1723  answer->xmlAnswer = NULL;
1724  answer->result = tcAccepted ? TC_CONFIRMED : TC_FAILED;
1725  }
1726  //stops the message exchange (if client needs time for showing the T & Cs, etc.)
1727  else if(XMLString::equals(reqName, TNC_INTERRUPT))
1728  {
1729  CAMsg::printMsg(LOG_DEBUG,"client requested interrupting the tc login.\n");
1730  answer->xmlAnswer = NULL;
1731  answer->result = TC_FAILED;
1732  }
1733  //Client sends an invalid message
1734  else
1735  {
1736  answer->xmlAnswer = NULL; //TODO: set errorMessage here
1737  answer->result = TC_FAILED;
1738  }
1739  return answer;
1740 }
1741 
1743 {
1744  INIT_STACK;
1746  FINISH_STACK("CAFirstMix::doUserLogin");
1747  return ret;
1748 }
1749 
1756  {
1757  SINT32 ret;
1758 
1759  INIT_STACK;
1760  BEGIN_STACK("CAFirstMix::doUserLogin");
1761 
1762 #ifdef __BUILD_AS_SHADOW_PLUGIN__ //the shadow simulator seems to love non-blocking I/O...
1764 #endif
1765 
1766  ret=pNewUser->getCASocket()->setKeepAlive(true);
1767  if(ret!=E_SUCCESS)
1768  CAMsg::printMsg(LOG_DEBUG,"Error setting KeepAlive for user login connection!");
1769 
1770  #ifdef DEBUG
1771  CAMsg::printMsg(LOG_DEBUG,"User login: start\n");
1772  #endif
1773 
1774  SAVE_STACK("CAFirstMix::doUserLogin", "after setting keep alive");
1775 
1776  // send the mix-keys to JAP
1778  {
1779  if (ret != E_UNKNOWN)
1780  {
1781  CAMsg::printMsg(LOG_DEBUG,"User login: Sending login data to client %u.%u.x.x has been interrupted! Reason: '%s' (%i)\n",
1783  }
1784  else
1785  {
1786  CAMsg::printMsg(LOG_DEBUG,"User login: Sending login data to client %u.%u.x.x has been interrupted!\n", peerIP[0],peerIP[1]);
1787  }
1788 
1790 
1791  delete pNewUser;
1792  pNewUser = NULL;
1794  return E_UNKNOWN;
1795  }
1796  #ifdef DEBUG
1797  CAMsg::printMsg(LOG_DEBUG,"User login: login data sent\n");
1798  #endif
1799  SAVE_STACK("CAFirstMix::doUserLogin", "after sending login data");
1800 
1801  //(pNewUser)->send(m_xmlKeyInfoBuff,m_xmlKeyInfoSize);
1802  // es kann nicht blockieren unter der Annahme das der TCP-Sendbuffer > m_xmlKeyInfoSize ist....
1803 
1804  //wait for keys from user
1805  UINT16 xml_len=0;
1806  if(pNewUser->getCASocket()->isClosed())
1807  {
1808  CAMsg::printMsg(LOG_DEBUG,"User login: Socket was closed while waiting for first symmetric key from client!\n");
1809  }
1811  {
1812  if (ret != E_UNKNOWN)
1813  {
1814  CAMsg::printMsg(LOG_DEBUG,"User login: Waiting for first symmetric key from client %u.%u.x.x! failed for reason: '%s' (%i)\n",
1816  }
1817  else
1818  {
1819  CAMsg::printMsg(LOG_DEBUG,"User login: Waiting for first symmetric key from client %u.%u.x.x! failed.\n",
1820  peerIP[0], peerIP[1]);
1821  }
1823 
1824  delete pNewUser;
1825  pNewUser = NULL;
1827  return E_UNKNOWN;
1828  }
1829  #ifdef DEBUG
1830  CAMsg::printMsg(LOG_DEBUG,"User login: received first symmetric key from client\n");
1831  #endif
1832  SAVE_STACK("CAFirstMix::doUserLogin", "received first symmetric key");
1833 
1834  xml_len=ntohs(xml_len);
1835  UINT8* xml_buff=new UINT8[xml_len+2]; //+2 for size...
1836  if(pNewUser->getCASocket()->isClosed() ||
1838  {
1839  if (pNewUser->getCASocket()->isClosed())
1840  {
1842  }
1843 
1844 
1845  if (ret != E_UNKNOWN)
1846  {
1847  CAMsg::printMsg(LOG_DEBUG,"User login: Waiting for second symmetric key from client failed for reason: '%s' (%i)\n",
1849  }
1850  else
1851  {
1852  CAMsg::printMsg(LOG_DEBUG,"User login: Waiting for second symmetric key from client failed.\n");
1853  }
1854 
1856 
1857  delete pNewUser;
1858  pNewUser = NULL;
1859  delete[] xml_buff;
1860  xml_buff = NULL;
1862  return E_UNKNOWN;
1863  }
1864 
1865  #ifdef DEBUG
1866  CAMsg::printMsg(LOG_DEBUG,"User login: received second symmetric key from client\n");
1867  #endif
1868  SAVE_STACK("CAFirstMix::doUserLogin", "received second symmetric key");
1869 
1870  XERCES_CPP_NAMESPACE::DOMDocument* doc=parseDOMDocument(xml_buff+2,xml_len);
1871  DOMElement* elemRoot=NULL;
1872  if(doc==NULL||(elemRoot=doc->getDocumentElement())==NULL||
1873  decryptXMLElement(elemRoot,m_pRSA)!=E_SUCCESS)
1874  {
1875  delete[] xml_buff;
1876  xml_buff = NULL;
1877  delete pNewUser;
1878  pNewUser = NULL;
1880  if(doc!=NULL)
1881  {
1882  doc->release();
1883  doc = NULL;
1884  }
1885  return E_UNKNOWN;
1886  }
1887  elemRoot=doc->getDocumentElement();
1888  if(!equals(elemRoot->getNodeName(),"JAPKeyExchange"))
1889  {
1890  if (doc != NULL)
1891  {
1892  doc->release();
1893  doc = NULL;
1894  }
1895  delete[] xml_buff;
1896  xml_buff = NULL;
1897  delete pNewUser;
1898  pNewUser = NULL;
1900  return E_UNKNOWN;
1901  }
1902  DOMElement* elemLinkEnc=NULL;
1903  DOMElement* elemMixEnc=NULL;
1904  getDOMChildByName(elemRoot,"LinkEncryption",elemLinkEnc,false);
1905  getDOMChildByName(elemRoot,"MixEncryption",elemMixEnc,false);
1906  UINT8 linkKey[255],mixKey[255];
1907  UINT32 linkKeyLen=255,mixKeyLen=255;
1908  if( getDOMElementValue(elemLinkEnc,linkKey,&linkKeyLen)!=E_SUCCESS||
1909  getDOMElementValue(elemMixEnc,mixKey,&mixKeyLen)!=E_SUCCESS||
1910  CABase64::decode(linkKey,linkKeyLen,linkKey,&linkKeyLen)!=E_SUCCESS||
1911  CABase64::decode(mixKey,mixKeyLen,mixKey,&mixKeyLen)!=E_SUCCESS||
1912  linkKeyLen!=64||mixKeyLen!=32)
1913  {
1914  if (doc != NULL)
1915  {
1916  doc->release();
1917  doc = NULL;
1918  }
1919  delete[] xml_buff;
1920  xml_buff = NULL;
1921  delete pNewUser;
1922  pNewUser = NULL;
1924  return E_UNKNOWN;
1925  }
1926  //Check access control credential if access control is enabled...
1927  if (CALibProxytest::getOptions()->isAccessControlEnabled())
1928  {
1929  DOMElement* elemCredential = NULL;
1930  UINT8 buffUserCredential[255], buffMixCredential[255];
1931  UINT32 lenUserCredential = 255, lenMixCredential = 255;
1932  getDOMChildByName(elemRoot, "AccessControlCredential", elemCredential, false);
1933  if(getDOMElementValue(elemCredential, buffUserCredential, &lenUserCredential)!=E_SUCCESS ||
1934  CALibProxytest::getOptions()->getAccessControlCredential(buffMixCredential, &lenMixCredential)!=E_SUCCESS ||
1935  lenUserCredential!= lenMixCredential ||
1936  memcmp(buffMixCredential, buffUserCredential, lenMixCredential)!=0)
1937  {
1938  if (doc != NULL)
1939  {
1940  doc->release();
1941  doc = NULL;
1942  }
1943  delete[] xml_buff;
1944  xml_buff = NULL;
1945  delete pNewUser;
1946  pNewUser = NULL;
1948  return E_UNKNOWN;
1949  }
1950  }
1951 
1952 
1953  //Getting control channel keys if available
1955  DOMElement* elemControlChannelEnc=NULL;
1956  getDOMChildByName(elemRoot,"ControlChannelEncryption",elemControlChannelEnc,false);
1957  UINT8 controlchannelKey[255];
1958  UINT32 controlchannelKeyLen=255;
1959  UINT8* controlchannelRecvKey=NULL;
1960  UINT8* controlchannelSentKey=NULL;
1961  if( getDOMElementValue(elemControlChannelEnc,controlchannelKey,&controlchannelKeyLen)==E_SUCCESS&&
1962  CABase64::decode(controlchannelKey,controlchannelKeyLen,controlchannelKey,&controlchannelKeyLen)==E_SUCCESS&&
1963  controlchannelKeyLen==32)
1964  {
1965  controlchannelRecvKey=controlchannelKey;
1966  controlchannelSentKey=controlchannelKey+16;
1967  }
1968 
1969  //Sending Signature....
1970  xml_buff[0]=(UINT8)(xml_len>>8);
1971  xml_buff[1]=(UINT8)(xml_len&0xFF);
1972  UINT8* sig=new UINT8[255];
1973  UINT32 siglen=255;
1974  //TODO change me to fully support MultiSig
1975  //m_pSignature->sign(xml_buff,xml_len+2,sig,&siglen);
1976  m_pMultiSignature->sign(xml_buff,xml_len+2,sig,&siglen);
1977  XERCES_CPP_NAMESPACE::DOMDocument* docSig=createDOMDocument();
1978 
1979  DOMElement *elemSig=NULL;
1980 
1981 #ifdef LOG_DIALOG
1982  DOMElement* elemDialog=NULL;
1983  getDOMChildByName(elemRoot,"Dialog",elemDialog,false);
1984  UINT8 strDialog[255];
1985  memset(strDialog,0,255);
1986  UINT32 dialogLen=255;
1987  getDOMElementValue(elemDialog,strDialog,&dialogLen);
1988 #endif
1989 #ifdef REPLAY_DETECTION
1990  //checking if Replay-Detection is enabled
1991  DOMElement *elemReplay=NULL;
1992  UINT8 replay[6];
1993  UINT32 replay_len=5;
1994  if( (getDOMChildByName(elemRoot,"ReplayDetection",elemReplay,false)==E_SUCCESS)&&
1995  (getDOMElementValue(elemReplay,replay,&replay_len)==E_SUCCESS)&&
1996  (strncmp((char*)replay,"true",5)==0)){
1997  elemRoot=createDOMElement(docSig,"MixExchange");
1998  elemReplay=createDOMElement(docSig,"Replay");
1999  docSig->appendChild(elemRoot);
2000  elemRoot->appendChild(elemReplay);
2001 
2002  UINT32 diff=(UINT32)(time(NULL)-m_u64LastTimestampReceived);
2003  for(SINT32 i=0;i<getMixCount()-1;i++)
2004  {
2005  DOMElement* elemMix=createDOMElement(docSig,"Mix");
2006  setDOMElementAttribute(elemMix,"id",m_arMixParameters[i].m_strMixID);
2007  DOMElement* elemReplayOffset=createDOMElement(docSig,"ReplayOffset");
2008  setDOMElementValue(elemReplayOffset,(UINT32) (m_arMixParameters[i].m_u32ReplayOffset+diff));
2009  elemMix->appendChild(elemReplayOffset);
2010  DOMElement* elemReplayBase=createDOMElement(docSig,"ReplayBase");
2011  setDOMElementValue(elemReplayBase,(UINT32) (m_arMixParameters[i].m_u32ReplayBase));
2012  elemMix->appendChild(elemReplayBase);
2013  elemReplay->appendChild(elemMix);
2014  }
2015 
2016  DOMElement* elemMix=createDOMElement(docSig,"Mix");
2017  UINT8 buff[255];
2018  CALibProxytest::getOptions()->getMixId(buff,255);
2019  setDOMElementAttribute(elemMix,"id",buff);
2020  DOMElement* elemReplayOffset=createDOMElement(docSig,"ReplayOffset");
2021  setDOMElementValue(elemReplayOffset,(UINT32) (time(NULL)-m_u64ReferenceTime));
2022  elemMix->appendChild(elemReplayOffset);
2023  DOMElement* elemReplayBase=createDOMElement(docSig,"ReplayBase");
2024  setDOMElementValue(elemReplayBase,(UINT32) (REPLAY_BASE));
2025  elemMix->appendChild(elemReplayOffset);
2026  elemReplay->appendChild(elemMix);
2027 
2028  elemSig=createDOMElement(docSig,"Signature");
2029  elemRoot->appendChild(elemSig);
2030 
2031  CAMsg::printMsg(LOG_DEBUG,"Replay Detection requested\n");
2032  }
2033  else {
2034  elemSig=createDOMElement(docSig,"Signature");
2035  docSig->appendChild(elemSig);
2036  }
2037 #endif
2038 #ifndef REPLAY_DETECTION
2039  elemSig=createDOMElement(docSig,"Signature");
2040  docSig->appendChild(elemSig);
2041 #endif
2042  DOMElement* elemSigValue=createDOMElement(docSig,"SignatureValue");
2043  elemSig->appendChild(elemSigValue);
2044  UINT32 u32=siglen;
2045  CABase64::encode(sig,u32,sig,&siglen);
2046  sig[siglen]=0;
2047  setDOMElementValue(elemSigValue,sig);
2048  delete[] sig;
2049  u32=xml_len;
2050  DOM_Output::dumpToMem(docSig,xml_buff+2,&u32);
2051  if (docSig != NULL)
2052  {
2053  docSig->release();
2054  docSig = NULL;
2055  }
2056  xml_buff[0]=(UINT8)(u32>>8);
2057  xml_buff[1]=(UINT8)(u32&0xFF);
2058 
2059  if (pNewUser->getCASocket()->isClosed() ||
2060  pNewUser->getCASocket()->sendFullyTimeOut(xml_buff,u32+2, 30000, 10000) != E_SUCCESS)
2061  {
2062  if (doc != NULL)
2063  {
2064  doc->release();
2065  doc = NULL;
2066  }
2067  CAMsg::printMsg(LOG_DEBUG,"User login: Sending key exchange signature has been interrupted!\n");
2069 
2070  delete[] xml_buff;
2071  xml_buff = NULL;
2072  delete pNewUser;
2073  pNewUser = NULL;
2075  return E_UNKNOWN;
2076  }
2077  #ifdef DEBUG
2078  CAMsg::printMsg(LOG_DEBUG,"User login: key exchange signature sent\n");
2079  #endif
2080  delete[] xml_buff;
2081  xml_buff = NULL;
2082 #if 0 //terms and conditions sending disabled.
2083  /* handle Terms And Conditions */
2084  bool loginFailed = false;
2085  bool tcProcedureFinished = false;
2086 
2087  while( !(tcProcedureFinished || loginFailed) )
2088  {
2089  UINT16 tcRequestDataLen = 0;
2090  if (pNewUser->getCASocket()->isClosed() ||
2091  (ret = pNewUser->getCASocket()->receiveFullyT((UINT8*)&tcRequestDataLen, 2, 10000)) != E_SUCCESS)
2092  {
2093  if (pNewUser->getCASocket()->isClosed())
2094  {
2096  }
2097 
2098  loginFailed = true;
2099  if (ret != E_UNKNOWN)
2100  {
2101  CAMsg::printMsg(LOG_ERR,"User login: Receiving t&c protocol data size has been interrupted. Reason: '%s' (%i)\n",
2103  }
2104  else
2105  {
2106  CAMsg::printMsg(LOG_ERR,"User login: Receiving t&c protocol data size has been interrupted.\n");
2107  }
2108  break;
2109  }
2110 
2111  tcRequestDataLen = ntohs(tcRequestDataLen);
2112  //CAMsg::printMsg(LOG_DEBUG,"User login: expecting %u bytes!\n", tcRequestDataLen);
2113  UINT8 tcDataBuf[tcRequestDataLen+1];
2114  tcDataBuf[tcRequestDataLen] = 0;
2115  if (pNewUser->getCASocket()->isClosed() ||
2116  (ret = pNewUser->getCASocket()->receiveFullyT(tcDataBuf, tcRequestDataLen, 10000)) != E_SUCCESS)
2117  {
2118  if (pNewUser->getCASocket()->isClosed())
2119  {
2121  }
2122 
2123  loginFailed = true;
2124 
2125  if (ret != E_UNKNOWN)
2126  {
2127  CAMsg::printMsg(LOG_ERR,"User login: Receiving t&c protocol data has been interrupted. Reason: '%s' (%i)\n",
2129  }
2130  else
2131  {
2132  CAMsg::printMsg(LOG_ERR,"User login: Receiving t&c protocol data has been interrupted.\n");
2133  }
2134  break;
2135  }
2136 
2137  XERCES_CPP_NAMESPACE::DOMDocument *tcData = parseDOMDocument(tcDataBuf, tcRequestDataLen);
2138  if( (tcData == NULL) || (tcData->getDocumentElement() == NULL) )
2139  {
2140  CAMsg::printMsg(LOG_ERR,"Could not parse t&c data!\n");
2141  loginFailed = true;
2142  break;
2143  }
2144 
2146  if(answer == NULL)
2147  {
2148  loginFailed = true;
2149  tcData->release();
2150  tcData = NULL;
2151  break;
2152  }
2153 
2154  if( (answer->xmlAnswer != NULL) )
2155  {
2156  UINT32 size = 0;
2157  UINT8 *answerBuff = DOM_Output::dumpToMem(answer->xmlAnswer, &size);
2158  if(answerBuff != NULL)
2159  {
2160  //CAMsg::printMsg(LOG_DEBUG,"User login: answer %s\n", answerBuff);
2161 
2162  UINT32 netSize = htonl(size);
2163 
2164  if (pNewUser->getCASocket()->isClosed() ||
2165  pNewUser->getCASocket()->sendFullyTimeOut((UINT8 *) &netSize, 4, 30000, 10000) != E_SUCCESS)
2166  {
2167  CAMsg::printMsg(LOG_DEBUG,"User login: sending t&c protocol data size has been interrupted!\n");
2168  loginFailed = true;
2169  }
2170  else if (pNewUser->getCASocket()->isClosed() ||
2171  pNewUser->getCASocket()->sendFullyTimeOut(answerBuff, size, 30000, 10000) != E_SUCCESS)
2172  {
2173  CAMsg::printMsg(LOG_DEBUG,"User login: Sending t&c protocol data has been interrupted!\n");
2174  loginFailed = true;
2175  }
2176  delete [] answerBuff;
2177  }
2178  }
2179  tcProcedureFinished = (answer->result != TC_UNFINISHED);
2180  loginFailed = (answer->result == TC_FAILED);
2181  cleanupTnCMixAnswer(answer);
2182  delete answer;
2183  answer = NULL;
2184  tcData->release();
2185  tcData = NULL;
2186  }
2187 
2188  //Only if a positive confirm message was received, the client may pass!
2189 
2190  if(loginFailed)
2191  {
2192  if (doc != NULL)
2193  {
2194  doc->release();
2195  doc = NULL;
2196  }
2197  CAMsg::printMsg(LOG_DEBUG,"User login: failed!\n");
2198  delete[] xml_buff;
2199  xml_buff = NULL;
2200  delete pNewUser;
2201  pNewUser = NULL;
2203  return E_UNKNOWN;
2204  }
2205  /* end Terms And Conditions negotiation */
2206 #endif
2207  SAVE_STACK("CAFirstMix::doUserLogin", "sent key exchange signature");
2208 
2210 
2211  SAVE_STACK("CAFirstMix::doUserLogin", "Creating CAQueue...");
2212  CAQueue* tmpQueue=new CAQueue(sizeof(tQueueEntry));
2213 
2214  SAVE_STACK("CAFirstMix::doUserLogin", "Adding user to connection list...");
2215 #ifdef LOG_DIALOG
2216  fmHashTableEntry* pHashEntry=m_pChannelList->add(pNewUser,peerIP,tmpQueue,strDialog);
2217 #else
2218 #ifndef MULTI_THREADED_PACKET_PROCESSING
2219  fmHashTableEntry* pHashEntry=m_pChannelList->add(pNewUser,peerIP,tmpQueue,controlchannelSentKey,controlchannelRecvKey);
2220 #else
2221  UINT32 threadID = pNewUser->getHashKey()%m_numThreads;
2222  CAFirstMixChannelList* pChannelList = m_arpChannelList[threadID];
2223  fmHashTableEntry* pHashEntry=pChannelList->add(pNewUser,peerIP,tmpQueue,controlchannelSentKey,controlchannelRecvKey);
2224 #endif
2225 #endif
2226  if( (pHashEntry == NULL) ||
2227  (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 ).
2228  {
2229  if (doc != NULL)
2230  {
2231  doc->release();
2232  doc = NULL;
2233  }
2234  CAMsg::printMsg(LOG_ERR,"User login: Could not add new socket to connection list!\n");
2235  if (pHashEntry != NULL)
2236  {
2237 #ifndef MULTI_THREADED_PACKET_PROCESSING
2239 #else
2240  pChannelList->remove(pNewUser);
2241 #endif
2242  }
2244  delete tmpQueue;
2245  tmpQueue = NULL;
2246  delete pNewUser;
2247  pNewUser = NULL;
2248  return E_UNKNOWN;
2249  }
2250 
2251  SAVE_STACK("CAFirstMix::doUserLogin", "socket added to connection list");
2252 #ifdef PAYMENT
2253  #ifdef DEBUG
2254  CAMsg::printMsg(LOG_DEBUG,"User login: registering payment control channel\n");
2255  #endif
2257  SAVE_STACK("CAFirstMix::doUserLogin", "payment registered");
2258 #endif
2259  pHashEntry->pSymCipher=CASymChannelCipherFactory::createCipher(CALibProxytest::getOptions()->getSymChannelCipherAlgorithm());
2260  pHashEntry->pSymCipher->setKey(mixKey);
2261  pHashEntry->pSymCipher->setIVs(mixKey+16);
2262  pNewUser->setReceiveKey(linkKey,32);
2263  pNewUser->setSendKey(linkKey+32,32);
2264  pNewUser->setCrypt(true);
2265 
2266  if (doc != NULL)
2267  {
2268  doc->release();
2269  doc = NULL;
2270  }
2271 #ifdef PAYMENT
2272 
2273  SAVE_STACK("CAFirstMix::doUserLogin", "Starting AI login procedure");
2274 #ifdef DEBUG
2275  CAMsg::printMsg(LOG_DEBUG,"Starting AI login procedure for owner %x \n", pHashEntry);
2276 #endif
2277  SINT32 ai_ret;
2278  MIXPACKET *paymentLoginPacket = new MIXPACKET;
2279  tQueueEntry *aiAnswerQueueEntry=new tQueueEntry;
2280  CAQueue *controlMessages = pHashEntry->pControlMessageQueue;
2281  UINT32 qlen=sizeof(tQueueEntry);
2282  SINT32 aiLoginStatus = 0;
2283  aiLoginStatus = CAAccountingInstance::loginProcessStatus(pHashEntry);
2284  while(aiLoginStatus & AUTH_LOGIN_NOT_FINISHED)
2285  {
2286  if(pNewUser->receive(paymentLoginPacket, AI_LOGIN_SO_TIMEOUT) != MIXPACKET_SIZE)
2287  {
2288  CAMsg::printMsg(LOG_INFO,"AI login: client receive timeout.\n");
2289  aiLoginStatus = AUTH_LOGIN_FAILED;
2290  break;
2291  }
2292  if(paymentLoginPacket->channel > 0 && paymentLoginPacket->channel < 256)
2293  {
2294  if(!pHashEntry->pControlChannelDispatcher->proccessMixPacket(paymentLoginPacket))
2295  {
2296  aiLoginStatus = AUTH_LOGIN_FAILED;
2297  break;
2298  }
2299 
2300  while(controlMessages->getSize()>0)
2301  {
2302  controlMessages->get((UINT8*)aiAnswerQueueEntry,&qlen);
2303  pNewUser->prepareForSend(&(aiAnswerQueueEntry->packet));
2304  ai_ret = pNewUser->getCASocket()->
2305  sendFullyTimeOut(((UINT8*)&(aiAnswerQueueEntry->packet)), MIXPACKET_SIZE, 3*(AI_LOGIN_SO_TIMEOUT), AI_LOGIN_SO_TIMEOUT);
2306  if (ai_ret != E_SUCCESS)
2307  {
2308  if(ai_ret == E_TIMEDOUT )
2309  {
2310  CAMsg::printMsg(LOG_INFO,"timeout occurred during AI login.");
2311  }
2312  aiLoginStatus = AUTH_LOGIN_FAILED;
2313  goto loop_break;
2314  }
2315  }
2316  if(aiLoginStatus == AUTH_LOGIN_FAILED)
2317  {
2318  break;
2319  }
2320  }
2321  aiLoginStatus = CAAccountingInstance::loginProcessStatus(pHashEntry);
2322  }
2323 loop_break:
2324  SAVE_STACK("CAFirstMix::doUserLogin", "AI login packages exchanged.");
2325  /* We have exchanged all AI login packets:
2326  * 1. AccountCert
2327  * 2. ChallengeResponse
2328  * 3. Cost confirmation.
2329  * Now start settlement to ensure that the clients account is balanced
2330  */
2331  if(!(aiLoginStatus & AUTH_LOGIN_FAILED))
2332  {
2333  if(!(aiLoginStatus & (AUTH_LOGIN_SKIP_SETTLEMENT )) || (aiLoginStatus & (AUTH_WAITING_FOR_FIRST_SETTLED_CC)) )
2334  {
2335 //#ifdef DEBUG
2336  CAMsg::printMsg(LOG_DEBUG,"AI login messages successfully exchanged: now starting settlement for user account balancing check\n");
2337 //#endif
2339  {
2340  aiLoginStatus |= AUTH_LOGIN_FAILED;
2341  }
2342  }
2343 //#ifdef DEBUG
2344  else
2345  {
2346  CAMsg::printMsg(LOG_DEBUG,"AI login messages successfully exchanged: skipping settlement, user has valid prepaid amount\n");
2347  }
2348 //#endif
2349  }
2350 
2351  if(!(aiLoginStatus & AUTH_LOGIN_FAILED))
2352  {
2353  aiLoginStatus = CAAccountingInstance::finishLoginProcess(pHashEntry);
2354  if(pNewUser != NULL)
2355  {
2356  while(controlMessages->getSize()>0)
2357  {
2358  controlMessages->get((UINT8*)aiAnswerQueueEntry,&qlen);
2359  pNewUser->prepareForSend(&(aiAnswerQueueEntry->packet));
2360 
2361  //not really elegant but works: if the client closed the socket during the settlement
2362  //the first send will succeed but the second one will fail.
2363  ai_ret = pNewUser->getCASocket()->
2364  sendFullyTimeOut(((UINT8*)&(aiAnswerQueueEntry->packet)), 499, 3*(AI_LOGIN_SO_TIMEOUT), AI_LOGIN_SO_TIMEOUT);
2365 
2366  ai_ret = pNewUser->getCASocket()->
2367  sendFullyTimeOut(((UINT8*)&(aiAnswerQueueEntry->packet)+499), 499, 3*(AI_LOGIN_SO_TIMEOUT), AI_LOGIN_SO_TIMEOUT);
2368  if (ai_ret != E_SUCCESS)
2369  {
2370  int errnum = errno;
2371  CAMsg::printMsg(LOG_INFO,"AI login: net error occured after settling: %s\n", strerror(errnum));
2372  aiLoginStatus |= AUTH_LOGIN_FAILED;
2373  break;
2374  }
2375  }
2376  }
2377  else
2378  {
2379  CAMsg::printMsg(LOG_DEBUG,"Socket was disposed.\n");
2380  aiLoginStatus |= AUTH_LOGIN_FAILED;
2381  }
2382  }
2383 
2384  delete paymentLoginPacket;
2385  paymentLoginPacket = NULL;
2386  delete aiAnswerQueueEntry;
2387  aiAnswerQueueEntry = NULL;
2388 
2389  SAVE_STACK("CAFirstMix::doUserLogin", "AI login procedure finished.");
2390 
2391  if((aiLoginStatus & AUTH_LOGIN_FAILED))
2392  {
2393 #ifdef DEBUG
2394  CAMsg::printMsg(LOG_INFO,"User AI login failed: deleting socket %x\n", pHashEntry);
2395 #endif
2398  delete pNewUser;
2399  pNewUser = NULL;
2401  return E_UNKNOWN;
2402  }
2403  /* Hot fix: push timeout entry only if login was succesful, otherwise
2404  * socket may be deleted due to timeout, login fails and the socket will be deleted
2405  * for second time causing a segfault.
2406  */
2407  m_pChannelList->pushTimeoutEntry(pHashEntry);
2408 
2409 
2410 #ifdef LOG_CRIME
2411  UINT64 accountNumber = CAAccountingInstance::unlockLogin(pHashEntry);
2412  UINT64* surveillanceAccounts = CALibProxytest::getOptions()->getCrimeSurveillanceAccounts();
2413  UINT32 nrOfSurveillanceAccounts = CALibProxytest::getOptions()->getNrOfCrimeSurveillanceAccounts();
2414 
2415  for (UINT32 iAccount = 0; iAccount < nrOfSurveillanceAccounts; iAccount++)
2416  {
2417  if (accountNumber == surveillanceAccounts[iAccount])
2418  {
2419  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]);
2420  break;
2421  }
2422  }
2423 #else
2425 #endif
2426 
2427 #ifdef DEBUG
2428  CAMsg::printMsg(LOG_INFO,"User AI login successful for owner %x\n", pHashEntry);
2429 #endif
2430 #endif
2431 
2432 #ifdef WITH_CONTROL_CHANNELS_TEST
2433  pHashEntry->pControlChannelDispatcher->registerControlChannel(new CAControlChannelTest());
2434 #endif
2435 #ifdef REPLAY_DETECTION
2437 #endif
2438 #ifdef COUNTRY_STATS
2439  incUsers(pHashEntry);
2440 #else
2441  incUsers();
2442 #endif
2443 #ifdef HAVE_EPOLL
2444 #ifndef MULTI_THREADED_PACKET_PROCESSING
2445  m_psocketgroupUsersRead->add(*pNewUser,m_pChannelList->get(pNewUser)); // add user socket to the established ones that we read data from.
2447 #else
2448  m_arpsocketgroupUsersRead[threadID]->add(*pNewUser,pChannelList->get(pNewUser)); // add user socket to the established ones that we read data from.
2449  m_arpsocketgroupUsersWrite[threadID]->add(*pNewUser,pChannelList->get(pNewUser));
2450 #endif
2451 #else //no E_POLL
2452 #ifndef MULTI_THREADED_PACKET_PROCESSING
2453  if(m_psocketgroupUsersRead->add(*pNewUser)!=E_SUCCESS)// add user socket to the established ones that we read data from.
2454  {
2455  CAMsg::printMsg(LOG_DEBUG,"User login: Adding to m_psocketgroupUsersRead failed!\n");
2456  }
2458  {
2459  CAMsg::printMsg(LOG_DEBUG,"User login: Adding to m_psocketgroupUsersWrite failed!\n");
2460  }
2461 #else
2462  if(m_arpsocketgroupUsersRead[threadID]->add(*pNewUser)!=E_SUCCESS)// add user socket to the established ones that we read data from.
2463  {
2464  CAMsg::printMsg(LOG_DEBUG,"User login: Adding to m_psocketgroupUsersRead failed!\n");
2465  }
2466  if( m_arpsocketgroupUsersWrite[threadID]->add(*pNewUser)!=E_SUCCESS)
2467  {
2468  CAMsg::printMsg(LOG_DEBUG,"User login: Adding to m_psocketgroupUsersWrite failed!\n");
2469  }
2470 #endif
2471 #endif
2472 
2473 #ifndef LOG_DIALOG
2474  CAMsg::printMsg(LOG_INFO,"User login: finished\n");
2475 #else
2476  CAMsg::printMsg(LOG_INFO,"User login: finished -- connection-ID: %Lu -- country-id: %u -- dialog: %s\n",pHashEntry->id,pHashEntry->countryID,pHashEntry->strDialog);
2477 #endif
2478  return E_SUCCESS;
2479  }
2480 
2481 #ifdef PAYMENT
2482 bool CAFirstMix::forceKickout(fmHashTableEntry* pHashTableEntry, const XERCES_CPP_NAMESPACE::DOMDocument *pErrDoc)
2483 {
2484  return m_pChannelList->forceKickout(pHashTableEntry, pErrDoc);
2485 }
2486 #endif
2487 //NEVER EVER DELETE THIS!
2488 /*
2489 THREAD_RETURN loopReadFromUsers(void* param)
2490  {
2491  CAFirstMix* pFirstMix=(CAFirstMix*)param;
2492  CAFirstMixChannelList* pChannelList=pFirstMix->m_pChannelList;
2493  CASocketGroup* psocketgroupUsersRead=pFirstMix->m_psocketgroupUsersRead;
2494  CASocketGroup* psocketgroupUsersWrite=pFirstMix->m_psocketgroupUsersWrite;
2495  CAQueue* pQueueSendToMix=pFirstMix->m_pQueueSendToMix;
2496 // CAInfoService* pInfoService=pFirstMix->m_pInfoService;
2497  CAASymCipher* pRSA=pFirstMix->m_pRSA;
2498  CAIPList* pIPList=pFirstMix->m_pIPList;
2499  CAMuxSocket* pNextMix=pFirstMix->m_pMuxOut;
2500 
2501  CAMuxSocket* pMuxSocket;
2502 
2503  SINT32 countRead;
2504  SINT32 ret;
2505  UINT8* ip=new UINT8[4];
2506  UINT8* tmpBuff=new UINT8[MIXPACKET_SIZE];
2507  MIXPACKET* pMixPacket=new MIXPACKET;
2508  UINT8* rsaBuff=new UINT8[RSA_SIZE];
2509 
2510  fmHashTableEntry* pHashEntry;
2511  fmChannelListEntry* pEntry;
2512  CASymCipher* pCipher=NULL;
2513 
2514  for(;;)
2515  {
2516  countRead=psocketgroupUsersRead->select(false,1000); //if we sleep here forever, we will not notice new sockets...
2517  if(countRead<0)
2518  { //check for error
2519  if(pFirstMix->m_bRestart ||countRead!=E_TIMEDOUT)
2520  goto END_THREAD;
2521  }
2522  pHashEntry=pChannelList->getFirst();
2523  while(pHashEntry!=NULL&&countRead>0)
2524  {
2525  pMuxSocket=pHashEntry->pMuxSocket;
2526  if(psocketgroupUsersRead->isSignaled(*pMuxSocket))
2527  {
2528  countRead--;
2529  ret=pMuxSocket->receive(pMixPacket,0);
2530  if(ret==SOCKET_ERROR)
2531  {
2532  pMuxSocket->getPeerIP(ip);
2533  pIPList->removeIP(ip);
2534  psocketgroupUsersRead->remove(pMuxSocket);
2535  psocketgroupUsersWrite->remove(pMuxSocket);
2536  pEntry=pChannelList->getFirstChannelForSocket(pMuxSocket);
2537  while(pEntry!=NULL)
2538  {
2539  pNextMix->close(pEntry->channelOut,tmpBuff);
2540  pQueueSendToMix->add(tmpBuff,MIXPACKET_SIZE);
2541  delete pEntry->pCipher;
2542  pEntry=pChannelList->getNextChannel(pEntry);
2543  }
2544  ASSERT(pHashEntry->pQueueSend!=NULL,"Send queue is NULL");
2545  delete pHashEntry->pQueueSend;
2546  pChannelList->remove(pMuxSocket);
2547  pMuxSocket->close();
2548  delete pMuxSocket;
2549  pFirstMix->decUsers();
2550  }
2551  else if(ret==MIXPACKET_SIZE)
2552  {
2553  if(pMixPacket->flags==CHANNEL_CLOSE)
2554  {
2555  pEntry=pChannelList->get(pMuxSocket,pMixPacket->channel);
2556  if(pEntry!=NULL)
2557  {
2558  pNextMix->close(pEntry->channelOut,tmpBuff);
2559  pQueueSendToMix->add(tmpBuff,MIXPACKET_SIZE);
2560  delete pEntry->pCipher;
2561  pChannelList->removeChannel(pMuxSocket,pMixPacket->channel);
2562  }
2563  else
2564  {
2565  #if defined(_DEBUG) && ! defined(__MIX_TEST)
2566  CAMsg::printMsg(LOG_DEBUG,"Invalid ID to close from Browser!\n");
2567  #endif
2568  }
2569  }
2570  else
2571  {
2572  pEntry=pChannelList->get(pMuxSocket,pMixPacket->channel);
2573  if(pEntry!=NULL&&pMixPacket->flags==CHANNEL_DATA)
2574  {
2575  pMixPacket->channel=pEntry->channelOut;
2576  pCipher=pEntry->pCipher;
2577  pCipher->decryptAES(pMixPacket->data,pMixPacket->data,DATA_SIZE);
2578  pNextMix->send(pMixPacket,tmpBuff);
2579  pQueueSendToMix->add(tmpBuff,MIXPACKET_SIZE);
2580  pFirstMix->incMixedPackets();
2581  }
2582  else if(pEntry==NULL&&(pMixPacket->flags==CHANNEL_OPEN_OLD||pMixPacket->flags==CHANNEL_OPEN_NEW))
2583  {
2584  pCipher= new CASymCipher();
2585  pRSA->decrypt(pMixPacket->data,rsaBuff);
2586  pCipher->setKeyAES(rsaBuff);
2587  pCipher->decryptAES(pMixPacket->data+RSA_SIZE,
2588  pMixPacket->data+RSA_SIZE-KEY_SIZE,
2589  DATA_SIZE-RSA_SIZE);
2590  memcpy(pMixPacket->data,rsaBuff+KEY_SIZE,RSA_SIZE-KEY_SIZE);
2591 
2592  if(pChannelList->addChannel(pMuxSocket,pMixPacket->channel,pCipher,&pMixPacket->channel)!=E_SUCCESS)
2593  {//todo --> maybe move up to not make decryption!!
2594  delete pCipher;
2595  }
2596  else
2597  {
2598  #if defined(_DEBUG) && !defined(__MIX_TEST)
2599  CAMsg::printMsg(LOG_DEBUG,"Added out channel: %u\n",pMixPacket->channel);
2600  #endif
2601  pNextMix->send(pMixPacket,tmpBuff);
2602  pQueueSendToMix->add(tmpBuff,MIXPACKET_SIZE);
2603  pFirstMix->incMixedPackets();
2604  }
2605  }
2606  }
2607  }
2608  }
2609  pHashEntry=pChannelList->getNext();
2610  }
2611  }
2612 END_THREAD:
2613  delete ip;
2614  delete tmpBuff;
2615  delete pMixPacket;
2616  delete rsaBuff;
2617  CAMsg::printMsg(LOG_DEBUG,"Exiting Thread ReadFromUser\n");
2618  THREAD_RETURN_SUCCESS;
2619  }
2620 */
2621 
2623  {
2624  //#ifdef _DEBUG
2625  CAMsg::printMsg(LOG_DEBUG,"CAFirstMix::clean() start\n");
2626  //#endif
2627  m_bRunLog=false;
2628  m_bRestart=true;
2629  if(m_pMuxOut!=NULL)
2630  {
2631  m_pMuxOut->close();
2632  }
2633 
2634  //writing some bytes to the queue...
2635  if(m_pQueueSendToMix!=NULL)
2636  {
2637  UINT8 b[sizeof(tQueueEntry)+1];
2638  m_pQueueSendToMix->add(b,sizeof(tQueueEntry)+1);
2639  }
2640 
2641  if(m_pthreadAcceptUsers!=NULL)
2642  {
2643  CAMsg::printMsg(LOG_CRIT,"Wait for LoopAcceptUsers!\n");
2645  delete m_pthreadAcceptUsers;
2646  }
2647  m_pthreadAcceptUsers=NULL;
2648  if(m_pthreadsLogin!=NULL)
2649  delete m_pthreadsLogin;
2650  m_pthreadsLogin=NULL;
2651  if(m_pInfoService!=NULL)
2652  {
2653  CAMsg::printMsg(LOG_CRIT,"Stopping InfoService....\n");
2654  CAMsg::printMsg (LOG_CRIT,"Memory usage before: %u\n",getMemoryUsage());
2655  m_pInfoService->stop();
2656  CAMsg::printMsg (LOG_CRIT,"Memory usage after: %u\n",getMemoryUsage());
2657  CAMsg::printMsg(LOG_CRIT,"Stopped InfoService!\n");
2658  // delete m_pInfoService;
2659  }
2660  // m_pInfoService=NULL;
2661 
2662  if(m_pthreadSendToMix!=NULL)
2663  {
2664  CAMsg::printMsg(LOG_CRIT,"Wait for LoopSendToMix!\n");
2666  delete m_pthreadSendToMix;
2667  }
2668  m_pthreadSendToMix=NULL;
2669  if(m_pthreadReadFromMix!=NULL)
2670  {
2671  CAMsg::printMsg(LOG_CRIT,"Wait for LoopReadFromMix!\n");
2673  delete m_pthreadReadFromMix;
2674  }
2675  m_pthreadReadFromMix=NULL;
2676 
2677 #ifdef CH_LOG_STUDY
2678  if(nrOfChThread != NULL)
2679  {
2680  nrOfChThread->join();
2681  delete nrOfChThread;
2682  nrOfChThread = NULL;
2683  }
2684 #endif
2685 
2686 #ifdef LOG_PACKET_TIMES
2687  if(m_pLogPacketStats!=NULL)
2688  {
2689  CAMsg::printMsg(LOG_CRIT,"Wait for LoopLogPacketStats to terminate!\n");
2690  m_pLogPacketStats->stop();
2691  delete m_pLogPacketStats;
2692  }
2693  m_pLogPacketStats=NULL;
2694 #endif
2695  if(m_arrSocketsIn!=NULL)
2696  {
2697  for(UINT32 i=0;i<m_nSocketsIn;i++)
2698  {
2699  if (m_arrSocketsIn[i] != NULL)
2700  {
2701  m_arrSocketsIn[i]->close();
2702  delete m_arrSocketsIn[i];
2703  m_arrSocketsIn[i] = NULL;
2704  }
2705  }
2706  delete[] m_arrSocketsIn;
2707  }
2708  m_arrSocketsIn=NULL;
2709 #ifdef REPLAY_DETECTION
2710  if(m_pReplayMsgProc!=NULL)
2711  {
2712  delete m_pReplayMsgProc;
2713  }
2714  m_pReplayMsgProc=NULL;
2715 #endif
2716 
2718  {
2720  }
2722 
2723  if(m_pMuxOut!=NULL)
2724  {
2725  m_pMuxOut->close();
2726  delete m_pMuxOut;
2727  }
2728  m_pMuxOut=NULL;
2729 #ifdef COUNTRY_STATS
2731 #endif
2732  if(m_pIPList!=NULL)
2733  delete m_pIPList;
2734  m_pIPList=NULL;
2735  if(m_pQueueSendToMix!=NULL)
2736  delete m_pQueueSendToMix;
2737  m_pQueueSendToMix=NULL;
2738  if(m_pQueueReadFromMix!=NULL)
2739  delete m_pQueueReadFromMix;
2740  m_pQueueReadFromMix=NULL;
2741 
2742 #ifndef MULTI_THREADED_PACKET_PROCESSING
2743  if(m_pChannelList!=NULL)
2744  {
2745  CAMsg::printMsg(LOG_CRIT,"Before deleting CAFirstMixChannelList()!\n");
2746  CAMsg::printMsg (LOG_CRIT,"Memory usage before: %u\n",getMemoryUsage());
2747  fmHashTableEntry* pHashEntry=m_pChannelList->getFirst();
2748  while(pHashEntry!=NULL)
2749  {
2750  CAMuxSocket * pMuxSocket=pHashEntry->pMuxSocket;
2751  delete pHashEntry->pQueueSend;
2752  pHashEntry->pQueueSend = NULL;
2753  delete pHashEntry->pSymCipher;
2754  pHashEntry->pSymCipher = NULL;
2755 
2757  while(pEntry!=NULL)
2758  {
2759  delete pEntry->pCipher;
2760  pEntry->pCipher = NULL;
2761  pEntry=m_pChannelList->getNextChannel(pEntry);
2762  }
2763  m_pChannelList->remove(pHashEntry->pMuxSocket);
2764  pMuxSocket->close();
2765  delete pMuxSocket;
2766  pMuxSocket = NULL;
2767  pHashEntry=m_pChannelList->getNext();
2768  }
2769  }
2770 
2771  if(m_pChannelList!=NULL)
2772  delete m_pChannelList;
2773  m_pChannelList=NULL;
2774 #endif
2775  CAMsg::printMsg (LOG_CRIT,"Memory usage after: %u\n",getMemoryUsage());
2776 #ifdef PAYMENT
2779 #endif
2780 #ifndef MULTI_THREADED_PACKET_PROCESSING
2781  if(m_psocketgroupUsersRead!=NULL)
2782  delete m_psocketgroupUsersRead;
2784  if(m_psocketgroupUsersWrite!=NULL)
2785  delete m_psocketgroupUsersWrite;
2787 #endif
2788  if(m_pRSA!=NULL)
2789  delete m_pRSA;
2790  m_pRSA=NULL;
2791  if(m_xmlKeyInfoBuff!=NULL)
2792  delete[] m_xmlKeyInfoBuff;
2793  m_xmlKeyInfoBuff=NULL;
2794  m_docMixCascadeInfo=NULL;
2795  if(m_arMixParameters!=NULL)
2796  {
2797  for(UINT32 i=0;i<m_u32MixCount-1;i++)
2798  {
2799  delete[] m_arMixParameters[i].m_strMixID;
2800  }
2801  delete[] m_arMixParameters;
2802  }
2803  m_arMixParameters=NULL;
2804  m_u32MixCount=0;
2805  m_nMixedPackets=0; //reset to zero after each restart (at the moment neccessary for infoservice)
2806  m_nUser=0;
2807 
2808 
2809  delete m_pIPBlockList;
2810  m_pIPBlockList = NULL;
2811 
2812  CAMsg::printMsg (LOG_CRIT,"before tc cleanup\n");
2813  for (UINT32 i = 0; i < m_nrOfTermsAndConditionsDefs; i++)
2814  {
2815  delete m_tnCDefs[i];
2816  m_tnCDefs[i] = NULL;
2817  }
2818  delete [] m_tnCDefs;
2819  m_tnCDefs = NULL;
2821  CAMsg::printMsg (LOG_CRIT,"before template cleanup\n");
2822  for(UINT32 i = 0; i < m_nrOfTermsAndConditionsTemplates; i++)
2823  {
2824  m_tcTemplates[i]->release();
2825  m_tcTemplates[i] = NULL;
2826  }
2827  delete [] m_tcTemplates;
2828  m_tcTemplates = NULL;
2829  CAMsg::printMsg (LOG_CRIT,"before template owner release\n");
2830  if(m_templatesOwner != NULL)
2831  {
2832  m_templatesOwner->release();
2833  m_templatesOwner = NULL;
2834  }
2835  CAMsg::printMsg (LOG_CRIT,"after template owner release\n");
2837  //#ifdef _DEBUG
2838  CAMsg::printMsg(LOG_DEBUG,"CAFirstMix::clean() finished\n");
2839  //#endif
2840 
2841  return E_SUCCESS;
2842  }
2843 
2844 #ifdef DELAY_USERS
2846  {
2847  CAMsg::printMsg(LOG_DEBUG,"Reconfiguring First Mix\n");
2848 #ifdef DELAY_USERS
2849  CAMsg::printMsg(LOG_DEBUG,"Set new ressources limitation parameters\n");
2850 #ifndef MULTI_THREADED_PACKET_PROCESSING
2851  if(m_pChannelList!=NULL)
2852  m_pChannelList->setDelayParameters( CALibProxytest::getOptions()->getDelayChannelUnlimitTraffic(),
2853  CALibProxytest::getOptions()->getDelayChannelBucketGrow(),
2854  CALibProxytest::getOptions()->getDelayChannelBucketGrowIntervall());
2855 #endif
2856 #endif
2857  return E_SUCCESS;
2858  }
2859 #endif
2860 
2863  {
2864  DOMNodeList* nl=getElementsByTagName(elemMixes,"Mix");
2865  m_u32MixCount=nl->getLength();
2868  UINT8 buff[255];
2869  CALibProxytest::getOptions()->getMixId(buff,255);
2870  UINT32 len=strlen((char*)buff)+1;
2871  UINT32 aktMix=0;
2872  for (UINT32 i = 0; i<m_u32MixCount; i++)
2873  {
2874  DOMNode* child=nl->item(i);
2875  len=255;
2876  getDOMElementAttribute(child,"id",buff,&len);
2877  m_arMixParameters[aktMix].m_strMixID=new UINT8[len+1];
2878  memcpy(m_arMixParameters[aktMix].m_strMixID,buff,len);
2879  m_arMixParameters[aktMix].m_strMixID[len]=0;
2880  aktMix++;
2881  }
2882  m_u32MixCount++;
2883  return E_SUCCESS;
2884  }
2885 
2887 {
2888  #ifdef PAYMENT
2890  #else
2891  return m_nUser;
2892  #endif
2893 }
2894 
2896 {
2897  set64(ppackets,m_nMixedPackets);
2898  return E_SUCCESS;
2899 }
2900 
2902 {
2903  *puser=(SINT32)getNrOfUsers();
2904  *prisk=-1;
2905  *ptraffic=-1;
2906  return E_SUCCESS;
2907 }
2908 
2909 #ifdef REPLAY_DETECTION
2911  {
2912  for(UINT32 i=0;i<m_u32MixCount-1;i++)
2913  {
2915  }
2916  return E_SUCCESS;
2917  }
2918 #endif //REPLAY_DETECTION
2919 
2920 #ifdef COUNTRY_STATS
2921 #define COUNTRY_STATS_DB "CountryStats"
2922 #define NR_OF_COUNTRIES 254
2923 
2927  {
2928  UINT32 i=0;
2929  while(str[i]!=0)
2930  {
2931  if(str[i]=='.'||str[i]==':'||str[i]=='/'||str[i]=='\\')
2932  str[i]='_';
2933  i++;
2934  }
2935  }
2936 
2937 SINT32 CAFirstMix::initCountryStats(char* db_host,char* db_user,char* db_passwd)
2938  {
2939  m_CountryStats=NULL;
2940  m_mysqlCon=mysql_init(NULL);
2941 #ifdef HAVE_MYSQL_OPT_RECONNECT
2942  my_bool thetrue=1;
2943  mysql_options(m_mysqlCon,MYSQL_OPT_RECONNECT,&thetrue);
2944 #endif
2945  MYSQL* tmp=NULL;
2946  tmp=mysql_real_connect(m_mysqlCon,db_host,db_user,db_passwd,COUNTRY_STATS_DB,0,NULL,0);
2947  if(tmp==NULL)
2948  {
2949  CAMsg::printMsg(LOG_DEBUG,"Could not connect to CountryStats DB!\n");
2950  mysql_thread_end();
2951  mysql_close(m_mysqlCon);
2952  m_mysqlCon=NULL;
2953  return E_UNKNOWN;
2954  }
2955  CAMsg::printMsg(LOG_DEBUG,"Connected to CountryStats DB!\n");
2956  char query[1024];
2957  UINT8 buff[255];
2959  mysqlEscapeTableName(buff);
2960  sprintf(query,"CREATE TABLE IF NOT EXISTS `stats_%s` (date timestamp,id int,count int,packets_in int,packets_out int)",buff);
2961  SINT32 ret=mysql_query(m_mysqlCon,query);
2962  if(ret!=0)
2963  {
2964  CAMsg::printMsg(LOG_INFO,"CountryStats DB - create table for %s failed!\n",buff);
2965  }
2967  memset((void*)m_CountryStats,0,sizeof(UINT32)*(NR_OF_COUNTRIES+1));
2969  //memset((void*)m_PacketsPerCountryIN,0,sizeof(UINT32)*(NR_OF_COUNTRIES+1));
2971  //memset((void*)m_PacketsPerCountryOUT,0,sizeof(UINT32)*(NR_OF_COUNTRIES+1));
2972  m_threadLogLoop=new CAThread((UINT8*)"Country Logger Thread");
2974  m_bRunLogCountries=true;
2975  m_threadLogLoop->start(this,true);
2976  return E_SUCCESS;
2977  }
2978 
2980  {
2981  m_bRunLogCountries=false;
2982  if(m_threadLogLoop!=NULL)
2983  {
2984  m_threadLogLoop->join();
2985  delete m_threadLogLoop;
2986  m_threadLogLoop=NULL;
2987  }
2988  if(m_mysqlCon!=NULL)
2989  {
2990  mysql_thread_end();
2991  mysql_close(m_mysqlCon);
2992  m_mysqlCon=NULL;
2993  }
2994 
2995  delete[] m_CountryStats;
2996  m_CountryStats=NULL;
2997 
2998  delete[] m_PacketsPerCountryIN;
2999  m_PacketsPerCountryIN=NULL;
3000 
3001  delete[] m_PacketsPerCountryOUT;
3003  return E_SUCCESS;
3004  }
3005 
3014 SINT32 CAFirstMix::updateCountryStats(const UINT8 ip[4],UINT32 a_countryID,bool bRemove)
3015  {
3016  if(!bRemove)
3017  {
3018  UINT32 countryID=a_countryID;
3019  if(ip!=NULL)
3020  {
3021  UINT32 u32ip=ip[0]<<24|ip[1]<<16|ip[2]<<8|ip[3];
3022  char query[1024];
3023  sprintf(query,"SELECT id FROM ip2c WHERE ip_lo<=\"%u\" and ip_hi>=\"%u\" LIMIT 1",u32ip,u32ip);
3024  int ret=mysql_query(m_mysqlCon,query);
3025  if(ret!=0)
3026  {
3027  CAMsg::printMsg(LOG_INFO,"CountryStatsDB - updateCountryStats - error (%i) in finding countryid for ip %u\n",ret,u32ip);
3028  goto RET;
3029  }
3030  MYSQL_RES* result=mysql_store_result(m_mysqlCon);
3031  if(result==NULL)
3032  {
3033  CAMsg::printMsg(LOG_INFO,"CountryStatsDB - updateCountryStats - error in retriving results of the query\n");
3034  goto RET;
3035  }
3036  MYSQL_ROW row=mysql_fetch_row(result);
3037  SINT32 t;
3038  if(row!=NULL&&(t=atoi(row[0]))>0&&t<=NR_OF_COUNTRIES)
3039  {
3040  countryID=t;
3041  #ifdef DEBUG
3042  CAMsg::printMsg(LOG_DEBUG,"Country ID for ip %u is %u\n",u32ip,countryID);
3043  #endif
3044  //temp hack
3045  if(countryID==99)
3046  {
3047  CAMsg::printMsg(LOG_DEBUG,"Country ID for ip %u.%u.%u.%u is %u\n",ip[0],ip[1],ip[2],ip[3],countryID);
3048  }
3049  }
3050  else
3051  {
3052  CAMsg::printMsg(LOG_DEBUG,"DO country stats query result no result for ip %u)\n",u32ip);
3053  }
3054  mysql_free_result(result);
3055  }
3056 RET:
3057  m_CountryStats[countryID]++;
3058  return countryID;
3059  }
3060  else//bRemove
3061  {
3062  m_CountryStats[a_countryID]--;
3063  }
3064  return a_countryID;
3065  }
3066 
3068  {
3069  mysql_thread_init();
3070  CAMsg::printMsg(LOG_DEBUG,"Starting iplist_loopDoLogCountries\n");
3071  CAFirstMix* pFirstMix=(CAFirstMix*)param;
3072  UINT32 s=0;
3073  UINT8 buff[255];
3074  memset(buff,0,255);
3076  mysqlEscapeTableName(buff);
3077  while(pFirstMix->m_bRunLogCountries)
3078  {
3080  {
3081  UINT8 aktDate[255];
3082  time_t aktTime=time(NULL);
3083  strftime((char*)aktDate,255,"%Y%m%d%H%M%S",gmtime(&aktTime));
3084  char query[1024];
3085  sprintf(query,"INSERT into `stats_%s` (date,id,count,packets_in,packets_out) VALUES (\"%s\",\"%%u\",\"%%u\",\"%%u\",\"%%u\")",buff,aktDate);
3086  pFirstMix->m_pmutexUser->lock();
3087  for(UINT32 i=0;i<NR_OF_COUNTRIES+1;i++)
3088  {
3089  if(pFirstMix->m_CountryStats[i]>0)
3090  {
3091  char aktQuery[1024];
3092  sprintf(aktQuery,query,i,pFirstMix->m_CountryStats[i],pFirstMix->m_PacketsPerCountryIN[i].getAndzero(),pFirstMix->m_PacketsPerCountryOUT[i].getAndzero());
3093  SINT32 ret=mysql_query(pFirstMix->m_mysqlCon,aktQuery);
3094  if(ret!=0)
3095  {
3096  CAMsg::printMsg(LOG_INFO,"CountryStats DB - failed to update CountryStats DB with new values - error %i\n",ret);
3097  }
3098  }
3099  }
3100  pFirstMix->m_pmutexUser->unlock();
3101  s=0;
3102  }
3103  sSleep(10);
3104  s++;
3105  }
3106  CAMsg::printMsg(LOG_DEBUG,"Exiting iplist_loopDoLogCountries\n");
3107  mysql_thread_end();
3109  }
3110 #endif
3111 #endif //ONLY_LOCAL_PROXY
#define OPTIONS_ATTRIBUTE_TNC_ID
#define OPTIONS_NODE_TNCS_TEMPLATES
#define OPTIONS_NODE_TNCS
#define OPTIONS_ATTRIBUTE_TNC_LOCALE
#define OPTIONS_ATTRIBUTE_TNC_TEMPLATE_REFID
#define OPTIONS_NODE_TNCS_TRANSLATION
#define NR_OF_COUNTRIES
THREAD_RETURN fm_loopLog(void *param)
THREAD_RETURN fm_loopDoUserLogin(void *param)
struct T_UserLoginData t_UserLoginData
THREAD_RETURN fm_loopReadFromMix(void *pParam)
THREAD_RETURN iplist_loopDoLogCountries(void *param)
#define COUNTRY_STATS_DB
THREAD_RETURN fm_loopAcceptUsers(void *param)
THREAD_RETURN fm_loopSendToMix(void *param)
How to end this thread: 0.
Definition: CAFirstMix.cpp:978
SINT32 isAllowedToPassRestrictions(CASocket *pNewMuxSocket)
void mysqlEscapeTableName(UINT8 *str)
Escape a string so tha it could be used as table anme.
#define TNC_RESPONSE_INVALID_REQUEST
Definition: CAFirstMix.hpp:68
#define TNC_RESOURCE_TEMPLATE
Definition: CAFirstMix.hpp:64
#define TNC_RESPONSE
Definition: CAFirstMix.hpp:60
#define TNC_REQ_TRANSLATION
Definition: CAFirstMix.hpp:62
#define TNC_TEMPLATE_ROOT_ELEMENT
Definition: CAFirstMix.hpp:65
#define TNC_RESOURCES
Definition: CAFirstMix.hpp:63
#define TNC_RESOURCE_CUSTOMIZED_SECT
Definition: CAFirstMix.hpp:66
#define KEYINFO_NODE_TNC_EXTENSION
Definition: CAMix.hpp:46
#define KEYINFO_NODE_EXTENSIONS
Definition: CAMix.hpp:45
#define REPLAY_BASE
#define MONITORING_FIRE_NET_EVENT(e_type)
@ NULL_CIPHER
#define INIT_STACK
Definition: CAThread.hpp:48
#define BEGIN_STACK(methodName)
Definition: CAThread.hpp:49
#define FINISH_STACK(methodName)
Definition: CAThread.hpp:50
#define SAVE_STACK(methodName, methodPosition)
Definition: CAThread.hpp:51
SINT32 setDOMElementAttribute(DOMNode *pElem, const char *attrName, const char *value)
Definition: CAUtil.cpp:831
SINT32 getcurrentTimeMillis(UINT64 &u64Time)
Gets the current Systemtime in milli seconds.
Definition: CAUtil.cpp:252
SINT32 getDOMElementValue(const DOMNode *const pElem, UINT8 *value, UINT32 *valuelen)
Returns the content of the text node(s) under elem as null-terminated C String.
Definition: CAUtil.cpp:746
UINT8 * readFile(const UINT8 *const name, UINT32 *size)
ONLY_LOCAL_PROXY or first.
Definition: CAUtil.cpp:1330
SINT32 setDOMElementValue(DOMElement *pElem, SINT32 value)
Definition: CAUtil.cpp:939
SINT32 getcurrentTimeMicros(UINT64 &u64Time)
Gets the current Systemtime in micros seconds.
Definition: CAUtil.cpp:280
UINT32 getMemoryUsage()
Definition: CAUtil.cpp:443
bool equals(const XMLCh *const e1, const char *const e2)
Definition: CAUtil.cpp:645
SINT32 sSleep(UINT32 sec)
Sleeps sec Seconds.
Definition: CAUtil.cpp:425
UINT8 * getTermsAndConditionsTemplateRefId(DOMNode *tcTemplateRoot)
Definition: CAUtil.cpp:865
XERCES_CPP_NAMESPACE::DOMDocument * parseDOMDocument(const UINT8 *const buff, UINT32 len)
Parses a buffer containing an XML document and returns this document.
Definition: CAUtil.cpp:663
DOMNodeList * getElementsByTagName(DOMElement *pElem, const char *const name)
Definition: CAUtil.cpp:1711
SINT32 getRandom(UINT32 *val)
Gets 32 random bits.
Definition: CAUtil.cpp:346
SINT32 decryptXMLElement(DOMNode *node, CAASymCipher *pRSA)
Replaces a DOM element with a deencrypted version of this element.
Definition: CAUtil.cpp:1224
XERCES_CPP_NAMESPACE::DOMDocument * createDOMDocument()
Parses a timestamp in JDBC timestamp escape format (as it comes from the BI) and outputs the value in...
Definition: CAUtil.cpp:1568
DOMElement * createDOMElement(XERCES_CPP_NAMESPACE::DOMDocument *pOwnerDoc, const char *const name)
Creates a new DOMElement with the given name which belongs to the DOMDocument owernDoc.
Definition: CAUtil.cpp:814
SINT32 getDOMChildByName(const DOMNode *pNode, const char *const name, DOMElement *&child, bool deep)
Definition: CAUtil.cpp:458
SINT32 getDOMElementAttribute(const DOMNode *const elem, const char *attrName, UINT8 *value, UINT32 *len)
Definition: CAUtil.cpp:780
void logMemoryUsage()
Log information about the current memory (heap) usage.
Definition: CAUtil.cpp:177
SINT32 saveFile(const UINT8 *const name, const UINT8 *const buff, UINT32 buffSize)
Definition: CAUtil.cpp:1352
SINT32 encodeXMLEncryptedKey(UINT8 *key, UINT32 keylen, UINT8 *xml, UINT32 *xmllen, CAASymCipher *pRSA)
Definition: CAUtil.cpp:1683
SINT32 msSleep(UINT32 ms)
Sleeps ms milliseconds.
Definition: CAUtil.cpp:406
UINT32 diff64(const UINT64 &bigop, const UINT64 &smallop)
Definition: CAUtil.hpp:398
void setZero64(UINT64 &op1)
Definition: CAUtil.hpp:355
#define TMP_LOCALE_SIZE
Definition: CAUtil.hpp:39
bool isZero64(UINT64 &op1)
Definition: CAUtil.hpp:464
#define TEMPLATE_REFID_MAXLEN
Definition: CAUtil.hpp:42
void set64(UINT64 &op1, UINT32 op2)
Definition: CAUtil.hpp:321
#define TMP_BUFF_SIZE
Definition: CAUtil.hpp:38
#define NUM_LOGIN_WORKER_TRHEADS
Definition: StdAfx.h:202
#define GET_NET_ERROR
Definition: StdAfx.h:469
#define GET_NET_ERROR_STR(x)
Definition: StdAfx.h:471
#define MIX_POOL_TIMEOUT
Definition: StdAfx.h:245
#define MIX_CASCADE_PROTOCOL_VERSION
Definition: StdAfx.h:264
#define THREAD_RETURN
Definition: StdAfx.h:540
#define ERR_INTERN_CONNREFUSED
Definition: StdAfx.h:475
#define THREAD_RETURN_SUCCESS
Definition: StdAfx.h:542
#define SET_NET_ERROR(x)
Definition: StdAfx.h:470
#define FIRST_MIX_RECEIVE_SYM_KEY_FROM_JAP_TIME_OUT
Definition: StdAfx.h:197
#define MAX_LOGIN_QUEUE
Definition: StdAfx.h:203
#define PAYMENT_VERSION
Definition: StdAfx.h:274
#define CHANNELS_PER_CLIENT
Definition: StdAfx.h:195
#define MAX_READ_FROM_NEXT_MIX_QUEUE_SIZE
Definition: StdAfx.h:227
#define ERR_INTERN_TIMEDOUT
Definition: StdAfx.h:474
#define AI_LOGIN_SO_TIMEOUT
Definition: StdAfx.h:199
#define DUMMY_CHANNEL
Definition: StdAfx.h:246
#define FM_PACKET_STATS_LOG_INTERVALL
Definition: StdAfx.h:248
#define LOG_COUNTRIES_INTERVALL
Definition: StdAfx.h:133
#define MIX_POOL_SIZE
Definition: StdAfx.h:243
#define max(a, b)
Definition: StdAfx.h:654
void cleanupTnCMixAnswer(termsAndConditionMixAnswer_t *answer)
IMPORTANT NOTE: all methods does NOT incorporate locking over the translation store and thus are NOT ...
@ TC_FAILED
@ TC_UNFINISHED
@ TC_CONFIRMED
unsigned short UINT16
Definition: basetypedefs.h:133
signed int SINT32
Definition: basetypedefs.h:132
unsigned char UINT8
Definition: basetypedefs.h:135
unsigned int UINT32
Definition: basetypedefs.h:131
SINT32 getPublicKeyAsDOMElement(DOMElement *&elemRoot, XERCES_CPP_NAMESPACE::DOMDocument *docOwner)
SINT32 setPublicKeyAsDOMNode(DOMNode *node)
SINT32 generateKeyPair(UINT32 size)
Generates a new random key-pair of size bits.
implementation of a per-user control-channel for the AccountingInstance.
static SINT32 init(CAFirstMix *callingMix)
Returns a reference to the Singleton instance.
static SINT32 loginProcessStatus(fmHashTableEntry *pHashEntry)
static SINT32 newSettlementTransaction()
static UINT64 unlockLogin(fmHashTableEntry *ownerRef)
release login (particularly for use in error case) this function is thread-safe.
static SINT32 finishLoginProcess(fmHashTableEntry *pHashEntry)
this method is for the corresponding CAFirstMix login thread to verify the result of the settlement.
static SINT32 encode(const UINT8 *in, UINT32 len, UINT8 *out, UINT32 *outlen)
fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff...
Definition: CABase64.cpp:102
static SINT32 decode(const UINT8 *in, UINT32 len, UINT8 *out, UINT32 *outlen)
fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff...
Definition: CABase64.cpp:41
CACertificate * verifyMixCert(DOMNode *mixNode)
This function parses the certificates from a <Mix>-node and tries to build a certPath to the trusted ...
UINT32 getListenerInterfaceCount()
SINT32 createSockets(bool a_bPrintMessages, CASocket **a_sockets, UINT32 a_socketsLen)
SINT32 getMixId(UINT8 *id, UINT32 len)
SINT32 getCascadeName(UINT8 *name, UINT32 len) const
UINT32 getKeepAliveRecvInterval()
CAMultiSignature * getMultiSigner()
UINT32 getMaxNrOfUsers()
SINT32 getCountryStatsDBConnectionLoginData(char **db_host, char **db_user, char **db_passwd)
CAListenerInterface * getListenerInterface(UINT32 nr)
CACertificate * getNextMixTestCertificate()
SINT32 setNextMixTestCertificate(CACertificate *cert)
UINT32 getKeepAliveSendInterval()
CACertStore * getTrustedCertificateStore()
UINT32 getTargetInterfaceCount()
bool verifyMixCertificates()
CAListenerInterface ** getInfoServices(UINT32 &r_size)
SINT32 getTargetInterface(CATargetInterface &oTargetInterface, UINT32 nr)
Fills a TargetInterface struct with the values which belongs to the target interface nr.
This class "dispatches" messages which it receives via proccessMixPacket() to the associated control ...
SINT32 registerControlChannel(CAAbstractControlChannel *pControlChannel)
Registers a control channel for receiving messages.
bool proccessMixPacket(const MIXPACKET *pPacket)
SINT32 start()
Definition: CADatabase.cpp:220
Data structure that stores all information about the currently open Mix channels.
fmChannelListEntry * getFirstChannelForSocket(CAMuxSocket *pMuxSocket)
Gets the first channel for a given connection.
void setDelayParameters(UINT32 unlimitTraffic, UINT32 bucketGrow, UINT32 intervall)
fmHashTableEntry * getFirst()
Gets the first connection of all connections in the list.
fmChannelListEntry * get(CAMuxSocket *pMuxSocket, HCHANNEL channelIn)
Returns the information for a given Input-Channel-ID.
fmHashTableEntry * getNext()
Gets the next entry in the connections-list.
bool forceKickout(fmHashTableEntry *pHashTableEntry, const XERCES_CPP_NAMESPACE::DOMDocument *pErrDoc)
forces a kickout for this entry if the entry is still valid and sends an errorMessage via the control...
fmChannelListEntry * getNextChannel(fmChannelListEntry *pEntry)
Gets the next channel for a given connection.
fmHashTableEntry * add(CAMuxSocket *pMuxSocket, const UINT8 peerIP[4], CAQueue *pQueueSend, UINT8 *controlChannelKeyRecv, UINT8 *controlChannelKeySent)
Adds a new TCP/IP connection (a new user) to the channel list.
SINT32 remove(CAMuxSocket *pMuxSocket)
Removes all channels, which belongs to the given connection and the connection itself from the list.
SINT32 pushTimeoutEntry(fmHashTableEntry *pHashTableEntry, bool kickoutForced=!KICKOUT_FORCED)
adds the entry to the timeout queue with mutex
CAThread * m_pthreadReadFromMix
Definition: CAFirstMix.hpp:507
CASocket ** m_arrSocketsIn
Definition: CAFirstMix.hpp:457
SINT32 updateCountryStats(const UINT8 ip[4], UINT32 a_countryID, bool bRemove)
Update the statisitics of the countries users come from.
const XMLCh * TNC_CONFIRM
Definition: CAFirstMix.hpp:517
friend THREAD_RETURN fm_loopSendToMix(void *)
How to end this thread: 0.
Definition: CAFirstMix.cpp:978
UINT32 m_nrOfTermsAndConditionsTemplates
Definition: CAFirstMix.hpp:511
virtual SINT32 processKeyExchange()
Definition: CAFirstMix.cpp:362
SINT32 init()
Definition: CAFirstMix.cpp:108
SINT32 doUserLogin(CAMuxSocket *pNewUSer, UINT8 perrIP[4])
termsAndConditionMixAnswer_t * handleTermsAndConditionsLogin(XERCES_CPP_NAMESPACE::DOMDocument *request)
SINT32 getLevel(SINT32 *puser, SINT32 *prisk, SINT32 *ptraffic)
SINT32 getMixedPackets(UINT64 &ppackets)
volatile bool m_bRestart
Definition: CAFirstMix.hpp:456
SINT32 initCountryStats(char *db_host, char *db_user, char *db_passwd)
tMixParameters * m_arMixParameters
Definition: CAFirstMix.hpp:461
DOMNode ** m_tcTemplates
Definition: CAFirstMix.hpp:512
CAMuxSocket * m_pMuxOut
Definition: CAFirstMix.hpp:490
CAThread * m_pthreadAcceptUsers
Definition: CAFirstMix.hpp:504
UINT64 m_nMixedPackets
Definition: CAFirstMix.hpp:496
CAQueue * m_pQueueSendToMix
Definition: CAFirstMix.hpp:448
volatile bool m_bRunLog
Definition: CAFirstMix.hpp:552
CAIPList * m_pIPList
Definition: CAFirstMix.hpp:446
DOMNode * getTermsAndConditionsTemplate(UINT8 *templateRefID)
Definition: CAFirstMix.cpp:953
volatile UINT32 m_newConnections
Definition: CAFirstMix.hpp:568
bool m_bIsShuttingDown
Definition: CAFirstMix.hpp:550
friend THREAD_RETURN iplist_loopDoLogCountries(void *param)
SINT32 incUsers(LP_fmHashTableEntry pHashEntry)
Definition: CAFirstMix.hpp:400
volatile bool m_bRunLogCountries
Definition: CAFirstMix.hpp:532
CASocketGroupEpoll * m_psocketgroupUsersWrite
Definition: CAFirstMix.hpp:467
UINT32 m_nrOfTermsAndConditionsDefs
Definition: CAFirstMix.hpp:509
XERCES_CPP_NAMESPACE::DOMDocument * m_templatesOwner
Definition: CAFirstMix.hpp:513
static const UINT32 MAX_CONCURRENT_NEW_CONNECTIONS
Definition: CAFirstMix.hpp:566
CAThread * m_threadLogLoop
Definition: CAFirstMix.hpp:539
volatile UINT32 m_nUser
Definition: CAFirstMix.hpp:454
const XMLCh * TNC_INTERRUPT
Definition: CAFirstMix.hpp:518
void incNewConnections()
Definition: CAFirstMix.hpp:571
CAThread * m_pthreadSendToMix
Definition: CAFirstMix.hpp:506
UINT64 m_u64LastTimestampReceived
Definition: CAFirstMix.hpp:393
UINT32 m_u32MixCount
Definition: CAFirstMix.hpp:459
SINT32 getMixCount()
Definition: CAFirstMix.hpp:374
CASocketGroupEpoll * m_psocketgroupUsersRead
Definition: CAFirstMix.hpp:466
CATempIPBlockList * m_pIPBlockList
Definition: CAFirstMix.hpp:447
tUINT32withLock * m_PacketsPerCountryOUT
Definition: CAFirstMix.hpp:537
SINT32 doUserLogin_internal(CAMuxSocket *pNewUSer, UINT8 perrIP[4])
Sends and receives all data neccessary for a User to "login".
CAMutex * m_pmutexUser
Definition: CAFirstMix.hpp:500
friend THREAD_RETURN fm_loopAcceptUsers(void *)
bool isShuttingDown()
Definition: CAFirstMix.cpp:64
SINT32 reconfigure()
void decNewConnections()
Definition: CAFirstMix.hpp:578
SINT32 setMixParameters(const tMixParameters &params)
Sets the parameters for the mix specified in the params.m_strMixID field.
Definition: CAFirstMix.cpp:784
friend THREAD_RETURN fm_loopReadFromMix(void *)
SINT32 sendReplayTimestampRequestsToAllMixes()
virtual SINT32 initOnce()
Definition: CAFirstMix.cpp:69
MYSQL * m_mysqlCon
Definition: CAFirstMix.hpp:540
CAFirstMixChannelList * m_pChannelList
Definition: CAFirstMix.hpp:464
TermsAndConditions * getTermsAndConditions(const UINT8 *opSki)
Definition: CAFirstMix.cpp:932
tUINT32withLock * m_PacketsPerCountryIN
Definition: CAFirstMix.hpp:536
SINT32 handleTermsAndConditionsExtension(DOMElement *extensionRoot)
Definition: CAFirstMix.cpp:825
bool forceKickout(fmHashTableEntry *pHashTableEntry, const XERCES_CPP_NAMESPACE::DOMDocument *pErrDoc=NULL)
UINT32 m_nSocketsIn
Definition: CAFirstMix.hpp:455
SINT32 clean()
UINT8 * m_xmlKeyInfoBuff
Definition: CAFirstMix.hpp:492
CAASymCipher * m_pRSA
Definition: CAFirstMix.hpp:497
CAThreadPool * m_pthreadsLogin
Definition: CAFirstMix.hpp:505
TermsAndConditions ** m_tnCDefs
Definition: CAFirstMix.hpp:510
const XMLCh * TNC_REQUEST
Definition: CAFirstMix.hpp:516
CAQueue * m_pQueueReadFromMix
Definition: CAFirstMix.hpp:449
volatile UINT32 * m_CountryStats
Definition: CAFirstMix.hpp:533
UINT32 getNrOfUsers()
UINT16 m_xmlKeyInfoSize
Definition: CAFirstMix.hpp:493
SINT32 initMixParameters(DOMElement *elemMixes)
Initialises the MixParameters info for each mix form the <Mixes> element received from the second mix...
SINT32 deleteCountryStats()
SINT32 connectToNextMix(CASocketAddr *a_pAddrNext)
Definition: CAFirstMix.cpp:307
SINT32 handleKeyInfoExtensions(DOMElement *root)
Definition: CAFirstMix.cpp:805
XERCES_CPP_NAMESPACE::DOMDocument * m_docMixCascadeInfo
Definition: CAFirstMix.hpp:495
The purpose of this class is to store a list of IP-Addresses.
Definition: CAIPList.hpp:62
SINT32 insertIP(const UINT8 ip[4])
Inserts the IP-Address into the list.
Definition: CAIPList.cpp:103
SINT32 removeIP(const UINT8 ip[4])
Removes the IP-Address from the list.
Definition: CAIPList.cpp:189
static CACmdLnOptions * getOptions()
SINT32 appendCompatibilityInfo(DOMNode *a_parent)
Definition: CAMix.cpp:634
SINT32 checkCompatibility(DOMNode *a_parent, const char *a_mixPosition)
Definition: CAMix.cpp:670
CAInfoService * m_pInfoService
Definition: CAMix.hpp:184
SINT32 signXML(DOMNode *a_element)
Definition: CAMix.cpp:806
static const UINT32 TIMEOUT_MIX_CONNECTION_ESTABLISHEMENT
Definition: CAMix.hpp:59
SINT32 addMixInfo(DOMNode *a_element, bool a_bForceFirstNode)
Definition: CAMix.cpp:437
CAControlChannelDispatcher * m_pMuxOutControlChannelDispatcher
Definition: CAMix.hpp:195
UINT32 m_u32KeepAliveRecvInterval
Definition: CAMix.hpp:186
CAMultiSignature * m_pMultiSignature
Definition: CAMix.hpp:183
virtual SINT32 initMixCascadeInfo(DOMElement *elemMixes)
This will initialize the XML Cascade Info struct XMLFirstMixToInfoService that is sent to the InfoSer...
Definition: CAMix.cpp:299
virtual SINT32 initOnce()
Definition: CAMix.cpp:78
UINT32 m_u32KeepAliveSendInterval
Definition: CAMix.hpp:187
CADatabase * m_pReplayDB
CAReplayCtrlChannelMsgProc * m_pReplayMsgProc
static SINT32 printMsg(UINT32 typ, const char *format,...)
Writes a given message to the log.
Definition: CAMsg.cpp:251
SINT32 sign(UINT8 *in, UINT32 inlen, UINT8 *sig, UINT32 *siglen)
Method for producing a single Signature for Key Exchange.
static SINT32 verifyXML(const UINT8 *const in, UINT32 inlen, CACertificate *a_cert)
SINT32 signXML(DOMNode *a_node, bool appendCerts)
SINT32 unlock()
Definition: CAMutex.hpp:52
SINT32 lock()
Definition: CAMutex.hpp:41
SINT32 close()
Closes the underlying socket.
SINT32 receive(MIXPACKET *pPacket)
Receives a whole MixPacket.
SINT32 connect(CASocketAddr &psa)
SINT32 setSendKey(UINT8 *key, UINT32 keyLen)
SINT32 setReceiveKey(UINT8 *key, UINT32 keyLen)
SINT32 setCrypt(bool b)
SINT32 send(MIXPACKET *pPacket)
Sends a MixPacket over the Network.
SINT32 getHashKey()
Returns a Hashkey which uniquely identifies this socket.
Definition: CAMuxSocket.hpp:52
SINT32 receiveFully(UINT8 *buff, UINT32 len)
Receives some "plain" bytes from the underlying socket - just a convenient function....
Definition: CAMuxSocket.hpp:69
CASocket * getCASocket()
Definition: CAMuxSocket.hpp:84
SINT32 prepareForSend(MIXPACKET *inoutPacket)
This class implements the pool strategie of a Mix.
Definition: CAPool.hpp:43
SINT32 pool(tPoolEntry *pPoolEntry)
Definition: CAPool.cpp:83
This is a simple FIFO-Queue.
Definition: CAQueue.hpp:50
SINT32 add(const void *buff, UINT32 size)
Adds data to the Queue.
Definition: CAQueue.cpp:76
SINT32 getOrWait(UINT8 *pbuff, UINT32 *psize)
Gets data from the Queue or waits until some data is available, if the Queue is empty.
Definition: CAQueue.cpp:209
SINT32 get(UINT8 *pbuff, UINT32 *psize)
Gets up to psize number of bytes from the Queue.
Definition: CAQueue.cpp:148
UINT32 getSize()
Returns the size of stored data in byte.
Definition: CAQueue.hpp:101
A Control channel for the exchange of the current replay detection timestamps.
SINT32 sendGetTimestamp(const UINT8 *strMixID)
Sends upstram a request for the replay timestamp for the given mix.
This is an abstract class for representing a socket address used in CASocket, CADatagramSocket and CA...
virtual SINT32 getType() const =0
The type (family) of socket for which this address is useful.
virtual SINT32 toString(UINT8 *buff, UINT32 bufflen) const =0
Returns a string which describes this address in a human readable form.
This class represents a socket address for Internet (IP) connections.
SINT32 getIP(UINT8 buff[4]) const
Returns the IP-Numbers for this address.
SINT32 remove(CASocket &s)
bool isSignaled(CASocket &s)
SINT32 add(CASocket &s)
Adds the socket s to the socket group.
SINT32 add(SOCKET &s)
virtual SINT32 send(const UINT8 *buff, UINT32 len)
Sends some data over the network.
Definition: CASocket.cpp:400
virtual SINT32 setKeepAlive(bool b)
Enables/disables the socket keep-alive option.
Definition: CASocket.cpp:906
virtual SINT32 setRecvBuff(UINT32 r)
Definition: CASocket.cpp:846
virtual SINT32 receiveFullyT(UINT8 *buff, UINT32 len, UINT32 msTimeOut)
Trys to receive all bytes.
Definition: CASocket.cpp:677
virtual SINT32 getSendBuff()
Definition: CASocket.cpp:873
virtual bool isClosed()
Definition: CASocket.hpp:132
virtual SINT32 getPeerIP(UINT8 ip[4])
Definition: CASocket.cpp:820
virtual SINT32 setNonBlocking(bool b)
Definition: CASocket.cpp:947
virtual SINT32 setSendBuff(SINT32 r)
Returns < 0 on error, otherwise the new sendbuffersize (which may be less than r)
Definition: CASocket.cpp:862
virtual SINT32 accept(CASocket &s)
Accepts a new connection.
Definition: CASocket.cpp:192
virtual SINT32 getRecvBuff()
Definition: CASocket.cpp:852
virtual SINT32 sendFullyTimeOut(const UINT8 *buff, UINT32 len, UINT32 msTimeOut, UINT32 msTimeOutSingleSend)
Sends all data over the network.
Definition: CASocket.cpp:488
virtual SINT32 create()
Definition: CASocket.cpp:73
static UINT32 countOpenSockets()
Definition: CASocket.hpp:128
virtual SINT32 close()
Definition: CASocket.cpp:351
static CASymChannelCipher * createCipher(SYMCHANNELCIPHER_ALGORITHM alg)
virtual SINT32 setKey(const UINT8 *key)=0
Sets the keys for crypt1() and crypt2() to the same key.
virtual SINT32 setIVs(const UINT8 *p_iv)=0
Sets iv1 and iv2 to p_iv.
TargetType getTargetType() const
CASocketAddr * getAddr() const
The purpose of this class is storing the IPs of JAP users who tried to hack/attack the payment system...
SINT32 insertIP(const UINT8 ip[4])
inserts an IP into the blocklist
SINT32 checkIP(const UINT8 ip[4])
check whether an IP is blocked
SINT32 start(void *param, bool bDaemon=false, bool bSilent=false)
Starts the execution of the main function of this thread.
Definition: CAThread.cpp:115
SINT32 setMainLoop(THREAD_MAIN_TYP fnc)
Sets the main function which will be executed within this thread.
Definition: CAThread.hpp:148
SINT32 join()
Waits for the main function to finish execution.
Definition: CAThread.cpp:187
This class bla bla.
SINT32 addRequest(THREAD_MAIN_TYP, void *args)
Adds a new request (task) to this threadpool.
UINT32 countRequests()
static SINT32 dumpToMem(const DOMNode *node, UINT8 *buff, UINT32 *size)
Dumps the node and all childs into buff.
Definition: DOM_Output.hpp:161
const termsAndConditionsTranslation_t * getTranslation(const UINT8 *locale)
returns the specific TermsAndconditions translation for the the language with the specified language ...
void addTranslation(const UINT8 *locale, DOMNode *tnc_customized, DOMNode *tnc_template)
add a language specific terms and Conditions document, which can be retrieved by *getTermsAndConditio...
#define E_SOCKETCLOSED
Definition: errorcodes.hpp:11
const SINT32 E_SUCCESS
Definition: errorcodes.hpp:2
#define E_SHUTDOWN
Definition: errorcodes.hpp:4
#define E_UNKNOWN
Definition: errorcodes.hpp:3
#define E_TIMEDOUT
Definition: errorcodes.hpp:10
@ ev_net_nextConnectionClosed
@ ev_net_keyExchangeNextSuccessful
@ ev_net_nextConnected
CAFirstMix * pMix
CAMuxSocket * pNewUser
HCHANNEL channel
Definition: typedefs.hpp:117
UINT8 data[DATA_SIZE]
Definition: typedefs.hpp:121
UINT16 flags
Definition: typedefs.hpp:118
CASymChannelCipher * pCipher
CASymChannelCipher * pSymCipher
CAControlChannelDispatcher * pControlChannelDispatcher
UINT16 m_u32ReplayBase
Definition: typedefs.hpp:219
UINT32 m_u32ReplayOffset
Definition: typedefs.hpp:218
UINT8 * m_strMixID
Definition: typedefs.hpp:216
Definition: typedefs.hpp:169
MIXPACKET packet
Definition: typedefs.hpp:170
XERCES_CPP_NAMESPACE::DOMDocument * xmlAnswer
@ TARGET_MIX
Definition: typedefs.hpp:32
#define MIXPACKET_SIZE
Definition: typedefs.hpp:40
#define CHANNEL_DEBUG
Definition: typedefs.hpp:51
#define AUTH_LOGIN_NOT_FINISHED
Definition: typedefs.hpp:288
@ RAW_TCP
Definition: typedefs.hpp:30
@ HTTP_TCP
Definition: typedefs.hpp:30
#define CHANNEL_DUMMY
Definition: typedefs.hpp:50
#define AUTH_LOGIN_FAILED
Definition: typedefs.hpp:289
#define AUTH_WAITING_FOR_FIRST_SETTLED_CC
First CC from client has not been settled yet.
Definition: typedefs.hpp:239
struct t_queue_entry tQueueEntry
Definition: typedefs.hpp:188
t_MixPacket MIXPACKET
Definition: typedefs.hpp:127
UINT16 len
Definition: typedefs.hpp:0
tQueueEntry tPoolEntry
Definition: typedefs.hpp:192
#define AUTH_LOGIN_SKIP_SETTLEMENT
Definition: typedefs.hpp:290
#define CHANNEL_OPEN
Definition: typedefs.hpp:43
#define DATA_SIZE
Definition: typedefs.hpp:69