Mixe for Privacy and Anonymity in the Internet
CAMix.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_MIDDLE_MIX || defined INCLUDE_LAST_MIX
30 #include "CAMix.hpp"
31 #include "CAUtil.hpp"
32 #include "CAInfoService.hpp"
33 #include "CACmdLnOptions.hpp"
34 #include "CAStatusManager.hpp"
35 #include "CALibProxytest.hpp"
36 
38 
40  {
42  //m_pSignature=NULL;
43  m_pMultiSignature=NULL;
44  m_pInfoService=NULL;
47  m_u32KeepAliveSendInterval=0;//zero means --> do not use
48  m_u32KeepAliveRecvInterval=0;//zero means --> do not use
49  m_bShutDown = false;
51  m_bConnected = false;
53 //#ifdef DYNAMIC_MIX
54  /* LERNGRUPPE: Run by default */
55  m_bLoop = true;
56 #ifdef DYNAMIC_MIX
57  m_bReconfiguring = false;
58  m_bCascadeEstablished = false;
59  m_bReconfigured = false;
60 #endif
61 #ifdef DATA_RETENTION_LOG
62  m_pDataRetentionLog=NULL;
63 #endif
64  }
65 
67  {
68 #ifdef DATA_RETENTION_LOG
69  if(m_pDataRetentionLog!=NULL)
70  {
71  delete m_pDataRetentionLog;
72  m_pDataRetentionLog=NULL;
73  }
74 #endif
75 
76  }
77 
79  {
80 #ifdef DATA_RETENTION_LOG
81  m_pDataRetentionLog=new CADataRetentionLog();
82  CAASymCipher* pKey=NULL;
83  CALibProxytest::getOptions()->getDataRetentionPublicEncryptionKey(&pKey);
84  if(m_pDataRetentionLog->setPublicEncryptionKey(pKey)!=E_SUCCESS)
85  { return E_UNKNOWN; }
86  UINT8 strDir[4096];
87  strDir[0]=0;
88  if(CALibProxytest::getOptions()->getDataRetentionLogDir(strDir,4096)!=E_SUCCESS ||
89  m_pDataRetentionLog->setLogDir(strDir)!=E_SUCCESS)
90  {
91  CAMsg::printMsg(LOG_ERR,"Data Retention Error: Could not set log dir to %s!\n",strDir);
92  return E_UNKNOWN;
93  }
94  else
95  {
96  CAMsg::printMsg(LOG_INFO,"Data Retention: Set log dir to: %s\n",strDir);
97  CAMsg::printMsg(LOG_INFO,"Data Retention: tQueueEntry size is: %u\n",sizeof(tQueueEntry));
98  }
99 
100 #endif
101  return E_SUCCESS;
102  }
103 
105  {
106  SINT32 initStatus;
107  m_bConnected = false;
109  m_bLoop=true;
110 
111  if(initOnce()!=E_SUCCESS)
112  { return E_UNKNOWN; }
113  if(m_pMultiSignature != NULL && CALibProxytest::getOptions()->isInfoServiceEnabled())
114  {
115  CAMsg::printMsg(LOG_DEBUG, "CAMix start: creating InfoService object\n");
116  m_pInfoService=new CAInfoService(this);
117 
118  //UINT32 opCertLength;
119  //CACertificate* opCert = CALibProxytest::getOptions()->getOpCertificate();
120  //CACertificate* pOwnCert=CALibProxytest::getOptions()->getOwnCertificate();
122  //delete pOwnCert;
123  //pOwnCert = NULL;
124  UINT64 currentMillis;
125  if (getcurrentTimeMillis(currentMillis) != E_SUCCESS)
126  {
127  currentMillis = 0;
128  }
129  m_pInfoService->setSerial(currentMillis);
130 
131  //delete opCert;
132  //opCert = NULL;
133 
134  bool allowReconf = CALibProxytest::getOptions()->acceptReconfiguration();
135  bool needReconf = needAutoConfig();
136 
137  m_pInfoService->setConfiguring(allowReconf && needReconf);
138  CAMsg::printMsg(LOG_DEBUG, "CAMix start: starting InfoService\n");
140  }
141  else
142  {
143  m_pInfoService = NULL;
144  }
145  bool allowReconf = CALibProxytest::getOptions()->acceptReconfiguration();
146 //#ifdef DYNAMIC_MIX
147  /* LERNGRUPPE: We might want to break out of this loop if the mix-type changes */
148  while(m_bLoop)
149 //#else
150 // for(;;)
151 //#endif
152  {
153  if (m_pInfoService != NULL)
154  { m_pInfoService->setConfiguring(allowReconf && needAutoConfig()); }
155  while(allowReconf && (needAutoConfig() || m_bReconfiguring))
156  {
157  CAMsg::printMsg(LOG_DEBUG, "Not configured -> sleeping\n");
158  sSleep(20);
159  }
160 //#ifdef DYNAMIC_MIX
161  // if we change the mix type, we must not enter init!
162  if(!m_bLoop) { goto SKIP; }
163 //#endif
164  CAMsg::printMsg(LOG_DEBUG, "CAMix main: before init()\n");
165  initStatus = init();
166  if(initStatus == E_SUCCESS)
167  {
168  m_lLastConnectionTime = time(NULL);
169  m_bConnected = true;
170  CAMsg::printMsg(LOG_DEBUG, "CAMix main: init() returned success\n");
171  if(m_pInfoService != NULL)
172  {
174  if( ! m_pInfoService->isRunning())
175  {
177  }
179  }
180 
181  CAMsg::printMsg(LOG_INFO, "The mix is now on-line.\n");
182 #ifdef DYNAMIC_MIX
183  m_bReconfiguring = false;
184  m_bCascadeEstablished = true;
185  m_bReconfigured = false;
186  if(CALibProxytest::getOptions()->isFirstMix() && CALibProxytest::getOptions()->isDynamic())
188 #endif
190  loop();
192 #ifdef DYNAMIC_MIX
193  m_bCascadeEstablished = false;
195  if(!m_bReconfiguring)
196  { m_pInfoService->dynamicCascadeConfiguration(); }
197 #endif
198  CAMsg::printMsg(LOG_DEBUG, "CAMix main: loop() returned, maybe connection lost.\n");
199  }
200  else if (initStatus == E_SHUTDOWN)
201  {
202  CAMsg::printMsg(LOG_DEBUG, "Mix has been stopped. Waiting for shutdown...\n");
203  //break;
204  }
205  else
206  {
207  CAMsg::printMsg(LOG_DEBUG, "init() failed, maybe no connection.\n");
208  }
209 //#ifdef DYNAMIC_MIX
210 SKIP:
211 //#endif
212  if(m_pInfoService != NULL)
213  {
214 //#ifndef DYNAMIC_MIX
215 // if(CALibProxytest::getOptions()->acceptReconfiguration())
216 //#else
217  // Only keep the InfoService alive if the Mix-Type doesn't change
218  if(CALibProxytest::getOptions()->acceptReconfiguration() && m_bLoop)
219 //#endif
221  /*else
222  {
223  CAMsg::printMsg(LOG_DEBUG, "CAMix main: stopping InfoService\n");
224  m_pInfoService->stop();
225  }*/
226  // maybe Cascade information (e.g. certificate validity) will change on next connection
227  UINT64 currentMillis;
228  if (getcurrentTimeMillis(currentMillis) != E_SUCCESS)
229  {
230  currentMillis = 0;
231  }
232  m_pInfoService->setSerial(currentMillis);
233  }
234  m_bConnected = false;
236  CAMsg::printMsg(LOG_DEBUG, "CAMix main: before clean()\n");
237  clean();
238  CAMsg::printMsg(LOG_DEBUG, "CAMix main: after clean()\n");
239 //#ifdef DYNAMIC_MIX
240  if(m_bLoop)
241 //#endif
242  sSleep(10);
243  }// Big loop....
244  if(m_pInfoService != NULL)
245  {
246  m_pInfoService->stop();
247  delete m_pInfoService;
248  m_pInfoService = NULL;
249  }
250  m_pInfoService=NULL;
251  return E_SUCCESS;
252  }
253 
254 
264  {
265  bool ret = false;
266 
267  if(!CALibProxytest::getOptions()->isLastMix())
268  {
269  ret = true;
270 
271  // look for usable target interfaces
273  {
274  CATargetInterface oNextMix;
276  if(oNextMix.getTargetType()==TARGET_MIX)
277  {
278  ret = false;
279  }
280  oNextMix.cleanAddr();
281  }
282 
283  if(!CALibProxytest::getOptions()->hasNextMixTestCertificate())
284  { ret = true; }
285  }
286 
287  if(!CALibProxytest::getOptions()->isFirstMix() && !CALibProxytest::getOptions()->hasPrevMixTestCertificate())
288  { ret = true; }
289 
290  return ret;
291  }
292 
300  {
301  UINT32 count;
303  DOMElement* elemRoot=createDOMElement(m_docMixCascadeInfo,"MixCascade");
304 #ifdef LOG_DIALOG
305  setDOMElementAttribute(elemRoot,"study",(UINT8*)"true");
306 #endif
307  if(CALibProxytest::getOptions()->isFirstMix())
308  {
310  if(maxUsers > 0)
311  {
312  setDOMElementAttribute(elemRoot,"maxUsers", maxUsers);
313  }
314  setDOMElementAttribute(elemRoot, "maxOpenChannels", CHANNELS_PER_CLIENT);
315 
316 #ifdef MANIOQ
317  setDOMElementAttribute(elemRoot,"context", (UINT8*) "jondonym.business");
318 #else
319 
320 #ifdef PAYMENT
321  setDOMElementAttribute(elemRoot,"context", (UINT8*) "jondonym.premium");
322 #else
323  setDOMElementAttribute(elemRoot,"context", (UINT8*) "jondonym");
324 #endif
325 #endif
326  }
327 
328  UINT8 id[50];
329  UINT8* cascadeID=NULL;
331 
332  UINT8 name[255];
333  m_docMixCascadeInfo->appendChild(elemRoot);
334  DOMElement* elem = NULL;
335 
336  if(CALibProxytest::getOptions()->getCascadeName(name,255) == E_SUCCESS)
337  {
338  elem = createDOMElement(m_docMixCascadeInfo,"Name");
339  setDOMElementValue(elem,name);
340  elemRoot->appendChild(elem);
341  }
342  else
343  {
344  CAMsg::printMsg(LOG_ERR,"No cascade name given!\n");
345  }
346 
347  elem=createDOMElement(m_docMixCascadeInfo,"Network");
348  elemRoot->appendChild(elem);
349  DOMElement* elemListenerInterfaces=createDOMElement(m_docMixCascadeInfo,"ListenerInterfaces");
350  elem->appendChild(elemListenerInterfaces);
351 
352 
354  {
356  if(pListener->isHidden())
357  {
358  //do nothing
359  }
360  else if(pListener->getType()==RAW_TCP|| pListener->getType() == RAW_UDP)
361  {//Only TCP or UDP interfaces are meaningfull for external connections...
362  DOMElement* elemTmpLI=NULL;
363  pListener->toDOMElement(elemTmpLI,m_docMixCascadeInfo);
364  elemListenerInterfaces->appendChild(elemTmpLI);
365  }
366  delete pListener;
367  pListener = NULL;
368  }
369 
370  DOMNode* elemMixesDocCascade=createDOMElement(m_docMixCascadeInfo,"Mixes");
371  DOMElement* elemMix=NULL;
372  count=1;
373  if(CALibProxytest::getOptions()->isFirstMix())
374  {
375  addMixInfo(elemMixesDocCascade, false);
376  getDOMChildByName(elemMixesDocCascade, "Mix", elemMix, false);
377  // create signature
378  if (signXML(elemMix) != E_SUCCESS)
379  {
380  CAMsg::printMsg(LOG_DEBUG,"Could not sign KeyInfo sent to users...\n");
381  }
382  //if(m_pSignature->signXML(docMixInfo,m_pcertstoreOwnCerts)!=E_SUCCESS)
383  //m_pSignature, CALibProxytest::getOptions()->getOwnCertificate()
384  /*
385  elemMixesDocCascade.appendChild(elemThisMix);*/
386  }
387  elemRoot->appendChild(elemMixesDocCascade);
388 
389 // UINT8 cascadeId[255];
390 // UINT32 cascadeIdLen=255;
391 
392  DOMNode* node=mixes->getFirstChild();
393  while(node!=NULL)
394  {
395  if(node->getNodeType()==DOMNode::ELEMENT_NODE&&equals(node->getNodeName(),"Mix"))
396  {
397  elemMixesDocCascade->appendChild(m_docMixCascadeInfo->importNode(node,true));
398  count++;
399 // cascadeId = static_cast<const DOM_Element&>(node).getAttribute("id").transcode();
400  }
401  node=node->getNextSibling();
402  }
403 
404  if(CALibProxytest::getOptions()->isLastMix())
405  {
406  addMixInfo(elemMixesDocCascade, false);
407  ::getLastDOMChildByName(elemMixesDocCascade, "Mix", elemMix);
408  // create signature
409  if (signXML(elemMix) != E_SUCCESS)
410  {
411  CAMsg::printMsg(LOG_DEBUG,"Could not sign KeyInfo sent to users...\n");
412  }
413  cascadeID = id;
414  }
415  else if(CALibProxytest::getOptions()->isFirstMix())
416  {
417  cascadeID = id;
418  }
419 
420  if(cascadeID != NULL)
421  { setDOMElementAttribute(elemRoot,"id",cascadeID); }
422  setDOMElementAttribute(elemMixesDocCascade,"count",count);
423 
424  DOMNode* elemPayment=createDOMElement(m_docMixCascadeInfo,"Payment");
425  elemRoot->appendChild(elemPayment);
426 #ifdef PAYMENT
427  setDOMElementAttribute(elemPayment,"required",(UINT8*)"true");
428  setDOMElementAttribute(elemPayment,"version",(UINT8*)PAYMENT_VERSION);
429  setDOMElementAttribute(elemPayment,"prepaidInterval", CALibProxytest::getOptions()->getPrepaidInterval());
430  setDOMElementAttribute(elemPayment,"piid", CALibProxytest::getOptions()->getBI()->getID());
431 #else
432  setDOMElementAttribute(elemPayment,"required",(UINT8*)"false");
433 #endif
434  return E_SUCCESS;
435  }
436 
437 SINT32 CAMix::addMixInfo(DOMNode* a_element, bool a_bForceFirstNode)
438  {
439  // this is a complete mixinfo node to be sent to the InfoService
440  XERCES_CPP_NAMESPACE::DOMDocument* docMixInfo=NULL;
441  if(CALibProxytest::getOptions()->getMixXml(docMixInfo)!=E_SUCCESS)
442  {
443  return E_UNKNOWN;
444  }
445  DOMNode* nodeMixInfo = a_element->getOwnerDocument()->importNode(docMixInfo->getDocumentElement(), true);
446  if (a_bForceFirstNode && a_element->hasChildNodes())
447  {
448  a_element->insertBefore(nodeMixInfo, a_element->getFirstChild());
449  }
450  else
451  {
452  a_element->appendChild(nodeMixInfo);
453  }
454  return E_SUCCESS;
455  }
456 
457 #ifdef PAYMENT
458 DOMNode *CAMix::appendTermsAndConditionsExtension(XERCES_CPP_NAMESPACE::DOMDocument *ownerDoc,DOMElement *root)
459  {
460  if(CALibProxytest::getOptions()->getTermsAndConditions() != NULL)
461  {
462  if( (root == NULL) || (ownerDoc == NULL) )
463  {
464  return NULL;
465  }
466 
467  DOMElement *elemTnCExtension = NULL, *elemExtensions = NULL,
468  *elemTemplates = NULL;
469  /* Tag for Nodes that can be removed without destroying the signature.
470  * To be appended to the "mixes"-node so older mix versions won't get confused.
471  */
472  getDOMChildByName(root, KEYINFO_NODE_EXTENSIONS, elemExtensions);
473  if(elemExtensions == NULL)
474  {
475  elemExtensions = createDOMElement(ownerDoc, KEYINFO_NODE_EXTENSIONS);
476  root->appendChild(elemExtensions);
477  }
478  else
479  {
480  getDOMChildByName(elemExtensions, KEYINFO_NODE_TNC_EXTENSION, elemTnCExtension);
481  }
482 
483  if(elemTnCExtension == NULL)
484  {
485  elemTnCExtension = createDOMElement(ownerDoc, KEYINFO_NODE_TNC_EXTENSION);
486  elemExtensions->appendChild(elemTnCExtension);
487  }
488 
489  //First add templates if there are any
491 
492  if(nrOfTemplates > 0)
493  {
494  UINT32 nrOfSentTemplates = 0;
495  UINT8 **sentTemplatesRefIds = NULL;
496  getDOMChildByName(elemTnCExtension, OPTIONS_NODE_TNCS_TEMPLATES, elemTemplates);
497  if(elemTemplates == NULL)
498  {
499  elemTemplates = createDOMElement(ownerDoc, OPTIONS_NODE_TNCS_TEMPLATES);
500  elemTnCExtension->appendChild(elemTemplates);
501  }
502  else
503  {
504  DOMNodeList *nl = getElementsByTagName(elemTemplates, "TermsAndConditionsTemplate");
505  nrOfSentTemplates = nl->getLength();
506  if(nrOfSentTemplates > 0)
507  {
508  sentTemplatesRefIds = new UINT8*[nrOfSentTemplates];
509  for (UINT32 i = 0; i < nrOfSentTemplates; i++)
510  {
511  sentTemplatesRefIds[i] = getTermsAndConditionsTemplateRefId(nl->item(i));
512  }
513  }
514  }
515 
516  XERCES_CPP_NAMESPACE::DOMDocument **allTemplates = CALibProxytest::getOptions()->getAllTermsAndConditionsTemplates();
517  UINT8 *currentTemplateRefId = NULL;
518  bool duplicate = false;
519  for(UINT32 i = 0; i < nrOfTemplates; i++)
520  {
521  currentTemplateRefId =
522  getTermsAndConditionsTemplateRefId(allTemplates[i]->getDocumentElement());
523  duplicate = false;
524  if(currentTemplateRefId != NULL)
525  {
526  for(UINT32 j=0; j < nrOfSentTemplates; j++)
527  {
528  if(strncmp((char *)currentTemplateRefId, (char *)sentTemplatesRefIds[j], TEMPLATE_REFID_MAXLEN) == 0)
529  {
530  duplicate = true;
531  break;
532  }
533  }
534  if(!duplicate)
535  {
536  //TODO: avoid duplicates.
537  elemTemplates->appendChild(ownerDoc->importNode(
538  allTemplates[i]->getDocumentElement(), true));
539  CAMsg::printMsg(LOG_DEBUG,"appended a tc template node!\n");
540  }
541  else
542  {
543  CAMsg::printMsg(LOG_DEBUG,"template '%s' already sent.\n", currentTemplateRefId);
544  }
545  delete [] currentTemplateRefId;
546  currentTemplateRefId = NULL;
547  }
548  }
549 
550  for(UINT32 i = 0; i < nrOfSentTemplates; i++)
551  {
552  delete [] sentTemplatesRefIds[i];
553  sentTemplatesRefIds[i] = NULL;
554  }
555  delete [] sentTemplatesRefIds;
556  sentTemplatesRefIds = NULL;
557  }
558 
559  DOMNode* elemTnCs = ownerDoc->importNode(CALibProxytest::getOptions()->getTermsAndConditions(), true);
560  UINT8 tmpOpSKIBuff[TMP_BUFF_SIZE];
561  UINT32 tmpOpSKILen = TMP_BUFF_SIZE;
562  memset(tmpOpSKIBuff, 0, tmpOpSKILen);
563  CALibProxytest::getOptions()->getOperatorSubjectKeyIdentifier(tmpOpSKIBuff, &tmpOpSKILen);
564  setDOMElementAttribute(elemTnCs, OPTIONS_ATTRIBUTE_TNC_ID, tmpOpSKIBuff);
565 
566  DOMNodeList *tncDefEntryList = getElementsByTagName((DOMElement *)elemTnCs, OPTIONS_NODE_TNCS_TRANSLATION);
567  for (XMLSize_t i = 0; i < tncDefEntryList->getLength(); i++)
568  {
569  //TODO don't know if to include certs here
570  m_pMultiSignature->signXML((DOMElement *)tncDefEntryList->item(i), false);
571  }
572  elemTnCExtension->appendChild(elemTnCs);
573  return elemTnCExtension;
574  }
575  else
576  {
577  return NULL;
578  }
579  }
580 
581 DOMNode *CAMix::termsAndConditionsInfoNode(XERCES_CPP_NAMESPACE::DOMDocument *ownerDoc)
582  {
583  if(CALibProxytest::getOptions()->getTermsAndConditions() != NULL)
584  {
585  DOMElement *elemTnCInfos = createDOMElement(ownerDoc, KEYINFO_NODE_TNC_INFOS);
586  UINT8 tmpBuff[TMP_BUFF_SIZE];
587  UINT32 tmpLen = TMP_BUFF_SIZE;
588  memset(tmpBuff, 0, tmpLen);
589 
590  DOMNodeList *list = getElementsByTagName(CALibProxytest::getOptions()->getTermsAndConditions(), OPTIONS_NODE_TNCS_TRANSLATION);
591  DOMElement *iterator = NULL;
592  DOMElement *currentInfoNode = NULL;
593  bool defaultLangDefined = false;
594  for (XMLSize_t i = 0; i < list->getLength(); i++)
595  {
596  iterator = (DOMElement *) list->item(i);
597  currentInfoNode = createDOMElement(ownerDoc, KEYINFO_NODE_TNC_INFO);
598 
599  getDOMElementAttribute(iterator, OPTIONS_ATTRIBUTE_TNC_LOCALE, tmpBuff, &tmpLen);
600  setDOMElementAttribute(currentInfoNode, OPTIONS_ATTRIBUTE_TNC_LOCALE, tmpBuff);
602  if(defaultLangDefined)
603  {
605  }
606  defaultLangDefined = false;
607  tmpLen = TMP_BUFF_SIZE;
608 
611  tmpLen = TMP_BUFF_SIZE;
612 
613  elemTnCInfos->appendChild(currentInfoNode);
614  }
615 
616  getDOMElementAttribute(CALibProxytest::getOptions()->getTermsAndConditions(), OPTIONS_ATTRIBUTE_TNC_DATE, tmpBuff, &tmpLen);
617  setDOMElementAttribute(elemTnCInfos, OPTIONS_ATTRIBUTE_TNC_DATE, tmpBuff);
618 
619  tmpLen = TMP_BUFF_SIZE;
620  //memset(tmpBuff, 0, tmpLen);
621 
623  setDOMElementAttribute(elemTnCInfos, OPTIONS_ATTRIBUTE_TNC_ID, tmpBuff);
624  return elemTnCInfos;
625  }
626  else
627  {
628  return NULL;
629  }
630 
631  }
632 
633 #endif
635  {
636  DOMElement* elemCompatibility=createDOMElement(a_parent->getOwnerDocument(),"Compatibility");
637  setDOMElementAttribute(elemCompatibility,"version",(UINT8*)MIX_VERSION);
638  a_parent->appendChild(elemCompatibility);
639 
640  DOMElement* elemFlags=NULL;
641  DOMElement* elemFlag=NULL;
642 
643  elemFlags = createDOMElement(a_parent->getOwnerDocument(), "Flags");
644  elemCompatibility->appendChild(elemFlags);
645 
647 #ifdef PAYMENT
648  elemFlag = createDOMElement(a_parent->getOwnerDocument(), PAYMENT_COMPATIBILITY);
649  //setDOMElementValue(elemFlag,(UINT8*)"true"); // you might add a version number here for a protocol etc.
650  elemFlags->appendChild(elemFlag);
651 #endif
652 
653  elemFlag = createDOMElement(a_parent->getOwnerDocument(), NEW_FLOW_CONTROL_COMPATIBILITY);
654  //setDOMElementValue(elemFlag,(UINT8*)"true");
655  elemFlags->appendChild(elemFlag);
656 
657  elemFlag = createDOMElement(a_parent->getOwnerDocument(), NEW_CHANNEL_ENCRYPTION_COMPATIBILITY);
658  //setDOMElementValue(elemFlag,(UINT8*)"true");
659  elemFlags->appendChild(elemFlag);
660 
661 #ifdef WITH_INTEGRITY_CHECK
662  elemFlag = createDOMElement(a_parent->getOwnerDocument(), WITH_INTEGRITY_CHECK_COMPATIBILITY);
663  //setDOMElementValue(elemFlag,(UINT8*)"true");
664  elemFlags->appendChild(elemFlag);
665 #endif
666 
667  return E_SUCCESS;
668  }
669 
670 SINT32 CAMix::checkCompatibility(DOMNode* a_parent, const char* a_mixPosition)
671  {
672  // get compatibility info
673  DOMElement* elemCompatibility=NULL;
674  DOMElement* elemFlags=NULL;
675  DOMElement* elemDummy=NULL;
676  UINT8 strAllFlags[500];
677  UINT32 lenAllFlags;
678  UINT8 strNodeName[50];
679  UINT32 lenNodeName=50;
680  UINT8 strVersion[50];
681  UINT32 len=50;
682  SINT32 iCompare;
683  UINT8* strComment;
684  UINT32 iCountFlags = 0;
685  UINT32 iLogLevel = LOG_INFO;
686  bool bCompatible = true;
687  bool bCompatibleFlags = true;
688 
689  if (getDOMChildByName(a_parent,"Compatibility",elemCompatibility,false) != E_SUCCESS ||
690  getDOMElementAttribute(elemCompatibility, "version", strVersion, &len) != E_SUCCESS)
691  {
692  CAMsg::printMsg(LOG_WARNING,"Could not get any compatibility information from the %s mix. It may or may not be compatible. If the connection fails for an unknown reason, the %s mix should be updated.\n", a_mixPosition, a_mixPosition);
693  return E_SUCCESS;
694  }
695 
696  iCompare = strncmp (MIX_VERSION, (char*)strVersion, len);
697 
698  if (iCompare == 0)
699  {
700  strComment = (UINT8*)" We have the same version.";
701  }
702  else if (iCompare < 0)
703  {
704  strComment = (UINT8*)" Our version (" MIX_VERSION ") might be too old. If the connection fails for an unknown reason, you should think about an update.";
705  iLogLevel = LOG_WARNING;
706  }
707  else
708  {
710  if (strncmp ("00.08.71", (char*)strVersion, len) > 0)
711  {
712  strComment = (UINT8*)" This version is NOT COMPATIBLE with our version (" MIX_VERSION ")! The mixes will not work together in a cascade.";
713  bCompatible = false;
714  iLogLevel = LOG_CRIT;
715  }
716  else
717  {
718  strComment = (UINT8*)" We have a newer version (" MIX_VERSION "), but both are known to work fine together.";
719  }
720  }
721 
722  CAMsg::printMsg(iLogLevel,"The software version of the %s mix is %s.%s\n", a_mixPosition, strVersion, strComment);
723 
725 #ifdef PAYMENT
726  iCountFlags++;
727 #endif
728 
729  iCountFlags++;
730 
731  iCountFlags++;
732 
733 #ifdef WITH_INTEGRITY_CHECK
734  iCountFlags++;
735 #endif
736 
737  if (getDOMChildByName(elemCompatibility, "Flags", elemFlags, false) == E_SUCCESS)
738  {
739  DOMNodeList* flags = elemFlags->getChildNodes();
740  if (flags->getLength() != iCountFlags)
741  {
742  bCompatibleFlags = false;
743  }
744 
746  // Hint: We might also check for a version of the compile flags if available; it should be set in the content of each tag instead of 'true'.
747 #ifdef PAYMENT
748  if (getDOMChildByName(elemFlags, PAYMENT_COMPATIBILITY, elemDummy, false) != E_SUCCESS)
749  {
750  bCompatibleFlags = false;
751  }
752 #endif
753  if (getDOMChildByName(elemFlags, NEW_FLOW_CONTROL_COMPATIBILITY, elemDummy, false) != E_SUCCESS)
754  {
755  bCompatibleFlags = false;
756  }
757  if (getDOMChildByName(elemFlags, NEW_CHANNEL_ENCRYPTION_COMPATIBILITY, elemDummy, false) != E_SUCCESS)
758  {
759  bCompatibleFlags = false;
760  }
761 #ifdef WITH_INTEGRITY_CHECK
762  if (getDOMChildByName(elemFlags, WITH_INTEGRITY_CHECK_COMPATIBILITY, elemDummy, false) != E_SUCCESS)
763  {
764  bCompatibleFlags = false;
765  }
766 #endif
767 
768  if (!bCompatibleFlags)
769  {
770  // get the flags of the other mix
771  strAllFlags[0] = 0;
772  lenAllFlags = 1;
773  for (UINT32 i = 0; i < flags->getLength(); i++)
774  {
775  if (::getNodeName(flags->item(i), strNodeName, &lenNodeName) == E_SUCCESS)
776  {
777 
778  lenAllFlags += strlen((char*)strNodeName) + 1;
779  if (lenAllFlags > 500)
780  {
781  break;
782  }
783  strcat((char*)strAllFlags, " ");
784  strcat((char*)strAllFlags, (char*)strNodeName);
785  }
786 
787  lenNodeName = 50;
788  }
789 
790  CAMsg::printMsg(LOG_CRIT, "The compile flags of the %s mix are NOT COMPATIBLE with our flags. We have: %s They have: %s --> The mixes won't run together.\n", a_mixPosition, MIX_VERSION_COMPATIBILITY, strAllFlags);
791  return E_UNKNOWN;
792 
793  }
794  }
795 
796 
797  if (!bCompatible)
798  {
799  return E_UNKNOWN;
800  }
801 
802  return E_SUCCESS;
803  }
804 
805 
806 SINT32 CAMix::signXML(DOMNode* a_element)
807  {
808  return m_pMultiSignature->signXML(a_element, true);
809  /*CACertStore* tmpCertStore=new CACertStore();
810 
811  CACertificate* ownCert=CALibProxytest::getOptions()->getOwnCertificate();
812  if(ownCert==NULL)
813  {
814  CAMsg::printMsg(LOG_DEBUG,"Own Test Cert is NULL!\n");
815  }
816 
817  // Operator Certificates
818  CACertificate* opCert = CALibProxytest::getOptions()->getOpCertificate();
819  if(opCert==NULL)
820  {
821  CAMsg::printMsg(LOG_DEBUG,"Op Test Cert is NULL!\n");
822  }
823  else
824  {
825  // Own Mix Certificates first, then Operator Certificates
826  tmpCertStore->add(opCert);
827  }
828  tmpCertStore->add(ownCert);
829 
830  if(m_pSignature->signXML(a_element, tmpCertStore)!=E_SUCCESS)
831  {
832  return E_UNKNOWN;
833  }
834 
835  CASignature* test = new CASignature();
836  test->setVerifyKey(ownCert);
837 
838  if(test->verifyXML(a_element) != E_SUCCESS)
839  {
840  CAMsg::printMsg(LOG_DEBUG, "Error verifying own Signature!!\n");
841  m_pSignature->signXML(a_element, tmpCertStore);
842  }
843  else
844  {
845  CAMsg::printMsg(LOG_DEBUG, "Own Signature looks ok!\n");
846  }
847 
848 
849  delete ownCert;
850  ownCert = NULL;
851 
852  delete opCert;
853  opCert = NULL;
854 
855  delete tmpCertStore;
856  tmpCertStore = NULL;
857 
858  return E_SUCCESS;*/
859  }
860 #ifdef DYNAMIC_MIX
872 SINT32 CAMix::dynaReconfigure(bool a_bChangeMixType)
873  {
874  SINT32 ret = E_UNKNOWN;
875  CASocket tmpSock;
876  const CASocketAddr* pAddr=NULL;
877 
878  m_bReconfigured = true;
879  m_bLoop = !a_bChangeMixType;
880 
881  if(m_bCascadeEstablished)
882  { stopCascade(); }
883  m_docMixCascadeInfo = NULL;
884 
887  CAListenerInterface* pListener=NULL;
889  for(UINT32 i=1; i<=interfaces; i++)
890  {
892  if(!pListener->isVirtual())
893  { break; }
894  delete pListener;
895  pListener=NULL;
896  }
897  if(pListener==NULL)
898  {
899  CAMsg::printMsg(LOG_CRIT," failed!\n");
900  CAMsg::printMsg(LOG_CRIT,"Reason: no useable (non virtual) interface found!\n");
901  goto EXIT;
902  }
903 
904  pAddr=pListener->getAddr();
905  delete pListener;
906  pListener = NULL;
907 
908  tmpSock.connect(*pAddr);
909  delete pAddr;
910  pAddr = NULL;
911  tmpSock.close();
912 
913  ret = E_SUCCESS;
914 EXIT:
915  CAMsg::printMsg(LOG_DEBUG, "Mix has been reconfigured!\n");
916  m_bReconfiguring = false;
917  return ret;
918  }
919 #endif //DYNAMIC_MIX
920 #endif //ONLY_LOCAL_PROXY
#define OPTIONS_ATTRIBUTE_TNC_ID
#define OPTIONS_NODE_TNCS_TEMPLATES
#define OPTIONS_ATTRIBUTE_TNC_DEFAULT_LANG
#define OPTIONS_ATTRIBUTE_TNC_DATE
#define OPTIONS_ATTRIBUTE_TNC_LOCALE
#define OPTIONS_ATTRIBUTE_TNC_DEFAULT_LANG_DEFINED
#define OPTIONS_ATTRIBUTE_TNC_TEMPLATE_REFID
#define OPTIONS_NODE_TNCS_TRANSLATION
#define KEYINFO_NODE_TNC_EXTENSION
Definition: CAMix.hpp:46
#define KEYINFO_NODE_EXTENSIONS
Definition: CAMix.hpp:45
#define KEYINFO_NODE_TNC_INFO
Definition: CAMix.hpp:43
#define KEYINFO_NODE_TNC_INFOS
Definition: CAMix.hpp:42
#define MONITORING_FIRE_SYS_EVENT(e_type)
SINT32 getNodeName(const DOMNode *const pElem, UINT8 *value, UINT32 *valuelen)
Definition: CAUtil.cpp:707
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 setDOMElementValue(DOMElement *pElem, SINT32 value)
Definition: CAUtil.cpp:939
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
DOMNodeList * getElementsByTagName(DOMElement *pElem, const char *const name)
Definition: CAUtil.cpp:1711
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
SINT32 getLastDOMChildByName(const DOMNode *pNode, const char *const name, DOMElement *&a_child)
Definition: CAUtil.cpp:1719
#define TEMPLATE_REFID_MAXLEN
Definition: CAUtil.hpp:42
#define TMP_BUFF_SIZE
Definition: CAUtil.hpp:38
#define MIX_VERSION
Definition: StdAfx.h:36
#define WITH_INTEGRITY_CHECK_COMPATIBILITY
Definition: StdAfx.h:735
#define NEW_FLOW_CONTROL_COMPATIBILITY
Definition: StdAfx.h:725
#define NEW_CHANNEL_ENCRYPTION_COMPATIBILITY
Definition: StdAfx.h:728
#define PAYMENT_COMPATIBILITY
Definition: StdAfx.h:712
#define PAYMENT_VERSION
Definition: StdAfx.h:274
#define CHANNELS_PER_CLIENT
Definition: StdAfx.h:195
#define MIX_VERSION_COMPATIBILITY
Definition: StdAfx.h:762
signed int SINT32
Definition: basetypedefs.h:132
unsigned char UINT8
Definition: basetypedefs.h:135
unsigned int UINT32
Definition: basetypedefs.h:131
UINT32 getListenerInterfaceCount()
SINT32 getMixId(UINT8 *id, UINT32 len)
UINT32 getNumberOfTermsAndConditionsTemplates()
Get the XML describing the Mix.
UINT32 getMaxNrOfUsers()
bool acceptReconfiguration()
SINT32 getOperatorSubjectKeyIdentifier(UINT8 *buffer, UINT32 *length)
Returns a COPY of the public test certifcate for that mix.
CAListenerInterface * getListenerInterface(UINT32 nr)
XERCES_CPP_NAMESPACE::DOMDocument ** getAllTermsAndConditionsTemplates()
UINT32 getTargetInterfaceCount()
SINT32 getTargetInterface(CATargetInterface &oTargetInterface, UINT32 nr)
Fills a TargetInterface struct with the values which belongs to the target interface nr.
SINT32 setMultiSignature(CAMultiSignature *pMultiSignature)
void setConfiguring(bool a_configuring)
SINT32 sendCascadeHelo()
void setSerial(UINT64 a_serial)
static CACmdLnOptions * getOptions()
CASocketAddr * getAddr() const
SINT32 toDOMElement(DOMElement *&elem, XERCES_CPP_NAMESPACE::DOMDocument *ownerDoc) const
NetworkType getType() const
volatile bool m_bConnected
Definition: CAMix.hpp:190
bool m_bReconfiguring
Definition: CAMix.hpp:143
virtual SINT32 loop()=0
virtual ~CAMix()
Definition: CAMix.cpp:66
volatile bool m_bLoop
Definition: CAMix.hpp:135
SINT32 appendCompatibilityInfo(DOMNode *a_parent)
Definition: CAMix.cpp:634
SINT32 checkCompatibility(DOMNode *a_parent, const char *a_mixPosition)
Definition: CAMix.cpp:670
SINT32 start()
Definition: CAMix.cpp:104
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
volatile UINT32 m_lLastConnectionTime
Definition: CAMix.hpp:191
SINT32 addMixInfo(DOMNode *a_element, bool a_bForceFirstNode)
Definition: CAMix.cpp:437
CAControlChannelDispatcher * m_pMuxOutControlChannelDispatcher
Definition: CAMix.hpp:195
CAControlChannelDispatcher * m_pMuxInControlChannelDispatcher
Definition: CAMix.hpp:196
virtual SINT32 clean()=0
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
bool needAutoConfig()
This method checks if target interfaces (network adress and port of next mix) have been specified in ...
Definition: CAMix.cpp:263
virtual SINT32 initOnce()
Definition: CAMix.cpp:78
virtual SINT32 init()=0
volatile bool m_bShutDown
Definition: CAMix.hpp:144
XERCES_CPP_NAMESPACE::DOMDocument * m_docMixCascadeInfo
Definition: CAMix.hpp:193
UINT32 m_u32KeepAliveSendInterval
Definition: CAMix.hpp:187
bool m_acceptReconfiguration
Definition: CAMix.hpp:189
CAMix()
Definition: CAMix.cpp:39
static SINT32 printMsg(UINT32 typ, const char *format,...)
Writes a given message to the log.
Definition: CAMsg.cpp:251
SINT32 signXML(DOMNode *a_node, bool appendCerts)
This is an abstract class for representing a socket address used in CASocket, CADatagramSocket and CA...
virtual SINT32 close()
Definition: CASocket.cpp:351
virtual SINT32 connect(const CASocketAddr &psa)
Definition: CASocket.hpp:64
TargetType getTargetType() const
const SINT32 E_SUCCESS
Definition: errorcodes.hpp:2
#define E_SHUTDOWN
Definition: errorcodes.hpp:4
#define E_UNKNOWN
Definition: errorcodes.hpp:3
@ ev_sys_enterMainLoop
@ ev_sys_leavingMainLoop
Definition: typedefs.hpp:169
@ TARGET_MIX
Definition: typedefs.hpp:32
@ RAW_TCP
Definition: typedefs.hpp:30
@ RAW_UDP
Definition: typedefs.hpp:30
UINT16 flags
Definition: typedefs.hpp:1
UINT16 len
Definition: typedefs.hpp:0