|
Mixe for Privacy and Anonymity in the Internet
|
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
1.7.6.1