Mixe for Privacy and Anonymity in the Internet
CALocalProxy.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 #include "CALocalProxy.hpp"
30 #include "CASocketList.hpp"
31 #include "CASocketGroup.hpp"
32 #include "CASocketGroupEpoll.hpp"
33 #include "CAMsg.hpp"
34 #include "CACmdLnOptions.hpp"
35 #include "CAUtil.hpp"
36 #include "CASocketAddrINet.hpp"
37 #include "CABase64.hpp"
38 #include "CALibProxytest.hpp"
39 #include "xml/DOM_Output.hpp"
40 #include "CASymChannelCipher.hpp"
41 #include "CASymCipherOFB.hpp"
43 #ifndef NEW_MIX_TYPE
44 
45 // signals the main loop whether to capture or replay packets
49 
50 // Signal handler for SIGUSR1.
51 // This starts the capture with the next channel-open message.
52 void SIGUSR1_handler(int signum)
53  {
54  CAMsg::printMsg(LOG_DEBUG,"Starting to capture packets for replay attack.\n");
57  }
58 
59 // Signal handler for SIGUSR2.
60 // This replays the currently captured packets.
61 void SIGUSR2_handler(int signum)
62  {
63  CAMsg::printMsg(LOG_DEBUG,"Starting replay of packets.\n");
65  }
66 
67 
69  {
70  if(initOnce()!=E_SUCCESS)
71  return E_UNKNOWN;
72  for(;;)
73  {
74  CAMsg::printMsg(LOG_DEBUG, "CALocalProxy main: before init()\n");
75  if(init() == E_SUCCESS)
76  {
77  CAMsg::printMsg(LOG_DEBUG, "CALocalProxy main: init() returned success\n");
78  CAMsg::printMsg(LOG_INFO, "The local proxy is now on-line.\n");
79  loop();
80  CAMsg::printMsg(LOG_DEBUG, "CAMix local proxy: loop() returned, maybe connection lost.\n");
81  }
82  else
83  {
84  CAMsg::printMsg(LOG_DEBUG, "init() failed, maybe no connection.\n");
85  }
86 
87  CAMsg::printMsg(LOG_DEBUG, "CALocalProxy main: before clean()\n");
88  clean();
89  CAMsg::printMsg(LOG_DEBUG, "CAMix LocalProxy: after clean()\n");
90  sSleep(20);
91  }
92 }
93 
94 
96  {
97  if(CALibProxytest::getOptions()->getListenerInterfaceCount()<1)
98  {
99  CAMsg::printMsg(LOG_CRIT,"No Listener Interface spezified!\n");
100  return E_UNKNOWN;
101  }
102 
104  #if defined(REPLAY_DETECTION)&&!defined(_WIN32)
105  // Set up signal handling for the replay attack.
106  signal(SIGUSR1, SIGUSR1_handler);
107  signal(SIGUSR2, SIGUSR2_handler);
108  #endif
109 
110  UINT8 strTarget[255];
111  if(CALibProxytest::getOptions()->getMixHost(strTarget,255)!=E_SUCCESS)
112  {
113  CAMsg::printMsg(LOG_CRIT,"No AnonServer specified!\n");
114  return E_UNKNOWN;
115  }
116  return E_SUCCESS;
117  }
118 
120  {
121  CAListenerInterface* pListener;
123  m_bWithNewFlowControl=false;
126  m_socketIn.create();
127  m_socketIn.setReuseAddr(true);
129  if(pListener==NULL)
130  {
131  CAMsg::printMsg(LOG_CRIT,"No listener specified\n");
132  return E_UNKNOWN;
133  }
134  CASocketAddrINet* pSocketAddrIn=(CASocketAddrINet*)pListener->getAddr();
135  delete pListener;
136  pListener = NULL;
137  if(pSocketAddrIn->isAnyIP())
138  pSocketAddrIn->setAddr((UINT8*)"127.0.0.1",pSocketAddrIn->getPort());
139  if(m_socketIn.listen(*pSocketAddrIn)!=E_SUCCESS)
140  {
141  CAMsg::printMsg(LOG_CRIT,"Cannot listen (1)\n");
142  delete pSocketAddrIn;
143  pSocketAddrIn = NULL;
144  return E_UNKNOWN;
145  }
146  if(CALibProxytest::getOptions()->getSOCKSServerPort()!=(UINT16)-1)
147  {
148  pSocketAddrIn->setAddr((UINT8*)"127.0.0.1",CALibProxytest::getOptions()->getSOCKSServerPort());
151  if(m_socketSOCKSIn.listen(*pSocketAddrIn)!=E_SUCCESS)
152  {
153  CAMsg::printMsg(LOG_CRIT,"Cannot listen (2)\n");
154  return E_UNKNOWN;
155  }
156  }
157  delete pSocketAddrIn;
158  pSocketAddrIn = NULL;
159  CASocketAddrINet addrNext;
160  UINT8 strTarget[255];
161  CALibProxytest::getOptions()->getMixHost(strTarget,255);
162  addrNext.setAddr(strTarget,CALibProxytest::getOptions()->getMixPort());
163  CAMsg::printMsg(LOG_INFO,"Try connecting to next Mix...\n");
164  m_pmuxOut = new CAMuxSocket(OFB);
168  if(m_pmuxOut->connect(addrNext)==E_SUCCESS)
169  {
170  CAMsg::printMsg(LOG_INFO," connected!\n");
171  UINT16 size;
172  UINT8 byte;
173  m_pmuxOut->getCASocket()->receiveFully((UINT8*)&size,2);
174  m_pmuxOut->getCASocket()->receiveFully((UINT8*)&byte,1);
175  CAMsg::printMsg(LOG_INFO,"Received Key Info!\n");
176  size=ntohs(size);
177 #ifdef _DEBUG
178  CAMsg::printMsg(LOG_INFO,"Key Info size is:%u\n",size);
179 #endif
180  if(byte=='<')//assuming XML
181  {
182 #ifdef _DEBUG
183  CAMsg::printMsg(LOG_INFO,"Key Info is XML!\n");
184 #endif
185  UINT8* buff=new UINT8[size+1];
186  buff[0]=byte;
187  m_pmuxOut->getCASocket()->receiveFully(buff+1,size-1);
188  buff[size]=0;
189 #ifdef _DEBUG
190  CAMsg::printMsg(LOG_INFO,"Key Info is:\n");
191  CAMsg::printMsg(LOG_INFO,"%s\n",buff);
192 #endif
193  SINT32 ret=processKeyExchange(buff,size);
194  delete[] buff;
195  buff = NULL;
196  if(ret!=E_SUCCESS)
197  return E_UNKNOWN;
198  }
199  else
200  {
201  return E_UNKNOWN;
202  }
203  return E_SUCCESS;
204  }
205  else
206  {
207  CAMsg::printMsg(LOG_CRIT,"Cannot connect to next Mix!\n");
208  return E_UNKNOWN;
209  }
210  }
211 
213  {
214  CASocketList* pSocketList = new CASocketList();
215 #ifdef __BUILD_AS_SHADOW_PLUGIN__
216  CASocketGroupEpoll* pSocketGroup = new CASocketGroupEpoll(false);
217 #else
218  CASocketGroup* pSocketGroup = new CASocketGroup(false);
219 #endif
220  pSocketGroup->add(m_socketIn);
222  bool bHaveSocks=(socksPort!=0xFFFF);
223  if(bHaveSocks)
224  pSocketGroup->add(m_socketSOCKSIn);
225  pSocketGroup->add(*m_pmuxOut);
226  MIXPACKET* pMixPacket=new MIXPACKET;
227 
228  memset(pMixPacket,0,MIXPACKET_SIZE);
229  SINT32 len,ret;
230  CASocket* newSocket;//,*tmpSocket;
231  CASymChannelCipher** newCipher;
232  int countRead;
233  CONNECTION oConnection;
234 
235  // Temporary storage for packets that could be replayed.
236  MIXPACKET* pReplayMixPackets=new MIXPACKET[REPLAY_COUNT];
237  memset(pReplayMixPackets,0,MIXPACKET_SIZE*REPLAY_COUNT);
238  // channel ID from which packets are captured
239  unsigned uCapturedChannel = 0;
240 
241 
242  for(;;)
243  {
244  // Add timeout to select to allow for a replay attack to take place.
245  if((countRead=pSocketGroup->select(100))==SOCKET_ERROR)
246  {
247  sSleep(1);
248  continue;
249  }
250 
251  // Start a replay attack, if a packet is present
252  if(bReplayPackets)
253  {
254  if(iCapturedPackets > 0)
255  {
256  for(int i = 0; i < iCapturedPackets; i++)
257  {
258  memcpy(pMixPacket,&pReplayMixPackets[i],MIXPACKET_SIZE);
259  CAMsg::printMsg(LOG_DEBUG,"Replaying packet #%d: %X %X %X %X\n", (i+1), *pMixPacket->data, *(pMixPacket->data+1), *(pMixPacket->data+2), *(pMixPacket->data+3));
260  if(m_pmuxOut->send(pMixPacket)==SOCKET_ERROR)
261  {
262  CAMsg::printMsg(LOG_CRIT,"Mux-Channel Sending Data Error - Exiting!\n");
263  ret=E_UNKNOWN;
264  goto MIX_CONNECTION_ERROR;
265  }
266  }
267  memset(pMixPacket,0,MIXPACKET_SIZE);
268  }
269  else
270  {
271  CAMsg::printMsg(LOG_DEBUG,"No captured packets found.\n");
272  }
273  CAMsg::printMsg(LOG_DEBUG,"Replay finished.\n");
274  bReplayPackets = false;
275  }
276 
277  if(pSocketGroup->isSignaled(m_socketIn))
278  {
279  countRead--;
280  #ifdef _DEBUG
281  CAMsg::printMsg(LOG_DEBUG,"New Connection from Browser!\n");
282  #endif
283  newSocket=new CASocket();
284  if(m_socketIn.accept(*newSocket)!=E_SUCCESS)
285  {
286  #ifdef _DEBUG
287  CAMsg::printMsg(LOG_DEBUG,"Accept Error - Connection from Browser!\n");
288  #endif
289  delete newSocket;
290  newSocket = NULL;
291  }
292  else
293  {
294  newCipher=new CASymChannelCipher*[m_chainlen];
295  for (UINT32 i = 0; i < m_chainlen; i++)
296  newCipher[i] = CASymChannelCipherFactory::createCipher(m_arSymCipherAlgorithms[i]);//new CASymCipherOFB();
297 #ifdef _DEBUG
298  CAMsg::printMsg(LOG_DEBUG, "Create new ciphers for new channel - pointer is: %p\n", newCipher);
299 #endif
300  pSocketList->add(newSocket,newCipher);
301  pSocketGroup->add(*newSocket);
302  }
303  }
304  if(bHaveSocks&&pSocketGroup->isSignaled(m_socketSOCKSIn))
305  {
306  countRead--;
307  #ifdef _DEBUG
308  CAMsg::printMsg(LOG_DEBUG,"New Connection from SOCKS!\n");
309  #endif
310  newSocket=new CASocket;
311  if(m_socketSOCKSIn.accept(*newSocket)!=E_SUCCESS)
312  {
313  #ifdef _DEBUG
314  CAMsg::printMsg(LOG_DEBUG,"Accept Error - Connection from SOCKS!\n");
315  #endif
316  delete newSocket;
317  newSocket = NULL;
318  }
319  else
320  {
321  newCipher=new CASymChannelCipher*[m_chainlen];
322  for (UINT32 i = 0; i < m_chainlen; i++)
323  newCipher[i] = CASymChannelCipherFactory::createCipher(m_arSymCipherAlgorithms[i]);// new CASymCipherOFB();
324  pSocketList->add(newSocket,newCipher);
325  pSocketGroup->add(*newSocket);
326  }
327  }
328  //Receive from next Mix
329  if(pSocketGroup->isSignaled(*m_pmuxOut))
330  {
331  countRead--;
332  ret=m_pmuxOut->receive(pMixPacket);
333  if(ret==SOCKET_ERROR)
334  {
335  CAMsg::printMsg(LOG_CRIT,"Mux-Channel Receiving Data Error - Exiting!\n");
336  ret=E_UNKNOWN;
337  goto MIX_CONNECTION_ERROR;
338  }
339 
340  if(pSocketList->get(pMixPacket->channel,&oConnection)==E_SUCCESS)
341  {
342  if(pMixPacket->flags==CHANNEL_CLOSE)
343  {
344  #ifdef _DEBUG
345  CAMsg::printMsg(LOG_DEBUG,"Closing Channel: %u ... ",pMixPacket->channel);
346  #endif
347  /*tmpSocket=*/pSocketList->remove(pMixPacket->channel);
348  if(oConnection.pSocket!=NULL)
349  {
350  pSocketGroup->remove(*oConnection.pSocket);
351  oConnection.pSocket->close();
352  #ifdef _DEBUG
353  CAMsg::printMsg(LOG_DEBUG,"closed!\n");
354  #endif
355  delete oConnection.pSocket;
356  oConnection.pSocket = NULL;
357  for (UINT32 i = 0; i < m_chainlen; i++)
358  delete oConnection.pCiphers [i];
359  delete [] oConnection.pCiphers;
360  oConnection.pCiphers = NULL;
361 
362  // stop capturing packets when the channel is closed
363  if(pMixPacket->channel == uCapturedChannel)
364  {
365  CAMsg::printMsg(LOG_DEBUG,"Stopping to capture packets.\n");
366  bCapturePackets = false;
367  }
368  }
369  }
370  else
371  {
372  for(UINT32 c=0;c<m_chainlen;c++)
373  oConnection.pCiphers[c]->crypt2(pMixPacket->data,pMixPacket->data,DATA_SIZE);
374  UINT32 truelen=ntohs(pMixPacket->payload.len);
375  truelen=truelen&PAYLOAD_LEN_MASK;
376  oConnection.pSocket->send(pMixPacket->payload.data,truelen);
377  #ifdef _DEBUG
378  CAMsg::printMsg(LOG_DEBUG,"Sending Data to Browser (%u bytes)!\n",truelen);
379  #endif
381  {
383  {
384  //send a SEND_ME MixPacket
385  pMixPacket->flags=CHANNEL_DATA;
386  pMixPacket->channel=oConnection.outChannel;
387  getRandom(pMixPacket->data,DATA_SIZE);
388  pMixPacket->payload.len=htons(NEW_FLOW_CONTROL_FLAG);
389  pMixPacket->payload.type=MIX_PAYLOAD_HTTP;
390  for(UINT32 c=0;c<m_chainlen;c++)
391  oConnection.pCiphers[c]->crypt1(pMixPacket->data,pMixPacket->data,DATA_SIZE);
392  m_pmuxOut->send(pMixPacket);
393  #ifdef _DEBUG
394  CAMsg::printMsg(LOG_DEBUG,"sent sendme!\n");
395  #endif
396  pSocketList->addSendMeCounter(oConnection.outChannel,-(m_nFlowControlDownstreamSendMe-1));
397  }
398  else
399  {
400  pSocketList->addSendMeCounter(oConnection.outChannel,1);
401  }
402  }
403  }
404  }
405  }
406  if(countRead>0)//incoming data from browser
407  {
408  CONNECTION* tmpCon=NULL;
409  tmpCon=pSocketList->getFirst();
410  while(tmpCon!=NULL&&countRead>0)
411  {
412  if(pSocketGroup->isSignaled(*tmpCon->pSocket))
413  {
414  countRead--;
415  if(!tmpCon->pCiphers[0]->isKeyValid())
417  else
418  len=tmpCon->pSocket->receive(pMixPacket->payload.data,PAYLOAD_SIZE);
419  if(len==SOCKET_ERROR||len==0)
420  {
421  CAMsg::printMsg(LOG_DEBUG,"client side close channel - upstream sent: %u\n",tmpCon->upstreamBytes);
422  CASocket* tmpSocket=pSocketList->remove(tmpCon->outChannel);
423  if(tmpSocket!=NULL)
424  {
425  pSocketGroup->remove(*tmpSocket);
426  pMixPacket->flags=CHANNEL_CLOSE;
427  pMixPacket->channel=tmpCon->outChannel;
428  getRandom(pMixPacket->data,DATA_SIZE);
429  m_pmuxOut->send(pMixPacket);
430  tmpSocket->close();
431  delete tmpSocket;
432  tmpSocket = NULL;
433  for (UINT32 i = 0; i < m_chainlen; i++)
434  delete tmpCon->pCiphers[i];
435  delete [] tmpCon->pCiphers;
436  tmpCon->pCiphers = NULL;
437  }
438  }
439  else
440  {
441  getRandom(pMixPacket->payload.data+len,PAYLOAD_SIZE-len); //fill 'empty' packet payload with random values
442  pMixPacket->channel=tmpCon->outChannel;
443  tmpCon->upstreamBytes+=len;
444  pMixPacket->payload.len=htons((UINT16)len);
445  if(bHaveSocks&&tmpCon->pSocket->getLocalPort()==socksPort)
446  {
447  pMixPacket->payload.type=MIX_PAYLOAD_SOCKS;
448  }
449  else
450  {
451  pMixPacket->payload.type=MIX_PAYLOAD_HTTP;
452  }
453  if(!tmpCon->pCiphers[0]->isKeyValid()) //First time --> rsa key
454  {
455  //Has to bee optimized!!!!
456  UINT8 buff[DATA_SIZE];
457  //UINT32 size=DATA_SIZE-KEY_SIZE;
458  //tmpCon->pCipher->generateEncryptionKey(); //generate Key
459  for(UINT32 c=0;c<m_chainlen;c++)
460  {
461 #ifdef _DEBUG
462  CAMsg::printMsg(LOG_DEBUG,"Creating keys (size: %u) for Mixes for Open-packet - Mix %u - cipher array pointer: %p\n.", m_SymChannelKeySize,c, tmpCon->pCiphers);
463 #endif
465  buff[0]&=0x7F; // Hack for RSA to ensure m < n !!!!!
466  tmpCon->pCiphers[c]->setKeys(buff,m_SymChannelKeySize);
467  /*
468  PROTOCOL CHANGE:
469  This is a change in the protocol between JAP and the mixes:
470  In the RSA encrypted part of the channel-open packet apart
471  from the symmetric key for each mix, we now include a
472  TIMESTAMP_SIZE bytes wide timestamp. This reduces the storage
473  space for symmetrical keys in the RSA_SIZE wide part of the
474  packet (from 8 to 7).
475  */
476  #ifdef WITH_TIMESTAMP
477  //TODO insert timesampt
478  //currentTimestamp(buff+KEY_SIZE,true);
479  #endif
481  {
482  //log symcrypto
483  //UINT8* tmpstr=bytes2hex(pMixPacket->data, DATA_SIZE);
484  //CAMsg::printMsg(LOG_DEBUG, "Plain Packet for LastMix: %s\n", tmpstr);
485  //delete tmpstr;
486  //end log symcrpyto
487  memcpy(buff+m_SymChannelKeySize,pMixPacket->data,DATA_SIZE-m_SymChannelKeySize);
489  UINT8 iv[16];
490  memset(iv,0xFF,16);
491  tmpCon->pCiphers[c]->setIV2(iv);
493  //log symcrypto
494  //tmpstr=bytes2hex(buff, DATA_SIZE);
495  //CAMsg::printMsg(LOG_DEBUG, "Plain Packet for FirstMix: %s\n", tmpstr);
496  //delete tmpstr;
497  //end log symcrpyto
498  }
499  else
500  {
503  {
504  UINT8 tmpBuff[1000];
505  UINT32 lk=1000;
506  m_arRSA[c].encryptOAEP(buff,128-42,tmpBuff,&lk);
507  tmpCon->pCiphers[c]->crypt1(buff+RSA_SIZE-42,tmpBuff+RSA_SIZE,DATA_SIZE-RSA_SIZE);
508  memcpy(buff,tmpBuff,DATA_SIZE);
509  }
510  else
511  {
512  m_arRSA[c].encrypt(buff,buff);
513  tmpCon->pCiphers[c]->crypt1(buff+RSA_SIZE,buff+RSA_SIZE,DATA_SIZE-RSA_SIZE);
514  }
515  // Does RSA_SIZE need to be increased by RSA_SIZE/KEY_SIZE*TIMESTAMP_SIZE?
516  }
517  memcpy(pMixPacket->data,buff,DATA_SIZE);
518  //size-=KEY_SIZE;
519  //len+=KEY_SIZE;
520  }
521  pMixPacket->flags=CHANNEL_OPEN;
522  }
523  else //sonst
524  {
525  for(UINT32 c=0;c<m_chainlen;c++)
526  tmpCon->pCiphers[c]->crypt1(pMixPacket->data,pMixPacket->data,DATA_SIZE);
527  pMixPacket->flags=CHANNEL_DATA;
528  }
529 
530  // Capture the this packet for future replay
531  if(bCapturePackets)
532  {
533  if(!iCapturedPackets && (pMixPacket->flags == CHANNEL_OPEN))
534  {
535  CAMsg::printMsg(LOG_DEBUG,"Captured channel-open packet: %X %X %X %X\n", *pMixPacket->data, *(pMixPacket->data+1), *(pMixPacket->data+2), *(pMixPacket->data+3));
536  memcpy(&pReplayMixPackets[iCapturedPackets++],pMixPacket,MIXPACKET_SIZE);
537  uCapturedChannel = pMixPacket->channel;
538  }
539  else if(iCapturedPackets && (uCapturedChannel == pMixPacket->channel))
540  {
541  CAMsg::printMsg(LOG_DEBUG,"Captured data packet: %X %X %X %X\n", *pMixPacket->data, *(pMixPacket->data+1), *(pMixPacket->data+2), *(pMixPacket->data+3));
542  memcpy(&pReplayMixPackets[iCapturedPackets++],pMixPacket,MIXPACKET_SIZE);
543  }
544  }
546  {
547  CAMsg::printMsg(LOG_DEBUG,"Storage full, stopping to capture packets.\n");
548  bCapturePackets = false;
549  }
550 
551  if(m_pmuxOut->send(pMixPacket)==SOCKET_ERROR)
552  {
553  CAMsg::printMsg(LOG_CRIT,"Mux-Channel Sending Data Error - Exiting!\n");
554  ret=E_UNKNOWN;
555  goto MIX_CONNECTION_ERROR;
556  }
557  }
558  break;
559  }
560  tmpCon=pSocketList->getNext();
561  }
562  }
563  }
564 MIX_CONNECTION_ERROR:
565  CONNECTION* tmpCon=pSocketList->getFirst();
566  while(tmpCon!=NULL)
567  {
568  for (UINT32 i = 0; i < m_chainlen; i++)
569  delete tmpCon->pCiphers[i];
570  delete [] tmpCon->pCiphers;
571  tmpCon->pCiphers = NULL;
572  delete tmpCon->pSocket;
573  tmpCon->pSocket = NULL;
574  tmpCon=tmpCon->next;
575  }
576  delete pMixPacket;
577  pMixPacket = NULL;
578  delete pSocketGroup;
579  delete pSocketList;
580  if(ret==E_SUCCESS)
581  return E_SUCCESS;
582  if(CALibProxytest::getOptions()->getAutoReconnect())
583  return E_UNKNOWN;
584  else
585  exit(-1);
586  }
587 
589  {
590  m_socketIn.close();
592  m_pmuxOut->close();
593  delete m_pmuxOut;
594 
595  delete[] m_arRSA;
596  m_arRSA=NULL;
597 
598  delete m_pSymCipher;
599  m_pSymCipher=NULL;
600 
601  return E_SUCCESS;
602  }
603 
605  {
608  CAMsg::printMsg(LOG_INFO,"Login process and key exchange started...\n");
609  //Parsing KeyInfo received from Mix n+1
610  XERCES_CPP_NAMESPACE::DOMDocument* doc=parseDOMDocument(buff,len);
611  if(doc==NULL)
612  {
613  CAMsg::printMsg(LOG_INFO,"Error parsing Key Info from Mix!\n");
614  return E_UNKNOWN;
615  }
616 
617 
618  DOMElement* root=doc->getDocumentElement();
619  DOMElement* elemVersion=NULL;
620  getDOMChildByName(root,"MixProtocolVersion",elemVersion,false);
621  UINT8 strVersion[255];
622  UINT32 tmpLen=255;
623  if(getDOMElementValue(elemVersion,strVersion,&tmpLen)==E_SUCCESS)
624  {
625 #ifdef _DEBUG
626  CAMsg::printMsg(LOG_INFO,"XML MixProtocolVersion value:%s\n",strVersion);
627 #endif
628  if(tmpLen==3&&memcmp(strVersion,"0.4",3)==0)
629  {
630  CAMsg::printMsg(LOG_INFO,"MixCascadeProtocolVersion: 0.4\n");
633  }
634  else if(tmpLen==3&&memcmp(strVersion,"0.3",3)==0)
635  {
636  CAMsg::printMsg(LOG_INFO,"MixCascadeProtocolVersion: 0.3\n");
638  }
639  else if(tmpLen==3&&memcmp(strVersion,"0.2",3)==0)
640  {
641  CAMsg::printMsg(LOG_INFO,"MixCascadeProtocolVersion: 0.2\n");
643  }
644  else if(tmpLen==4&&memcmp(strVersion,"0.10",4)==0)
645  {
646  CAMsg::printMsg(LOG_INFO,"MixCascadeProtocolVersion: 0.10\n");
652  }
653  else
654  {
655  CAMsg::printMsg(LOG_ERR,"Unsupported MixProtocolVersion!\n");
656  return E_UNKNOWN;
657  }
658  }
659  else
660  {
661 #ifdef _DEBUG
662  CAMsg::printMsg(LOG_ERR,"No MixProtocolVersion given!\n");
663  return E_UNKNOWN;
664 #endif
665  }
666  DOMElement* elemMixes=NULL;
667  getDOMChildByName(root,"Mixes",elemMixes,false);
668  SINT32 chainlen=-1;
669  if(elemMixes==NULL||getDOMElementAttribute(elemMixes,"count",&chainlen)!=E_SUCCESS)
670  {
671 #ifdef _DEBUG
672  CAMsg::printMsg(LOG_ERR,"No count of Mixes given!\n");
673  return E_UNKNOWN;
674 #endif
675  }
676  m_chainlen=(UINT32)chainlen;
677 #ifdef _DEBUG
678  CAMsg::printMsg(LOG_INFO,"Number of Mixes is: %u\n",m_chainlen);
679 #endif
680  if(m_chainlen==0)
681  {
682 #ifdef _DEBUG
683  CAMsg::printMsg(LOG_ERR,"Number of Mixes is 0!\n");
684  return E_UNKNOWN;
685 #endif
686  }
687  UINT32 iMixIndex =0;
690  DOMNode* child=elemMixes->getLastChild();
691  bool bIsLast=true;
692  while(child!= NULL&&chainlen>0)
693  {
694  if(equals(child->getNodeName(),"Mix"))
695  {
696  DOMNode* nodeKey=child->getFirstChild();
697  if(m_arRSA[iMixIndex].setPublicKeyAsDOMNode(nodeKey)!=E_SUCCESS)
698  {
699 #ifdef _DEBUG
700  CAMsg::printMsg(LOG_ERR,"Error in parsing the public key of a Mix\n");
701  return E_UNKNOWN;
702 #endif
703  }
704  DOMNode* tmpNode = NULL;
705  UINT8 tmpBuff[255];
706  UINT32 tmpBuffLen = 255;
707  getDOMChildByName(child, "ChannelSymmetricChipher", tmpNode);
708  getDOMElementValue(tmpNode, tmpBuff, &tmpBuffLen);
710  if (m_arSymCipherAlgorithms[iMixIndex] == UNDEFINED_CIPHER)
711  {
712  m_arSymCipherAlgorithms[iMixIndex] = OFB;
713  }
714  if(bIsLast)
715  {
716  getDOMChildByName(child,"MixProtocolVersion",tmpNode);
717  tmpBuffLen=255;
718  if(getDOMElementValue(tmpNode,tmpBuff,&tmpBuffLen)==E_SUCCESS)
719  {
720  CAMsg::printMsg(LOG_DEBUG,"Last Mix Protcol Version %s\n",tmpBuff);
721  if(strcmp("0.6",(char*)tmpBuff)==0)
722  {
724  CAMsg::printMsg(LOG_DEBUG,"Last Mix uses new flow control\n");
725  }
726  }
728  {
729  getDOMChildByName(child,"FlowControl",tmpNode);
730  DOMElement* nodeDownstreamSendMe=NULL;
731  getDOMChildByName(tmpNode,"DownstreamSendMe",nodeDownstreamSendMe);
733  CAMsg::printMsg(LOG_DEBUG,"Last Mix new flow control downstream send me: %u\n",m_nFlowControlDownstreamSendMe);
734  }
735  bIsLast=false;
736  }
737 
738  iMixIndex++;
739  chainlen--;
740  }
741  child=child->getPreviousSibling();
742  }
743  if(chainlen!=0)
744  {
745 #ifdef _DEBUG
746  CAMsg::printMsg(LOG_ERR,"Expected information for %u Mixes but found only %u!\n",m_chainlen,m_chainlen-chainlen);
747  return E_UNKNOWN;
748 #endif
749  }
750 
752 
753 
754  //Now sending SymKeys....
756  {
757  MIXPACKET oPacket;
758  getRandom((UINT8*)&oPacket,MIXPACKET_SIZE);
759  oPacket.flags=0;
760  oPacket.channel=0;
761  UINT8 keys[32];
762  getRandom(keys,32);
763  m_pmuxOut->setReceiveKey(keys,16);
764  m_pmuxOut->setSendKey(keys+16,16);
765  memcpy(oPacket.data,"KEYPACKET",9);
766  memcpy(oPacket.data+9,keys,32);
767  m_arRSA[m_chainlen-1].encrypt(oPacket.data,oPacket.data);
768  m_pmuxOut->send(&oPacket);
769  m_pmuxOut->setCrypt(true);
770  }
771  else
772  {
773  const char* XML_HEADER="<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
774  const UINT32 XML_HEADER_SIZE=strlen(XML_HEADER);
775  const char* XML_JAP_KEY_TEMPLATE="<JAPKeyExchange version=\"0.1\"><LinkEncryption>%s</LinkEncryption><MixEncryption>%s</MixEncryption><AccessControlCredential>%s</AccessControlCredential></JAPKeyExchange>";
776  //DOM_Document doc=DOM_Document::createDocument();
777  //DOM_Element e = doc.createElement("JAPKeyExchange");
778  //doc.appendChild(e);
779  //e.setAttribute("version", "0.1");
780  //DOM_Element elemLinkEnc = doc.createElement("LinkEncryption");
781  UINT8* buff=new UINT8[9000];
782  UINT8 linkKeys[64];
783  getRandom(linkKeys,64);
784  UINT8 outBuffLinkKey[512];
785  UINT32 outlenLinkKey=512;
786  CABase64::encode(linkKeys,64,outBuffLinkKey,&outlenLinkKey);
787  outBuffLinkKey[outlenLinkKey]=0;
788  //setDOMElementValue(elemLinkEnc,outBuff);
789  //e.appendChild(elemLinkEnc);
790  //DOM_Element elemMixEnc = doc.createElement("MixEncryption");
791  UINT8 mixKeys[32];
792  getRandom(mixKeys,32);
794  m_pSymCipher->setKey(mixKeys);
795  m_pSymCipher->setIVs(mixKeys+16);
796  UINT8 outBuffMixKey[512];
797  UINT32 outlenMixKey=512;
798  CABase64::encode(mixKeys,32,outBuffMixKey,&outlenMixKey);
799  outBuffMixKey[outlenMixKey]=0;
800  //setDOMElementValue(elemMixEnc,outBuff);
801  //e.appendChild(elemMixEnc);
802  CABase64::encode(mixKeys,32,outBuffMixKey,&outlenMixKey);
803  outBuffMixKey[outlenMixKey]=0;
804  UINT8 strCredential[512];
805  UINT32 strCredentialLen=512;
806  strCredential[0] = 0;
807  CALibProxytest::getOptions()->getCredential(strCredential, strCredentialLen);
808 
809  sprintf((char*)buff,XML_JAP_KEY_TEMPLATE,outBuffLinkKey,outBuffMixKey,strCredential);
810  UINT32 encbufflen;
811  UINT8* encbuff=encryptXMLElement(buff,strlen((char*)buff),encbufflen,&m_arRSA[m_chainlen-1]);
812  UINT16 size2=htons((UINT16)(encbufflen+XML_HEADER_SIZE));
813  SINT32 ret=m_pmuxOut->getCASocket()->sendFully((UINT8*)&size2,2);
814  if (ret == E_SUCCESS)
815  {
816  ret = m_pmuxOut->getCASocket()->sendFully((UINT8*)XML_HEADER, XML_HEADER_SIZE);
817  }
818  if (ret == E_SUCCESS)
819  {
820  ret=m_pmuxOut->getCASocket()->sendFully(encbuff,encbufflen);
821  }
822  delete[] encbuff;
823  encbuff = NULL;
824  delete[] buff;
825  buff = NULL;
826  if (ret != E_SUCCESS)
827  {
828  CAMsg::printMsg(LOG_DEBUG, "Error sending keys etc. \n");
829  return E_UNKNOWN;
830  }
831 
832 
833  // Checking Signature send from Mix
834  ret=m_pmuxOut->getCASocket()->receiveFully((UINT8*)&size2,2);
835  size2=ntohs(size2);
836  UINT8* xmlbuff=new UINT8[size2];
837  if (ret == E_SUCCESS)
838  {
839  ret = m_pmuxOut->getCASocket()->receiveFully(xmlbuff, size2);
840  }
841  delete[] xmlbuff;
842  if (ret != E_SUCCESS)
843  {
844  CAMsg::printMsg(LOG_DEBUG, "Error receiving final login message. \n");
845  return E_UNKNOWN;
846  }
847  xmlbuff = NULL;
848  m_pmuxOut->setSendKey(linkKeys,32);
849  m_pmuxOut->setReceiveKey(linkKeys+32,32);
850  m_pmuxOut->setCrypt(true);
851  }
852  if (doc != NULL)
853  {
854  doc->release();
855  doc = NULL;
856  }
857  CAMsg::printMsg(LOG_INFO,"Login process and key exchange finished!\n");
858  return E_SUCCESS;
859  }
860 #endif
#define RSA_SIZE
void SIGUSR2_handler(int signum)
void SIGUSR1_handler(int signum)
#define REPLAY_COUNT
SYMCHANNELCIPHER_ALGORITHM
@ UNDEFINED_CIPHER
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
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
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
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
SINT32 encryptXMLElement(DOMNode *node, CAASymCipher *pRSA)
The resulting encrypted xml struct is as follows:
Definition: CAUtil.cpp:1086
#define MIX_CASCADE_PROTOCOL_VERSION_0_3
Definition: StdAfx.h:260
#define SOCKET_ERROR
Definition: StdAfx.h:464
#define MIX_CASCADE_PROTOCOL_VERSION_0_2
Definition: StdAfx.h:261
#define MIX_CASCADE_PROTOCOL_VERSION_0_1_0
Definition: StdAfx.h:253
#define MIX_CASCADE_PROTOCOL_VERSION_0_4
Definition: StdAfx.h:259
#define FLOW_CONTROL_SENDME_SOFT_LIMIT
Definition: StdAfx.h:223
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 encryptOAEP(const UINT8 *from, UINT32 fromlen, UINT8 *to, UINT32 *len)
Encrypts one block of plain text using OAEP padding.
SINT32 encrypt(const UINT8 *from, UINT8 *to)
Encrypts exactly one block which is stored in from.
static SINT32 encode(const UINT8 *in, UINT32 len, UINT8 *out, UINT32 *outlen)
fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff...
Definition: CABase64.cpp:102
SINT32 receiveFully(UINT8 *buff, UINT32 len)
Receives all len bytes.
SINT32 getCredential(UINT8 *name, UINT32 len)
SINT32 getMixHost(UINT8 *host, UINT32 len)
CAListenerInterface * getListenerInterface(UINT32 nr)
UINT16 getSOCKSServerPort()
static CACmdLnOptions * getOptions()
CASocketAddr * getAddr() const
CAMuxSocket * m_pmuxOut
static bool bCapturePackets
CASocket m_socketSOCKSIn
UINT32 m_MixCascadeProtocolVersion
UINT32 m_SymChannelEncryptedKeySize
CASocket m_socketIn
bool m_bWithEnhancedChannelEncryption
CAASymCipher * m_arRSA
SINT32 clean()
bool m_bWithNewFlowControl
SINT32 initOnce()
bool m_bWithFirstMixSymmetric
SYMCHANNELCIPHER_ALGORITHM * m_arSymCipherAlgorithms
static int iCapturedPackets
UINT32 m_SymChannelKeySize
UINT32 m_nFlowControlDownstreamSendMe
static bool bReplayPackets
SINT32 start()
UINT32 m_chainlen
CASymChannelCipher * m_pSymCipher
SINT32 processKeyExchange(UINT8 *buff, UINT32 size)
static SINT32 printMsg(UINT32 typ, const char *format,...)
Writes a given message to the log.
Definition: CAMsg.cpp:251
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.
CASocket * getCASocket()
Definition: CAMuxSocket.hpp:84
SINT32 setCipher(SYMCHANNELCIPHER_ALGORITHM algCipher)
Definition: CAMuxSocket.cpp:90
This class represents a socket address for Internet (IP) connections.
SINT32 setAddr(const UINT8 *szIP, UINT16 port)
Sets the address to szIP and port.
UINT16 getPort() const
Returns the port value of the address.
SINT32 remove(CASocket &s)
bool isSignaled(CASocket &s)
SINT32 add(CASocket &s)
Adds the socket s to the socket group.
virtual SINT32 receive(UINT8 *buff, UINT32 len)
Will receive some bytes from the socket.
Definition: CASocket.cpp:645
virtual SINT32 listen(const CASocketAddr &psa)
Starts listening on address psa.
Definition: CASocket.cpp:142
virtual SINT32 send(const UINT8 *buff, UINT32 len)
Sends some data over the network.
Definition: CASocket.cpp:400
virtual SINT32 setRecvBuff(UINT32 r)
Definition: CASocket.cpp:846
virtual SINT32 setReuseAddr(bool b)
Definition: CASocket.cpp:839
virtual SINT32 sendFully(const UINT8 *buff, UINT32 len)
Sends all data over the network.
Definition: CASocket.cpp:587
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 create()
Definition: CASocket.cpp:73
virtual SINT32 close()
Definition: CASocket.cpp:351
virtual SINT32 getLocalPort()
Definition: CASocket.cpp:811
SINT32 add(CASocket *pSocket, CASymChannelCipher **pCiphers)
Add a new channel to the channel-list.
SINT32 addSendMeCounter(HCHANNEL in, SINT32 value)
CASocket * remove(HCHANNEL id)
SINT32 get(HCHANNEL in, CONNECTION *out)
Gets a copy of an entry form the channel-list.
CONNECTION * getFirst()
Gets the first entry of the channel-list.
CONNECTION * getNext()
Gets the next entry of the channel-list.
static SYMCHANNELCIPHER_ALGORITHM getAlgIDFromString(UINT8 *strAlgID)
static CASymChannelCipher * createCipher(SYMCHANNELCIPHER_ALGORITHM alg)
virtual bool isKeyValid()=0
virtual SINT32 setKeys(const UINT8 *key, UINT32 keysize)=0
Sets the keys for crypt1() and crypt2() either to the same key (if keysize==KEY_SIZE) or to different...
virtual SINT32 setIV2(const UINT8 *p_iv)=0
Sets iv2 to p_iv.
virtual SINT32 crypt2(const UINT8 *in, UINT8 *out, UINT32 len)=0
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.
virtual SINT32 crypt1(const UINT8 *in, UINT8 *out, UINT32 len)=0
const SINT32 E_SUCCESS
Definition: errorcodes.hpp:2
#define E_UNKNOWN
Definition: errorcodes.hpp:3
CASymChannelCipher ** pCiphers
UINT32 upstreamBytes
connlist * next
UINT32 currentSendMeCounter
HCHANNEL outChannel
CASocket * pSocket
HCHANNEL channel
Definition: typedefs.hpp:117
struct t_MixPacketPayload payload
Definition: typedefs.hpp:122
UINT8 data[DATA_SIZE]
Definition: typedefs.hpp:121
UINT16 flags
Definition: typedefs.hpp:118
UINT8 data[PAYLOAD_SIZE]
Definition: typedefs.hpp:113
#define CHANNEL_DATA
Definition: typedefs.hpp:42
#define MIXPACKET_SIZE
Definition: typedefs.hpp:40
#define PAYLOAD_SIZE
Definition: typedefs.hpp:73
#define MIX_PAYLOAD_HTTP
Definition: typedefs.hpp:35
#define MIX_PAYLOAD_SOCKS
Definition: typedefs.hpp:36
#define CHANNEL_CLOSE
Definition: typedefs.hpp:47
#define NEW_FLOW_CONTROL_FLAG
Definition: typedefs.hpp:63
#define PAYLOAD_LEN_MASK
Definition: typedefs.hpp:79
t_MixPacket MIXPACKET
Definition: typedefs.hpp:127
UINT16 len
Definition: typedefs.hpp:0
#define CHANNEL_OPEN
Definition: typedefs.hpp:43
#define DATA_SIZE
Definition: typedefs.hpp:69