Mixe for Privacy and Anonymity in the Internet
CAMix.cpp
Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2000, The JAP-Team
00003 All rights reserved.
00004 Redistribution and use in source and binary forms, with or without modification,
00005 are permitted provided that the following conditions are met:
00006 
00007   - Redistributions of source code must retain the above copyright notice,
00008     this list of conditions and the following disclaimer.
00009 
00010   - Redistributions in binary form must reproduce the above copyright notice,
00011     this list of conditions and the following disclaimer in the documentation and/or
00012     other materials provided with the distribution.
00013 
00014   - Neither the name of the University of Technology Dresden, Germany nor the names of its contributors
00015     may be used to endorse or promote products derived from this software without specific
00016     prior written permission.
00017 
00018 
00019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
00020 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
00021 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS
00022 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00023 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00024 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
00025 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00026 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00027 */
00028 #include "StdAfx.h"
00029 #ifndef ONLY_LOCAL_PROXY
00030 #include "CAMix.hpp"
00031 #include "CAUtil.hpp"
00032 #include "CAInfoService.hpp"
00033 #include "CACmdLnOptions.hpp"
00034 #include "CAStatusManager.hpp"
00035 #include "CALibProxytest.hpp"
00036 
00037 const UINT32 CAMix::TIMEOUT_MIX_CONNECTION_ESTABLISHEMENT = 60000;
00038 
00039 CAMix::CAMix()
00040 {
00041     m_acceptReconfiguration = CALibProxytest::getOptions()->acceptReconfiguration();
00042     //m_pSignature=NULL;
00043     m_pMultiSignature=NULL;
00044     m_pInfoService=NULL;
00045     m_pMuxOutControlChannelDispatcher=NULL;
00046     m_pMuxInControlChannelDispatcher=NULL;
00047     m_u32KeepAliveSendInterval=0;//zero means --> do not use
00048     m_u32KeepAliveRecvInterval=0;//zero means --> do not use
00049     m_bShutDown = false;
00050     m_docMixCascadeInfo=NULL;
00051     m_bConnected = false;
00052     m_lLastConnectionTime = 0;
00053 #ifdef DYNAMIC_MIX
00054     /* LERNGRUPPE: Run by default */
00055     m_bLoop = true;
00056     m_bReconfiguring = false;
00057     m_bCascadeEstablished = false;
00058     m_bReconfigured = false;
00059 #endif
00060 #ifdef DATA_RETENTION_LOG
00061     m_pDataRetentionLog=NULL;
00062 #endif
00063   }
00064 
00065 CAMix::~CAMix()
00066   {
00067 #ifdef DATA_RETENTION_LOG
00068     if(m_pDataRetentionLog!=NULL)
00069       {
00070         delete m_pDataRetentionLog;
00071         m_pDataRetentionLog=NULL;
00072       }
00073 #endif
00074 
00075   }
00076 
00077 SINT32 CAMix::initOnce()
00078   {
00079 #ifdef DATA_RETENTION_LOG
00080     m_pDataRetentionLog=new CADataRetentionLog();
00081     CAASymCipher* pKey=NULL;
00082     CALibProxytest::getOptions()->getDataRetentionPublicEncryptionKey(&pKey);
00083     if(m_pDataRetentionLog->setPublicEncryptionKey(pKey)!=E_SUCCESS)
00084       return E_UNKNOWN;
00085     UINT8 strDir[4096];
00086     strDir[0]=0;
00087     if(CALibProxytest::getOptions()->getDataRetentionLogDir(strDir,4096)!=E_SUCCESS ||
00088        m_pDataRetentionLog->setLogDir(strDir)!=E_SUCCESS)
00089       {
00090         CAMsg::printMsg(LOG_ERR,"Data Retention Error: Could not set log dir to %s!\n",strDir);
00091         return E_UNKNOWN;
00092       }
00093     else
00094       {
00095         CAMsg::printMsg(LOG_INFO,"Data Retention: Set log dir to: %s\n",strDir);
00096         CAMsg::printMsg(LOG_INFO,"Data Retention: tQueueEntry size is: %u\n",sizeof(tQueueEntry));
00097       }
00098 
00099 #endif
00100     return E_SUCCESS;
00101   }
00102 
00103 SINT32 CAMix::start()
00104   {
00105     SINT32 initStatus;
00106     m_bConnected = false;
00107     m_lLastConnectionTime = 0;
00108 
00109     if(initOnce()!=E_SUCCESS)
00110       return E_UNKNOWN;
00111     if(m_pMultiSignature != NULL && CALibProxytest::getOptions()->isInfoServiceEnabled())
00112     {
00113       CAMsg::printMsg(LOG_DEBUG, "CAMix start: creating InfoService object\n");
00114       m_pInfoService=new CAInfoService(this);
00115 
00116       //UINT32 opCertLength;
00117       //CACertificate* opCert = CALibProxytest::getOptions()->getOpCertificate();
00118       //CACertificate* pOwnCert=CALibProxytest::getOptions()->getOwnCertificate();
00119       m_pInfoService->setMultiSignature(m_pMultiSignature);
00120       //delete pOwnCert;
00121       //pOwnCert = NULL;
00122       UINT64 currentMillis;
00123       if (getcurrentTimeMillis(currentMillis) != E_SUCCESS)
00124       {
00125         currentMillis = 0;
00126       }
00127       m_pInfoService->setSerial(currentMillis);
00128 
00129       //delete opCert;
00130       //opCert = NULL;
00131 
00132           bool allowReconf = CALibProxytest::getOptions()->acceptReconfiguration();
00133           bool needReconf = needAutoConfig();
00134 
00135           m_pInfoService->setConfiguring(allowReconf && needReconf);
00136       CAMsg::printMsg(LOG_DEBUG, "CAMix start: starting InfoService\n");
00137       m_pInfoService->start();
00138     }
00139     else
00140     {
00141       m_pInfoService = NULL;
00142     }
00143     bool allowReconf = CALibProxytest::getOptions()->acceptReconfiguration();
00144 #ifdef DYNAMIC_MIX
00145     /* LERNGRUPPE: We might want to break out of this loop if the mix-type changes */
00146     while(m_bLoop)
00147 #else
00148     for(;;)
00149 #endif
00150       {
00151         if (m_pInfoService != NULL)
00152           m_pInfoService->setConfiguring(allowReconf && needAutoConfig());
00153       while(allowReconf && (needAutoConfig() || m_bReconfiguring))
00154       {
00155         CAMsg::printMsg(LOG_DEBUG, "Not configured -> sleeping\n");
00156               sSleep(20);
00157           }
00158 #ifdef DYNAMIC_MIX
00159       // if we change the mix type, we must not enter init!
00160       if(!m_bLoop) goto SKIP;
00161 #endif
00162       CAMsg::printMsg(LOG_DEBUG, "CAMix main: before init()\n");
00163       initStatus = init();
00164       if(initStatus == E_SUCCESS)
00165         {
00166           m_lLastConnectionTime = time(NULL);
00167           m_bConnected = true;
00168           CAMsg::printMsg(LOG_DEBUG, "CAMix main: init() returned success\n");
00169           if(m_pInfoService != NULL)
00170             {
00171               m_pInfoService->setConfiguring(false);
00172               if( ! m_pInfoService->isRunning())
00173                 {
00174                   m_pInfoService->start();
00175                 }
00176               m_pInfoService->signal();
00177             }
00178 
00179           CAMsg::printMsg(LOG_INFO, "The mix is now on-line.\n");
00180 #ifdef DYNAMIC_MIX
00181           m_bReconfiguring = false;
00182           m_bCascadeEstablished = true;
00183           m_bReconfigured = false;
00184           if(CALibProxytest::getOptions()->isFirstMix() && CALibProxytest::getOptions()->isDynamic())
00185             m_pInfoService->sendCascadeHelo();
00186 #endif
00187           MONITORING_FIRE_SYS_EVENT(ev_sys_enterMainLoop);
00188           loop();
00189           MONITORING_FIRE_SYS_EVENT(ev_sys_leavingMainLoop);
00190 #ifdef DYNAMIC_MIX
00191           m_bCascadeEstablished = false;
00193           if(!m_bReconfiguring)
00194             m_pInfoService->dynamicCascadeConfiguration();
00195 #endif
00196           CAMsg::printMsg(LOG_DEBUG, "CAMix main: loop() returned, maybe connection lost.\n");
00197         }
00198       else if (initStatus == E_SHUTDOWN)
00199         {
00200           CAMsg::printMsg(LOG_DEBUG, "Mix has been stopped. Waiting for shutdown...\n");
00201         //break;
00202         }
00203       else
00204         {
00205           CAMsg::printMsg(LOG_DEBUG, "init() failed, maybe no connection.\n");
00206         }
00207 #ifdef DYNAMIC_MIX
00208 SKIP:
00209 #endif
00210         if(m_pInfoService != NULL)
00211           {
00212 #ifndef DYNAMIC_MIX
00213               if(CALibProxytest::getOptions()->acceptReconfiguration())
00214 #else
00215         // Only keep the InfoService alive if the Mix-Type doesn't change
00216         if(CALibProxytest::getOptions()->acceptReconfiguration() && m_bLoop)
00217 #endif
00218                   m_pInfoService->setConfiguring(true);
00219               /*else
00220         {
00221           CAMsg::printMsg(LOG_DEBUG, "CAMix main: stopping InfoService\n");
00222                   m_pInfoService->stop();
00223         }*/
00224               // maybe Cascade information (e.g. certificate validity) will change on next connection
00225               UINT64 currentMillis;
00226               if (getcurrentTimeMillis(currentMillis) != E_SUCCESS)
00227               {
00228                 currentMillis = 0;
00229               }
00230               m_pInfoService->setSerial(currentMillis);
00231           }
00232           m_bConnected = false;
00233       m_lLastConnectionTime = 0;
00234       CAMsg::printMsg(LOG_DEBUG, "CAMix main: before clean()\n");
00235       clean();
00236       CAMsg::printMsg(LOG_DEBUG, "CAMix main: after clean()\n");
00237 #ifdef DYNAMIC_MIX
00238       if(m_bLoop)
00239 #endif
00240       sSleep(10);
00241     }// Big loop....
00242     if(m_pInfoService != NULL)
00243     {
00244       m_pInfoService->stop();
00245       delete m_pInfoService;
00246       m_pInfoService = NULL;
00247     }
00248     m_pInfoService=NULL;
00249     return E_SUCCESS;
00250   }
00251 
00252 
00261 bool CAMix::needAutoConfig()
00262 {
00263     bool ret = false;
00264 
00265     if(!CALibProxytest::getOptions()->isLastMix())
00266     {
00267         ret = true;
00268 
00269         // look for usable target interfaces
00270         for(UINT32 i=0;i<CALibProxytest::getOptions()->getTargetInterfaceCount();i++)
00271         {
00272             CATargetInterface oNextMix;
00273             CALibProxytest::getOptions()->getTargetInterface(oNextMix,i+1);
00274             if(oNextMix.getTargetType()==TARGET_MIX)
00275             {
00276                 ret = false;
00277             }
00278             oNextMix.cleanAddr();
00279         }
00280 
00281         if(!CALibProxytest::getOptions()->hasNextMixTestCertificate())
00282             ret = true;
00283     }
00284 
00285     if(!CALibProxytest::getOptions()->isFirstMix() && !CALibProxytest::getOptions()->hasPrevMixTestCertificate())
00286         ret = true;
00287 
00288     return ret;
00289 }
00290 
00297 SINT32 CAMix::initMixCascadeInfo(DOMElement* mixes)
00298 {
00299     UINT32 count;
00300     m_docMixCascadeInfo=createDOMDocument();
00301     DOMElement* elemRoot=createDOMElement(m_docMixCascadeInfo,"MixCascade");
00302 #ifdef LOG_DIALOG
00303     setDOMElementAttribute(elemRoot,"study",(UINT8*)"true");
00304 #endif
00305     if(CALibProxytest::getOptions()->isFirstMix())
00306     {
00307       UINT32 maxUsers = CALibProxytest::getOptions()->getMaxNrOfUsers();
00308       if(maxUsers > 0)
00309       {
00310         setDOMElementAttribute(elemRoot,"maxUsers", maxUsers);
00311       }
00312 #ifdef MANIOQ
00313       setDOMElementAttribute(elemRoot,"context", (UINT8*) "jondonym.business");
00314 #else
00315 
00316 #ifdef PAYMENT
00317       setDOMElementAttribute(elemRoot,"context", (UINT8*) "jondonym.premium");
00318 #else
00319       setDOMElementAttribute(elemRoot,"context", (UINT8*) "jondonym");
00320 #endif
00321 #endif
00322     }
00323 
00324     UINT8 id[50];
00325     UINT8* cascadeID=NULL;
00326     CALibProxytest::getOptions()->getMixId(id,50);
00327 
00328     UINT8 name[255];
00329     m_docMixCascadeInfo->appendChild(elemRoot);
00330     DOMElement* elem = NULL;
00331 
00332     if(CALibProxytest::getOptions()->getCascadeName(name,255) == E_SUCCESS)
00333     {
00334       elem = createDOMElement(m_docMixCascadeInfo,"Name");
00335       setDOMElementValue(elem,name);
00336       elemRoot->appendChild(elem);
00337   }
00338     else
00339     {
00340       CAMsg::printMsg(LOG_ERR,"No cascade name given!\n");
00341     }
00342 
00343     elem=createDOMElement(m_docMixCascadeInfo,"Network");
00344     elemRoot->appendChild(elem);
00345     DOMElement* elemListenerInterfaces=createDOMElement(m_docMixCascadeInfo,"ListenerInterfaces");
00346     elem->appendChild(elemListenerInterfaces);
00347 
00348 
00349     for(UINT32 i=1;i<=CALibProxytest::getOptions()->getListenerInterfaceCount();i++)
00350     {
00351         CAListenerInterface* pListener=CALibProxytest::getOptions()->getListenerInterface(i);
00352         if(pListener->isHidden())
00353         {//do nothing
00354         }
00355         else if(pListener->getType()==RAW_TCP)
00356         {
00357             DOMElement* elemTmpLI=NULL;
00358             pListener->toDOMElement(elemTmpLI,m_docMixCascadeInfo);
00359             elemListenerInterfaces->appendChild(elemTmpLI);
00360         }
00361         delete pListener;
00362         pListener = NULL;
00363     }
00364 
00365     DOMNode* elemMixesDocCascade=createDOMElement(m_docMixCascadeInfo,"Mixes");
00366     DOMElement* elemMix=NULL;
00367     count=1;
00368     if(CALibProxytest::getOptions()->isFirstMix())
00369     {
00370       addMixInfo(elemMixesDocCascade, false);
00371     getDOMChildByName(elemMixesDocCascade, "Mix", elemMix, false);
00372       // create signature
00373     if (signXML(elemMix) != E_SUCCESS)
00374     {
00375       CAMsg::printMsg(LOG_DEBUG,"Could not sign KeyInfo sent to users...\n");
00376     }
00377       //if(m_pSignature->signXML(docMixInfo,m_pcertstoreOwnCerts)!=E_SUCCESS)
00378     //m_pSignature, CALibProxytest::getOptions()->getOwnCertificate()
00379     /*
00380         elemMixesDocCascade.appendChild(elemThisMix);*/
00381     }
00382     elemRoot->appendChild(elemMixesDocCascade);
00383 
00384 //    UINT8 cascadeId[255];
00385 //    UINT32 cascadeIdLen=255;
00386 
00387     DOMNode* node=mixes->getFirstChild();
00388     while(node!=NULL)
00389     {
00390         if(node->getNodeType()==DOMNode::ELEMENT_NODE&&equals(node->getNodeName(),"Mix"))
00391         {
00392             elemMixesDocCascade->appendChild(m_docMixCascadeInfo->importNode(node,true));
00393             count++;
00394  //           cascadeId = static_cast<const DOM_Element&>(node).getAttribute("id").transcode();
00395         }
00396         node=node->getNextSibling();
00397     }
00398 
00399     if(CALibProxytest::getOptions()->isLastMix())
00400     {
00401       addMixInfo(elemMixesDocCascade, false);
00402       getLastDOMChildByName(elemMixesDocCascade, "Mix", elemMix);
00403       // create signature
00404     if (signXML(elemMix) != E_SUCCESS)
00405     {
00406       CAMsg::printMsg(LOG_DEBUG,"Could not sign KeyInfo sent to users...\n");
00407     }
00408         cascadeID = id;
00409     }
00410     else if(CALibProxytest::getOptions()->isFirstMix())
00411     {
00412         cascadeID = id;
00413     }
00414 
00415     if(cascadeID != NULL)
00416         setDOMElementAttribute(elemRoot,"id",cascadeID);
00417     setDOMElementAttribute(elemMixesDocCascade,"count",count);
00418 
00419   DOMNode* elemPayment=createDOMElement(m_docMixCascadeInfo,"Payment");
00420   elemRoot->appendChild(elemPayment);
00421 #ifdef PAYMENT
00422   setDOMElementAttribute(elemPayment,"required",(UINT8*)"true");
00423   setDOMElementAttribute(elemPayment,"version",(UINT8*)PAYMENT_VERSION);
00424   setDOMElementAttribute(elemPayment,"prepaidInterval", CALibProxytest::getOptions()->getPrepaidInterval());
00425   setDOMElementAttribute(elemPayment,"piid", CALibProxytest::getOptions()->getBI()->getID());
00426 #else
00427   setDOMElementAttribute(elemPayment,"required",(UINT8*)"false");
00428 #endif
00429     return E_SUCCESS;
00430 }
00431 
00432 SINT32 CAMix::addMixInfo(DOMNode* a_element, bool a_bForceFirstNode)
00433 {
00434   // this is a complete mixinfo node to be sent to the InfoService
00435   XERCES_CPP_NAMESPACE::DOMDocument* docMixInfo=NULL;
00436   if(CALibProxytest::getOptions()->getMixXml(docMixInfo)!=E_SUCCESS)
00437   {
00438     return E_UNKNOWN;
00439   }
00440   DOMNode* nodeMixInfo = a_element->getOwnerDocument()->importNode(
00441     docMixInfo->getDocumentElement(), true);
00442   if (a_bForceFirstNode && a_element->hasChildNodes())
00443   {
00444     a_element->insertBefore(nodeMixInfo, a_element->getFirstChild());
00445   }
00446   else
00447   {
00448     a_element->appendChild(nodeMixInfo);
00449   }
00450   return E_SUCCESS;
00451 }
00452 
00453 DOMNode *CAMix::appendTermsAndConditionsExtension(XERCES_CPP_NAMESPACE::DOMDocument *ownerDoc,
00454     DOMElement *root)
00455 {
00456   if(CALibProxytest::getOptions()->getTermsAndConditions() != NULL)
00457   {
00458     if( (root == NULL) || (ownerDoc == NULL) )
00459     {
00460       return NULL;
00461     }
00462 
00463     DOMElement *elemTnCExtension = NULL, *elemExtensions = NULL,
00464           *elemTemplates = NULL;
00465     /* Tag for Nodes that can be removed without destroying the signature.
00466      * To be appended to the "mixes"-node so older mix versions won't get confused.
00467      */
00468     getDOMChildByName(root, KEYINFO_NODE_EXTENSIONS, elemExtensions);
00469     if(elemExtensions == NULL)
00470     {
00471       elemExtensions = createDOMElement(ownerDoc, KEYINFO_NODE_EXTENSIONS);
00472       root->appendChild(elemExtensions);
00473     }
00474     else
00475     {
00476       getDOMChildByName(elemExtensions, KEYINFO_NODE_TNC_EXTENSION, elemTnCExtension);
00477     }
00478 
00479     if(elemTnCExtension == NULL)
00480     {
00481       elemTnCExtension = createDOMElement(ownerDoc, KEYINFO_NODE_TNC_EXTENSION);
00482       elemExtensions->appendChild(elemTnCExtension);
00483     }
00484 
00485     //First add templates if there are any
00486     UINT32 nrOfTemplates = CALibProxytest::getOptions()->getNumberOfTermsAndConditionsTemplates();
00487 
00488     if(nrOfTemplates > 0)
00489     {
00490       UINT32 nrOfSentTemplates = 0;
00491       UINT8 **sentTemplatesRefIds = NULL;
00492       getDOMChildByName(elemTnCExtension, OPTIONS_NODE_TNCS_TEMPLATES, elemTemplates);
00493       if(elemTemplates == NULL)
00494       {
00495         elemTemplates = createDOMElement(ownerDoc, OPTIONS_NODE_TNCS_TEMPLATES);
00496         elemTnCExtension->appendChild(elemTemplates);
00497       }
00498       else
00499       {
00500         DOMNodeList *nl = getElementsByTagName(elemTemplates, "TermsAndConditionsTemplate");
00501         nrOfSentTemplates = nl->getLength();
00502         if(nrOfSentTemplates > 0)
00503         {
00504           sentTemplatesRefIds = new UINT8*[nrOfSentTemplates];
00505           for (UINT32 i = 0; i < nrOfSentTemplates; i++)
00506           {
00507             sentTemplatesRefIds[i] = getTermsAndConditionsTemplateRefId(nl->item(i));
00508           }
00509         }
00510       }
00511 
00512       XERCES_CPP_NAMESPACE::DOMDocument **allTemplates = CALibProxytest::getOptions()->getAllTermsAndConditionsTemplates();
00513       UINT8 *currentTemplateRefId = NULL;
00514       bool duplicate = false;
00515       for(UINT32 i = 0; i < nrOfTemplates; i++)
00516       {
00517         currentTemplateRefId =
00518           getTermsAndConditionsTemplateRefId(allTemplates[i]->getDocumentElement());
00519         duplicate = false;
00520         if(currentTemplateRefId != NULL)
00521         {
00522           for(UINT32 j=0; j < nrOfSentTemplates; j++)
00523           {
00524             if(strncmp((char *)currentTemplateRefId, (char *)sentTemplatesRefIds[j], TEMPLATE_REFID_MAXLEN) == 0)
00525             {
00526               duplicate = true;
00527               break;
00528             }
00529           }
00530           if(!duplicate)
00531           {
00532             //TODO: avoid duplicates.
00533             elemTemplates->appendChild(ownerDoc->importNode(
00534                 allTemplates[i]->getDocumentElement(), true));
00535             CAMsg::printMsg(LOG_DEBUG,"appended a tc template node!\n");
00536           }
00537           else
00538           {
00539             CAMsg::printMsg(LOG_DEBUG,"template '%s' already sent.\n", currentTemplateRefId);
00540           }
00541           delete [] currentTemplateRefId;
00542           currentTemplateRefId = NULL;
00543         }
00544       }
00545 
00546       for(UINT32 i = 0; i < nrOfSentTemplates; i++)
00547       {
00548         delete [] sentTemplatesRefIds[i];
00549         sentTemplatesRefIds[i] = NULL;
00550       }
00551       delete [] sentTemplatesRefIds;
00552       sentTemplatesRefIds = NULL;
00553     }
00554 
00555     DOMNode* elemTnCs = ownerDoc->importNode(CALibProxytest::getOptions()->getTermsAndConditions(), true);
00556     UINT8 tmpOpSKIBuff[TMP_BUFF_SIZE];
00557     UINT32 tmpOpSKILen = TMP_BUFF_SIZE;
00558     memset(tmpOpSKIBuff, 0, tmpOpSKILen);
00559     CALibProxytest::getOptions()->getOperatorSubjectKeyIdentifier(tmpOpSKIBuff, &tmpOpSKILen);
00560     setDOMElementAttribute(elemTnCs, OPTIONS_ATTRIBUTE_TNC_ID, tmpOpSKIBuff);
00561 
00562     DOMNodeList *tncDefEntryList = getElementsByTagName((DOMElement *)elemTnCs, OPTIONS_NODE_TNCS_TRANSLATION);
00563     for (XMLSize_t i = 0; i < tncDefEntryList->getLength(); i++)
00564     {
00565       //TODO don't know if to include certs here
00566       m_pMultiSignature->signXML((DOMElement *)tncDefEntryList->item(i), false);
00567     }
00568     elemTnCExtension->appendChild(elemTnCs);
00569     return elemTnCExtension;
00570   }
00571   else
00572   {
00573     return NULL;
00574   }
00575 }
00576 
00577 DOMNode *CAMix::termsAndConditionsInfoNode(XERCES_CPP_NAMESPACE::DOMDocument *ownerDoc)
00578 {
00579   if(CALibProxytest::getOptions()->getTermsAndConditions() != NULL)
00580   {
00581     DOMElement *elemTnCInfos = createDOMElement(ownerDoc, KEYINFO_NODE_TNC_INFOS);
00582     UINT8 tmpBuff[TMP_BUFF_SIZE];
00583     UINT32 tmpLen = TMP_BUFF_SIZE;
00584     memset(tmpBuff, 0, tmpLen);
00585 
00586     DOMNodeList *list = getElementsByTagName(CALibProxytest::getOptions()->getTermsAndConditions(), OPTIONS_NODE_TNCS_TRANSLATION);
00587     DOMElement *iterator = NULL;
00588     DOMElement *currentInfoNode = NULL;
00589     bool defaultLangDefined = false;
00590     for (XMLSize_t i = 0; i < list->getLength(); i++)
00591     {
00592       iterator = (DOMElement *) list->item(i);
00593       currentInfoNode = createDOMElement(ownerDoc, KEYINFO_NODE_TNC_INFO);
00594 
00595       getDOMElementAttribute(iterator, OPTIONS_ATTRIBUTE_TNC_LOCALE, tmpBuff, &tmpLen);
00596       setDOMElementAttribute(currentInfoNode, OPTIONS_ATTRIBUTE_TNC_LOCALE, tmpBuff);
00597       getDOMElementAttribute(iterator, OPTIONS_ATTRIBUTE_TNC_DEFAULT_LANG_DEFINED, defaultLangDefined);
00598       if(defaultLangDefined)
00599       {
00600         setDOMElementAttribute(elemTnCInfos, OPTIONS_ATTRIBUTE_TNC_DEFAULT_LANG, tmpBuff);
00601       }
00602       defaultLangDefined = false;
00603       tmpLen = TMP_BUFF_SIZE;
00604 
00605       getDOMElementAttribute(iterator, OPTIONS_ATTRIBUTE_TNC_TEMPLATE_REFID, tmpBuff, &tmpLen);
00606       setDOMElementAttribute(currentInfoNode, OPTIONS_ATTRIBUTE_TNC_TEMPLATE_REFID, tmpBuff);
00607       tmpLen = TMP_BUFF_SIZE;
00608 
00609       elemTnCInfos->appendChild(currentInfoNode);
00610     }
00611 
00612     getDOMElementAttribute(CALibProxytest::getOptions()->getTermsAndConditions(), OPTIONS_ATTRIBUTE_TNC_DATE, tmpBuff, &tmpLen);
00613     setDOMElementAttribute(elemTnCInfos, OPTIONS_ATTRIBUTE_TNC_DATE, tmpBuff);
00614 
00615     tmpLen = TMP_BUFF_SIZE;
00616     //memset(tmpBuff, 0, tmpLen);
00617 
00618     CALibProxytest::getOptions()->getOperatorSubjectKeyIdentifier(tmpBuff, &tmpLen);
00619     setDOMElementAttribute(elemTnCInfos, OPTIONS_ATTRIBUTE_TNC_ID, tmpBuff);
00620     return elemTnCInfos;
00621   }
00622   else
00623   {
00624     return NULL;
00625   }
00626 
00627 }
00628 
00629 
00630 SINT32 CAMix::appendCompatibilityInfo(DOMNode* a_parent)
00631 {
00632   DOMElement* elemCompatibility=createDOMElement(a_parent->getOwnerDocument(),"Compatibility");
00633   setDOMElementAttribute(elemCompatibility,"version",(UINT8*)MIX_VERSION);
00634   a_parent->appendChild(elemCompatibility);
00635 
00636   DOMElement* elemFlags=NULL;
00637   DOMElement* elemFlag=NULL;
00638 
00639   elemFlags = createDOMElement(a_parent->getOwnerDocument(), "Flags");
00640   elemCompatibility->appendChild(elemFlags);
00641 
00643 #ifdef PAYMENT
00644   elemFlag = createDOMElement(a_parent->getOwnerDocument(), PAYMENT_COMPATIBILITY);
00645   //setDOMElementValue(elemFlag,(UINT8*)"true"); // you might add a version number here for a protocol etc.
00646   elemFlags->appendChild(elemFlag);
00647 #endif
00648 
00649   elemFlag = createDOMElement(a_parent->getOwnerDocument(), NEW_FLOW_CONTROL_COMPATIBILITY);
00650   //setDOMElementValue(elemFlag,(UINT8*)"true");
00651   elemFlags->appendChild(elemFlag);
00652 
00653   elemFlag = createDOMElement(a_parent->getOwnerDocument(), NEW_CHANNEL_ENCRYPTION_COMPATIBILITY);
00654   //setDOMElementValue(elemFlag,(UINT8*)"true");
00655   elemFlags->appendChild(elemFlag);
00656 
00657 #ifdef WITH_INTEGRITY_CHECK
00658   elemFlag = createDOMElement(a_parent->getOwnerDocument(), WITH_INTEGRITY_CHECK_COMPATIBILITY);
00659   //setDOMElementValue(elemFlag,(UINT8*)"true");
00660   elemFlags->appendChild(elemFlag);
00661 #endif
00662 
00663   return E_SUCCESS;
00664 }
00665 
00666 SINT32 CAMix::checkCompatibility(DOMNode* a_parent, const char* a_mixPosition)
00667 {
00668   // get compatibility info
00669   DOMElement* elemCompatibility=NULL;
00670   DOMElement* elemFlags=NULL;
00671   DOMElement* elemDummy=NULL;
00672   UINT8 strAllFlags[500];
00673   UINT32 lenAllFlags;
00674   UINT8 strNodeName[50];
00675   UINT32 lenNodeName=50;
00676   UINT8 strVersion[50];
00677   UINT32 len=50;
00678   SINT32 iCompare;
00679   UINT8* strComment;
00680   UINT32 iCountFlags = 0;
00681   UINT32 iLogLevel = LOG_INFO;
00682   bool bCompatible = true;
00683   bool bCompatibleFlags = true;
00684 
00685   if (getDOMChildByName(a_parent,"Compatibility",elemCompatibility,false) != E_SUCCESS ||
00686     getDOMElementAttribute(elemCompatibility, "version", strVersion, &len) != E_SUCCESS)
00687   {
00688     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);
00689     return E_SUCCESS;
00690   }
00691 
00692   iCompare = strncmp (MIX_VERSION, (char*)strVersion, len);
00693 
00694   if (iCompare == 0)
00695   {
00696     strComment = (UINT8*)" We have the same version.";
00697   }
00698   else if (iCompare < 0)
00699   {
00700     strComment = (UINT8*)" Our version (" MIX_VERSION ") might be too old. If the connection fails for an unknown reason, you should think about an update.";
00701     iLogLevel = LOG_WARNING;
00702   }
00703   else
00704   {
00706     if (strncmp ("00.08.71", (char*)strVersion, len) > 0)
00707     {
00708       strComment = (UINT8*)" This version is NOT COMPATIBLE with our version (" MIX_VERSION ")! The mixes will not work together in a cascade.";
00709       bCompatible = false;
00710       iLogLevel = LOG_CRIT;
00711     }
00712     else
00713     {
00714       strComment = (UINT8*)" We have a newer version (" MIX_VERSION "), but both are known to work fine together.";
00715     }
00716   }
00717 
00718   CAMsg::printMsg(iLogLevel,"The software version of the %s mix is %s.%s\n", a_mixPosition, strVersion, strComment);
00719 
00721 #ifdef PAYMENT
00722   iCountFlags++;
00723 #endif
00724 
00725   iCountFlags++;
00726 
00727   iCountFlags++;
00728 
00729 #ifdef WITH_INTEGRITY_CHECK
00730   iCountFlags++;
00731 #endif
00732 
00733   if (getDOMChildByName(elemCompatibility, "Flags", elemFlags, false) == E_SUCCESS)
00734   {
00735     DOMNodeList* flags = elemFlags->getChildNodes();
00736     if (flags->getLength() != iCountFlags)
00737     {
00738       bCompatibleFlags = false;
00739     }
00740 
00742     // 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'.
00743 #ifdef PAYMENT
00744     if (getDOMChildByName(elemFlags, PAYMENT_COMPATIBILITY, elemDummy, false) != E_SUCCESS)
00745     {
00746       bCompatibleFlags = false;
00747     }
00748 #endif
00749     if (getDOMChildByName(elemFlags, NEW_FLOW_CONTROL_COMPATIBILITY, elemDummy, false) != E_SUCCESS)
00750     {
00751       bCompatibleFlags = false;
00752     }
00753     if (getDOMChildByName(elemFlags, NEW_CHANNEL_ENCRYPTION_COMPATIBILITY, elemDummy, false) != E_SUCCESS)
00754     {
00755       bCompatibleFlags = false;
00756     }
00757 #ifdef WITH_INTEGRITY_CHECK
00758     if (getDOMChildByName(elemFlags, WITH_INTEGRITY_CHECK_COMPATIBILITY, elemDummy, false) != E_SUCCESS)
00759     {
00760       bCompatibleFlags = false;
00761     }
00762 #endif
00763 
00764     if (!bCompatibleFlags)
00765     {
00766       // get the flags of the other mix
00767       strAllFlags[0] = 0;
00768       lenAllFlags = 1;
00769       for (UINT32 i = 0; i < flags->getLength(); i++)
00770       {
00771         if (getNodeName(flags->item(i), strNodeName, &lenNodeName) == E_SUCCESS)
00772         {
00773 
00774           lenAllFlags += strlen((char*)strNodeName) + 1;
00775           if (lenAllFlags > 500)
00776           {
00777             break;
00778           }
00779           strcat((char*)strAllFlags, " ");
00780           strcat((char*)strAllFlags, (char*)strNodeName);
00781         }
00782 
00783         lenNodeName = 50;
00784       }
00785 
00786       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);
00787       return E_UNKNOWN;
00788 
00789     }
00790   }
00791 
00792 
00793   if (!bCompatible)
00794   {
00795     return E_UNKNOWN;
00796   }
00797 
00798   return E_SUCCESS;
00799 }
00800 
00801 
00802 SINT32 CAMix::signXML(DOMNode* a_element)
00803   {
00804     return m_pMultiSignature->signXML(a_element, true);
00805     /*CACertStore* tmpCertStore=new CACertStore();
00806 
00807     CACertificate* ownCert=CALibProxytest::getOptions()->getOwnCertificate();
00808     if(ownCert==NULL)
00809       {
00810         CAMsg::printMsg(LOG_DEBUG,"Own Test Cert is NULL!\n");
00811       }
00812 
00813     // Operator Certificates
00814     CACertificate* opCert = CALibProxytest::getOptions()->getOpCertificate();
00815     if(opCert==NULL)
00816   {
00817         CAMsg::printMsg(LOG_DEBUG,"Op Test Cert is NULL!\n");
00818   }
00819   else
00820   {
00821     // Own  Mix Certificates first, then Operator Certificates
00822     tmpCertStore->add(opCert);
00823   }
00824     tmpCertStore->add(ownCert);
00825 
00826     if(m_pSignature->signXML(a_element, tmpCertStore)!=E_SUCCESS)
00827   {
00828     return E_UNKNOWN;
00829   }
00830 
00831   CASignature* test = new CASignature();
00832   test->setVerifyKey(ownCert);
00833 
00834   if(test->verifyXML(a_element) != E_SUCCESS)
00835   {
00836     CAMsg::printMsg(LOG_DEBUG, "Error verifying own Signature!!\n");
00837     m_pSignature->signXML(a_element, tmpCertStore);
00838   }
00839   else
00840   {
00841     CAMsg::printMsg(LOG_DEBUG, "Own Signature looks ok!\n");
00842   }
00843 
00844 
00845     delete ownCert;
00846     ownCert = NULL;
00847 
00848   delete opCert;
00849   opCert = NULL;
00850 
00851     delete tmpCertStore;
00852     tmpCertStore = NULL;
00853 
00854     return E_SUCCESS;*/
00855 }
00856 #ifdef DYNAMIC_MIX
00857 
00868 SINT32 CAMix::dynaReconfigure(bool a_bChangeMixType)
00869 {
00870   SINT32 ret = E_UNKNOWN;
00871   CASocket tmpSock;
00872   const CASocketAddr* pAddr=NULL;
00873 
00874   m_bReconfigured = true;
00875   m_bLoop = !a_bChangeMixType;
00876 
00877   if(m_bCascadeEstablished)
00878     stopCascade();
00879   m_docMixCascadeInfo = NULL;
00880 
00883   CAListenerInterface* pListener=NULL;
00884   UINT32 interfaces=CALibProxytest::getOptions()->getListenerInterfaceCount();
00885   for(UINT32 i=1;i<=interfaces;i++)
00886   {
00887     pListener=CALibProxytest::getOptions()->getListenerInterface(i);
00888     if(!pListener->isVirtual())
00889       break;
00890     delete pListener;
00891     pListener=NULL;
00892   }
00893   if(pListener==NULL)
00894   {
00895     CAMsg::printMsg(LOG_CRIT," failed!\n");
00896     CAMsg::printMsg(LOG_CRIT,"Reason: no useable (non virtual) interface found!\n");
00897     goto EXIT;
00898   }
00899 
00900   pAddr=pListener->getAddr();
00901   delete pListener;
00902   pListener = NULL;
00903 
00904   tmpSock.connect(*pAddr);
00905   delete pAddr;
00906   pAddr = NULL;
00907   tmpSock.close();
00908 
00909   ret = E_SUCCESS;
00910 EXIT:
00911   CAMsg::printMsg(LOG_DEBUG, "Mix has been reconfigured!\n");
00912   m_bReconfiguring = false;
00913   return ret;
00914 }
00915 #endif //DYNAMIC_MIX
00916 #endif //ONLY_LOCAL_PROXY