Mixe for Privacy and Anonymity in the Internet
CALastMix.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_LAST_MIX
30 #include "CALastMix.hpp"
31 #ifdef NEW_MIX_TYPE // TypeB mixes
32  #include "TypeB/typedefsb.hpp"
33 #else // not TypeB mixes
34  /* TypeB mixes doesn't use the default-implementation */
35  #include "CALastMixChannelList.hpp"
36 #endif
37 #include "CALibProxytest.hpp"
38 #include "CASocketGroup.hpp"
39 #include "CASingleSocketGroup.hpp"
40 #include "CAMsg.hpp"
41 #include "CACmdLnOptions.hpp"
42 #ifdef HAVE_UNIX_DOMAIN_PROTOCOL
43  #include "CASocketAddrUnix.hpp"
44 #endif
45 #include "CACertStore.hpp"
46 #include "CABase64.hpp"
47 #include "CAPool.hpp"
48 #include "xml/DOM_Output.hpp"
49 #include "CAStatusManager.hpp"
51 /*******************************************************************************/
52 // ----------START NEW VERSION -----------------------
53 //---------------------------------------------------------
54 /********************************************************************************/
55 
57  {
58  SINT32 ret=CAMix::initOnce();
59  if(ret!=E_SUCCESS)
60  return ret;
61  if(setTargets()!=E_SUCCESS)
62  {
63  CAMsg::printMsg(LOG_CRIT,"Could not set Targets (proxies)!\n");
64  return E_UNKNOWN;
65  }
66 
67  //m_pSignature=CALibProxytest::getOptions()->getSignKey();
69  if(m_pMultiSignature==NULL)
70  return E_UNKNOWN;
71  if(CALibProxytest::getOptions()->getListenerInterfaceCount()<1)
72  {
73  CAMsg::printMsg(LOG_CRIT,"No ListenerInterfaces specified!\n");
74  return E_UNKNOWN;
75  }
76 #ifndef INCLUDE_LAST_MIX
78  if(CALibProxytest::getOptions()->getCascadeXML() != NULL)
80 #endif
81  return E_SUCCESS;
82  }
83 
85  {
86  m_pRSA=new CAASymCipher();
87 #ifdef EXPORT_ASYM_PRIVATE_KEY
88  if(CALibProxytest::getOptions()->isImportKey())
89  {
90  UINT32 keyFileBuffLen=8096;
91  UINT8* keyFileBuff=new UINT8[keyFileBuffLen];
92  CALibProxytest::getOptions()->getEncryptionKeyImportFile(keyFileBuff,keyFileBuffLen);
93  UINT8* keyBuff=readFile(keyFileBuff,&keyFileBuffLen);
94  m_pRSA->setPrivateKeyAsXML(keyBuff,keyFileBuffLen);
95  delete[] keyFileBuff;
96  delete[] keyBuff;
97  }
98  else
99 #endif
100  {
101  if(m_pRSA->generateKeyPair(1024)!=E_SUCCESS)
102  {
103  CAMsg::printMsg(LOG_CRIT,"Could not generate a valid key pair\n");
104  return E_UNKNOWN;
105  }
106  }
107 #ifdef EXPORT_ASYM_PRIVATE_KEY
108  if(CALibProxytest::getOptions()->isExportKey())
109  {
110  UINT32 keyFileBuffLen=8096;
111  UINT8* keyFileBuff=new UINT8[keyFileBuffLen];
112  UINT8* keyBuff=new UINT8[keyFileBuffLen];
113  CALibProxytest::getOptions()->getEncryptionKeyExportFile(keyFileBuff,keyFileBuffLen);
114  m_pRSA->getPrivateKeyAsXML(keyBuff,&keyFileBuffLen);
115  saveFile(keyFileBuff,keyBuff,keyFileBuffLen);
116  delete[] keyFileBuff;
117  delete[] keyBuff;
118  }
119 #endif
120 
121  CAListenerInterface* pListener=NULL;
123  for(UINT32 i=1;i<=interfaces;i++)
124  {
126  if(!pListener->isVirtual())
127  break;
128  delete pListener;
129  pListener=NULL;
130  }
131  if(pListener==NULL)
132  {
133  CAMsg::printMsg(LOG_CRIT,"Initialization failed! Reason: No usable (non virtual) interface was found! Hint: Virtual interfaces only needed if you are behind a NAT/network address translation, and therefore have to publish other external IP addresses to the InfoServices than your internal/hidden IP addresses.\n");
134  return E_UNKNOWN;
135  }
136 
137  const CASocketAddr* pAddr=NULL;
138  pAddr=pListener->getAddr();
139  delete pListener;
140  pListener = NULL;
141  UINT8 buff[255];
142  pAddr->toString(buff,255);
143 
144  CAMsg::printMsg(LOG_INFO,"Waiting for connection from previous Mix on %s...\n", buff);
145 
146  m_pMuxIn=new CAMuxSocket(OFB);
147  SINT32 ret=m_pMuxIn->accept(*pAddr);
148 #ifdef __BUILD_AS_SHADOW_PLUGIN__
150 #endif
151  delete pAddr;
152  pAddr = NULL;
153  if(ret!=E_SUCCESS)
154  {
155  CAMsg::printMsg(LOG_CRIT,"Initialization failed! Reason: Call to accept() failed with error '%s' (%i)\n",
157  return ret;
158  }
159  // connected to previous mix
163 
165  CAMsg::printMsg(LOG_INFO,"connected!\n");
166 
167 #ifdef LOG_CRIME
168  m_nCrimeRegExpsURL=0;
169  m_pCrimeRegExpsURL=CALibProxytest::getOptions()->getCrimeRegExpsURL(&m_nCrimeRegExpsURL);
170  m_nCrimeRegExpsPayload = 0;
171  m_pCrimeRegExpsPayload = CALibProxytest::getOptions()->getCrimeRegExpsPayload(&m_nCrimeRegExpsPayload);
172  m_pSquidLogHelper = new CASquidLogHelper(this,1);
173  if (m_pSquidLogHelper->start()!=E_SUCCESS)
174  {
175  CAMsg::printMsg(LOG_ERR, "Could not start SquidLogHelper!\n");
176  return E_UNKNOWN;
177  }
178 
179 #endif
180  ret=processKeyExchange();
181  if(ret!=E_SUCCESS)
182  {
184  return ret;
185  }
187  //keyexchange successful
188 #ifdef REPLAY_DETECTION
189  m_pReplayDB=new CADatabase();
190  m_pReplayDB->start();
191 #endif
194 
196 #ifdef REPLAY_DETECTION
199  m_u64ReferenceTime=time(NULL);
200 #endif
201 
202  m_bRestart=false;
203  //Starting thread for Step 1a
204  m_pthreadReadFromMix=new CAThread((UINT8*)"CALastMix - ReadFromMix");
207 
208  //Starting thread for Step 4
209  m_pthreadSendToMix=new CAThread((UINT8*)"CALastMix - SendToMix");
211  m_pthreadSendToMix->start(this);
212 
213  //Starting thread for logging
214 #ifdef LOG_PACKET_TIMES
215  m_pLogPacketStats=new CALogPacketStats();
216  m_pLogPacketStats->setLogIntervallInMinutes(LM_PACKET_STATS_LOG_INTERVALL);
217  m_pLogPacketStats->start();
218 #endif
219  #ifndef NEW_MIX_TYPE // not TypeB mixes
220  /* TypeB mixes are using an own implementation */
222  #endif
223  return E_SUCCESS;
224  }
225 
237  {
238  XERCES_CPP_NAMESPACE::DOMDocument* doc=createDOMDocument();
239  DOMElement* elemMixes=createDOMElement(doc,"Mixes");
240  setDOMElementAttribute(elemMixes,"count",(UINT32)1);
241  //UINT8 cName[128];
242  //CALibProxytest::getOptions()->getCascadeName(cName,128);
243  //setDOMElementAttribute(elemMixes,"cascadeName",cName);
244  doc->appendChild(elemMixes);
245 
246  addMixInfo(elemMixes, false);
247  DOMElement* elemMix=NULL;
248  getDOMChildByName(elemMixes, "Mix", elemMix, false);
249 
250  //Inserting MixProtocol Version
251  // Version 0.3 - "normal", initial mix protocol
252  // Version 0.4 - with new flow control [was only used for tests]
253  // Version 0.5 - end-to-end 1:n channels (only between client and last mix)
254  // Version 0.6 - with new flow control for downstream [productive]
255  // Version 0.7 - with new flow control for downstream AND upstream
256  DOMElement* elemMixProtocolVersion=createDOMElement(doc,"MixProtocolVersion");
257  elemMix->appendChild(elemMixProtocolVersion);
258  #ifdef NEW_MIX_TYPE // TypeB mixes
259  setDOMElementValue(elemMixProtocolVersion,(UINT8*)"0.5");
260  DOM_Element elemDownstreamPackets = doc.createElement("DownstreamPackets");
261  setDOMElementValue(elemDownstreamPackets, (UINT32)CHANNEL_DOWNSTREAM_PACKETS);
262  elemMixProtocolVersion.appendChild(elemDownstreamPackets);
263  DOM_Element elemChannelTimeout = doc.createElement("ChannelTimeout");
264  /* let the client use our channel-timeout + 5 seconds */
265  setDOMElementValue(elemChannelTimeout, (UINT32)(CHANNEL_TIMEOUT + 5));
266  elemMixProtocolVersion.appendChild(elemChannelTimeout);
267  DOM_Element elemChainTimeout = doc.createElement("ChainTimeout");
268  /* let the client use our chain-timeout - 5 seconds */
269  setDOMElementValue(elemChainTimeout, (UINT32)(CHAIN_TIMEOUT - 5));
270  elemMixProtocolVersion.appendChild(elemChainTimeout);
271  #else
272  setDOMElementValue(elemMixProtocolVersion,(UINT8*)"0.6");
273  DOMElement* elemFlowControl=createDOMElement(doc,"FlowControl");
274  DOMElement* elemUpstreamSendMe=createDOMElement(doc,"UpstreamSendMe");
275  DOMElement* elemDownstreamSendMe=createDOMElement(doc,"DownstreamSendMe");
276  elemMix->appendChild(elemFlowControl);
277  elemFlowControl->appendChild(elemUpstreamSendMe);
278  elemFlowControl->appendChild(elemDownstreamSendMe);
281  setDOMElementAttribute(elemFlowControl,"withUpstreamFlowControl",true);
282  #endif
283  //Inserting RSA-Key
284  DOMElement* nodeRsaKey=NULL;
285  m_pRSA->getPublicKeyAsDOMElement(nodeRsaKey,doc);
286  elemMix->appendChild(nodeRsaKey);
287 
288  appendCompatibilityInfo(elemMix);
289 
290  //inserting Nonce
291  DOMElement* elemNonce=createDOMElement(doc,"Nonce");
292  UINT8 arNonce[16];
293  getRandom(arNonce,16);
294  UINT8 tmpBuff[50];
295  UINT32 tmpLen=50;
296  CABase64::encode(arNonce,16,tmpBuff,&tmpLen);
297  tmpBuff[tmpLen]=0;
298  setDOMElementValue(elemNonce,tmpBuff);
299  elemMix->appendChild(elemNonce);
300 
301 
302 
303 // Add Info about KeepAlive traffic
304  DOMElement* elemKeepAlive=NULL;
305  UINT32 u32KeepAliveSendInterval=CALibProxytest::getOptions()->getKeepAliveSendInterval();
306  UINT32 u32KeepAliveRecvInterval=CALibProxytest::getOptions()->getKeepAliveRecvInterval();
307  elemKeepAlive=createDOMElement(doc,"KeepAlive");
308  DOMElement* elemKeepAliveSendInterval=NULL;
309  DOMElement* elemKeepAliveRecvInterval=NULL;
310  elemKeepAliveSendInterval=createDOMElement(doc,"SendInterval");
311  elemKeepAliveRecvInterval=createDOMElement(doc,"ReceiveInterval");
312  elemKeepAlive->appendChild(elemKeepAliveSendInterval);
313  elemKeepAlive->appendChild(elemKeepAliveRecvInterval);
314  setDOMElementValue(elemKeepAliveSendInterval,u32KeepAliveSendInterval);
315  setDOMElementValue(elemKeepAliveRecvInterval,u32KeepAliveRecvInterval);
316  elemMix->appendChild(elemKeepAlive);
317 
318  CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Offering -- SendInterval %u -- Receive Interval %u\n",u32KeepAliveSendInterval,u32KeepAliveRecvInterval);
319 
320 #ifdef PAYMENT
321  /* append the terms and conditions, if there are any, to the KeyInfo
322  * Extensions, (nodes that can be removed from the KeyInfo without
323  * destroying the signature of the "Mix"-node).
324  */
325  if(CALibProxytest::getOptions()->getTermsAndConditions() != NULL)
326  {
327  appendTermsAndConditionsExtension(doc, elemMixes);
328  elemMix->appendChild(termsAndConditionsInfoNode(doc));
329  }
330 #endif
331 
332  // create signature
333  if (signXML(elemMix) != E_SUCCESS)
334  {
335  CAMsg::printMsg(LOG_DEBUG,"Could not sign KeyInfo sent to users...\n");
336  }
337 
338  UINT32 len=0;
339  UINT8* messageBuff=DOM_Output::dumpToMem(doc,&len);
340  if (doc != NULL)
341  {
342  doc->release();
343  doc = NULL;
344  }
345  UINT32 tmp = htonl(len);
346  CAMsg::printMsg(LOG_INFO,"Sending Infos (chain length and RSA-Key, Message-Size %u)\n",len);
347 
348  if (len > 100000)
349  {
350  CAMsg::printMsg(LOG_WARNING,"Unrealistic length for key info: %u We might not be able to get a connection.\n",len);
351  }
352 
353  if( (m_pMuxIn->getCASocket()->send((UINT8*)&tmp, sizeof(tmp)) != sizeof(tmp)) ||
354  m_pMuxIn->getCASocket()->send(messageBuff,len)!=(SINT32)len)
355  {
356  CAMsg::printMsg(LOG_ERR,"Error sending Key-Info!\n");
357  delete []messageBuff;
358  messageBuff = NULL;
359  return E_UNKNOWN;
360  }
361  delete[] messageBuff;
362  messageBuff = NULL;
363 
364  SINT32 ret;
365  //Now receiving the symmetric key
366  CAMsg::printMsg(LOG_INFO,"Waiting for length of symmetric key from previous Mix...\n");
367 #ifdef __BUILD_AS_SHADOW_PLUGIN__
368  if ((ret = m_pMuxIn->receiveFully((UINT8*)&tmp, sizeof(tmp))) != E_SUCCESS)
369 #else
370  if((ret = m_pMuxIn->receiveFully((UINT8*) &tmp, sizeof(tmp), TIMEOUT_MIX_CONNECTION_ESTABLISHEMENT)) != E_SUCCESS)
371 #endif
372  {
373  if (ret != E_UNKNOWN)
374  {
375  CAMsg::printMsg(LOG_CRIT,"Error receiving symmetric key info length! Reason: '%s' (%i)\n",
377  }
378  else
379  {
380  CAMsg::printMsg(LOG_CRIT,"Error receiving symmetric key info length!\n");
381  }
382  return ret;
383  }
384  len = ntohl(tmp);
385 
386  if (len > 100000)
387  {
388  CAMsg::printMsg(LOG_WARNING,"Unrealistic length for key info: %u We might not be able to get a connection.\n",len);
389  }
390 
391  messageBuff=new UINT8[len+1]; //+1 for the closing Zero
392  CAMsg::printMsg(LOG_INFO,"Waiting for symmetric key from previous Mix with length %i...\n", len);
394  {
395  if (ret != E_UNKNOWN)
396  {
397  CAMsg::printMsg(LOG_ERR,"Socket error occurred while receiving the symmetric key from the previous mix! Reason: '%s' (%i) The previous mix might be unable to verify our Mix certificate(s) and therefore closed the connection. Please ask the operator for the log, and exchange your certificates if necessary.\n",
399  }
400  else
401  {
402  CAMsg::printMsg(LOG_ERR,"Socket error occurred while receiving the symmetric key from the previous mix! The previous mix might be unable to verify our Mix certificate(s) and therefore closed the connection. Please ask the operator for the log, and exchange your certificates if necessary.\n");
403  }
404  delete []messageBuff;
405  messageBuff = NULL;
406  return ret;
407  }
408  messageBuff[len]=0;
409  CAMsg::printMsg(LOG_INFO,"Symmetric Key Info received from previous mix is:\n");
410  CAMsg::printMsg(LOG_INFO,"%s\n",(char*)messageBuff);
411  //get document
412  doc=parseDOMDocument(messageBuff,len);
413  if(doc == NULL)
414  {
415  CAMsg::printMsg(LOG_CRIT,"Could not parse symmetric key of the previous mix!\n");
416  delete []messageBuff;
417  messageBuff = NULL;
418  return E_UNKNOWN;
419  }
420  DOMElement* elemRoot=doc->getDocumentElement();
421  if(elemRoot == NULL)
422  {
423  CAMsg::printMsg(LOG_CRIT,"Symmetric key XML structure of previous mix is invalid!\n");
424  delete []messageBuff;
425  messageBuff = NULL;
426  if (doc != NULL)
427  {
428  doc->release();
429  doc = NULL;
430  }
431  return E_UNKNOWN;
432  }
433  //verify certificate from previous mix if enabled
434  if(CALibProxytest::getOptions()->verifyMixCertificates())
435  {
437  if(prevMixCert != NULL)
438  {
439  CAMsg::printMsg(LOG_DEBUG, "Previous mix certificate was verified by a trusted root CA.\n");
441  }
442  else
443  {
444  CAMsg::printMsg(LOG_ERR, "Could not verify certificate received from previous mix!\n");
445  return E_UNKNOWN;
446  }
447  }
448  //verify signature
449  //CASignature oSig;
451  SINT32 result = CAMultiSignature::verifyXML(messageBuff, len, pCert);
452  //oSig.setVerifyKey(pCert);
453  delete pCert;
454  pCert = NULL;
455  //if(oSig.verifyXML(messageBuff,len)!=E_SUCCESS)
456  if(result != E_SUCCESS)
457  {
458  CAMsg::printMsg(LOG_CRIT,"Could not verify the symmetric key!\n");
459  delete []messageBuff;
460  messageBuff = NULL;
461  return E_UNKNOWN;
462  }
463 
464  if ((result = checkCompatibility(elemRoot, "previous")) != E_SUCCESS)
465  {
466  delete []messageBuff;
467  messageBuff = NULL;
468  if (doc != NULL)
469  {
470  doc->release();
471  doc = NULL;
472  }
473  return result;
474  }
475 
476 
477  elemNonce=NULL;
478  getDOMChildByName(elemRoot,"Nonce",elemNonce,false);
479  tmpLen=50;
480  memset(tmpBuff,0,tmpLen);
481  if(elemNonce==NULL||getDOMElementValue(elemNonce,tmpBuff,&tmpLen)!=E_SUCCESS||
482  CABase64::decode(tmpBuff,tmpLen,tmpBuff,&tmpLen)!=E_SUCCESS||
483  tmpLen!=SHA_DIGEST_LENGTH ||
484  memcmp(SHA1(arNonce,16,NULL),tmpBuff,SHA_DIGEST_LENGTH)!=0
485  )
486  {
487  CAMsg::printMsg(LOG_CRIT,"Could not verify the nonce from previous mix!\n");
488  delete []messageBuff;
489  messageBuff = NULL;
490  if (doc != NULL)
491  {
492  doc->release();
493  doc = NULL;
494  }
495  return E_UNKNOWN;
496  }
497  CAMsg::printMsg(LOG_INFO,"Verified the symmetric key from previous mix!\n");
498 
499  UINT8 key[150];
500  UINT32 keySize=150;
501  ret=decodeXMLEncryptedKey(key,&keySize,messageBuff,len,m_pRSA);
502  delete []messageBuff;
503  messageBuff = NULL;
504  if(ret!=E_SUCCESS||keySize!=64)
505  {
506  CAMsg::printMsg(LOG_CRIT,"Could not decrypt the symmetric key from previous mix!\n");
507  if (doc != NULL)
508  {
509  doc->release();
510  doc = NULL;
511  }
512  return E_UNKNOWN;
513  }
514  if(m_pMuxIn->setReceiveKey(key,32)!=E_SUCCESS||m_pMuxIn->setSendKey(key+32,32)!=E_SUCCESS)
515  {
516  CAMsg::printMsg(LOG_CRIT,"Could not set the symmetric key to be used by the MuxSocket!\n");
517  if (doc != NULL)
518  {
519  doc->release();
520  doc = NULL;
521  }
522  return E_UNKNOWN;
523  }
524  m_pMuxIn->setCrypt(true);
526  elemKeepAlive=NULL;
527  elemKeepAliveSendInterval=NULL;
528  elemKeepAliveRecvInterval=NULL;
529  getDOMChildByName(elemRoot,"KeepAlive",elemKeepAlive);
530  getDOMChildByName(elemKeepAlive,"SendInterval",elemKeepAliveSendInterval);
531  getDOMChildByName(elemKeepAlive,"ReceiveInterval",elemKeepAliveRecvInterval);
532  UINT32 tmpSendInterval,tmpRecvInterval;
533  getDOMElementValue(elemKeepAliveSendInterval,tmpSendInterval,0xFFFFFFFF); //if now send interval was given set it to "infinite"
534  getDOMElementValue(elemKeepAliveRecvInterval,tmpRecvInterval,0xFFFFFFFF); //if no recv interval was given --> set it to "infinite"
535  CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Getting offer -- SendInterval %u -- Receive Interval %u\n",tmpSendInterval,tmpRecvInterval);
536  m_u32KeepAliveSendInterval = u32KeepAliveSendInterval;
537  if (m_u32KeepAliveSendInterval > tmpRecvInterval - 10000)
538  m_u32KeepAliveSendInterval-=10000; //make the send interval a little bit smaller than the related receive interval
539  m_u32KeepAliveRecvInterval=max(u32KeepAliveRecvInterval,tmpSendInterval);
540  if (m_u32KeepAliveRecvInterval - 10000 < tmpSendInterval)
541  {
543  }
544  CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Calculated -- SendInterval %u -- Receive Interval %u\n",m_u32KeepAliveSendInterval,m_u32KeepAliveRecvInterval);
545 
546  if (doc != NULL)
547  {
548  doc->release();
549  doc = NULL;
550  }
551 
552  return E_SUCCESS;
553  }
554 
555 #ifdef NEW_MIX_TYPE // TypeB mixes
556  void CALastMix::reconfigureMix() {
557  }
558 #endif
559 
561  {
562  CAMsg::printMsg(LOG_DEBUG,"Reconfiguring Last Mix\n");
563  CAMsg::printMsg(LOG_DEBUG,"Re-read cache proxies\n");
564  if(setTargets()!=E_SUCCESS)
565  CAMsg::printMsg(LOG_DEBUG,"Could not set new cache proxies\n");
566 #ifdef LOG_CRIME
567  CAMsg::printMsg(LOG_DEBUG,"Re-read crime settings\n");
568 
569 #endif
570  #ifndef NEW_MIX_TYPE // not TypeB mixes
571  #if defined (DELAY_CHANNELS)||defined (DELAY_CHANNELS_LATENCY)
572  CAMsg::printMsg(LOG_DEBUG,"Set new resources limitation parameters\n");
573  if(m_pChannelList!=NULL) {
574  #if defined (DELAY_CHANNELS)
575  m_pChannelList->setDelayParameters( CALibProxytest::getOptions()->getDelayChannelUnlimitTraffic(),
576  CALibProxytest::getOptions()->getDelayChannelBucketGrow(),
577  CALibProxytest::getOptions()->getDelayChannelBucketGrowIntervall());
578  #endif
579  #if defined (DELAY_CHANNELS_LATENCY)
580  UINT32 utemp=CALibProxytest::getOptions()->getDelayChannelLatency();
581  m_pChannelList->setDelayLatencyParameters( utemp);
582  #endif
583  }
584  #endif
585  #else // TypeB mixes
586  reconfigureMix();
587  #endif
588  return E_SUCCESS;
589  }
590 
592  {
593  CALastMix* pLastMix=static_cast<CALastMix*>(param);
594  UINT32 countLog=0;
595  UINT8 buff[256];
596  while(pLastMix->m_bRunLog)
597  {
598  if((countLog%10)==0)
599  {
600  logMemoryUsage();
601  }
602  if(countLog==0)
603  {
604  CAMsg::printMsg(LOG_DEBUG,"Uploaded Packets: %u\n",pLastMix->m_logUploadedPackets);
605  CAMsg::printMsg(LOG_DEBUG,"Downloaded Packets: %u\n",pLastMix->m_logDownloadedPackets);
606  print64(buff,(UINT64&)pLastMix->m_logUploadedBytes);
607  CAMsg::printMsg(LOG_DEBUG,"Uploaded Bytes : %s\n",buff);
608  print64(buff,(UINT64&)pLastMix->m_logDownloadedBytes);
609  CAMsg::printMsg(LOG_DEBUG,"Downloaded Bytes : %s\n",buff);
610  countLog=30;
611  }
612  sSleep(30);
613  countLog--;
614  }
616  }
617 
624  {
625  #ifdef ENABLE_GPERFTOOLS_CPU_PROFILER
626  ProfilerRegisterThread();
627  #endif
628 
629  CALastMix* pLastMix = static_cast<CALastMix*>(param);
630  CAQueue* pQueue=pLastMix->m_pQueueSendToMix;
631  CAMuxSocket* pMuxSocket=pLastMix->m_pMuxIn;
632  SINT32 ret;
633  UINT32 len;
634  UINT32 u32KeepAliveSendInterval=pLastMix->m_u32KeepAliveSendInterval;
635 #ifndef USE_POOL
636  tQueueEntry* pQueueEntry=new tQueueEntry;
637  MIXPACKET* pMixPacket=&pQueueEntry->packet;
638 
639  while(!pLastMix->m_bRestart)
640  {
641  len=sizeof(tQueueEntry);
642  ret=pQueue->getOrWait((UINT8*)pQueueEntry,&len,u32KeepAliveSendInterval);
643  if(ret==E_TIMEDOUT)
644  {
645  pMixPacket->flags=CHANNEL_DUMMY;
646  pMixPacket->channel=DUMMY_CHANNEL;
647  getRandom(pMixPacket->data,DATA_SIZE);
648  }
649  else if(ret!=E_SUCCESS||len!=sizeof(tQueueEntry))
650  {
651  CAMsg::printMsg(LOG_ERR,"CALastMix::lm_loopSendToMix - Error in dequeueing MixPaket\n");
652  CAMsg::printMsg(LOG_ERR,"ret=%i len=%i\n",ret,len);
654  break;
655  }
656 #ifdef ANON_DEBUG_MODE
657  if (pMixPacket->flags&CHANNEL_DEBUG)
658  {
659  UINT8 base64Payload[DATA_SIZE << 1];
660  EVP_EncodeBlock(base64Payload, pMixPacket->data, DATA_SIZE);//base64 encoding (without newline!)
661  CAMsg::printMsg(LOG_DEBUG, "Send Downstream AN.ON packet to previous Mix debug: %s\n", base64Payload);
662  }
663 #endif
664  if (pMuxSocket->send(pMixPacket) != MIXPACKET_SIZE)
665  {
666  CAMsg::printMsg(LOG_ERR,"CALastMix::lm_loopSendToMix - Error in sending MixPaket\n");
668  break;
669  }
670 #ifdef LOG_PACKET_TIMES
671  if(!isZero64(pQueueEntry->timestamp_proccessing_start))
672  {
673  getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end);
674  pLastMix->m_pLogPacketStats->addToTimeingStats(*pQueueEntry,CHANNEL_DATA,false);
675  }
676 #endif
677  }
678  delete pQueueEntry;
679  pQueueEntry = NULL;
680 #else
681  CAPool* pPool=new CAPool(MIX_POOL_SIZE);
682  tPoolEntry* pPoolEntry=new tPoolEntry;
683  MIXPACKET* pMixPacket=&pPoolEntry->packet;
684  while(!pLastMix->m_bRestart)
685  {
686  len=sizeof(tQueueEntry);
687  SINT32 ret=pQueue->getOrWait((UINT8*)pPoolEntry,&len,MIX_POOL_TIMEOUT);
688  if(ret==E_TIMEDOUT)
689  {
690  pMixPacket->flags=CHANNEL_DUMMY;
691  pMixPacket->channel=DUMMY_CHANNEL;
692  getRandom(pMixPacket->data,DATA_SIZE);
693  #ifdef LOG_PACKET_TIMES
694  setZero64(pPoolEntry->timestamp_proccessing_start);
695  #endif
696  }
697  else if(ret!=E_SUCCESS||len!=sizeof(tQueueEntry))
698  {
699  break;
700  }
701  #ifdef LOG_PACKET_TIMES
702  getcurrentTimeMicros(pPoolEntry->pool_timestamp_in);
703  #endif
704  pPool->pool(pPoolEntry);
705  #ifdef LOG_PACKET_TIMES
706  getcurrentTimeMicros(pPoolEntry->pool_timestamp_out);
707  #endif
708  if(pMuxSocket->send(pMixPacket)!=MIXPACKET_SIZE)
709  break;
710 #ifdef LOG_PACKET_TIMES
711  if(!isZero64(pPoolEntry->timestamp_proccessing_start))
712  {
713  getcurrentTimeMicros(pPoolEntry->timestamp_proccessing_end);
714  pLastMix->m_pLogPacketStats->addToTimeingStats(*pPoolEntry,CHANNEL_DATA,false);
715  }
716 #endif
717  }
718  delete pPoolEntry;
719  pPoolEntry = NULL;
720  delete pPool;
721  pPool = NULL;
722 #endif
723  CAMsg::printMsg(LOG_DEBUG,"Exiting Thread SendToMix\n");
725  }
726 
727 
728 /* How to end this thread:
729  * 1. set m_brestart=true
730  */
732  {
733  #ifdef ENABLE_GPERFTOOLS_CPU_PROFILER
734  ProfilerRegisterThread();
735  #endif
736  CALastMix* pLastMix = static_cast<CALastMix*>(pParam);
737  CAMuxSocket* pMuxSocket=pLastMix->m_pMuxIn;
738  CAQueue* pQueue=pLastMix->m_pQueueReadFromMix;
739  tQueueEntry* pQueueEntry=new tQueueEntry;
740  MIXPACKET* pMixPacket=&pQueueEntry->packet;
741  CASingleSocketGroup* pSocketGroup=new CASingleSocketGroup(false);
742  pSocketGroup->add(*pMuxSocket);
743  #ifdef USE_POOL
744  CAPool* pPool=new CAPool(MIX_POOL_SIZE);
745  #endif
746  UINT64 keepaliveNow,keepaliveLast;
747  UINT32 u32KeepAliveRecvInterval=pLastMix->m_u32KeepAliveRecvInterval;
748  getcurrentTimeMillis(keepaliveLast);
749  while(!pLastMix->m_bRestart)
750  {
752  {
753 #ifdef DEBUG
754  CAMsg::printMsg(LOG_DEBUG,"CAFirstMix::Queue is full!\n");
755 #endif
756  msSleep(200);
757  getcurrentTimeMillis(keepaliveLast);
758  continue;
759  }
760  //check if the connection is broken because we did not receive a Keep_alive-Message
761  getcurrentTimeMillis(keepaliveNow);
762  UINT32 keepaliveDiff=diff64(keepaliveNow,keepaliveLast);
763  if(keepaliveDiff>u32KeepAliveRecvInterval)
764  {
765  CAMsg::printMsg(LOG_ERR,"CALastMix::loopReadFromMix() -- restart because of KeepAlive-Traffic Timeout!\n");
766  pLastMix->m_bRestart=true;
768  break;
769  }
770  SINT32 ret=pSocketGroup->select(MIX_POOL_TIMEOUT);
771  if(ret < 0)
772  {
773  if (ret == E_TIMEDOUT)
774  {
775  #ifdef USE_POOL
776  pMixPacket->flags=CHANNEL_DUMMY;
777  pMixPacket->channel=DUMMY_CHANNEL;
778  getRandom(pMixPacket->data,DATA_SIZE);
779  #ifdef LOG_PACKET_TIMES
780  setZero64(pQueueEntry->timestamp_proccessing_start);
781  #endif
782  #else
783  continue;
784  #endif
785  }
786  else
787  {
788  /* another error occured (happens sometimes while debugging because
789  * of interruption, if a breakpoint is reached -> poll() returns
790  * errorcode EINTR)
791  * Note: Any Error on select() does not mean, that the underliny connections have some error state, because
792  * in this case select() returns the socket and than this socket returns the error
793  */
794  continue;
795  }
796  }
797  else if(ret>0)
798  {
799  ret=pMuxSocket->receive(pMixPacket); //receives a whole MixPacket
800  #ifdef LOG_PACKET_TIMES
801  getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_start);
802  #endif
803  #ifdef DATA_RETENTION_LOG
804  pQueueEntry->dataRetentionLogEntry.t_in=htonl(time(NULL));
805  #endif
806  if(ret!=MIXPACKET_SIZE)
807  {//something goes wrong...
808  CAMsg::printMsg(LOG_ERR,"CALastMix::lm_loopReadFromMix - received returned: %i\n",ret);
809  pLastMix->m_bRestart=true;
811  break;
812  }
813  }
814  #ifdef USE_POOL
815  #ifdef LOG_PACKET_TIMES
816  getcurrentTimeMicros(pQueueEntry->pool_timestamp_in);
817  #endif
818  pPool->pool((tPoolEntry*) pQueueEntry);
819  #ifdef LOG_PACKET_TIMES
820  getcurrentTimeMicros(pQueueEntry->pool_timestamp_out);
821  #endif
822  #endif
823  pQueue->add(pQueueEntry,sizeof(tQueueEntry));
824  getcurrentTimeMillis(keepaliveLast);
825  }
826  delete pQueueEntry;
827  pQueueEntry = NULL;
828  delete pSocketGroup;
829  pSocketGroup = NULL;
830  #ifdef USE_POOL
831  delete pPool;
832  pPool = NULL;
833  #endif
835  }
836 
837 #ifdef LOG_CRIME
838 //Assuming we have aligned HTTP or SOCKS protocolData
839  UINT8* CALastMix::parseDomainFromPayload(const UINT8 *payloadData, UINT32 payloadDataLength)
840  {
841  if( (payloadDataLength < 5) ||
842  (payloadDataLength > PAYLOAD_SIZE) )
843  {
844  return NULL;
845  }
846 
847  if( (payloadData[0] == 0x05) && (payloadData[1] & 0x03) )
848  {
849  //in this case we have a SOCKS message
850  UINT32 tempUrlLength = 0, urlStartOffset = 0;
851  //of which address type is the dst address?
852  switch(payloadData[3])
853  {
854  case 0x01: //IPv4_Address
855  {
856  tempUrlLength = 4;
857  urlStartOffset = 4;
858  break;
859  }
860 
861  case 0x03: //Domain name
862  {
863  tempUrlLength = payloadData[4];
864  urlStartOffset = 5;
865  //CAMsg::printMsg(LOG_ERR,"SOCKS v5 domain name length %u.\n", tempUrlLength);
866  break;
867  }
868 
869  case 0x4: //IPv6 address
870  {
871  tempUrlLength = 16;
872  urlStartOffset = 4;
873  break;
874  }
875 
876  default:
877  {
878  return NULL;
879  }
880  }
881  if(payloadDataLength < (urlStartOffset + tempUrlLength) )
882  {
883  return NULL;
884  }
885  UINT8 *address = new UINT8[tempUrlLength+1];
886  memcpy(address, payloadData+urlStartOffset, tempUrlLength);
887  address[tempUrlLength] = 0;
888  //CAMsg::printMsg(LOG_ERR,"SOCKS v5 found with address %s.\n", address);
889  return address;
890  }
891  else
892  {
893  //In this case the message is handled as a common HTTP request
894  //So we lock for the Request-Line
895  //Note according to [HTTP 1.1] the Request-Line might be preceded by CRLF
896  //Snip: In the interest of robustness, servers SHOULD ignore any empty
897  // line(s) received where a Request-Line is expected. In other words, if
898  // the server is reading the protocol stream at the beginning of a
899  // message and receives a CRLF first, it should ignore the CRLF.
900 
901  //OK lets try to use a regular expression for the task instead of a hand crafted parser...
902  //do the match...
903  tre_regmatch_t theMatches[3];
904  int ret=tre_regnexec(m_pregexpRequestLine,(const char*)payloadData,payloadDataLength,3,theMatches,0);
905  if(ret!=0)
906  return NULL;
907 
908  const UINT8* httpVerb=payloadData+theMatches[1].rm_so;
909  UINT8* domainName=NULL;
910  if((payloadData+theMatches[1].rm_eo-payloadData+theMatches[1].rm_so)>6 && strncasecmp("CONNECT",(const char*)httpVerb,7)==0)
911  {//Connect request --> URI is domain [:port]
912  UINT32 matchLen=theMatches[2].rm_eo-theMatches[2].rm_so;
913  domainName=new UINT8[matchLen+1];
914  memcpy(domainName,payloadData+theMatches[2].rm_so,matchLen);
915  domainName[matchLen]=0;
916  strtok((char*)domainName,":");
917  }
918  else
919  {
920  //do the match...
921  tre_regmatch_t theDomainMatches[2];
922  ret=tre_regnexec(m_pregexpDomainOfURI,(const char*)payloadData+theMatches[2].rm_so,theMatches[2].rm_eo-theMatches[2].rm_so,2,theDomainMatches,0);
923  if(ret!=0)
924  return NULL;
925  UINT32 matchLen=theDomainMatches[1].rm_eo-theDomainMatches[1].rm_so;
926  domainName=new UINT8[matchLen+1];
927  memcpy(domainName,payloadData+theMatches[2].rm_so+theDomainMatches[1].rm_so,matchLen);
928  domainName[matchLen]=0;
929  }
930  return domainName;
931  }
932  }
933 
934  bool CALastMix::checkCrime(const UINT8* payLoad,UINT32 payLen,bool bURLCheck)
935  {
936  //Lots of TODO!!!!
937  //DNS Lookup may block if Host does not exists!!!!!
938  //so we use regexp....
939  if(bURLCheck&&m_nCrimeRegExpsURL>0)
940  {
941  UINT8 *startOfUrl = parseDomainFromPayload(payLoad, payLen);
942  if(startOfUrl!=NULL)
943  {
944  UINT32 strLen = strlen((char *)startOfUrl);
945  for(UINT32 i = 0; i < m_nCrimeRegExpsURL; i++)
946  {
947  if(tre_regnexec(&m_pCrimeRegExpsURL[i],(char*)startOfUrl,strLen,0,NULL,0)==0)
948  {
949  delete [] startOfUrl;
950  return true;
951  }
952  }
953  delete [] startOfUrl;
954  }
955  }
956  for(UINT32 i = 0; i < m_nCrimeRegExpsPayload; i++)
957  {
958  if (tre_regnexec(&m_pCrimeRegExpsPayload[i],(const char*)payLoad ,payLen,0,NULL,0)==0)
959  {
960  return true;
961  }
962  }
963  return false;
964  }
965 #endif
966 
972  {
974  if(cntTargets==0)
975  {
976  CAMsg::printMsg(LOG_CRIT,"No Targets (proxies) specified!\n");
977  return E_UNKNOWN;
978  }
979  m_pCacheLB->clean();
980  m_pSocksLB->clean();
981  m_pVPNLB->clean();
982  UINT32 i;
983  for(i=1;i<=cntTargets;i++)
984  {
985  CATargetInterface oTargetInterface;
986  CALibProxytest::getOptions()->getTargetInterface(oTargetInterface,i);
987  if(oTargetInterface.getTargetType()==TARGET_HTTP_PROXY)
988  {
989  m_pCacheLB->add(oTargetInterface.getAddr());
990  }
991  else if(oTargetInterface.getTargetType()==TARGET_SOCKS_PROXY)
992  {
993  m_pSocksLB->add(oTargetInterface.getAddr());
994  }
995  else if (oTargetInterface.getTargetType() == TARGET_VPN_PROXY)
996  {
997  m_pVPNLB->add(oTargetInterface.getAddr());
998  }
999  oTargetInterface.cleanAddr();
1000  }
1001  CAMsg::printMsg(LOG_DEBUG,"This mix will use the following proxies:\n");
1002  for(i=0;i<m_pCacheLB->getElementCount();i++)
1003  {
1004  CASocketAddrINet* pAddr=m_pCacheLB->get();
1005  UINT8 ip[4];
1006  pAddr->getIP(ip);
1007  UINT32 port=pAddr->getPort();
1008  CAMsg::printMsg(LOG_DEBUG,"%u. HTTP Proxy's Address: %u.%u.%u.%u:%u\n",i+1,ip[0],ip[1],ip[2],ip[3],port);
1009  }
1010  for(i=0;i<m_pSocksLB->getElementCount();i++)
1011  {
1012  CASocketAddrINet* pAddr=m_pSocksLB->get();
1013  UINT8 ip[4];
1014  pAddr->getIP(ip);
1015  UINT32 port=pAddr->getPort();
1016  CAMsg::printMsg(LOG_DEBUG,"%u. SOCKS Proxy's Address: %u.%u.%u.%u:%u\n",i+1,ip[0],ip[1],ip[2],ip[3],port);
1017  }
1018  for (i = 0; i<m_pVPNLB->getElementCount(); i++)
1019  {
1020  CASocketAddrINet* pAddr = m_pVPNLB->get();
1021  UINT8 ip[4];
1022  pAddr->getIP(ip);
1023  UINT32 port = pAddr->getPort();
1024  CAMsg::printMsg(LOG_DEBUG, "%u. VPN Proxy's Address: %u.%u.%u.%u:%u\n", i + 1, ip[0], ip[1], ip[2], ip[3], port);
1025  }
1026 
1027 
1028  return E_SUCCESS;
1029  }
1030 
1032 {
1033 #ifdef LOG_CRIME
1034  if (m_pSquidLogHelper != NULL)
1035  {
1036  m_pSquidLogHelper->stop();
1037  delete m_pSquidLogHelper;
1038  m_pSquidLogHelper = NULL;
1039  }
1040 #endif
1041 
1042  m_bRestart=true;
1044  m_bRunLog=false;
1045 #ifdef REPLAY_DETECTION
1046  if(m_pReplayMsgProc!=NULL)
1047  {
1048  delete m_pReplayMsgProc;
1049  m_pReplayMsgProc = NULL;
1050  }
1051  m_pReplayMsgProc=NULL;
1052 #endif
1053 
1055  {
1058  }
1060 
1061  if(m_pMuxIn!=NULL)
1062  {
1063  m_pMuxIn->close();
1064  }
1065  //writing some bytes to the queue...
1066  if(m_pQueueSendToMix!=NULL)
1067  {
1068  UINT8 b[sizeof(tQueueEntry)+1];
1069  m_pQueueSendToMix->add(b,sizeof(tQueueEntry)+1);
1070  }
1071 
1072  if(m_pthreadSendToMix!=NULL)
1073  {
1074  CAMsg::printMsg(LOG_CRIT,"Wait for LoopSendToMix!\n");
1076  delete m_pthreadSendToMix;
1077  m_pthreadSendToMix = NULL;
1078  }
1079  m_pthreadSendToMix=NULL;
1080  if(m_pthreadReadFromMix!=NULL)
1081  {
1082  CAMsg::printMsg(LOG_CRIT,"Wait for LoopReadFromMix!\n");
1084  CAMsg::printMsg(LOG_CRIT, "Thread LoopReadFromMix joind successful!\n");
1085  delete m_pthreadReadFromMix;
1086  m_pthreadReadFromMix = NULL;
1087  }
1088  m_pthreadReadFromMix=NULL;
1089 
1090 #ifdef LOG_PACKET_TIMES
1091  CAMsg::printMsg(LOG_CRIT,"Wait for LoopLogPacketStats to terminate!\n");
1092  if(m_pLogPacketStats!=NULL)
1093  {
1094  m_pLogPacketStats->stop();
1095  delete m_pLogPacketStats;
1096  m_pLogPacketStats = NULL;
1097  }
1098  m_pLogPacketStats=NULL;
1099 #endif
1100  if(m_pChannelList!=NULL)
1101  {
1102  lmChannelListEntry* pChannelListEntry=m_pChannelList->getFirstSocket();
1103  while(pChannelListEntry!=NULL)
1104  {
1105  delete pChannelListEntry->pCipher;
1106  pChannelListEntry->pCipher = NULL;
1107  delete pChannelListEntry->pQueueSend;
1108  pChannelListEntry->pQueueSend = NULL;
1109  if (pChannelListEntry->pSocket != NULL)
1110  {
1111  pChannelListEntry->pSocket->close();
1112  delete pChannelListEntry->pSocket;
1113  pChannelListEntry->pSocket = NULL;
1114  }
1115  pChannelListEntry=m_pChannelList->getNextSocket();
1116  }
1117  }
1118  delete m_pQueueReadFromMix;
1119  m_pQueueReadFromMix = NULL;
1120  delete m_pQueueSendToMix;
1121  m_pQueueSendToMix = NULL;
1122  #ifndef NEW_MIX_TYPE // not TypeB mixes
1123  /* TypeB mixes are using an own implementation */
1124  delete m_pChannelList;
1125  m_pChannelList = NULL;
1126  if(m_pMuxIn != NULL)
1127  {
1128  m_pMuxIn->close();
1129  delete m_pMuxIn;
1130  m_pMuxIn=NULL;
1131  }
1132 
1133  delete m_pRSA;
1134  m_pRSA = NULL;
1135  #endif
1136  CAMsg::printMsg(LOG_CRIT, "LastMix:clean() finished!\n");
1137  return E_SUCCESS;
1138  }
1139 
1141 {
1142  SINT32 r = CAMix::initMixCascadeInfo(mixes);
1143  DOMElement* cascade = m_docMixCascadeInfo->getDocumentElement();
1144  setDOMElementAttribute(cascade,"create",(UINT8*)"true");
1145  return r;
1146 }
1147 
1148 
1149 #ifdef LOG_CRIME
1150 void CALastMix::externalCrimeNotifier(UINT8 lastMixToProxyConnectionSrcIP[4],
1151  UINT16 lastMixToProxyConnectionSrcPort,
1152  UINT8 lastMixToProxyConnectionDstIP[4],
1153  UINT16 lastMixToProxyConnectionDstPort, UINT8* pstrExternalLogEntry)
1154 {
1155  int log = LOG_ENCRYPTED;
1156  if (!CALibProxytest::getOptions()->isEncryptedLogEnabled())
1157  log = LOG_CRIT;
1158  //Find corresponding channel and set channel to be a crime one
1159 
1160  HCHANNEL channel;
1161  if (m_pChannelList->getChannelAndSetCrime(lastMixToProxyConnectionSrcIP, lastMixToProxyConnectionSrcPort, lastMixToProxyConnectionDstIP, lastMixToProxyConnectionDstPort, channel) != E_SUCCESS)
1162  {
1163  CAMsg::printMsg(log, "Crime detected (external notification) -- but channel already closed! "
1164  " -- External Log Entry: \n%s\n", pstrExternalLogEntry);
1165  return;
1166  }
1167 
1168  tQueueEntry* pQueueEntryCrime = new tQueueEntry;
1169  memset(pQueueEntryCrime, 0, sizeof(tQueueEntry));
1170  m_pMuxIn->sigCrime(channel, &(pQueueEntryCrime->packet));
1171  m_pQueueSendToMix->add(pQueueEntryCrime, sizeof(tQueueEntry));
1172  delete pQueueEntryCrime;
1173  CAMsg::printMsg(log, "Crime detected (external notification) -- previous mix channel: "
1174  "%u -- Proxy Connection source port: %u -- External Log Entry: \n%s\n", channel, lastMixToProxyConnectionSrcPort,
1175  pstrExternalLogEntry);
1176 
1177 }
1178 #endif //LOG_CRIME
1179 
1180 #endif //ONLY_LOCAL_PROXY
THREAD_RETURN lm_loopReadFromMix(void *pParam)
Definition: CALastMix.cpp:731
THREAD_RETURN lm_loopSendToMix(void *param)
How to end this thread: 0.
Definition: CALastMix.cpp:623
THREAD_RETURN lm_loopLog(void *param)
Definition: CALastMix.cpp:591
#define LOG_ENCRYPTED
Definition: CAMsg.hpp:46
#define MONITORING_FIRE_NET_EVENT(e_type)
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
SINT32 sSleep(UINT32 sec)
Sleeps sec Seconds.
Definition: CAUtil.cpp:425
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
SINT32 getRandom(UINT32 *val)
Gets 32 random bits.
Definition: CAUtil.cpp:346
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
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 decodeXMLEncryptedKey(UINT8 *key, UINT32 *keylen, const UINT8 *const xml, UINT32 xmllen, CAASymCipher *pRSA)
Definition: CAUtil.cpp:1625
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
bool isZero64(UINT64 &op1)
Definition: CAUtil.hpp:464
void print64(UINT8 *buff, UINT64 num)
Definition: CAUtil.hpp:482
#define LM_PACKET_STATS_LOG_INTERVALL
Definition: StdAfx.h:249
#define GET_NET_ERROR
Definition: StdAfx.h:469
#define MAX_READ_FROM_PREV_MIX_QUEUE_SIZE
Definition: StdAfx.h:226
#define GET_NET_ERROR_STR(x)
Definition: StdAfx.h:471
#define MIX_POOL_TIMEOUT
Definition: StdAfx.h:245
#define REPLAY_TIMESTAMP_PROPAGATION_INTERVALL
Definition: StdAfx.h:176
#define THREAD_RETURN
Definition: StdAfx.h:540
#define THREAD_RETURN_SUCCESS
Definition: StdAfx.h:542
#define FLOW_CONTROL_SENDME_SOFT_LIMIT
Definition: StdAfx.h:223
#define DUMMY_CHANNEL
Definition: StdAfx.h:246
#define MIX_POOL_SIZE
Definition: StdAfx.h:243
#define max(a, b)
Definition: StdAfx.h:654
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 generateKeyPair(UINT32 size)
Generates a new random key-pair of size bits.
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
SINT32 add(CASocketAddr *const pAddr)
CASocketAddrINet * get()
Gets the 'next' Address according to the Load-Balancing algorithm.
SINT32 clean()
Deletes all information.
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 setPrevMixTestCertificate(CACertificate *cert)
UINT32 getKeepAliveRecvInterval()
CAMultiSignature * getMultiSigner()
CAListenerInterface * getListenerInterface(UINT32 nr)
UINT32 getKeepAliveSendInterval()
CACertStore * getTrustedCertificateStore()
UINT32 getTargetInterfaceCount()
CACertificate * getPrevMixTestCertificate()
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 start()
Definition: CADatabase.cpp:220
lmChannelListEntry * getFirstSocket()
lmChannelListEntry * getNextSocket()
volatile bool m_bRunLog
Definition: CALastMix.hpp:189
volatile UINT32 m_logDownloadedPackets
Definition: CALastMix.hpp:192
CAQueue * m_pQueueSendToMix
Definition: CALastMix.hpp:153
volatile UINT64 m_logDownloadedBytes
Definition: CALastMix.hpp:193
SINT32 initMixCascadeInfo(DOMElement *)
This will initialize the XML Cascade Info struct XMLFirstMixToInfoService that is sent to the InfoSer...
Definition: CALastMix.cpp:1140
SINT32 setTargets()
Reads the configured proxies from options.
Definition: CALastMix.cpp:971
friend THREAD_RETURN lm_loopReadFromMix(void *pParam)
Definition: CALastMix.cpp:731
volatile UINT64 m_logUploadedBytes
Definition: CALastMix.hpp:191
virtual SINT32 processKeyExchange()
Processes the startup communication with the preceeding mix.
Definition: CALastMix.cpp:236
CACacheLoadBalancing * m_pVPNLB
Definition: CALastMix.hpp:160
CAASymCipher * m_pRSA
Definition: CALastMix.hpp:161
CALastMixChannelList * m_pChannelList
Definition: CALastMix.hpp:166
virtual SINT32 initOnce()
Definition: CALastMix.cpp:56
friend THREAD_RETURN lm_loopSendToMix(void *param)
How to end this thread: 0.
Definition: CALastMix.cpp:623
CAQueue * m_pQueueReadFromMix
Definition: CALastMix.hpp:154
CAThread * m_pthreadReadFromMix
Definition: CALastMix.hpp:163
CAThread * m_pthreadSendToMix
Definition: CALastMix.hpp:162
CACacheLoadBalancing * m_pCacheLB
Definition: CALastMix.hpp:158
volatile UINT32 m_logUploadedPackets
Definition: CALastMix.hpp:190
SINT32 reconfigure()
Definition: CALastMix.cpp:560
CAMuxSocket * m_pMuxIn
Definition: CALastMix.hpp:152
volatile bool m_bRestart
Definition: CALastMix.hpp:151
SINT32 clean()
Definition: CALastMix.cpp:1031
SINT32 init()
Definition: CALastMix.cpp:84
CACacheLoadBalancing * m_pSocksLB
Definition: CALastMix.hpp:159
static CACmdLnOptions * getOptions()
CASocketAddr * getAddr() const
SINT32 appendCompatibilityInfo(DOMNode *a_parent)
Definition: CAMix.cpp:634
SINT32 checkCompatibility(DOMNode *a_parent, const char *a_mixPosition)
Definition: CAMix.cpp:670
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_pMuxInControlChannelDispatcher
Definition: CAMix.hpp:196
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
XERCES_CPP_NAMESPACE::DOMDocument * m_docMixCascadeInfo
Definition: CAMix.hpp:193
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
static SINT32 verifyXML(const UINT8 *const in, UINT32 inlen, CACertificate *a_cert)
SINT32 close()
Closes the underlying socket.
SINT32 accept(UINT16 port)
SINT32 receive(MIXPACKET *pPacket)
Receives a whole MixPacket.
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 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
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
UINT32 getSize()
Returns the size of stored data in byte.
Definition: CAQueue.hpp:101
SINT32 startTimeStampPorpagation(UINT32 minutesPropagationIntervall)
Sends the current replay timestamp periodically on the downstream replay control channel.
This is an abstract class for representing a socket address used in CASocket, CADatagramSocket and CA...
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.
UINT16 getPort() const
Returns the port value of the address.
SINT32 getIP(UINT8 buff[4]) const
Returns the IP-Numbers for this address.
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 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 close()
Definition: CASocket.cpp:351
TargetType getTargetType() const
CASocketAddr * getAddr() const
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
static SINT32 dumpToMem(const DOMNode *node, UINT8 *buff, UINT32 *size)
Dumps the node and all childs into buff.
Definition: DOM_Output.hpp:161
const SINT32 E_SUCCESS
Definition: errorcodes.hpp:2
#define E_UNKNOWN
Definition: errorcodes.hpp:3
#define E_TIMEDOUT
Definition: errorcodes.hpp:10
@ ev_net_keyExchangePrevSuccessful
@ ev_net_prevConnectionClosed
@ ev_net_keyExchangePrevFailed
@ ev_net_prevConnected
HCHANNEL channel
Definition: typedefs.hpp:117
UINT8 data[DATA_SIZE]
Definition: typedefs.hpp:121
UINT16 flags
Definition: typedefs.hpp:118
CASymChannelCipher * pCipher
Definition: typedefs.hpp:169
MIXPACKET packet
Definition: typedefs.hpp:170
#define CHANNEL_DATA
Definition: typedefs.hpp:42
HCHANNEL channel
Definition: typedefs.hpp:0
@ TARGET_VPN_PROXY
Definition: typedefs.hpp:32
@ TARGET_SOCKS_PROXY
Definition: typedefs.hpp:32
@ TARGET_HTTP_PROXY
Definition: typedefs.hpp:32
#define MIXPACKET_SIZE
Definition: typedefs.hpp:40
#define CHANNEL_DEBUG
Definition: typedefs.hpp:51
#define PAYLOAD_SIZE
Definition: typedefs.hpp:73
#define CHANNEL_DUMMY
Definition: typedefs.hpp:50
UINT32 HCHANNEL
Definition: typedefs.hpp:34
struct t_queue_entry tQueueEntry
Definition: typedefs.hpp:188
UINT16 len
Definition: typedefs.hpp:0
tQueueEntry tPoolEntry
Definition: typedefs.hpp:192
#define DATA_SIZE
Definition: typedefs.hpp:69
#define CHAIN_TIMEOUT
Definition: typedefsb.hpp:37
#define CHANNEL_TIMEOUT
Definition: typedefsb.hpp:36
#define CHANNEL_DOWNSTREAM_PACKETS
Definition: typedefsb.hpp:35