|
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 00029 #include "StdAfx.h" 00030 #include "CACmdLnOptions.hpp" 00031 #include "CAUtil.hpp" 00032 #include "CAMix.hpp" 00033 #include "CAMsg.hpp" 00034 #include "CASocketAddrINet.hpp" 00035 #include "CAIPAddrWithNetmask.hpp" 00036 #include "CASocket.hpp" 00037 #include "CAXMLBI.hpp" 00038 #include "xml/DOM_Output.hpp" 00039 #include "CABase64.hpp" 00040 #include "CADynaNetworking.hpp" 00041 #ifdef PAYMENT 00042 #include "CAAccountingDBInterface.hpp" 00043 #endif 00044 //#ifdef LOG_CRIME 00045 #include "tre/regex.h" 00046 //#endif 00047 00048 CACmdLnOptions::CACmdLnOptions() 00049 { 00050 m_bDaemon=false; 00051 m_bSyslog=false; 00052 m_bLogConsole = false; 00053 m_bSocksSupport = false; 00054 m_bLocalProxy=m_bFirstMix=m_bLastMix=m_bMiddleMix=false; 00055 00056 #ifndef ONLY_LOCAL_PROXY 00057 m_bIsRunReConfigure=false; 00058 m_addrInfoServices = NULL; 00059 m_addrInfoServicesSize=0; 00060 m_pcsReConfigure=new CAMutex(); 00061 //m_pSignKey=NULL; 00062 //m_pOwnCertificate=NULL; 00063 m_OpCert=NULL; 00064 m_pMultiSignature=NULL; 00065 m_pPrevMixCertificate=NULL; 00066 m_pNextMixCertificate=NULL; 00067 m_pTrustedRootCertificates=NULL; 00068 m_bVerifyMixCerts=false; 00069 m_bCompressedLogs=false; 00070 m_pLogEncryptionCertificate=NULL; 00071 m_bIsEncryptedLogEnabled=false; 00072 m_docMixInfo= createDOMDocument(); 00073 m_docMixXml=NULL; 00074 m_pCascadeXML=NULL; 00075 m_docOpTnCs=NULL; //Operator Terms and Conditions (if any) 00076 m_bAcceptReconfiguration=false; 00077 m_maxNrOfUsers = 0; 00078 00079 #ifdef PAYMENT 00080 m_PaymentReminderProbability= -1; 00081 #else 00082 m_PaymentReminderProbability= -1; 00083 #endif 00084 00085 #ifdef COUNTRY_STATS 00086 m_dbCountryStatsHost=m_dbCountryStatsPasswd=m_dbCountryStatsUser=NULL; 00087 #endif 00088 #endif //ONLY_LOCAL_PROXY 00089 m_iTargetPort=m_iSOCKSPort=m_iSOCKSServerPort=0xFFFF; 00090 m_strTargetHost=m_strSOCKSHost=NULL; 00091 m_strUser=NULL; 00092 m_strCascadeName=NULL; 00093 m_strLogDir=NULL; 00094 m_strLogLevel=NULL; 00095 setZero64(m_maxLogFileSize); 00096 m_strEncryptedLogDir=NULL; 00097 m_arTargetInterfaces=NULL; 00098 m_cnTargets=0; 00099 m_arListenerInterfaces=NULL; 00100 m_cnListenerInterfaces=0; 00101 m_arStrVisibleAddresses=NULL; 00102 m_cnVisibleAddresses=0; 00103 m_nrOfOpenFiles=-1; 00104 m_strMixID=NULL; 00105 m_strMixName=NULL; 00106 m_bAutoReconnect=false; 00107 m_strConfigFile=NULL; 00108 m_strPidFile=NULL; 00109 #ifdef PAYMENT 00110 m_pBI=NULL; 00111 m_strDatabaseHost=NULL; 00112 m_strDatabaseName=NULL; 00113 m_strDatabaseUser=NULL; 00114 m_strDatabasePassword=NULL; 00115 m_strAiID=NULL; 00116 #endif 00117 #ifdef SERVER_MONITORING 00118 m_strMonitoringListenerHost = NULL; 00119 m_iMonitoringListenerPort = 0xFFFF; 00120 #endif 00121 m_termsAndConditionsTemplates = NULL; 00122 m_nrOfTermsAndConditionsTemplates = 0; 00123 00124 #ifdef LOG_CRIME 00125 m_logPayload = false; 00126 m_arCrimeRegExpsURL=NULL; 00127 m_nCrimeRegExpsURL=0; 00128 m_arCrimeRegExpsPayload=NULL; 00129 m_nCrimeRegExpsPayload=0; 00130 m_nrOfSurveillanceIPs = 0; 00131 m_surveillanceIPs = NULL; 00132 m_nrOfSurveillanceAccounts = 0; 00133 m_surveillanceAccounts = NULL; 00134 #endif 00135 00136 #ifdef DATA_RETENTION_LOG 00137 m_strDataRetentionLogDir=NULL; 00138 #endif 00139 00140 #ifdef EXPORT_ASYM_PRIVATE_KEY 00141 m_strImportKeyFile=NULL; 00142 m_strExportKeyFile=NULL; 00143 #endif 00144 00145 #ifdef DYNAMIC_MIX 00146 m_strLastCascadeProposal = NULL; 00147 #endif 00148 00149 #if defined(DELAY_CHANNELS) && defined(DELAY_USERS) 00150 if(isFirstMix()) 00151 { 00152 m_u32DelayChannelUnlimitTraffic=DELAY_USERS_TRAFFIC; 00153 m_u32DelayChannelBucketGrow=DELAY_USERS_BUCKET_GROW; 00154 m_u32DelayChannelBucketGrowIntervall=DELAY_USERS_BUCKET_GROW_INTERVALL; 00155 } 00156 else 00157 { 00158 m_u32DelayChannelUnlimitTraffic=DELAY_CHANNEL_TRAFFIC; 00159 m_u32DelayChannelBucketGrow=DELAY_BUCKET_GROW; 00160 m_u32DelayChannelBucketGrowIntervall=DELAY_BUCKET_GROW_INTERVALL; 00161 } 00162 #elif defined(DELAY_CHANNELS) 00163 m_u32DelayChannelUnlimitTraffic=DELAY_CHANNEL_TRAFFIC; 00164 m_u32DelayChannelBucketGrow=DELAY_BUCKET_GROW; 00165 m_u32DelayChannelBucketGrowIntervall=DELAY_BUCKET_GROW_INTERVALL; 00166 #elif defined (DELAY_USERS) 00167 m_u32DelayChannelUnlimitTraffic=DELAY_USERS_TRAFFIC; 00168 m_u32DelayChannelBucketGrow=DELAY_USERS_BUCKET_GROW; 00169 m_u32DelayChannelBucketGrowIntervall=DELAY_USERS_BUCKET_GROW_INTERVALL; 00170 #endif 00171 00172 #if defined(DELAY_CHANNELS_LATENCY) 00173 m_u32DelayChannelLatency = DELAY_CHANNEL_LATENCY; 00174 #endif 00175 00176 /* initialize pointer to option setter functions */ 00177 initMainOptionSetters(); 00178 initGeneralOptionSetters(); 00179 initCertificateOptionSetters(); 00180 #ifdef PAYMENT 00181 initAccountingOptionSetters(); 00182 #endif 00183 initNetworkOptionSetters(); 00184 initTermsAndConditionsOptionSetters(); 00185 #ifdef LOG_CRIME 00186 initCrimeDetectionOptionSetters(); 00187 #endif 00188 } 00189 00190 CACmdLnOptions::~CACmdLnOptions() 00191 { 00192 cleanup(); 00193 } 00194 00195 void CACmdLnOptions::initMainOptionSetters() 00196 { 00197 mainOptionSetters = new optionSetter_pt[MAIN_OPTION_SETTERS_NR]; 00198 memset(mainOptionSetters,0,sizeof(optionSetter_pt)*MAIN_OPTION_SETTERS_NR); 00199 int count = -1; 00200 00201 mainOptionSetters[++count]= 00202 &CACmdLnOptions::setGeneralOptions; 00203 mainOptionSetters[++count]= 00204 &CACmdLnOptions::setMixDescription; 00205 mainOptionSetters[++count]= 00206 &CACmdLnOptions::setCertificateOptions; 00207 #ifdef PAYMENT 00208 mainOptionSetters[++count]= 00209 &CACmdLnOptions::setAccountingOptions; 00210 #endif 00211 mainOptionSetters[++count]= 00212 &CACmdLnOptions::setNetworkOptions; 00213 mainOptionSetters[++count]= 00214 &CACmdLnOptions::setRessourceOptions; 00215 mainOptionSetters[++count]= 00216 &CACmdLnOptions::setTermsAndConditions; 00217 #ifdef LOG_CRIME 00218 mainOptionSetters[++count]= 00219 &CACmdLnOptions::setCrimeDetectionOptions; 00220 #endif 00221 } 00222 00223 void CACmdLnOptions::initGeneralOptionSetters() 00224 { 00225 generalOptionSetters = new optionSetter_pt[GENERAL_OPTIONS_NR]; 00226 memset(generalOptionSetters,0,sizeof(optionSetter_pt)*GENERAL_OPTIONS_NR); 00227 int count = -1; 00228 00229 generalOptionSetters[++count]= 00230 &CACmdLnOptions::setDaemonMode; 00231 generalOptionSetters[++count]= 00232 &CACmdLnOptions::setNrOfFileDescriptors; 00233 generalOptionSetters[++count]= 00234 &CACmdLnOptions::setUserID; 00235 generalOptionSetters[++count]= 00236 &CACmdLnOptions::setLoggingOptions; 00237 generalOptionSetters[++count]= 00238 &CACmdLnOptions::setMixType; 00239 generalOptionSetters[++count]= 00240 &CACmdLnOptions::setMixName; 00241 generalOptionSetters[++count]= 00242 &CACmdLnOptions::setMixID; 00243 generalOptionSetters[++count]= 00244 &CACmdLnOptions::setDynamicMix; 00245 generalOptionSetters[++count]= 00246 &CACmdLnOptions::setMinCascadeLength; 00247 generalOptionSetters[++count]= 00248 &CACmdLnOptions::setCascadeNameFromOptions; 00249 generalOptionSetters[++count]= 00250 &CACmdLnOptions::setMaxUsers; 00251 generalOptionSetters[++count]= 00252 &CACmdLnOptions::setPaymentReminder; 00253 } 00254 00255 void CACmdLnOptions::initCertificateOptionSetters() 00256 { 00257 certificateOptionSetters = new optionSetter_pt[MAX_CERTIFICATE_OPTIONS_NR]; 00258 m_nCertificateOptionsSetters = 0; 00259 00260 certificateOptionSetters[m_nCertificateOptionsSetters++]=&CACmdLnOptions::setOwnOperatorCertificate; 00261 certificateOptionSetters[m_nCertificateOptionsSetters++]=&CACmdLnOptions::setOwnCertificate; 00262 certificateOptionSetters[m_nCertificateOptionsSetters++]=&CACmdLnOptions::setNextMixCertificate; 00263 certificateOptionSetters[m_nCertificateOptionsSetters++]=&CACmdLnOptions::setPrevMixCertificate; 00264 } 00265 00266 #ifdef PAYMENT 00267 void CACmdLnOptions::initAccountingOptionSetters() 00268 { 00269 accountingOptionSetters = new optionSetter_pt[ACCOUNTING_OPTIONS_NR]; 00270 int count = -1; 00271 00272 accountingOptionSetters[++count]= 00273 &CACmdLnOptions::setPaymentInstance; 00274 accountingOptionSetters[++count]= 00275 &CACmdLnOptions::setPriceCertificate; 00276 accountingOptionSetters[++count]= 00277 &CACmdLnOptions::setAccountingSoftLimit; 00278 accountingOptionSetters[++count]= 00279 &CACmdLnOptions::setAccountingHardLimit; 00280 accountingOptionSetters[++count]= 00281 &CACmdLnOptions::setPrepaidInterval; 00282 accountingOptionSetters[++count]= 00283 &CACmdLnOptions::setSettleInterval; 00284 accountingOptionSetters[++count]= 00285 &CACmdLnOptions::setAccountingDatabase; 00286 } 00287 #endif 00288 void CACmdLnOptions::initNetworkOptionSetters() 00289 { 00290 networkOptionSetters = new optionSetter_pt[NETWORK_OPTIONS_NR]; 00291 int count = -1; 00292 00293 networkOptionSetters[++count]= 00294 &CACmdLnOptions::setInfoServices; 00295 networkOptionSetters[++count]= 00296 &CACmdLnOptions::setListenerInterfaces; 00297 networkOptionSetters[++count]= 00298 &CACmdLnOptions::setTargetInterfaces; 00299 networkOptionSetters[++count]= 00300 &CACmdLnOptions::setServerMonitoring; 00301 networkOptionSetters[++count]= 00302 &CACmdLnOptions::setKeepAliveTraffic; 00303 } 00304 00305 void CACmdLnOptions::initTermsAndConditionsOptionSetters() 00306 { 00307 00308 termsAndConditionsOptionSetters = new optionSetter_pt[TERMS_AND_CONDITIONS_OPTIONS_NR]; 00309 int count = -1; 00310 00311 termsAndConditionsOptionSetters[++count]= 00312 &CACmdLnOptions::setTermsAndConditionsTemplates; 00313 termsAndConditionsOptionSetters[++count]= 00314 &CACmdLnOptions::setTermsAndConditionsList; 00315 } 00316 00317 #ifdef LOG_CRIME 00318 void CACmdLnOptions::initCrimeDetectionOptionSetters() 00319 { 00320 crimeDetectionOptionSetters = new optionSetter_pt[CRIME_DETECTION_OPTIONS_NR]; 00321 int count = -1; 00322 00323 crimeDetectionOptionSetters[++count]= 00324 &CACmdLnOptions::setCrimeURLRegExp; 00325 crimeDetectionOptionSetters[++count]= 00326 &CACmdLnOptions::setCrimePayloadRegExp; 00327 crimeDetectionOptionSetters[++count]= 00328 &CACmdLnOptions::setCrimeSurveillanceAccounts; 00329 crimeDetectionOptionSetters[++count]= 00330 &CACmdLnOptions::setCrimeSurveillanceIP; 00331 } 00332 #endif 00333 00335 SINT32 CACmdLnOptions::cleanup() 00336 { 00337 clean(); 00338 #ifndef ONLY_LOCAL_PROXY 00339 delete m_pcsReConfigure; 00340 m_pcsReConfigure=NULL; 00341 #endif 00342 return E_SUCCESS; 00343 } 00344 00347 SINT32 CACmdLnOptions::clearTargetInterfaces() 00348 { 00349 if(m_arTargetInterfaces!=NULL) 00350 { 00351 for(UINT32 i=0;i<m_cnTargets;i++) 00352 { 00353 m_arTargetInterfaces[i].cleanAddr(); 00354 } 00355 delete[] m_arTargetInterfaces; 00356 m_arTargetInterfaces = NULL; 00357 } 00358 m_cnTargets=0; 00359 m_arTargetInterfaces=NULL; 00360 return E_SUCCESS; 00361 } 00362 00365 SINT32 CACmdLnOptions::clearListenerInterfaces() 00366 { 00367 if(m_arListenerInterfaces!=NULL) 00368 { 00369 for(UINT32 i=0;i<m_cnListenerInterfaces;i++) 00370 { 00371 delete m_arListenerInterfaces[i]; 00372 m_arListenerInterfaces[i] = NULL; 00373 } 00374 delete[] m_arListenerInterfaces; 00375 } 00376 m_cnListenerInterfaces=0; 00377 m_arListenerInterfaces=NULL; 00378 return E_SUCCESS; 00379 } 00380 00381 #ifndef ONLY_LOCAL_PROXY 00382 00384 SINT32 CACmdLnOptions::clearVisibleAddresses() 00385 { 00386 if(m_arStrVisibleAddresses!=NULL) 00387 { 00388 for(UINT32 i=0;i<m_cnVisibleAddresses;i++) 00389 { 00390 delete[] m_arStrVisibleAddresses[i]; 00391 m_arStrVisibleAddresses[i] = NULL; 00392 } 00393 delete[] m_arStrVisibleAddresses; 00394 } 00395 m_cnVisibleAddresses=0; 00396 m_arStrVisibleAddresses=NULL; 00397 return E_SUCCESS; 00398 } 00399 00414 SINT32 CACmdLnOptions::addVisibleAddresses(DOMNode* nodeProxy) 00415 { 00416 if(nodeProxy==NULL) return E_UNKNOWN; 00417 ASSERT_PARENT_NODE_NAME 00418 (nodeProxy->getNodeName(), OPTIONS_NODE_PROXY, OPTIONS_NODE_VISIBLE_ADDRESS_LIST); 00419 DOMNode* elemVisAdresses=NULL; 00420 getDOMChildByName(nodeProxy, OPTIONS_NODE_VISIBLE_ADDRESS_LIST, elemVisAdresses); 00421 DOMNode* elemVisAddress=NULL; 00422 getDOMChildByName(elemVisAdresses, OPTIONS_NODE_VISIBLE_ADDRESS ,elemVisAddress); 00423 while(elemVisAddress!=NULL) 00424 { 00425 if(equals(elemVisAddress->getNodeName(), OPTIONS_NODE_VISIBLE_ADDRESS)) 00426 { 00427 DOMElement* elemHost=NULL; 00428 if(getDOMChildByName(elemVisAddress, OPTIONS_NODE_HOST ,elemHost)==E_SUCCESS) 00429 { 00430 UINT8 tmp[TMP_BUFF_SIZE]; 00431 UINT32 len = TMP_BUFF_SIZE; 00432 if(getDOMElementValue(elemHost,tmp,&len)==E_SUCCESS) 00433 {//append the new address to the list of addresses 00434 UINT8** tmpAr=new UINT8*[m_cnVisibleAddresses+1]; 00435 if(m_arStrVisibleAddresses!=NULL) 00436 { 00437 memcpy(tmpAr,m_arStrVisibleAddresses,m_cnVisibleAddresses*sizeof(UINT8*)); 00438 delete[] m_arStrVisibleAddresses; 00439 m_arStrVisibleAddresses = NULL; 00440 } 00441 tmpAr[m_cnVisibleAddresses]=new UINT8[len+1]; 00442 memcpy(tmpAr[m_cnVisibleAddresses],tmp,len+1); 00443 m_cnVisibleAddresses++; 00444 m_arStrVisibleAddresses=tmpAr; 00445 } 00446 } 00447 } 00448 elemVisAddress=elemVisAddress->getNextSibling(); 00449 } 00450 return E_SUCCESS; 00451 } 00452 00453 SINT32 CACmdLnOptions::getVisibleAddress(UINT8* strAddressBuff, UINT32 len,UINT32 nr) 00454 { 00455 if(strAddressBuff==NULL||nr==0||nr>m_cnVisibleAddresses) 00456 { 00457 return E_UNKNOWN; 00458 } 00459 if(strlen((char*)m_arStrVisibleAddresses[nr-1] )>=len) 00460 { 00461 return E_SPACE; 00462 } 00463 strcpy((char*)strAddressBuff,(char*)m_arStrVisibleAddresses[nr-1]); 00464 return E_SUCCESS; 00465 } 00466 #endif //ONLY_LOCAL_PROXY 00467 00469 void CACmdLnOptions::clean() 00470 { 00471 delete[] m_strConfigFile; 00472 m_strConfigFile=NULL; 00473 00474 delete[] m_strTargetHost; 00475 m_strTargetHost=NULL; 00476 00477 delete[] m_strSOCKSHost; 00478 m_strSOCKSHost=NULL; 00479 00480 #ifndef ONLY_LOCAL_PROXY 00481 if (m_addrInfoServices != NULL) 00482 { 00483 for (UINT32 i = 0; i < m_addrInfoServicesSize; i++) 00484 { 00485 delete m_addrInfoServices[i]; 00486 m_addrInfoServices[i] = NULL; 00487 } 00488 delete[] m_addrInfoServices; 00489 m_addrInfoServices=NULL; 00490 m_addrInfoServicesSize = 0; 00491 } 00492 #endif //ONLY_LOCAL_PROXY 00493 00494 00495 delete[] m_strCascadeName; 00496 m_strCascadeName=NULL; 00497 00498 delete[] m_strLogDir; 00499 m_strLogDir=NULL; 00500 00501 delete[] m_strLogLevel; 00502 m_strLogLevel=NULL; 00503 00504 delete[] m_strPidFile; 00505 m_strPidFile=NULL; 00506 00507 delete[] m_strEncryptedLogDir; 00508 m_strEncryptedLogDir=NULL; 00509 00510 delete[] m_strUser; 00511 m_strUser=NULL; 00512 00513 delete[] m_strMixID; 00514 m_strMixID=NULL; 00515 00516 delete[] m_strMixName; 00517 m_strMixName=NULL; 00518 00519 clearTargetInterfaces(); 00520 clearListenerInterfaces(); 00521 #ifndef ONLY_LOCAL_PROXY 00522 if(m_docMixInfo!=NULL) 00523 m_docMixInfo=NULL; 00524 clearVisibleAddresses(); 00525 00526 //delete m_pSignKey; 00527 //m_pSignKey=NULL; 00528 00529 //delete m_pOwnCertificate; 00530 //m_pOwnCertificate=NULL; 00531 00532 delete m_pMultiSignature; 00533 m_pMultiSignature = NULL; 00534 00535 delete m_OpCert; 00536 m_OpCert=NULL; 00537 00538 delete m_pNextMixCertificate; 00539 m_pNextMixCertificate=NULL; 00540 00541 delete m_pPrevMixCertificate; 00542 m_pPrevMixCertificate=NULL; 00543 00544 delete m_pLogEncryptionCertificate; 00545 m_pLogEncryptionCertificate=NULL; 00546 00547 if(m_docMixInfo!=NULL) 00548 { 00549 m_docMixInfo->release(); 00550 m_docMixInfo=NULL; 00551 } 00552 00553 if(m_docMixXml!=NULL) 00554 { 00555 m_docMixXml->release(); 00556 m_docMixXml=NULL; 00557 } 00558 00559 if(m_docOpTnCs!=NULL) 00560 { 00561 m_docOpTnCs->release(); 00562 m_docOpTnCs=NULL; 00563 } 00564 00565 #ifdef COUNTRY_STATS 00566 delete[] m_dbCountryStatsHost; 00567 m_dbCountryStatsHost = NULL; 00568 delete[] m_dbCountryStatsUser; 00569 m_dbCountryStatsUser = NULL; 00570 delete[] m_dbCountryStatsPasswd; 00571 m_dbCountryStatsPasswd = NULL; 00572 #endif 00573 00574 #ifdef DATA_RETENTION_LOG 00575 delete[] m_strDataRetentionLogDir; 00576 m_strDataRetentionLogDir=NULL; 00577 #endif 00578 00579 #ifdef EXPORT_ASYM_PRIVATE_KEY 00580 if(m_strImportKeyFile!=NULL) 00581 delete[] m_strImportKeyFile; 00582 m_strImportKeyFile=NULL; 00583 if(m_strExportKeyFile!=NULL) 00584 delete[] m_strExportKeyFile; 00585 m_strExportKeyFile=NULL; 00586 #endif 00587 00588 00589 #endif //ONLY_LOCAL_PROXY 00590 #ifdef SERVER_MONITORING 00591 if(m_strMonitoringListenerHost != NULL) 00592 { 00593 delete[] m_strMonitoringListenerHost; 00594 m_strMonitoringListenerHost = NULL; 00595 } 00596 #endif 00597 delete [] mainOptionSetters; 00598 mainOptionSetters = NULL; 00599 delete [] generalOptionSetters; 00600 generalOptionSetters = NULL; 00601 delete certificateOptionSetters; 00602 certificateOptionSetters = NULL; 00603 #ifdef PAYMENT 00604 delete [] accountingOptionSetters; 00605 accountingOptionSetters = NULL; 00606 #endif 00607 delete [] networkOptionSetters; 00608 networkOptionSetters = NULL; 00609 } 00610 00611 SINT32 CACmdLnOptions::parse(int argc,const char** argv) 00612 { 00613 int iDaemon=0; 00614 char* target=NULL; 00615 int iLocalProxy=0; 00616 int SOCKSport=-1; 00617 char* socks=NULL; 00618 char* logdir=NULL; 00619 int iCompressedLogs=0; 00620 char* serverPort=NULL; 00621 int iVersion=0; 00622 char* configfile=NULL; 00623 int iAutoReconnect=0; 00624 char* strPidFile=NULL; 00625 char* strCreateConf=NULL; 00626 #ifdef EXPORT_ASYM_PRIVATE_KEY 00627 char* strImportKey=NULL; 00628 char* strExportKey=NULL; 00629 #endif 00630 //DOM_Document docMixXml; 00631 poptOption theOptions[]= 00632 { 00633 {"localproxy",'j',POPT_ARG_NONE,&iLocalProxy,0,"act as local proxy",NULL}, 00634 {"daemon",'d',POPT_ARG_NONE,&iDaemon,0,"start as daemon [only for local proxy]",NULL}, 00635 {"next",'n',POPT_ARG_STRING,&target,0,"first mix of cascade [only for local proxy]","<ip:port>"}, 00636 {"autoreconnect",'a',POPT_ARG_NONE,&iAutoReconnect,0,"auto reconnects if connection to first mix was lost [only for local proxy]",NULL}, 00637 {"port",'p',POPT_ARG_STRING,&serverPort,0,"listening on [host:]port|path [only for local proxy]","<[host:]port|path>"}, 00638 {"socksport",'s',POPT_ARG_INT,&SOCKSport,0,"listening port for socks","<portnumber>"}, 00639 {"logdir",'l',POPT_ARG_STRING,&logdir,0,"directory where log files go to [only for local proxy]","<dir>"}, 00640 #ifdef COMPRESSED_LOGS 00641 {"gzip",'z',POPT_ARG_NONE,&iCompressedLogs,0,"create gziped logs",NULL}, 00642 #endif 00643 {"config",'c',POPT_ARG_STRING,&configfile,0,"config file to use [for a real Mix in a cascade]","<file>"}, 00644 {"version",'v',POPT_ARG_NONE,&iVersion,0,"show version",NULL}, 00645 {"pidfile",'r',POPT_ARG_STRING,&strPidFile,0,"file where the PID will be stored","<file>"}, 00646 {"createConf",0,POPT_ARG_STRING,&strCreateConf,0,"creates a generic configuration for MixOnCD","[<file>]"}, 00647 #ifdef EXPORT_ASYM_PRIVATE_KEY 00648 {"exportKey",0,POPT_ARG_STRING,&strExportKey,0,"export private encryption key to file","<file>"}, 00649 {"importKey",0,POPT_ARG_STRING,&strImportKey,0,"import private encryption key from file","<file>"}, 00650 #endif 00651 POPT_AUTOHELP 00652 {NULL,0,0, 00653 NULL,0,NULL,NULL} 00654 }; 00655 poptContext ctx=poptGetContext(NULL,argc,argv,theOptions,0); 00656 SINT32 ret=poptGetNextOpt(ctx); 00657 while(ret==POPT_ERROR_BADOPT) 00658 ret=poptGetNextOpt(ctx); 00659 poptFreeContext(ctx); 00660 if(iVersion!=0) 00661 { 00662 printf(MIX_VERSION_INFO); 00663 for(UINT32 t=0;t<10000;t++) 00664 { 00665 CASocket* pSocket=new CASocket; 00666 if(pSocket->create(false)!=E_SUCCESS) 00667 { 00668 printf("Max open sockets: %u\n",t); 00669 exit(0); 00670 } 00671 } 00672 printf("Max open sockets: >10000\n"); 00673 exit(0); 00674 } 00675 00676 if (MIX_VERSION_TESTING) 00677 { 00678 CAMsg::printMsg(LOG_WARNING, MIX_VERSION_TESTING_TEXT); 00679 } 00680 00681 #ifndef ONLY_LOCAL_PROXY 00682 if(strCreateConf!=NULL) 00683 { 00684 createMixOnCDConfiguration((UINT8*)strCreateConf); 00685 exit(0); 00686 } 00687 #endif 00688 if(iLocalProxy!=0) 00689 m_bLocalProxy=true; 00690 if(m_bLocalProxy&&iAutoReconnect!=0) 00691 m_bAutoReconnect=true; 00692 00693 /* LERNGRUPPE: Also try to use default config file for Mix Category 1 */ 00694 if(configfile == NULL) 00695 { 00696 configfile = (char*) malloc(sizeof(char) * (strlen(DEFAULT_CONFIG_FILE)+1)); 00697 strncpy(configfile, DEFAULT_CONFIG_FILE, (strlen(DEFAULT_CONFIG_FILE)+1)); 00698 00699 #if defined (_WIN32) &&!defined(__CYGWIN__) 00700 // R_OK is not defined in Windows POSIX implementation 00701 #define R_OK 4 00702 #endif 00703 00704 int err = access(configfile, R_OK); 00705 if( err ) 00706 { 00707 if(configfile != NULL) 00708 { 00709 free(configfile); 00710 configfile = NULL; 00711 } 00712 } 00713 } 00714 /* END LERNGRUPPE */ 00715 00716 00717 if(configfile!=NULL) 00718 { 00719 #ifndef ONLY_LOCAL_PROXY 00720 ret=readXmlConfiguration(m_docMixXml,(UINT8*)configfile); 00721 if(ret==E_FILE_OPEN) 00722 CAMsg::printMsg(LOG_CRIT,"Could not open config file: %s\n",configfile); 00723 else if(ret==E_FILE_READ) 00724 CAMsg::printMsg(LOG_CRIT,"Could not read config file: %s\n",configfile); 00725 else if(ret==E_XML_PARSE) 00726 CAMsg::printMsg(LOG_CRIT,"Could not parse config file: %s\n",configfile); 00727 else 00728 { 00729 m_strConfigFile=new UINT8[strlen(configfile)+1]; 00730 memcpy(m_strConfigFile,configfile,strlen(configfile)+1); 00731 } 00732 #endif 00733 free(configfile); 00734 } 00735 if(iDaemon!=0) 00736 m_bDaemon=true; 00737 if(target!=NULL) 00738 { 00739 if(target[0]=='/') //Unix Domain Sockaet 00740 { 00741 m_strTargetHost=new char[strlen(target)+1]; 00742 strcpy(m_strTargetHost,target); 00743 } 00744 else 00745 { 00746 char tmpHostname[TMP_BUFF_SIZE]; 00747 SINT32 tmpPort; 00748 char* tmpStr1=strchr(target,':'); 00749 if(tmpStr1!=NULL) 00750 { 00751 memcpy(tmpHostname,target,tmpStr1-target); 00752 tmpHostname[tmpStr1-target]=0; 00753 tmpPort=(SINT32)atol(tmpStr1+1); 00754 } 00755 else 00756 {//TODO what if not in right form ? 00757 //try if it is a number --> use it as port 00758 //and use 'localhost' as traget-host 00759 tmpPort=(SINT32)atol(target); 00760 if(tmpPort!=0) //we get it 00761 { 00762 strcpy(tmpHostname,"localhost"); 00763 } 00764 else //we try to use it as host and use the default port 00765 { 00766 /* LERNGRUPPE moved the define to CACmdLnOption.hpp because we need it elsewhere too */ 00767 //#define DEFAULT_TARGET_PORT 6544 00768 tmpPort=DEFAULT_TARGET_PORT; 00769 strcpy(tmpHostname,target); 00770 } 00771 } 00772 m_strTargetHost=new char[strlen(tmpHostname)+1]; 00773 strcpy(m_strTargetHost,tmpHostname); 00774 m_iTargetPort=(UINT16)tmpPort; 00775 } 00776 free(target); 00777 } 00778 if(socks!=NULL) 00779 { 00780 char* tmpStr; 00781 if((tmpStr=strchr(socks,':'))!=NULL) 00782 { 00783 m_strSOCKSHost=new char[tmpStr-socks+1]; 00784 (*tmpStr)=0; 00785 strcpy(m_strSOCKSHost,socks); 00786 m_iSOCKSPort=(UINT16)atol(tmpStr+1); 00787 } 00788 free(socks); 00789 } 00790 if(logdir!=NULL) 00791 { 00792 m_strLogDir=new char[strlen(logdir)+1]; 00793 strcpy(m_strLogDir,logdir); 00794 free(logdir); 00795 } 00796 if(strPidFile!=NULL) 00797 { 00798 m_strPidFile=new char[strlen(strPidFile)+1]; 00799 strcpy(m_strPidFile,strPidFile); 00800 free(strPidFile); 00801 } 00802 #ifdef EXPORT_ASYM_PRIVATE_KEY 00803 if(strExportKey!=NULL) 00804 { 00805 m_strExportKeyFile=new UINT8[strlen(strExportKey)+1]; 00806 strcpy((char*)m_strExportKeyFile,strExportKey); 00807 free(strExportKey); 00808 } 00809 if(strImportKey!=NULL) 00810 { 00811 m_strImportKeyFile=new UINT8[strlen(strImportKey)+1]; 00812 strcpy((char*)m_strImportKeyFile,strImportKey); 00813 free(strImportKey); 00814 } 00815 #endif 00816 if(iCompressedLogs!=0) 00817 m_bCompressedLogs=true; 00818 00819 if(serverPort!=NULL&&m_bLocalProxy) 00820 { 00821 m_arListenerInterfaces=new CAListenerInterface*[1]; 00822 m_arListenerInterfaces[0]=NULL; 00823 m_cnListenerInterfaces=0; 00824 char* tmpStr; 00825 if(serverPort[0]=='/') //Unix Domain Socket 00826 { 00827 m_arListenerInterfaces[0]=CAListenerInterface::getInstance(RAW_UNIX,(UINT8*)serverPort); 00828 } 00829 else //Internet Socket 00830 { 00831 char* strServerHost=NULL; 00832 SINT32 iServerPort; 00833 if((tmpStr=strchr(serverPort,':'))!=NULL) //host:port 00834 { 00835 strServerHost=new char[tmpStr-serverPort+1]; 00836 (*tmpStr)=0; 00837 strcpy(strServerHost,serverPort); 00838 iServerPort=(SINT32)atol(tmpStr+1); 00839 } 00840 else //port only ? 00841 { 00842 iServerPort=(SINT32)atol(serverPort); 00843 } 00844 m_arListenerInterfaces[0]=CAListenerInterface::getInstance(RAW_TCP,(UINT8*)strServerHost,(UINT16)iServerPort); 00845 delete [] strServerHost; 00846 strServerHost = NULL; 00847 } 00848 free(serverPort); 00849 if(m_arListenerInterfaces[0]!=0) 00850 m_cnListenerInterfaces=1; 00851 } 00852 00853 m_iSOCKSServerPort=(UINT16)SOCKSport; 00854 #ifndef ONLY_LOCAL_PROXY 00855 if(!m_bLocalProxy) 00856 { 00857 ret=processXmlConfiguration(m_docMixXml); 00858 #ifndef DYNAMIC_MIX 00859 if(ret!=E_SUCCESS) 00860 return ret; 00861 } 00862 #else 00863 /* LERNGRUPPE: Let's try to recover and build a default configuration */ 00864 if(ret!=E_SUCCESS) 00865 { 00866 createDefaultConfiguration(); 00867 ret=processXmlConfiguration(m_docMixXml); 00868 if(ret!=E_SUCCESS) 00869 return ret; 00870 } 00871 } 00872 #endif 00873 00874 /* Try to read InfoService configuration from external file infoservices.xml */ 00875 XERCES_CPP_NAMESPACE::DOMDocument* infoservices; 00876 if( readXmlConfiguration(infoservices,(UINT8*)"infoservices.xml") == E_SUCCESS ) 00877 { 00878 CAMsg::printMsg(LOG_DEBUG, "Will now get InfoServices from infoservices.xml (this overrides the InfoServices from the default config!)\n"); 00879 DOMElement* elemIs=infoservices->getDocumentElement(); 00880 parseInfoServices(elemIs); 00881 } 00882 00883 #ifdef DYNAMIC_MIX 00884 /* Ok, at this point we should make sure that we have a minimal configuration. 00885 If not we try to fill up the missing parameters with default values*/ 00886 if( checkCertificates() != E_SUCCESS ) 00887 { 00888 CAMsg::printMsg(LOG_CRIT, "I was not able to get a working certificate, please check the configuration! Exiting now\n"); 00889 exit(0); 00890 } 00891 UINT32 running = 0; 00892 CAMsg::printMsg( LOG_INFO, "I will now test if I have enough information about InfoServices...\n"); 00893 if( checkInfoServices(&running) != E_SUCCESS ) 00894 { 00896 CAMsg::printMsg(LOG_CRIT, "Problems with InfoServices\nI need at least %i running InfoServices, but i only know about %i at the moment.\n", MIN_INFOSERVICES, running); 00897 exit(0); 00898 } 00899 CAMsg::printMsg( LOG_INFO, "InfoService information ok\n"); 00900 if( checkListenerInterfaces() != E_SUCCESS ) 00901 { 00902 CAMsg::printMsg(LOG_CRIT, "I don't have any usefull ListenerInterfaces and I canot determine one. please check the configuration! Hints should have been given\n"); 00903 exit(0); 00904 } 00905 if( checkMixId() != E_SUCCESS) 00906 { 00907 CAMsg::printMsg(LOG_CRIT, "ARGS, I don't have an unique ID, cannot create one! Exiting now\n"); 00908 exit(0); 00909 } 00910 #endif // DYNAMIC_MIX 00911 #endif //ONLY_LOCAL_PROXY 00912 return E_SUCCESS; 00913 } 00914 00915 #ifndef ONLY_LOCAL_PROXY 00916 struct t_CMNDLN_REREAD_PARAMS 00917 { 00918 CACmdLnOptions* pCmdLnOptions; 00919 CAMix* pMix; 00920 }; 00921 #endif //ONLY_LOCAL_PROXY 00922 00930 SINT32 CACmdLnOptions::setNewValues(CACmdLnOptions& newOptions) 00931 { 00932 //Copy Targets 00933 if(newOptions.getTargetInterfaceCount()>0) 00934 { 00935 clearTargetInterfaces(); 00936 m_cnTargets=newOptions.getTargetInterfaceCount(); 00937 m_arTargetInterfaces=new CATargetInterface[m_cnTargets]; 00938 for(UINT32 i=0;i<m_cnTargets;i++) 00939 newOptions.getTargetInterface(m_arTargetInterfaces[i],i+1); 00940 } 00941 #if defined( DELAY_CHANNELS)||defined(DELAY_USERS) 00942 //Copy ressources limitation 00943 m_u32DelayChannelUnlimitTraffic=newOptions.getDelayChannelUnlimitTraffic(); 00944 m_u32DelayChannelBucketGrow=newOptions.getDelayChannelBucketGrow(); 00945 m_u32DelayChannelBucketGrowIntervall=newOptions.getDelayChannelBucketGrowIntervall(); 00946 #endif 00947 #if defined( DELAY_CHANNELS_LATENCY) 00948 //Copy ressources limitation 00949 m_u32DelayChannelLatency=newOptions.getDelayChannelLatency(); 00950 #endif 00951 if(newOptions.getMaxNrOfUsers()>0) 00952 m_maxNrOfUsers=newOptions.getMaxNrOfUsers(); 00953 return E_SUCCESS; 00954 } 00955 00956 #ifndef ONLY_LOCAL_PROXY 00957 00962 #ifndef DYNAMIC_MIX 00963 SINT32 CACmdLnOptions::setNextMix(XERCES_CPP_NAMESPACE::DOMDocument* doc) 00964 { 00965 CAMsg::printMsg(LOG_DEBUG,"setNextMix() - start\n"); 00966 DOMElement* elemRoot = doc->getDocumentElement(); 00967 00968 //getCertificates if given... 00969 DOMElement* elemSig; 00970 getDOMChildByName(elemRoot, OPTIONS_NODE_SIGNATURE, elemSig, false); 00971 //Own Certiticate first 00972 //nextMixCertificate if given 00973 DOMElement* elemCert; 00974 getDOMChildByName(elemSig, OPTIONS_NODE_X509DATA, elemCert,true); 00975 if(elemSig!=NULL) 00976 m_pNextMixCertificate = CACertificate::decode(elemCert->getFirstChild(),CERT_X509CERTIFICATE); 00977 00978 DOMElement* elemOptionsRoot = m_docMixXml->getDocumentElement(); 00979 DOMElement* elemOptionsCerts; 00980 getDOMChildByName(elemOptionsRoot, OPTIONS_NODE_CERTIFICATE_LIST, elemOptionsCerts, false); 00981 DOMElement* elemOptionsNextMixCert; 00982 00983 if(getDOMChildByName(elemOptionsRoot, OPTIONS_NODE_NEXT_MIX_CERTIFICATE, elemOptionsNextMixCert, false) != E_SUCCESS) 00984 { 00985 elemOptionsNextMixCert = createDOMElement(m_docMixXml, OPTIONS_NODE_NEXT_MIX_CERTIFICATE); 00986 elemOptionsCerts->appendChild(elemOptionsNextMixCert); 00987 elemOptionsNextMixCert->appendChild(m_docMixXml->importNode(elemCert->getFirstChild(),true)); 00988 } 00989 else 00990 { 00991 if(elemOptionsNextMixCert->hasChildNodes()) 00992 { 00993 elemOptionsNextMixCert->replaceChild(m_docMixXml->importNode(elemCert->getFirstChild(),true), 00994 elemOptionsNextMixCert->getFirstChild()); 00995 } 00996 else 00997 { 00998 elemOptionsNextMixCert->appendChild(m_docMixXml->importNode(elemCert->getFirstChild(),true)); 00999 } 01000 } 01001 CAMsg::printMsg(LOG_DEBUG,"setNextMix() - certificates done\n"); 01002 DOMElement* elemNextMix; 01003 getDOMChildByName(elemRoot, OPTIONS_NODE_LISTENER_INTERFACE, elemNextMix,true); 01004 01005 DOMElement* elemOptionsNetwork; 01006 DOMElement* elemOptionsNextMixInterface; 01007 01008 if(getDOMChildByName(elemOptionsRoot, OPTIONS_NODE_NETWORK, elemOptionsNetwork, false) != E_SUCCESS) 01009 { 01010 elemOptionsNetwork = createDOMElement(m_docMixXml, OPTIONS_NODE_NETWORK); 01011 elemOptionsRoot->appendChild(elemOptionsNetwork); 01012 } 01013 01014 if(getDOMChildByName(elemOptionsNetwork, OPTIONS_NODE_NEXT_MIX, elemOptionsNextMixInterface, false) != E_SUCCESS) 01015 { 01016 elemOptionsNextMixInterface = createDOMElement(m_docMixXml, OPTIONS_NODE_NEXT_MIX); 01017 elemOptionsNetwork->appendChild(elemOptionsNextMixInterface); 01018 } 01019 else 01020 { 01021 while(elemOptionsNextMixInterface->hasChildNodes()) 01022 { 01023 elemOptionsNextMixInterface->removeChild(elemOptionsNextMixInterface->getFirstChild()); 01024 } 01025 } 01026 01027 DOMNode* interfaceData = elemNextMix->getFirstChild(); 01028 while(interfaceData != NULL) 01029 { 01030 elemOptionsNextMixInterface->appendChild(m_docMixXml->importNode(interfaceData,true)); 01031 interfaceData = interfaceData->getNextSibling(); 01032 } 01033 01034 CAMsg::printMsg(LOG_DEBUG,"setNextMix() - end\n"); 01035 return processXmlConfiguration(m_docMixXml); 01036 } 01037 01038 #else //DYNAMIC_MIX 01039 01040 SINT32 CACmdLnOptions::setNextMix(DOM_Document& doc) 01041 { 01042 resetNextMix(); 01044 DOM_Element elemRoot = doc.getDocumentElement(); 01045 //getCertificates if given... 01046 DOM_Element elemSig; 01047 getDOMChildByName(elemRoot,(UINT8*) OPTIONS_NODE_SIGNATURE, elemSig, false); 01048 DOM_Element elemCert; 01049 getDOMChildByName(elemSig,(UINT8*) OPTIONS_NODE_X509DATA, elemCert, true); 01050 if(elemCert!=NULL) 01051 m_pNextMixCertificate = CACertificate::decode(elemCert.getFirstChild(),CERT_X509CERTIFICATE); 01053 DOM_Node elemNextMix; 01054 DOM_Element elemListeners; 01055 // Search through the ListenerInterfaces an use a non-hidden one! 01056 getDOMChildByName(elemRoot,(UINT8*) OPTIONS_NODE_LISTENER_INTERFACE_LIST, elemListeners, true); 01057 DOM_NodeList nlListenerInterfaces = elemListeners.getElementsByTagName(CAListenerInterface::XML_ELEMENT_NAME); 01058 UINT32 len = nlListenerInterfaces.getLength(); 01059 bool foundNonHiddenInterface = false; 01060 for(UINT32 i=0;i<len;i++) 01061 { 01062 elemNextMix=nlListenerInterfaces.item(i); 01063 SINT32 ret = E_SUCCESS; 01064 ret = getDOMElementAttribute(elemNextMix,"hidden",foundNonHiddenInterface); 01065 // Interface was not hidden or "hidden"-Attribute was not specified 01066 if(foundNonHiddenInterface || ret == E_UNSPECIFIED) 01067 { 01068 foundNonHiddenInterface = true; 01069 break; 01070 } 01071 } 01072 if(!foundNonHiddenInterface) 01073 { 01074 CAMsg::printMsg(LOG_ERR, "NEXT MIX HAS NO REAL LISTENERINTERFACES!\n"); 01075 exit(0); 01076 return E_UNKNOWN; 01077 } 01079 clearTargetInterfaces(); 01080 //get TargetInterfaces 01081 m_cnTargets=0; 01082 TargetInterface* targetInterfaceNextMix=NULL; 01083 if(elemNextMix!=NULL) 01084 { 01085 NetworkType type; 01086 CASocketAddr* addr=NULL; 01087 DOM_Element elemType; 01088 getDOMChildByName(elemNextMix,(UINT8*) OPTIONS_NODE_NETWORK, elemType, false); 01089 UINT8 tmpBuff[TMP_BUFF_SIZE]; 01090 UINT32 tmpLen = TMP_BUFF_SIZE; 01091 if(getDOMElementValue(elemType,tmpBuff,&tmpLen)!=E_SUCCESS) 01092 goto SKIP_NEXT_MIX; 01093 strtrim(tmpBuff); 01094 if(strcmp((char*)tmpBuff,"RAW/TCP")==0) 01095 type=RAW_TCP; 01096 else if(strcmp((char*)tmpBuff,"RAW/UNIX")==0) 01097 type=RAW_UNIX; 01098 else if(strcmp((char*)tmpBuff,"SSL/TCP")==0) 01099 type=SSL_TCP; 01100 else if(strcmp((char*)tmpBuff,"SSL/UNIX")==0) 01101 type=SSL_UNIX; 01102 else 01103 goto SKIP_NEXT_MIX; 01104 if(type==SSL_TCP||type==RAW_TCP) 01105 { 01106 DOM_Element elemPort; 01107 DOM_Element elemHost; 01108 DOM_Element elemIP; 01109 UINT8 buffHost[255]; 01110 UINT32 buffHostLen=255; 01111 UINT16 port; 01112 getDOMChildByName(elemNextMix,(UINT8*) OPTIONS_NODE_PORT, elemPort, false); 01113 if(getDOMElementValue(elemPort,&port)!=E_SUCCESS) 01114 goto SKIP_NEXT_MIX; 01115 addr=new CASocketAddrINet; 01116 bool bAddrIsSet=false; 01117 getDOMChildByName(elemNextMix,(UINT8*) OPTIONS_NODE_HOST, elemHost, false); 01118 /* The rules for <Host> and <IP> are as follows: 01119 * 1. if <Host> is given and not empty take the <Host> value for the address of the next mix; if not go to 2 01120 * 2. if <IP> if given and not empty take <IP> value for the address of the next mix; if not goto 3. 01121 * 3. this entry for the next mix is invalid!*/ 01122 if(elemHost!=NULL) 01123 { 01124 if(getDOMElementValue(elemHost,buffHost,&buffHostLen)==E_SUCCESS&&((CASocketAddrINet*)addr)->setAddr(buffHost,port)==E_SUCCESS) 01125 { 01126 bAddrIsSet=true; 01127 } 01128 } 01129 if(!bAddrIsSet)//now try <IP> 01130 { 01131 getDOMChildByName(elemNextMix,(UINT8*) OPTIONS_NODE_IP, elemIP, false); 01132 if(elemIP == NULL || getDOMElementValue(elemIP,buffHost,&buffHostLen)!=E_SUCCESS) 01133 goto SKIP_NEXT_MIX; 01134 if(((CASocketAddrINet*)addr)->setAddr(buffHost,port)!=E_SUCCESS) 01135 goto SKIP_NEXT_MIX; 01136 } 01137 CAMsg::printMsg(LOG_INFO, "Setting target interface: %s:%d\n", buffHost, port); 01138 } 01139 else 01140 #ifdef HAVE_UNIX_DOMAIN_PROTOCOL 01141 01142 { 01143 DOM_Element elemFile; 01144 getDOMChildByName(elemNextMix,(UINT8*) OPTIONS_NODE_FILE, elemFile, false); 01145 tmpLen=255; 01146 if(getDOMElementValue(elemFile,tmpBuff,&tmpLen)!=E_SUCCESS) 01147 goto SKIP_NEXT_MIX; 01148 tmpBuff[tmpLen]=0; 01149 strtrim(tmpBuff); 01150 addr=new CASocketAddrUnix; 01151 if(((CASocketAddrUnix*)addr)->setPath((char*)tmpBuff)!=E_SUCCESS) 01152 goto SKIP_NEXT_MIX; 01153 } 01154 #else 01155 goto SKIP_NEXT_MIX; 01156 #endif 01157 targetInterfaceNextMix=new TargetInterface; 01158 targetInterfaceNextMix->target_type=TARGET_MIX; 01159 targetInterfaceNextMix->net_type=type; 01160 targetInterfaceNextMix->addr=addr->clone(); 01161 m_cnTargets=1; 01162 if(targetInterfaceNextMix!=NULL) 01163 { 01164 if(m_arTargetInterfaces==NULL) 01165 { 01166 m_cnTargets=0; 01167 m_arTargetInterfaces=new TargetInterface[1]; 01168 } 01169 m_arTargetInterfaces[m_cnTargets].net_type=targetInterfaceNextMix->net_type; 01170 m_arTargetInterfaces[m_cnTargets].target_type=targetInterfaceNextMix->target_type; 01171 m_arTargetInterfaces[m_cnTargets++].addr=targetInterfaceNextMix->addr; 01172 delete targetInterfaceNextMix; 01173 targetInterfaceNextMix = NULL; 01174 } 01175 01176 SKIP_NEXT_MIX: 01177 delete addr; 01178 addr = NULL; 01179 } 01180 01181 CAMsg::printMsg(LOG_DEBUG,"setNextMix() - end\n"); 01182 return E_SUCCESS; 01183 } 01184 #endif //DYNAMIC_MIX 01185 01186 #endif //ONLY_LOCAL_PROXY 01187 01188 #ifndef ONLY_LOCAL_PROXY 01189 01194 #ifndef DYNAMIC_MIX 01195 SINT32 CACmdLnOptions::setPrevMix(XERCES_CPP_NAMESPACE::DOMDocument* doc) 01196 { 01197 CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - start\n"); 01198 DOMElement* elemRoot = doc->getDocumentElement(); 01199 01200 //getCertificates if given... 01201 DOMElement* elemSig; 01202 getDOMChildByName(elemRoot, OPTIONS_NODE_SIGNATURE, elemSig, false); 01203 //Own Certiticate first 01204 //nextMixCertificate if given 01205 DOMElement* elemCert; 01206 getDOMChildByName(elemSig, OPTIONS_NODE_X509DATA, elemCert, true); 01207 if(elemCert!=NULL) 01208 { 01209 CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - elem cert found in data from infoservice\n"); 01210 DOMElement* elemOptionsRoot = m_docMixXml->getDocumentElement(); 01211 CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - got current options root element\n"); 01212 DOMElement* elemOptionsCerts; 01213 getDOMChildByName 01214 (elemOptionsRoot, OPTIONS_NODE_CERTIFICATE_LIST, elemOptionsCerts, false); 01215 DOMElement* elemOptionsPrevMixCert; 01216 01217 if(getDOMChildByName 01218 (elemOptionsRoot,OPTIONS_NODE_PREV_MIX_CERTIFICATE, elemOptionsPrevMixCert, false) != E_SUCCESS) 01219 { 01220 CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - no prev cert set at the moment\n"); 01221 elemOptionsPrevMixCert =createDOMElement( m_docMixXml,"PrevMixCertificate"); 01222 elemOptionsCerts->appendChild(elemOptionsPrevMixCert); 01223 CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - try to import the one we got from infoservice\n"); 01224 getDOMChildByName 01225 (elemCert, OPTIONS_NODE_X509_CERTIFICATE, elemCert, false); 01226 01227 CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - Cert to be imported:\n"); 01228 UINT8 buff[8192]; 01229 UINT32 len=8192; 01230 DOM_Output::dumpToMem(elemCert,buff,&len); 01231 CAMsg::printMsg(LOG_DEBUG,(char*)buff); 01232 01233 elemOptionsPrevMixCert->appendChild(m_docMixXml->importNode(elemCert,true)); 01234 CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - MixConf now:\n"); 01235 len=8192; 01236 DOM_Output::dumpToMem(m_docMixXml,buff,&len); 01237 buff[len]=0; 01238 CAMsg::printMsg(LOG_DEBUG,(char*)buff); 01239 } 01240 else 01241 { 01242 if(elemOptionsPrevMixCert->hasChildNodes()) 01243 { 01244 elemOptionsPrevMixCert->replaceChild(m_docMixXml->importNode(elemCert->getFirstChild(),true), 01245 elemOptionsPrevMixCert->getFirstChild()); 01246 } 01247 else 01248 { 01249 elemOptionsPrevMixCert->appendChild(m_docMixXml->importNode(elemCert->getFirstChild(),true)); 01250 } 01251 } 01252 CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - end\n"); 01253 return processXmlConfiguration(m_docMixXml); 01254 } 01255 CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - end with error\n"); 01256 return E_UNKNOWN; 01257 } 01258 01259 #else //DYNAMIC_MIX 01260 01261 SINT32 CACmdLnOptions::setPrevMix(DOM_Document& doc) 01262 { 01263 resetPrevMix(); 01264 CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - start\n"); 01265 DOM_Element elemRoot = doc.getDocumentElement(); 01266 DOM_Element elemSig; 01267 getDOMChildByName(elemRoot,(UINT8*) OPTIONS_NODE_SIGNATURE, elemSig, false); 01268 DOM_Element elemCert; 01269 getDOMChildByName(elemSig,(UINT8*) OPTIONS_NODE_X509DATA, elemCert,true); 01270 01271 if(elemCert!=NULL) 01272 { 01273 m_pPrevMixCertificate=CACertificate::decode(elemCert.getFirstChild(),CERT_X509CERTIFICATE); 01274 return E_SUCCESS; //processXmlConfiguration(m_docMixXml); 01275 } 01276 CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - end with error\n"); 01277 return E_UNKNOWN; 01278 } 01279 #endif //DYNAMIC_MIX 01280 #endif //ONLY_LOCAL_PROXY 01281 01282 #ifndef ONLY_LOCAL_PROXY 01283 #ifdef DYNAMIC_MIX 01284 SINT32 CACmdLnOptions::resetNextMix() 01285 { 01286 if(m_pNextMixCertificate != NULL) 01287 { 01288 delete m_pNextMixCertificate; 01289 m_pNextMixCertificate = NULL; 01290 } 01291 DOM_Element elemOptionsRoot = m_docMixXml.getDocumentElement(); 01292 DOM_Element elemOptionsCerts; 01293 getDOMChildByName(elemOptionsRoot, (UINT8*) OPTIONS_NODE_CERTIFICATE_LIST, elemOptionsCerts, false); 01294 DOM_Element elemTmp; 01295 // Remove existing certificates 01296 if(getDOMChildByName(elemOptionsCerts, (UINT8*) OPTIONS_NODE_PREV_MIX_CERTIFICATE, elemTmp, false) == E_SUCCESS) 01297 { 01298 01299 elemOptionsCerts.removeChild(elemTmp); 01300 } 01301 if(getDOMChildByName(elemOptionsCerts, (UINT8*) OPTIONS_NODE_PREV_OPERATOR_CERTIFICATE, elemTmp, false) == E_SUCCESS) 01302 { 01303 01304 elemOptionsCerts.removeChild(elemTmp); 01305 } 01306 clearTargetInterfaces(); 01307 return E_SUCCESS; 01308 } 01309 01310 SINT32 CACmdLnOptions::resetPrevMix() 01311 { 01312 if(m_pPrevMixCertificate != NULL) 01313 { 01314 delete m_pPrevMixCertificate; 01315 m_pPrevMixCertificate = NULL; 01316 } 01317 DOM_Element elemOptionsRoot = m_docMixXml.getDocumentElement(); 01318 DOM_Element elemOptionsCerts; 01319 getDOMChildByName(elemOptionsRoot, (UINT8*) OPTIONS_NODE_CERTIFICATE_LIST, elemOptionsCerts, false); 01320 DOM_Element elemTmp; 01321 // Remove existing certificates 01322 if(getDOMChildByName(elemOptionsCerts, (UINT8*) OPTIONS_NODE_NEXT_MIX_CERTIFICATE, elemTmp, false) == E_SUCCESS) 01323 { 01324 01325 elemOptionsCerts.removeChild(elemTmp); 01326 } 01327 if(getDOMChildByName(elemOptionsCerts, (UINT8*) OPTIONS_NODE_NEXT_OPERATOR_CERTIFICATE, elemTmp, false) == E_SUCCESS) 01328 { 01329 01330 elemOptionsCerts.removeChild(elemTmp); 01331 } 01332 return E_SUCCESS; 01333 01334 } 01335 #endif //DYNAMIC_MIX 01336 #endif //ONLY_LOCAL_PROXY 01337 01338 #ifndef ONLY_LOCAL_PROXY 01339 01346 SINT32 CACmdLnOptions::reread(CAMix* pMix) 01347 { 01348 if(m_bIsRunReConfigure) 01349 return E_UNKNOWN; 01350 m_bIsRunReConfigure=true; 01351 m_threadReConfigure.setMainLoop(threadReConfigure); 01352 t_CMNDLN_REREAD_PARAMS* param=new t_CMNDLN_REREAD_PARAMS; 01353 param->pCmdLnOptions=this; 01354 param->pMix=pMix; 01355 m_threadReConfigure.start(param,true,false); 01356 return E_SUCCESS; 01357 } 01358 01363 THREAD_RETURN threadReConfigure(void *param) 01364 { 01365 CACmdLnOptions* pOptions=((t_CMNDLN_REREAD_PARAMS*)param)->pCmdLnOptions; 01366 CAMix* pMix=((t_CMNDLN_REREAD_PARAMS*)param)->pMix; 01367 //pOptions->m_pcsReConfigure->lock(); 01368 CAMsg::printMsg(LOG_DEBUG,"ReConfiguration of the Mix is under way....\n"); 01369 CACmdLnOptions otmpOptions; 01370 XERCES_CPP_NAMESPACE::DOMDocument* docConfig=NULL; 01371 if(otmpOptions.readXmlConfiguration(docConfig,pOptions->m_strConfigFile)!=E_SUCCESS) 01372 { 01373 CAMsg::printMsg(LOG_DEBUG,"Could not re-read the config file!\n"); 01374 goto REREAD_FINISH; 01375 } 01376 CAMsg::printMsg(LOG_DEBUG,"Re-readed config file -- start processing config file!\n"); 01377 if(otmpOptions.processXmlConfiguration(docConfig)!=E_SUCCESS) 01378 { 01379 CAMsg::printMsg(LOG_DEBUG,"Re-readed config file -- could not process configuration!\n"); 01380 goto REREAD_FINISH; 01381 } 01382 pOptions->setNewValues(otmpOptions); 01383 if(pMix!=NULL) 01384 pMix->reconfigure(); 01385 01386 REREAD_FINISH: 01387 CAMsg::printMsg(LOG_DEBUG,"ReConfiguration of the Mix finished!\n"); 01388 //pOptions->m_pcsReConfigure->unlock(); 01389 pOptions->m_bIsRunReConfigure=false; 01390 THREAD_RETURN_SUCCESS; 01391 } 01392 #endif //ONLY_LOCAL_PROXY 01393 01394 bool CACmdLnOptions::getDaemon() 01395 { 01396 return m_bDaemon; 01397 } 01398 01399 SINT32 CACmdLnOptions::getMixId(UINT8* id,UINT32 len) 01400 { 01401 if(len<24||m_strMixID==NULL) //we need 24 chars (including final \0) 01402 return E_UNKNOWN; 01403 strcpy((char*)id,m_strMixID); 01404 return E_SUCCESS; 01405 } 01406 01407 01408 UINT16 CACmdLnOptions::getSOCKSServerPort() 01409 { 01410 return m_iSOCKSServerPort; 01411 } 01412 01413 UINT16 CACmdLnOptions::getMixPort() 01414 { 01415 return m_iTargetPort; 01416 } 01417 01418 01419 SINT32 CACmdLnOptions::getMixHost(UINT8* host,UINT32 len) 01420 { 01421 if(m_strTargetHost==NULL) 01422 return E_UNKNOWN; 01423 if(len<=(UINT32)strlen(m_strTargetHost)) 01424 { 01425 return E_UNKNOWN; 01426 } 01427 strcpy((char*)host,m_strTargetHost); 01428 return E_SUCCESS; 01429 } 01430 01431 #ifndef ONLY_LOCAL_PROXY 01432 UINT16 CACmdLnOptions::getSOCKSPort() 01433 { 01434 return m_iSOCKSPort; 01435 } 01436 01437 SINT32 CACmdLnOptions::getSOCKSHost(UINT8* host,UINT32 len) 01438 { 01439 if(m_strSOCKSHost==NULL) 01440 return E_UNKNOWN; 01441 if(len<=(UINT32)strlen(m_strSOCKSHost)) 01442 { 01443 return E_UNKNOWN; 01444 } 01445 strcpy((char*)host,m_strSOCKSHost); 01446 return (SINT32)strlen(m_strSOCKSHost); 01447 } 01448 #endif //ONLY_LOCAL_PROXY 01449 01450 #ifdef PAYMENT 01451 01456 CAXMLBI* CACmdLnOptions::getBI() 01457 { 01458 return m_pBI; 01459 } 01460 01461 SINT32 CACmdLnOptions::getDatabaseHost(UINT8 * host, UINT32 len) 01462 { 01463 if(m_strDatabaseHost==NULL) 01464 return E_UNKNOWN; 01465 if(len<=(UINT32)strlen((char *)m_strDatabaseHost)) 01466 { 01467 return E_UNKNOWN; 01468 } 01469 strcpy((char*)host,(char *)m_strDatabaseHost); 01470 return E_SUCCESS; 01471 } 01472 01473 UINT16 CACmdLnOptions::getDatabasePort() 01474 { 01475 return m_iDatabasePort; 01476 } 01477 01478 SINT32 CACmdLnOptions::getDatabaseName(UINT8 * name, UINT32 len) 01479 { 01480 if(m_strDatabaseName==NULL) 01481 return E_UNKNOWN; 01482 if(len<=(UINT32)strlen((char *)m_strDatabaseName)) 01483 { 01484 return E_UNKNOWN; 01485 } 01486 strcpy((char*)name,(char *)m_strDatabaseName); 01487 return E_SUCCESS; 01488 } 01489 01490 SINT32 CACmdLnOptions::getDatabaseUsername(UINT8 * user, UINT32 len) 01491 { 01492 if(m_strDatabaseUser==NULL) 01493 return E_UNKNOWN; 01494 if(len<=(UINT32)strlen((char *)m_strDatabaseUser)) 01495 { 01496 return E_UNKNOWN; 01497 } 01498 strcpy((char*)user,(char *)m_strDatabaseUser); 01499 return E_SUCCESS; 01500 } 01501 01502 SINT32 CACmdLnOptions::getDatabasePassword(UINT8 * pass, UINT32 len) 01503 { 01504 if(m_strDatabasePassword==NULL) 01505 return E_UNKNOWN; 01506 if(len<=(UINT32)strlen((char *)m_strDatabasePassword)) 01507 { 01508 return E_UNKNOWN; 01509 } 01510 strcpy((char*)pass,(char *)m_strDatabasePassword); 01511 return E_SUCCESS; 01512 } 01513 01514 SINT32 CACmdLnOptions::getAiID(UINT8 * id, UINT32 len) 01515 { 01516 if(m_strAiID==NULL) 01517 return E_UNKNOWN; 01518 if(len<=(UINT32)strlen((char *)m_strAiID)) 01519 { 01520 return E_UNKNOWN; 01521 } 01522 strcpy((char*)id,(char *)m_strAiID); 01523 return E_SUCCESS; 01524 } 01525 01526 UINT32 CACmdLnOptions::getPaymentHardLimit() 01527 { 01528 return m_iPaymentHardLimit; 01529 } 01530 01531 UINT32 CACmdLnOptions::getPrepaidInterval() 01532 { 01533 return m_iPrepaidInterval; 01534 } 01535 01536 UINT32 CACmdLnOptions::getPaymentSoftLimit() 01537 { 01538 return m_iPaymentSoftLimit; 01539 } 01540 01541 UINT32 CACmdLnOptions::getPaymentSettleInterval() 01542 { 01543 return m_iPaymentSettleInterval; 01544 } 01545 01546 #endif /* ifdef PAYMENT */ 01547 01548 SINT32 CACmdLnOptions::getOperatorSubjectKeyIdentifier(UINT8 *buffer, UINT32 *length) 01549 { 01550 if(m_OpCert == NULL) 01551 { 01552 (*length) = 0; 01553 return E_UNKNOWN; 01554 } 01555 return m_OpCert->getSubjectKeyIdentifier(buffer, length); 01556 01557 } 01558 01559 #ifndef ONLY_LOCAL_PROXY 01560 CAListenerInterface** CACmdLnOptions::getInfoServices(UINT32& r_size) 01561 { 01562 r_size = m_addrInfoServicesSize; 01563 return m_addrInfoServices; 01564 } 01565 01566 SINT32 CACmdLnOptions::getCascadeName(UINT8* name,UINT32 len) const 01567 { 01568 if(m_strCascadeName==NULL) 01569 return E_UNKNOWN; 01570 if(len<=(UINT32)strlen((char*)m_strCascadeName)) 01571 { 01572 return E_UNKNOWN; 01573 } 01574 strcpy((char*)name,(char*)m_strCascadeName); 01575 return E_SUCCESS; 01576 } 01577 01578 01579 SINT32 CACmdLnOptions::getEncryptedLogDir(UINT8* name,UINT32 len) 01580 { 01581 if(m_strEncryptedLogDir==NULL||name==NULL) 01582 return E_UNKNOWN; 01583 if(len<=(UINT32)strlen(m_strEncryptedLogDir)) 01584 return E_UNKNOWN; 01585 strcpy((char*)name,m_strEncryptedLogDir); 01586 return E_SUCCESS; 01587 } 01588 #endif //ONLY_LOCAL_PROXY 01589 01590 SINT32 CACmdLnOptions::getLogDir(UINT8* name,UINT32 len) 01591 { 01592 if(m_strLogDir==NULL||name==NULL) 01593 return E_UNKNOWN; 01594 if(len<=(UINT32)strlen(m_strLogDir)) 01595 { 01596 return E_SPACE; 01597 } 01598 strcpy((char*)name,m_strLogDir); 01599 return E_SUCCESS; 01600 } 01601 01602 SINT32 CACmdLnOptions::setLogDir(const UINT8* name,UINT32 len) 01603 { 01604 if(m_strLogDir!=NULL) 01605 { 01606 delete[] m_strLogDir; 01607 m_strLogDir = NULL; 01608 } 01609 m_strLogDir=new char[len+1]; 01610 memcpy(m_strLogDir,name,len); 01611 m_strLogDir[len]=0; 01612 return E_SUCCESS; 01613 } 01614 01615 SINT32 CACmdLnOptions::getPidFile(UINT8* pidfile,UINT32 len) 01616 { 01617 if(m_strPidFile==NULL||pidfile==NULL) 01618 return E_UNKNOWN; 01619 if(len<=(UINT32)strlen(m_strPidFile)) 01620 { 01621 return E_SPACE; 01622 } 01623 strcpy((char*)pidfile,m_strPidFile); 01624 return E_SUCCESS; 01625 } 01626 01627 01628 SINT32 CACmdLnOptions::getUser(UINT8* user,UINT32 len) 01629 { 01630 if(m_strUser==NULL||user==NULL) 01631 { 01632 return E_UNKNOWN; 01633 } 01634 if(len<=(UINT32)strlen(m_strUser)) 01635 { 01636 return E_UNKNOWN; 01637 } 01638 strcpy((char*)user,m_strUser); 01639 return E_SUCCESS; 01640 } 01641 01642 bool CACmdLnOptions::isFirstMix() 01643 { 01644 return m_bFirstMix; 01645 } 01646 01647 bool CACmdLnOptions::isMiddleMix() 01648 { 01649 return m_bMiddleMix; 01650 } 01651 01652 bool CACmdLnOptions::isLastMix() 01653 { 01654 return m_bLastMix; 01655 } 01656 01657 bool CACmdLnOptions::isLocalProxy() 01658 { 01659 return m_bLocalProxy; 01660 } 01661 01662 01663 #ifdef SERVER_MONITORING 01664 char *CACmdLnOptions::getMonitoringListenerHost() 01665 { 01666 return m_strMonitoringListenerHost; 01667 } 01668 01669 UINT16 CACmdLnOptions::getMonitoringListenerPort() 01670 { 01671 return m_iMonitoringListenerPort; 01672 } 01673 #endif /* SERVER_MONITORING */ 01674 01675 #ifndef ONLY_LOCAL_PROXY 01676 01682 SINT32 CACmdLnOptions::getMixXml(XERCES_CPP_NAMESPACE::DOMDocument* & docMixInfo) 01683 { 01684 if(m_docMixInfo == NULL) 01685 { 01686 CAMsg::printMsg(LOG_CRIT,"No mixinfo document initialized!\n"); 01687 return E_UNKNOWN; 01688 } 01689 docMixInfo=m_docMixInfo; 01690 //insert (or update) the Timestamp 01691 DOMElement* elemTimeStamp=NULL; 01692 DOMElement* elemRoot=docMixInfo->getDocumentElement(); 01693 if(getDOMChildByName(elemRoot, UNIVERSAL_NODE_LAST_UPDATE, elemTimeStamp, false)!=E_SUCCESS) 01694 { 01695 elemTimeStamp=createDOMElement(docMixInfo, UNIVERSAL_NODE_LAST_UPDATE); 01696 elemRoot->appendChild(elemTimeStamp); 01697 } 01698 UINT64 currentMillis; 01699 getcurrentTimeMillis(currentMillis); 01700 UINT8 tmpStrCurrentMillis[50]; 01701 print64(tmpStrCurrentMillis,currentMillis); 01702 setDOMElementValue(elemTimeStamp,tmpStrCurrentMillis); 01703 return E_SUCCESS; 01704 } 01705 01706 UINT32 CACmdLnOptions::getNumberOfTermsAndConditionsTemplates() 01707 { 01708 return m_nrOfTermsAndConditionsTemplates; 01709 } 01710 XERCES_CPP_NAMESPACE::DOMDocument **CACmdLnOptions::getAllTermsAndConditionsTemplates() 01711 { 01712 return m_termsAndConditionsTemplates; 01713 } 01714 01715 /* a reference to the Terms and conditions document stored by this class. 01716 * this method does not return a copy of the doc so don't release it. 01717 */ 01718 XERCES_CPP_NAMESPACE::DOMElement* CACmdLnOptions::getTermsAndConditions() 01719 { 01720 //DOMElement *docElement = NULL; 01721 if(m_docOpTnCs == NULL) 01722 { 01723 return NULL; 01724 } 01725 UINT8 tmpBuff[TMP_BUFF_SIZE]; 01726 UINT32 tmpLen = TMP_BUFF_SIZE; 01727 memset(tmpBuff, 0, tmpLen); 01728 getOperatorSubjectKeyIdentifier(tmpBuff, &tmpLen); 01729 setDOMElementAttribute(m_docOpTnCs->getDocumentElement(), OPTIONS_ATTRIBUTE_TNC_ID, tmpBuff); 01730 return m_docOpTnCs->getDocumentElement(); 01731 //docElement = m_docOpTnCs->getDocumentElement(); 01732 //return (docElement == NULL) ? NULL : getElementsByTagName(docElement, OPTION_NODE_TNCS); 01733 } 01734 01744 SINT32 CACmdLnOptions::readXmlConfiguration(XERCES_CPP_NAMESPACE::DOMDocument* & docConfig,const UINT8* const configFile) 01745 { 01746 int handle; 01747 handle=open((char*)configFile,O_BINARY|O_RDONLY); 01748 if(handle==-1) 01749 return E_FILE_OPEN; 01750 SINT32 len=filesize32(handle); 01751 UINT8* tmpChar=new UINT8[len]; 01752 int ret=read(handle,tmpChar,len); 01753 close(handle); 01754 if(ret!=len) 01755 return E_FILE_READ; 01756 SINT32 retVal = readXmlConfiguration(docConfig, tmpChar, len); 01757 delete[] tmpChar; 01758 tmpChar = NULL; 01759 return retVal; 01760 } 01761 01771 SINT32 CACmdLnOptions::readXmlConfiguration(XERCES_CPP_NAMESPACE::DOMDocument* & docConfig,const UINT8* const buf, UINT32 len) 01772 { 01773 docConfig=parseDOMDocument(buf,len); 01774 if(docConfig==NULL) 01775 { 01776 CAMsg::printMsg(LOG_CRIT, "Your configuration is not a valid XML document and therefore could not be parsed. Please repair the configuration structure or create a new configuration.\n"); 01777 return E_UNKNOWN; 01778 } 01779 return E_SUCCESS; 01780 } 01781 01782 /* this method is only for internal use in order to intialize the 01783 * mixinfo structure when the options are parsed. Don't get confused 01784 * with the method addMixInfo of class CAMix which appends an 01785 * additional timestamp. 01786 * if NULL is specified as name the name of a_node is used 01787 */ 01788 SINT32 CACmdLnOptions::appendMixInfo_internal(DOMNode* a_node, bool with_subtree) 01789 { 01790 DOMNode *importedNode = NULL; 01791 DOMNode *appendedNode = NULL; 01792 01793 if(a_node == NULL) 01794 { 01795 CAMsg::printMsg(LOG_CRIT,"No node specified!\n"); 01796 return E_UNKNOWN; 01797 } 01798 if(m_docMixInfo == NULL) 01799 { 01800 CAMsg::printMsg(LOG_CRIT,"No mixinfo document initialized!\n"); 01801 return E_UNKNOWN; 01802 } 01803 if(m_docMixInfo->getDocumentElement() == NULL) 01804 { 01805 CAMsg::printMsg(LOG_CRIT,"No mixinfo dom structure initialized!\n"); 01806 return E_UNKNOWN; 01807 } 01808 01809 importedNode = m_docMixInfo->importNode(a_node, with_subtree); 01810 01811 if(importedNode != NULL) 01812 { 01814 if (importedNode->getNodeType() == DOMNode::ELEMENT_NODE) 01815 { 01816 DOMNodeList* nodesMail = getElementsByTagName((DOMElement*)importedNode, "EMail"); 01817 for (UINT32 i = 0; i < nodesMail->getLength (); i++) 01818 { 01819 nodesMail->item(i)->getParentNode()->removeChild(nodesMail->item(i)); 01820 } 01821 } 01822 01823 appendedNode = m_docMixInfo->getDocumentElement()->appendChild(importedNode); 01824 if( appendedNode != NULL ) 01825 { 01826 return E_SUCCESS; 01827 } 01828 } 01829 CAMsg::printMsg(LOG_CRIT,"Could not append Node \"%s\" to Mixinfo!\n", a_node->getNodeName()); 01830 return E_UNKNOWN; 01831 } 01832 01836 inline SINT32 CACmdLnOptions::addMixIdToMixInfo() 01837 { 01838 if( (m_docMixInfo != NULL) && (m_strMixID != NULL) ) 01839 { 01840 return setDOMElementAttribute 01841 (m_docMixInfo->getDocumentElement(), MIXINFO_ATTRIBUTE_MIX_ID, (UINT8*) m_strMixID); 01842 } 01843 CAMsg::printMsg(LOG_CRIT,"No mixinfo document initialized!\n"); 01844 return E_UNKNOWN; 01845 } 01846 01847 01853 SINT32 CACmdLnOptions::invokeOptionSetters (const optionSetter_pt *optionsSetters, DOMElement* optionsSource, SINT32 optionsSettersLength) 01854 { 01855 SINT32 i = 0; 01856 SINT32 ret = E_SUCCESS; 01857 01858 if( optionsSetters == NULL ) 01859 { 01860 CAMsg::printMsg(LOG_CRIT,"Error parsing config file: OptionSetters not initialized!\n"); 01861 return E_UNKNOWN; 01862 } 01863 01864 if( optionsSettersLength < 0) 01865 { 01866 CAMsg::printMsg(LOG_CRIT,"Error parsing config file: Negative number of option setters specified!\n"); 01867 return E_UNKNOWN; 01868 } 01869 01870 /* Only warn when we have a null DOM Element */ 01871 if( optionsSource == NULL ) 01872 { 01873 CAMsg::printMsg(LOG_INFO, "Found NULL DOM element. " 01874 "NULL element handling is delegated to the specified setter method!\n"); 01875 } 01876 01877 for(i=0; i < optionsSettersLength; i++ ) 01878 { 01879 if(optionsSetters[i]!=NULL) 01880 { 01881 ret = (this->*(optionsSetters[i]))(optionsSource); 01882 if(ret != E_SUCCESS) 01883 { 01884 return ret; 01885 } 01886 } 01887 } 01888 return E_SUCCESS; 01889 } 01890 01891 /*********************************** 01892 * general option setter functions * 01893 ***********************************/ 01894 SINT32 CACmdLnOptions::setGeneralOptions(DOMElement* elemRoot) 01895 { 01896 DOMElement* elemGeneral=NULL; 01897 01898 if (getDOMChildByName(elemRoot, OPTIONS_NODE_GENERAL, 01899 elemGeneral,false) != E_SUCCESS) 01900 { 01901 LOG_NODE_NOT_FOUND(OPTIONS_NODE_GENERAL); 01902 return E_UNKNOWN; 01903 } 01904 01905 return invokeOptionSetters 01906 (generalOptionSetters, elemGeneral, GENERAL_OPTIONS_NR); 01907 } 01908 01913 SINT32 CACmdLnOptions::setMixType(DOMElement* elemGeneral) 01914 { 01915 DOMElement* elemMixType=NULL; 01916 UINT8 tmpBuff[TMP_BUFF_SIZE]; 01917 UINT32 tmpLen = TMP_BUFF_SIZE; 01918 01919 if(elemGeneral == NULL) return E_UNKNOWN; 01920 ASSERT_GENERAL_OPTIONS_PARENT 01921 (elemGeneral->getNodeName(), OPTIONS_NODE_MIX_TYPE); 01922 01923 //getMixType 01924 if (getDOMChildByName(elemGeneral, OPTIONS_NODE_MIX_TYPE, 01925 elemMixType,false) != E_SUCCESS) 01926 { 01927 LOG_NODE_NOT_FOUND(OPTIONS_NODE_MIX_TYPE); 01928 return E_UNKNOWN; 01929 } 01930 01931 if( getDOMElementValue(elemMixType,tmpBuff,&tmpLen) == E_SUCCESS ) 01932 { 01933 if(memcmp(tmpBuff,"FirstMix",8) == 0) 01934 { 01935 m_bFirstMix = true; 01936 } 01937 else if (memcmp(tmpBuff,"MiddleMix",9) == 0) 01938 { 01939 m_bMiddleMix = true; 01940 } 01941 else if (memcmp(tmpBuff,"LastMix",7) == 0) 01942 { 01943 m_bLastMix = true; 01944 } 01945 if ( appendMixInfo_internal(elemMixType, WITH_SUBTREE) != E_SUCCESS ) 01946 { 01947 return E_UNKNOWN; 01948 } 01949 } 01950 else 01951 { 01952 LOG_NODE_EMPTY_OR_INVALID(OPTIONS_NODE_MIX_TYPE); 01953 return E_UNKNOWN; 01954 } 01955 return E_SUCCESS; 01956 } 01957 01958 SINT32 CACmdLnOptions::setMixName(DOMElement* elemGeneral) 01959 { 01960 DOMElement *elemMixName = NULL, *elemMixInfoName = NULL; 01961 UINT8 tmpBuff[TMP_BUFF_SIZE]; 01962 UINT32 tmpLen = TMP_BUFF_SIZE; 01963 UINT8 *typeValue = NULL; //(UINT8 *) OPTIONS_VALUE_NAMETYPE_DEFAULT; 01964 //uncomment the above line to enable a default name type 01965 01966 if(elemGeneral == NULL) return E_UNKNOWN; 01967 ASSERT_GENERAL_OPTIONS_PARENT 01968 (elemGeneral->getNodeName(), OPTIONS_NODE_MIX_NAME); 01969 01970 //Inserting the Name if given... 01971 getDOMChildByName(elemGeneral, OPTIONS_NODE_MIX_NAME, elemMixName, false); 01972 if(elemMixName != NULL) 01973 { 01974 if(getDOMElementValue(elemMixName, tmpBuff, &tmpLen) == E_SUCCESS) 01975 { 01976 m_strMixName = new char[tmpLen+1]; 01977 memset(m_strMixName, 0, tmpLen+1); 01978 memcpy(m_strMixName, tmpBuff, tmpLen); 01979 } 01980 tmpLen = TMP_BUFF_SIZE; 01981 getDOMElementAttribute(elemMixName, OPTIONS_ATTRIBUTE_NAME_FOR_CASCADE, tmpBuff, &tmpLen); 01982 } 01983 else 01984 { 01985 tmpLen = 0; 01986 m_strMixName = NULL; 01987 } 01988 01989 /* now append the values to the mix info 01990 * conditions: 01991 * - if name is set, m_strMixname points to it. 01992 * - if name type is set then it is in tmpBuff. 01993 */ 01994 elemMixInfoName = createDOMElement(m_docMixInfo, MIXINFO_NODE_MIX_NAME); 01995 01996 /* if name is set */ 01997 if(m_strMixName != NULL) 01998 { 01999 setDOMElementValue(elemMixInfoName, (UINT8*) m_strMixName); 02000 } 02001 02002 if( tmpLen != 0 ) /* if name type is set */ 02003 { 02004 if( strncasecmp( ((char *)tmpBuff), 02005 OPTIONS_VALUE_OPERATOR_NAME, 02006 strlen(OPTIONS_VALUE_OPERATOR_NAME)) == 0 ) /* type is operator name*/ 02007 { 02008 typeValue = (UINT8 *) OPTIONS_VALUE_OPERATOR_NAME; 02009 } 02010 else if( strncasecmp( ((char *)tmpBuff), 02011 OPTIONS_VALUE_MIX_NAME, 02012 strlen(OPTIONS_VALUE_MIX_NAME)) == 0 ) /* type is mix name*/ 02013 { 02014 typeValue = (UINT8 *) OPTIONS_VALUE_MIX_NAME; 02015 } 02016 } 02017 if(typeValue != NULL) 02018 { 02019 setDOMElementAttribute(elemMixInfoName, 02020 OPTIONS_ATTRIBUTE_NAME_FOR_CASCADE, typeValue); 02021 } 02022 02023 if(m_docMixInfo->getDocumentElement() != NULL) 02024 { 02025 m_docMixInfo->getDocumentElement()->appendChild(elemMixInfoName); 02026 } 02027 else 02028 { 02029 //Should never happen 02030 return E_UNKNOWN; 02031 } 02032 return E_SUCCESS; 02033 } 02034 02035 SINT32 CACmdLnOptions::setMixID(DOMElement* elemGeneral) 02036 { 02037 DOMElement* elemMixID=NULL; 02038 UINT8 tmpBuff[TMP_BUFF_SIZE]; 02039 UINT32 tmpLen = TMP_BUFF_SIZE; 02040 size_t mixID_strlen = 0; 02041 02042 if(elemGeneral == NULL) return E_UNKNOWN; 02043 ASSERT_GENERAL_OPTIONS_PARENT 02044 (elemGeneral->getNodeName(), OPTIONS_NODE_MIX_NAME); 02045 02046 getDOMChildByName(elemGeneral, OPTIONS_NODE_MIX_ID, elemMixID, false); 02047 if(elemMixID != NULL) 02048 { 02049 if(getDOMElementValue(elemMixID,tmpBuff,&tmpLen) == E_SUCCESS) 02050 { 02051 strtrim(tmpBuff); 02052 mixID_strlen = strlen((char*)tmpBuff)+1; 02053 m_strMixID = new char[strlen((char*)tmpBuff)+1]; 02054 memset(m_strMixID, 0, mixID_strlen); 02055 memcpy(m_strMixID, tmpBuff, mixID_strlen); 02056 02057 return addMixIdToMixInfo(); 02058 } 02059 } 02060 return E_SUCCESS; 02061 02062 } 02067 SINT32 CACmdLnOptions::setDynamicMix(DOMElement* elemGeneral) 02068 { 02069 // LERNGRUPPE 02070 // get Dynamic flag 02071 DOMElement* elemDynamic=NULL; 02072 UINT8 tmpBuff[TMP_BUFF_SIZE]; 02073 UINT32 tmpLen = TMP_BUFF_SIZE; 02074 m_bDynamic = false; 02075 02076 if(elemGeneral == NULL) return E_UNKNOWN; 02077 ASSERT_GENERAL_OPTIONS_PARENT 02078 (elemGeneral->getNodeName(), OPTIONS_NODE_DYNAMIC_MIX); 02079 02080 getDOMChildByName(elemGeneral, OPTIONS_NODE_DYNAMIC_MIX, elemDynamic, false); 02081 if(elemDynamic != NULL) 02082 { 02083 if(getDOMElementValue(elemDynamic, tmpBuff, &tmpLen)==E_SUCCESS) 02084 { 02085 m_bDynamic = (strcmp("True",(char*)tmpBuff) == 0); 02086 } 02087 } 02088 if(m_bDynamic) 02089 { 02090 CAMsg::printMsg( LOG_DEBUG, "I am a dynamic mix\n"); 02091 } 02092 return E_SUCCESS; 02093 } 02094 02095 SINT32 CACmdLnOptions::setMinCascadeLength(DOMElement* elemGeneral) 02096 { 02097 DOMElement* elemMinCascadeLength = NULL; 02098 if(elemGeneral == NULL) return E_UNKNOWN; 02099 ASSERT_GENERAL_OPTIONS_PARENT 02100 (elemGeneral->getNodeName(), OPTIONS_NODE_MIN_CASCADE_LENGTH); 02101 //Inserting the min. cascade length if given... 02102 getDOMChildByName 02103 (elemGeneral, OPTIONS_NODE_MIN_CASCADE_LENGTH, elemMinCascadeLength, false); 02104 if(elemMinCascadeLength != NULL) 02105 { 02106 appendMixInfo_internal(elemMinCascadeLength, WITH_SUBTREE); 02107 } 02108 return E_SUCCESS; 02109 } 02110 02111 SINT32 CACmdLnOptions::setCascadeNameFromOptions(DOMElement* elemGeneral) 02112 { 02113 DOMElement* elemCascadeName=NULL; 02114 UINT8 tmpBuff[TMP_BUFF_SIZE]; 02115 UINT32 tmpLen = TMP_BUFF_SIZE; 02116 02117 if(elemGeneral == NULL) return E_UNKNOWN; 02118 ASSERT_GENERAL_OPTIONS_PARENT 02119 (elemGeneral->getNodeName(), OPTIONS_NODE_CASCADE_NAME); 02120 02121 //getCascadeName 02122 getDOMChildByName(elemGeneral, OPTIONS_NODE_CASCADE_NAME, elemCascadeName, false); 02123 02124 #ifdef DYNAMIC_MIX 02125 bool bNeedCascadeNameFromMixID=false; 02126 #endif 02127 if(getDOMElementValue(elemCascadeName,tmpBuff,&tmpLen)==E_SUCCESS) 02128 { 02129 setCascadeName(tmpBuff); 02130 } 02131 #ifdef DYNAMIC_MIX 02132 /* LERNGRUPPE: Dynamic Mixes must have a cascade name, as MiddleMixes may be reconfigured to be FirstMixes */ 02133 else 02134 { 02135 bNeedCascadeNameFromMixID=true; 02136 setCascadeName(m_strMixID); 02137 } 02138 #endif 02139 return E_SUCCESS; 02140 } 02141 02142 SINT32 CACmdLnOptions::setUserID(DOMElement* elemGeneral) 02143 { 02144 DOMElement* elemUID=NULL; 02145 UINT8 tmpBuff[TMP_BUFF_SIZE]; 02146 UINT32 tmpLen = TMP_BUFF_SIZE; 02147 02148 if(elemGeneral == NULL) return E_UNKNOWN; 02149 ASSERT_GENERAL_OPTIONS_PARENT 02150 (elemGeneral->getNodeName(), OPTIONS_NODE_USER_ID); 02151 02152 //get Username to run as... 02153 getDOMChildByName(elemGeneral, OPTIONS_NODE_USER_ID, elemUID,false); 02154 02155 if(getDOMElementValue(elemUID,tmpBuff,&tmpLen)==E_SUCCESS) 02156 { 02157 m_strUser=new char[tmpLen+1]; 02158 memcpy(m_strUser,tmpBuff,tmpLen); 02159 m_strUser[tmpLen]=0; 02160 } 02161 02162 #ifndef WIN32 02163 UINT8 buff[255]; 02164 if(getUser(buff,255)==E_SUCCESS) //switching user 02165 { 02166 struct passwd* pwd=getpwnam((char*)buff); 02167 if(pwd==NULL || (setegid(pwd->pw_gid)==-1) || (seteuid(pwd->pw_uid)==-1) ) 02168 { 02169 if (pwd==NULL) 02170 { 02171 CAMsg::printMsg(LOG_ERR, 02172 "Could not switch to effective user '%s'! Reason: User '%s' does not exist on this system. Create this user first.\n", 02173 buff, buff); 02174 } 02175 else 02176 { 02177 CAMsg::printMsg(LOG_ERR,"Could not switch to effective user '%s'! Reason: %s (%i)\n", 02178 buff, GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR); 02179 } 02180 } 02181 else 02182 CAMsg::printMsg(LOG_INFO,"Switched to effective user '%s'!\n",buff); 02183 } 02184 02185 if(geteuid()==0) 02186 CAMsg::printMsg(LOG_WARNING,"Mix is running as root/superuser!\n"); 02187 #endif 02188 return E_SUCCESS; 02189 } 02190 02191 SINT32 CACmdLnOptions::setNrOfFileDescriptors(DOMElement* elemGeneral) 02192 { 02193 DOMElement* elemNrFd=NULL; 02194 UINT32 tmp = 0; 02195 02196 if(elemGeneral == NULL) return E_UNKNOWN; 02197 ASSERT_GENERAL_OPTIONS_PARENT 02198 (elemGeneral->getNodeName(), OPTIONS_NODE_FD_NR); 02199 02200 //get Number of File Descriptors to use 02201 getDOMChildByName(elemGeneral, OPTIONS_NODE_FD_NR, elemNrFd, false); 02202 02203 if(getDOMElementValue(elemNrFd,&tmp) == E_SUCCESS) 02204 { 02205 m_nrOfOpenFiles=tmp; 02206 } 02207 02208 #ifndef WIN32 02209 02210 struct rlimit coreLimit; 02211 coreLimit.rlim_cur = coreLimit.rlim_max = RLIM_INFINITY; 02212 if (setrlimit(RLIMIT_CORE, &coreLimit) != 0) 02213 { 02214 CAMsg::printMsg(LOG_CRIT,"Could not set RLIMIT_CORE (max core file size) to unlimited size. -- Core dumps might not be generated!\n",m_nrOfOpenFiles); 02215 } 02216 02217 if(m_nrOfOpenFiles>0) 02218 { 02219 struct rlimit lim; 02220 // Set the new MAX open files limit 02221 lim.rlim_cur = lim.rlim_max = m_nrOfOpenFiles; 02222 if (setrlimit(RLIMIT_NOFILE, &lim) != 0) 02223 { 02224 CAMsg::printMsg(LOG_CRIT,"Could not set MAX open files to: %u Reason: %s (%i) \nYou might have insufficient user rights. If so, switch to a privileged user or do not set the number of file descriptors. -- Exiting!\n", 02225 m_nrOfOpenFiles, GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR); 02226 exit(EXIT_FAILURE); 02227 } 02228 } 02229 #endif 02230 02231 return E_SUCCESS; 02232 } 02233 02234 SINT32 CACmdLnOptions::setDaemonMode(DOMElement* elemGeneral) 02235 { 02236 DOMElement* elemDaemonMode = NULL; 02237 UINT8 tmpBuff[TMP_BUFF_SIZE]; 02238 UINT32 tmpLen = TMP_BUFF_SIZE; 02239 02240 if(elemGeneral == NULL) return E_UNKNOWN; 02241 ASSERT_GENERAL_OPTIONS_PARENT 02242 (elemGeneral->getNodeName(), OPTIONS_NODE_DAEMON); 02243 02244 //get Run as Daemon 02245 getDOMChildByName(elemGeneral, OPTIONS_NODE_DAEMON, elemDaemonMode,false); 02246 02247 if(getDOMElementValue(elemDaemonMode, tmpBuff, &tmpLen) == E_SUCCESS && 02248 memcmp(tmpBuff,"True",4)==0) 02249 { 02250 m_bDaemon=true; 02251 } 02252 return E_SUCCESS; 02253 } 02254 02255 SINT32 CACmdLnOptions::setMaxUsers(DOMElement* elemGeneral) 02256 { 02257 DOMElement* elemMaxUsers=NULL; 02258 UINT32 tmp = 0; 02259 02260 if(elemGeneral == NULL) return E_UNKNOWN; 02261 ASSERT_GENERAL_OPTIONS_PARENT 02262 (elemGeneral->getNodeName(), OPTIONS_NODE_MAX_USERS); 02263 02264 // get max users 02265 getDOMChildByName(elemGeneral, OPTIONS_NODE_MAX_USERS, elemMaxUsers, false); 02266 if(elemMaxUsers!=NULL) 02267 { 02268 if(getDOMElementValue(elemMaxUsers, &tmp)==E_SUCCESS) 02269 { 02270 m_maxNrOfUsers = tmp; 02271 } 02272 } 02273 return E_SUCCESS; 02274 } 02275 02276 SINT32 CACmdLnOptions::setPaymentReminder(DOMElement* elemGeneral) 02277 { 02278 DOMElement* elemPaymentReminder=NULL; 02279 m_PaymentReminderProbability = -1; 02280 02281 if(elemGeneral == NULL) 02282 return E_UNKNOWN; 02283 ASSERT_GENERAL_OPTIONS_PARENT (elemGeneral->getNodeName(), OPTIONS_NODE_PAYMENT_REMINDER); 02284 02285 // get payment reminder probabilty 02286 getDOMChildByName(elemGeneral, OPTIONS_NODE_PAYMENT_REMINDER, elemPaymentReminder, false); 02287 bool bEnabled=false; 02288 getDOMElementAttribute(elemPaymentReminder, "enable", bEnabled); 02289 if (!bEnabled) 02290 { 02291 m_PaymentReminderProbability = -1; 02292 } 02293 else 02294 { 02295 getDOMElementValue(elemPaymentReminder, &m_PaymentReminderProbability); 02296 } 02297 return E_SUCCESS; 02298 } 02299 02300 02301 02302 SINT32 CACmdLnOptions::initLogging() 02303 { 02304 SINT32 ret = E_SUCCESS; 02305 UINT8 buff[2000]; 02306 UINT32 iLogOptions = 0; 02307 02308 CAMsg::init(); 02309 02310 02311 #ifndef ONLY_LOCAL_PROXY 02312 if(isSyslogEnabled()) 02313 { 02314 iLogOptions |= MSG_LOG; 02315 } 02316 #endif 02317 if(getLogDir((UINT8*)buff,2000)==E_SUCCESS) 02318 { 02319 if(getCompressLogs()) 02320 iLogOptions |= MSG_COMPRESSED_FILE; 02321 else 02322 iLogOptions |= MSG_FILE; 02323 } 02324 #ifndef ONLY_LOCAL_PROXY 02325 02326 if (m_bLogConsole || iLogOptions == 0) 02327 { 02328 iLogOptions |= MSG_STDOUT; 02329 } 02330 ret = CAMsg::setLogOptions(iLogOptions); 02331 02332 if(m_strLogLevel!=NULL) 02333 { 02334 if (strcmp(m_strLogLevel,"info") == 0) 02335 { 02336 CAMsg::setLogLevel(LOG_INFO); 02337 } 02338 else if (strcmp(m_strLogLevel,"warning") == 0) 02339 { 02340 CAMsg::setLogLevel(LOG_WARNING); 02341 } 02342 else if (strcmp(m_strLogLevel,"error") == 0) 02343 { 02344 CAMsg::setLogLevel(LOG_ERR); 02345 } 02346 else if (strcmp(m_strLogLevel,"critical") == 0) 02347 { 02348 CAMsg::setLogLevel(LOG_CRIT); 02349 } 02350 } 02351 if(isEncryptedLogEnabled()) 02352 { 02353 SINT32 retEncr; 02354 if ((retEncr = CAMsg::openEncryptedLog()) != E_SUCCESS) 02355 { 02356 CAMsg::printMsg(LOG_ERR,"Could not open encrypted log - exiting!\n"); 02357 return retEncr; 02358 } 02359 } 02360 #endif 02361 02362 if(getDaemon() && ret != E_SUCCESS) 02363 { 02364 CAMsg::printMsg(LOG_CRIT, "We need a log file in daemon mode in order to get any messages! Exiting...\n"); 02365 return ret; 02366 } 02367 02368 return E_SUCCESS; 02369 } 02370 02371 SINT32 CACmdLnOptions::setLoggingOptions(DOMElement* elemGeneral) 02372 { 02373 //get Logging 02374 DOMElement* elemLogging=NULL; 02375 DOMElement* elemEncLog=NULL; 02376 DOMElement* elem=NULL; 02377 02378 UINT8 tmpBuff[TMP_BUFF_SIZE]; 02379 UINT32 tmpLen = TMP_BUFF_SIZE; 02380 02381 SINT32 maxLogFilesTemp = 0; 02382 if(elemGeneral == NULL) return E_UNKNOWN; 02383 ASSERT_GENERAL_OPTIONS_PARENT 02384 (elemGeneral->getNodeName(), OPTIONS_NODE_LOGGING); 02385 02386 getDOMChildByName(elemGeneral, OPTIONS_NODE_LOGGING, elemLogging, false); 02387 if(elemLogging != NULL) 02388 { 02389 if (getDOMElementAttribute(elemLogging, "level", tmpBuff, &tmpLen) == E_SUCCESS) 02390 { 02391 strtrim(tmpBuff); 02392 toLower(tmpBuff); 02393 m_strLogLevel = new char[strlen((char*)tmpBuff)+1]; 02394 strcpy(m_strLogLevel, (char*)tmpBuff); 02395 } 02396 else 02397 { 02398 m_strLogLevel = new char[strlen("debug")+1]; 02399 strcpy(m_strLogLevel, "debug"); 02400 } 02401 02402 02403 02404 getDOMChildByName(elemLogging, OPTIONS_NODE_LOGGING_FILE, elem, false); 02405 tmpLen = TMP_BUFF_SIZE; 02406 if(getDOMElementValue(elem, tmpBuff, &tmpLen) == E_SUCCESS) 02407 { 02408 strtrim(tmpBuff); 02409 m_strLogDir = new char[strlen((char*)tmpBuff)+1]; 02410 strcpy(m_strLogDir, (char*)tmpBuff); 02411 getDOMElementAttribute 02412 (elem, OPTIONS_ATTRIBUTE_LOGGING_MAXFILESIZE, m_maxLogFileSize); 02413 //Set maximum number of logging files 02414 //CAMsg::printMsg(LOG_ERR,"!!!!!!!!\n"); 02415 if((getDOMElementAttribute 02416 (elem, OPTIONS_ATTRIBUTE_LOGGING_MAXFILES, &maxLogFilesTemp) != E_SUCCESS) || 02417 (maxLogFilesTemp == 0) ) 02418 { 02419 m_maxLogFiles = LOGGING_MAXFILES_DEFAULT; 02420 } 02421 else 02422 { 02423 if(maxLogFilesTemp < 0) 02424 { 02425 //CAMsg::printMsg(LOG_ERR,"Negative number of log files specified.\n"); 02426 return E_UNKNOWN; 02427 } 02428 m_maxLogFiles = (UINT32) maxLogFilesTemp; 02429 //CAMsg::printMsg(LOG_ERR,"Max log files are %u\n", m_maxLogFiles); 02430 } 02431 } 02432 getDOMChildByName(elemLogging, OPTIONS_NODE_SYSLOG, elem, false); 02433 tmpLen = TMP_BUFF_SIZE; 02434 memset(tmpBuff, 0, tmpLen); 02435 if( (getDOMElementValue(elem, tmpBuff, &tmpLen) == E_SUCCESS) && 02436 (memcmp(tmpBuff,"True",4) == 0) ) 02437 { 02438 m_bSyslog = true; 02439 } 02440 02441 getDOMChildByName(elemLogging, OPTIONS_NODE_LOGGING_CONSOLE, elem, false); 02442 tmpLen = TMP_BUFF_SIZE; 02443 memset(tmpBuff, 0, tmpLen); 02444 if( (getDOMElementValue(elem, tmpBuff, &tmpLen) == E_SUCCESS) && 02445 (memcmp(tmpBuff,"True",4) == 0) ) 02446 { 02447 m_bLogConsole = true; 02448 } 02449 02450 //get Encrypted Log Info 02451 if( getDOMChildByName 02452 (elemLogging, OPTIONS_NODE_ENCRYPTED_LOG, elemEncLog,false) == E_SUCCESS ) 02453 { 02454 m_bIsEncryptedLogEnabled = true; 02455 getDOMChildByName(elemEncLog, OPTIONS_NODE_LOGGING_FILE, elem, false); 02456 02457 tmpLen = TMP_BUFF_SIZE; 02458 memset(tmpBuff, 0, tmpLen); 02459 if( getDOMElementValue(elem, tmpBuff, &tmpLen) == E_SUCCESS ) 02460 { 02461 strtrim(tmpBuff); 02462 m_strEncryptedLogDir = new char[strlen((char*)tmpBuff)+1]; 02463 strcpy(m_strEncryptedLogDir, (char*)tmpBuff); 02464 } 02465 DOMElement* elemKeyInfo; 02466 DOMElement* elemX509Data; 02467 if(getDOMChildByName 02468 (elemEncLog, OPTIONS_NODE_LOGGING_KEYINFO, elemKeyInfo, false) == E_SUCCESS && 02469 getDOMChildByName 02470 (elemKeyInfo, OPTIONS_NODE_X509DATA, elemX509Data, false) == E_SUCCESS ) 02471 { 02472 m_pLogEncryptionCertificate = 02473 CACertificate::decode(elemX509Data->getFirstChild(), CERT_X509CERTIFICATE); 02474 } 02475 } 02476 else 02477 { 02478 m_bIsEncryptedLogEnabled=false; 02479 } 02480 02481 } 02482 02483 SINT32 ret = initLogging(); 02484 if (ret == E_SUCCESS) 02485 { 02486 CAMsg::printMsg(LOG_INFO,MIX_VERSION_INFO); 02487 if (MIX_VERSION_TESTING) 02488 { 02489 CAMsg::printMsg(LOG_WARNING, MIX_VERSION_TESTING_TEXT); 02490 } 02491 } 02492 02493 return ret; 02494 } 02495 02496 /* append the mix description to the mix info DOM structure 02497 * this is a main option (child of <MixConfiguration>) 02498 */ 02499 SINT32 CACmdLnOptions::setMixDescription(DOMElement* elemRoot) 02500 { 02501 SINT32 ret = E_SUCCESS; 02502 DOMElement* elemMixDescription = NULL; 02503 if(elemRoot == NULL) 02504 { 02505 return E_UNKNOWN; 02506 } 02507 ret = getDOMChildByName 02508 (elemRoot, OPTIONS_NODE_DESCRIPTION, elemMixDescription, false); 02509 02510 if(elemMixDescription != NULL ) 02511 { 02512 DOMNode* tmpChild = elemMixDescription->getFirstChild(); 02513 while( (tmpChild != NULL) && (ret == E_SUCCESS) ) 02514 { 02515 ret = appendMixInfo_internal(tmpChild, WITH_SUBTREE); 02516 tmpChild=tmpChild->getNextSibling(); 02517 } 02518 } 02519 return ret; 02520 } 02521 02522 /*************************************** 02523 * certificate option setter functions * 02524 ***************************************/ 02525 SINT32 CACmdLnOptions::setCertificateOptions(DOMElement* elemRoot) 02526 { 02527 02528 DOMElement* elemCertificates; 02529 02530 if (getDOMChildByName 02531 (elemRoot, OPTIONS_NODE_CERTIFICATE_LIST, elemCertificates, false) != E_SUCCESS) 02532 { 02533 LOG_NODE_NOT_FOUND(OPTIONS_NODE_CERTIFICATE_LIST); 02534 return E_UNKNOWN; 02535 } 02536 02537 return invokeOptionSetters(certificateOptionSetters, elemCertificates, m_nCertificateOptionsSetters); 02538 } 02539 02540 SINT32 CACmdLnOptions::setOwnCertificate(DOMElement *elemCertificates) 02541 { 02542 DOMElement* elemOwnCert=NULL; 02543 UINT8 tmpBuff[TMP_BUFF_SIZE]; 02544 UINT32 tmpLen = TMP_BUFF_SIZE; 02545 02546 UINT8 passwd[500]; 02547 passwd[0] = 0; 02548 02549 if(elemCertificates == NULL) return E_UNKNOWN; 02550 ASSERT_CERTIFICATES_OPTIONS_PARENT 02551 (elemCertificates->getNodeName(), OPTIONS_NODE_OWN_CERTIFICATE); 02552 02553 //Own Certiticate first 02554 getDOMChildByName(elemCertificates, OPTIONS_NODE_OWN_CERTIFICATE, elemOwnCert, false); 02555 if (elemOwnCert == NULL) 02556 { 02557 LOG_NODE_NOT_FOUND(OPTIONS_NODE_OWN_CERTIFICATE); 02558 return E_UNKNOWN; 02559 } 02560 02561 /*m_pSignKey = new CASignature(); 02562 02563 if(m_pSignKey->setSignKey 02564 (elemOwnCert->getFirstChild(), SIGKEY_PKCS12) != E_SUCCESS) 02565 { 02566 //Maybe not an empty passwd 02567 printf("I need a passwd for the SignKey: "); 02568 fflush(stdout); 02569 readPasswd(passwd, 500); 02570 if(m_pSignKey->setSignKey 02571 (elemOwnCert->getFirstChild(), 02572 SIGKEY_PKCS12,(char*)passwd) != E_SUCCESS) 02573 { 02574 CAMsg::printMsg(LOG_CRIT,"Could not read own signature key!\n"); 02575 delete m_pSignKey; 02576 m_pSignKey=NULL; 02577 } 02578 }*/ 02579 02580 /*m_pOwnCertificate = 02581 CACertificate::decode(elemOwnCert->getFirstChild(), CERT_PKCS12, (char*)passwd); 02582 if (m_pOwnCertificate == NULL) 02583 { 02584 CAMsg::printMsg(LOG_CRIT, "Could not decode mix certificate!\n"); 02585 return E_UNKNOWN; 02586 }*/ 02587 02588 // new 02589 //m_ownCertsLength = 0; 02590 //m_opCertsLength = 0; 02591 02592 //decode OpCerts 02593 UINT32 opCertsLen = m_opCertList->getLength(); 02594 CACertificate** opCerts=new CACertificate*[opCertsLen]; 02595 for(UINT32 j=0; j<opCertsLen; j++) 02596 { 02597 DOMNode* a_opCert = m_opCertList->item(j); 02598 opCerts[j] = CACertificate::decode(a_opCert,CERT_X509CERTIFICATE); 02599 if(opCerts[j] == NULL) 02600 { 02601 CAMsg::printMsg(LOG_CRIT, "Error while decoding operator certificates!"); 02602 delete[] opCerts; 02603 return E_UNKNOWN; 02604 } 02605 } 02606 02607 DOMNodeList* ownCertList = getElementsByTagName(elemOwnCert, OPTIONS_NODE_X509_PKCS12); 02608 02609 m_pMultiSignature = new CAMultiSignature(); 02610 for (UINT32 i=0; i<ownCertList->getLength(); i++) 02611 { 02612 DOMNode* a_cert = ownCertList->item(i); 02613 CASignature* signature = new CASignature(); 02614 CACertStore* certs = new CACertStore(); 02615 02616 //try to get signature key from ownCert 02617 if(signature->setSignKey(a_cert, SIGKEY_PKCS12, (char*)passwd) != E_SUCCESS) 02618 { 02619 //Read password if necessary 02620 printf("I need a password for the private Mix certificate nr. %d: ", i+1); 02621 fflush(stdout); 02622 readPasswd(passwd,500); 02623 printf("\n"); 02624 if(signature->setSignKey(a_cert, SIGKEY_PKCS12, (char*)passwd) != E_SUCCESS) 02625 { 02626 CAMsg::printMsg(LOG_CRIT,"Unable to load private Mix certificate nr. %d! Please check your password.\n", i+1); 02627 delete signature; 02628 delete[] opCerts; 02629 signature = NULL; 02630 return E_UNKNOWN; 02631 } 02632 } 02633 //decode own certifciate 02634 CACertificate* tmpCert = CACertificate::decode(a_cert, CERT_PKCS12, (char*)passwd); 02635 if(tmpCert== NULL) 02636 { 02637 CAMsg::printMsg(LOG_CRIT, "Error while getting own certificate %d!\n", i+1); 02638 delete[] opCerts; 02639 return E_UNKNOWN; 02640 } 02641 02642 //get SKI 02643 UINT32 tmpSKIlen = 255; 02644 UINT8 tmpSKI[255]; 02645 if(tmpCert->getSubjectKeyIdentifier(tmpSKI, &tmpSKIlen) != E_SUCCESS) 02646 { 02647 CAMsg::printMsg(LOG_CRIT, "Error while getting SKI of own certificate %d!\n", i+1); 02648 delete[] opCerts; 02649 return E_UNKNOWN; 02650 } 02651 //CAMsg::printMsg(LOG_DEBUG, "SKI of own cert %d is: %s\n", i+1, tmpSKI); 02652 //get AKI 02653 UINT32 tmpAKIlen = 255; 02654 UINT8 tmpAKI[255]; 02655 if(tmpCert->getAuthorityKeyIdentifier(tmpAKI, &tmpAKIlen) != E_SUCCESS) 02656 { 02657 CAMsg::printMsg(LOG_WARNING, "Could not get AKI of own certificate. This is not a critical problem, but you have a very old mix certificate. Create a new one as soon as possible.\n"); 02658 } 02659 else 02660 { 02661 //CAMsg::printMsg(LOG_DEBUG, "AKI of own cert %d is: %s\n", i+1, tmpAKI); 02662 } 02663 //try to find right opCert 02664 for(UINT32 j=0; j<opCertsLen; j++) 02665 { 02666 if(tmpCert->verify(opCerts[j]) == E_SUCCESS) 02667 { 02668 //found right operator cert -> add it to store 02669 // CAMsg::printMsg(LOG_DEBUG, "Found operator cert for sign key %d!\n", i+1); 02670 certs->add(opCerts[j]); 02671 break; 02672 } 02673 } 02674 if(certs->getNumber() == 0) 02675 { 02676 CAMsg::printMsg(LOG_CRIT, "Could not find operator cert for sign key %d! Please check your configuration. Exiting...\n", i+1); 02677 exit(EXIT_FAILURE); 02678 } 02679 //add own cert to store 02680 certs->add(tmpCert); 02681 //get Raw SKI 02682 UINT32 tmpRawSKIlen = 255; 02683 UINT8 tmpRawSKI[255]; 02684 if(tmpCert->getRawSubjectKeyIdentifier(tmpRawSKI, &tmpRawSKIlen) != E_SUCCESS) 02685 { 02686 delete[] opCerts; 02687 return E_UNKNOWN; 02688 } 02689 if (certs->getNumber() < 2) 02690 { 02691 CAMsg::printMsg(LOG_CRIT, "We have less than two certificates (only %d), but we need at least one mix and one operator certificate. There must be something wrong with the cert store. Exiting...\n", certs->getNumber()); 02692 exit(EXIT_FAILURE); 02693 } 02694 CAMsg::printMsg(LOG_DEBUG, "Adding Sign-Key %d with %d certificate(s).\n", i+1, certs->getNumber()); 02695 m_pMultiSignature->addSignature(signature, certs, tmpRawSKI, tmpRawSKIlen); 02696 } 02697 if (m_pMultiSignature->getSignatureCount() == 0) 02698 { 02699 CAMsg::printMsg(LOG_CRIT, "Could not set a signature key for MultiCert!\n"); 02700 delete m_pMultiSignature; 02701 m_pMultiSignature = NULL; 02702 delete[] opCerts; 02703 return E_UNKNOWN; 02704 } 02705 //end new 02706 /*if ( (m_pOwnCertificate->getSubjectKeyIdentifier(tmpBuff, &tmpLen) != E_SUCCESS) && 02707 (m_strMixID == NULL)) 02708 { 02709 LOG_NODE_NOT_FOUND(OPTIONS_NODE_MIX_ID); 02710 return E_UNKNOWN; 02711 }*/ 02712 //check Mix-ID 02713 if(m_pMultiSignature->getXORofSKIs(tmpBuff, tmpLen) != E_SUCCESS) 02714 { 02715 delete[] opCerts; 02716 return E_UNKNOWN; 02717 } 02718 02719 if(m_strMixID != NULL ) 02720 { 02721 if(strncmp(m_strMixID, (char*)tmpBuff, strlen((char*)tmpBuff) ) != 0) 02722 { 02723 CAMsg::printMsg(LOG_CRIT,"The configuration file seems inconsistent: it contains another Mix ID (%s) than calculated from the Mix certificate(s), which is %s. Please re-import you mix certificate in the configuration tool, or set the correct mix ID manually by editing the configuration file.\n", m_strMixID, tmpBuff); 02724 delete[] opCerts; 02725 return E_UNKNOWN; 02726 } 02727 } 02728 else 02729 { 02730 m_strMixID=new char[strlen((char*)tmpBuff)+1]; 02731 m_strMixID[strlen((char*)tmpBuff)]= (char) 0; 02732 strcpy(m_strMixID,(char*) tmpBuff); 02733 delete[] opCerts; 02734 return addMixIdToMixInfo(); 02735 } 02736 02737 #ifdef PAYMENT 02738 if (m_strAiID != NULL && m_pMultiSignature->findSKI(m_strAiID) != E_SUCCESS) 02739 { 02740 CAMsg::printMsg(LOG_CRIT, "Your price certificate does not fit to your mix certificate(s). Please import the proper price certificate or mix certificate.\n"); 02741 } 02742 #endif 02743 02744 #ifdef DYNAMIC_MIX 02745 /* LERNGRUPPE: Dynamic Mixes must have a cascade name, as MiddleMixes may be reconfigured to be FirstMixes */ 02746 if(bNeedCascadeNameFromMixID) 02747 { 02748 m_strCascadeName = new char[strlen(m_strMixID) + 1]; 02749 memset(m_strCascadeName, 0, strlen(m_strMixID) + 1); 02750 strncpy(m_strCascadeName, m_strMixID, strlen(m_strMixID)+1); 02751 } 02752 #endif 02753 delete[] opCerts; 02754 return E_SUCCESS; 02755 } 02756 02757 SINT32 CACmdLnOptions::setOwnOperatorCertificate(DOMElement *elemCertificates) 02758 { 02759 DOMElement* elemOpCert = NULL; 02760 DOMElement *opCertX509 = NULL; 02761 02762 if(elemCertificates == NULL) return E_UNKNOWN; 02763 ASSERT_CERTIFICATES_OPTIONS_PARENT 02764 (elemCertificates->getNodeName(), OPTIONS_NODE_OWN_OPERATOR_CERTIFICATE); 02765 02766 //then Operator Certificate 02767 if (getDOMChildByName 02768 (elemCertificates, OPTIONS_NODE_OWN_OPERATOR_CERTIFICATE, 02769 elemOpCert, false) != E_SUCCESS) 02770 { 02771 LOG_NODE_NOT_FOUND(OPTIONS_NODE_OWN_OPERATOR_CERTIFICATE); 02772 return E_UNKNOWN; 02773 } 02774 02775 if (elemOpCert != NULL) 02776 { 02777 m_opCertList = getElementsByTagName(elemOpCert, "X509Certificate"); 02778 02779 getDOMChildByName(elemOpCert, OPTIONS_NODE_X509_CERTIFICATE, opCertX509, true); 02780 if( opCertX509 != NULL) 02781 { 02782 m_OpCert = CACertificate::decode(opCertX509, CERT_X509CERTIFICATE); 02783 } 02784 else 02785 { 02786 LOG_NODE_NOT_FOUND(OPTIONS_NODE_X509_CERTIFICATE); 02787 return E_UNKNOWN; 02788 } 02789 } 02790 return E_SUCCESS; 02791 } 02792 02793 SINT32 CACmdLnOptions::setMixCertificateVerification(DOMElement *elemCertificates) 02794 { 02795 DOMElement *elemMixVerify; 02796 UINT8 tmpBuff[TMP_BUFF_SIZE]; 02797 UINT32 tmpLen = TMP_BUFF_SIZE; 02798 02799 if(elemCertificates == NULL) return E_UNKNOWN; 02800 ASSERT_CERTIFICATES_OPTIONS_PARENT 02801 (elemCertificates->getNodeName(), OPTIONS_NODE_MIX_CERTIFICATE_VERIFICATION); 02802 02803 getDOMChildByName(elemCertificates, OPTIONS_NODE_MIX_CERTIFICATE_VERIFICATION, elemMixVerify, false); 02804 if(elemMixVerify != NULL) 02805 { 02806 if(getDOMElementValue(elemMixVerify, tmpBuff, &tmpLen) == E_SUCCESS && 02807 memcmp(tmpBuff,"True",4)==0) 02808 { 02809 m_bVerifyMixCerts = true; 02810 m_pTrustedRootCertificates = new CACertStore(); 02811 CAMsg::printMsg(LOG_INFO, "Mix certificate verification is enabled.\n"); 02812 } 02813 } 02814 return E_SUCCESS; 02815 } 02816 02817 SINT32 CACmdLnOptions::setNextMixCertificate(DOMElement *elemCertificates) 02818 { 02819 DOMElement* elemNextCert = NULL; 02820 02821 if(!m_bVerifyMixCerts) 02822 { 02823 if(elemCertificates == NULL) return E_UNKNOWN; 02824 ASSERT_CERTIFICATES_OPTIONS_PARENT 02825 (elemCertificates->getNodeName(), OPTIONS_NODE_NEXT_MIX_CERTIFICATE); 02826 02827 //nextMixCertificate if given 02828 getDOMChildByName(elemCertificates, OPTIONS_NODE_NEXT_MIX_CERTIFICATE, elemNextCert,false); 02829 if(elemNextCert!=NULL) 02830 { 02831 m_pNextMixCertificate= 02832 CACertificate::decode(elemNextCert->getFirstChild(),CERT_X509CERTIFICATE); 02833 if(m_pNextMixCertificate == NULL) 02834 { 02835 CAMsg::printMsg(LOG_CRIT,"Could not decode the certificate of the next mix!\n"); 02836 return E_UNKNOWN; 02837 } 02838 } 02839 } 02840 return E_SUCCESS; 02841 02842 } 02843 02844 SINT32 CACmdLnOptions::setPrevMixCertificate(DOMElement *elemCertificates) 02845 { 02846 //prevMixCertificate if given 02847 DOMElement* elemPrevCert=NULL; 02848 02849 if(!m_bVerifyMixCerts) 02850 { 02851 if(elemCertificates == NULL) return E_UNKNOWN; 02852 ASSERT_CERTIFICATES_OPTIONS_PARENT 02853 (elemCertificates->getNodeName(), OPTIONS_NODE_PREV_MIX_CERTIFICATE); 02854 02855 getDOMChildByName(elemCertificates, OPTIONS_NODE_PREV_MIX_CERTIFICATE, elemPrevCert, false); 02856 if(elemPrevCert!=NULL) 02857 { 02858 m_pPrevMixCertificate= 02859 CACertificate::decode(elemPrevCert->getFirstChild(),CERT_X509CERTIFICATE); 02860 } 02861 } 02862 return E_SUCCESS; 02863 02864 } 02865 02866 SINT32 CACmdLnOptions::setTrustedRootCertificates(DOMElement *elemCertificates) 02867 { 02868 DOMElement* elemTrustedCerts=NULL; 02869 DOMNodeList* trustedCerts=NULL; 02870 CACertificate* cert; 02871 02872 if(m_bVerifyMixCerts) 02873 { 02874 if(elemCertificates == NULL) return E_UNKNOWN; 02875 ASSERT_CERTIFICATES_OPTIONS_PARENT 02876 (elemCertificates->getNodeName(), OPTIONS_NODE_TRUSTED_ROOT_CERTIFICATES); 02877 02878 getDOMChildByName(elemCertificates, OPTIONS_NODE_TRUSTED_ROOT_CERTIFICATES, elemTrustedCerts, false); 02879 if(elemTrustedCerts!=NULL) 02880 { 02881 trustedCerts = getElementsByTagName(elemTrustedCerts, OPTIONS_NODE_X509_CERTIFICATE); 02882 02883 for(UINT32 i=0; i<trustedCerts->getLength(); i++) 02884 { 02885 cert = CACertificate::decode(trustedCerts->item(i), CERT_X509CERTIFICATE); 02886 if(cert != NULL) 02887 { 02888 m_pTrustedRootCertificates->add(cert); 02889 } 02890 else 02891 { 02892 CAMsg::printMsg(LOG_WARNING, "Root certificate could not be decoded\n"); 02893 } 02894 } 02895 } 02896 else 02897 { 02898 LOG_NODE_NOT_FOUND(OPTIONS_NODE_TRUSTED_ROOT_CERTIFICATES); 02899 return E_UNKNOWN; 02900 } 02901 if(m_pTrustedRootCertificates->getNumber() == 0) 02902 { 02903 CAMsg::printMsg(LOG_CRIT, "No trusted root certificates found.\n"); 02904 return E_UNKNOWN; 02905 } 02906 CAMsg::printMsg(LOG_INFO, "Loaded %d trusted root certificates.\n", m_pTrustedRootCertificates->getNumber()); 02907 } 02908 return E_SUCCESS; 02909 } 02910 02911 /************************************** 02912 * accounting option setter functions * 02913 **************************************/ 02914 #ifdef PAYMENT 02915 SINT32 CACmdLnOptions::setAccountingOptions(DOMElement *elemRoot) 02916 { 02917 // the accoutning options are added by Bastian Voigt 02918 DOMElement* elemAccounting=NULL; 02919 if (getDOMChildByName 02920 (elemRoot, OPTIONS_NODE_ACCOUNTING, elemAccounting, false) != E_SUCCESS) 02921 { 02922 LOG_NODE_NOT_FOUND(OPTIONS_NODE_ACCOUNTING); 02923 return E_UNKNOWN; 02924 } 02925 02926 return invokeOptionSetters 02927 (accountingOptionSetters, elemAccounting, ACCOUNTING_OPTIONS_NR); 02928 return E_SUCCESS; 02929 } 02930 02931 02932 SINT32 CACmdLnOptions::setPriceCertificate(DOMElement *elemAccounting) 02933 { 02934 02935 DOMElement* elemPriceCert = NULL; 02936 02937 if(elemAccounting == NULL) return E_UNKNOWN; 02938 ASSERT_ACCOUNTING_OPTIONS_PARENT 02939 (elemAccounting->getNodeName(), OPTIONS_NODE_PRICE_CERTIFICATE); 02940 02941 //function in CAUtil, last param is "deep", needs to be set to include child elems 02942 getDOMChildByName 02943 (elemAccounting, OPTIONS_NODE_PRICE_CERTIFICATE, elemPriceCert, false); 02944 if (elemPriceCert == NULL) 02945 { 02946 CAMsg::printMsg(LOG_CRIT, "Did you really want to compile the mix with payment support?\n"); 02947 LOG_NODE_NOT_FOUND(OPTIONS_NODE_PRICE_CERTIFICATE); 02948 return E_UNKNOWN; 02949 } 02950 else 02951 { 02952 /*UINT8 digest[SHA_DIGEST_LENGTH]; 02953 UINT8* out=new UINT8[5000]; 02954 UINT32 outlen=5000; 02955 02956 DOM_Output::makeCanonical(elemPriceCert,out,&outlen); 02957 out[outlen] = 0; 02958 //#ifdef DEBUG 02959 CAMsg::printMsg(LOG_DEBUG, "price cert (%u bytes) to be hashed: %s\n",outlen, out); 02960 //#endif 02961 SHA1(out,outlen,digest); 02962 delete[] out; 02963 out = NULL; 02964 02965 UINT32 len2 = 1024; 02966 UINT8* tmpBuff2 = new UINT8[len2+1]; 02967 memset(tmpBuff2, 0, len2+1); 02968 CABase64::encode(digest,SHA_DIGEST_LENGTH, tmpBuff2, &len2); 02969 CAMsg::printMsg(LOG_CRIT,"hash: %s\n", tmpBuff2); 02970 exit(0);*/ 02971 m_pPriceCertificate = CAXMLPriceCert::getInstance(elemPriceCert); 02972 if (m_pPriceCertificate == NULL) 02973 { 02974 CAMsg::printMsg(LOG_CRIT, "Could not parse price certificate!"); 02975 return E_UNKNOWN; 02976 } 02977 m_strAiID = m_pPriceCertificate->getSubjectKeyIdentifier(); 02978 02979 if (m_pMultiSignature != NULL && m_pMultiSignature->findSKI(m_strAiID) != E_SUCCESS) 02980 { 02981 CAMsg::printMsg(LOG_CRIT,"Your price certificate does not fit to your mix certificate(s). Please import the proper price certificate or mix certificate.\n"); 02982 return E_UNKNOWN; 02983 } 02984 02985 if (m_pBI == NULL) 02986 { 02987 CAMsg::printMsg(LOG_CRIT,"Could not verify price certificate, as no payment instance was found!\n"); 02988 return E_UNKNOWN; 02989 } 02990 02991 02992 if (CAMultiSignature::verifyXML(elemPriceCert, m_pBI->getCertificate()) != E_SUCCESS) 02993 { 02994 CAMsg::printMsg(LOG_CRIT,"Signature of price certificate is invalid! It may be damaged, or maybe you are using the wrong payment instance certificate?\n"); 02995 return E_UNKNOWN; 02996 } 02997 02998 } 02999 03000 //insert price certificate 03001 return appendMixInfo_internal(elemPriceCert, WITH_SUBTREE); 03002 03003 return E_SUCCESS; 03004 } 03005 03006 SINT32 CACmdLnOptions::setPaymentInstance(DOMElement *elemAccounting) 03007 { 03008 03009 DOMElement* elemJPI = NULL; 03010 03011 if(elemAccounting == NULL) return E_UNKNOWN; 03012 ASSERT_ACCOUNTING_OPTIONS_PARENT 03013 (elemAccounting->getNodeName(), OPTIONS_NODE_PAYMENT_INSTANCE); 03014 03015 CAMsg::printMsg(LOG_DEBUG, "Parsing JPI values.\n"); 03016 03017 getDOMChildByName(elemAccounting, OPTIONS_NODE_PAYMENT_INSTANCE, elemJPI, false); 03018 m_pBI = CAXMLBI::getInstance(elemJPI); 03019 if (m_pBI == NULL) 03020 { 03021 CAMsg::printMsg(LOG_CRIT,"Could not instantiate payment instance interface. Did you really want to compile the mix with payment support?\n"); 03022 return E_UNKNOWN; 03023 } 03024 return E_SUCCESS; 03025 } 03026 03027 03028 SINT32 CACmdLnOptions::setAccountingSoftLimit(DOMElement *elemAccounting) 03029 { 03030 03031 DOMElement* elemAISoftLimit = NULL; 03032 UINT32 tmp = 0; 03033 03034 if(elemAccounting == NULL) return E_UNKNOWN; 03035 ASSERT_ACCOUNTING_OPTIONS_PARENT 03036 (elemAccounting->getNodeName(), OPTIONS_NODE_AI_SOFT_LIMIT); 03037 03038 if (getDOMChildByName 03039 (elemAccounting, OPTIONS_NODE_AI_SOFT_LIMIT, elemAISoftLimit, false) != E_SUCCESS) 03040 { 03041 LOG_NODE_NOT_FOUND(OPTIONS_NODE_AI_SOFT_LIMIT); 03042 return E_UNKNOWN; 03043 } 03044 if(getDOMElementValue(elemAISoftLimit, &tmp)==E_SUCCESS) 03045 { 03046 m_iPaymentSoftLimit = tmp; 03047 } 03048 else 03049 { 03050 //or better set default values? 03051 LOG_NODE_EMPTY_OR_INVALID(OPTIONS_NODE_AI_SOFT_LIMIT); 03052 return E_UNKNOWN; 03053 } 03054 return E_SUCCESS; 03055 } 03056 03057 03058 SINT32 CACmdLnOptions::setAccountingHardLimit(DOMElement *elemAccounting) 03059 { 03060 03061 DOMElement* elemAIHardLimit = NULL; 03062 UINT32 tmp = 0; 03063 03064 if(elemAccounting == NULL) return E_UNKNOWN; 03065 ASSERT_ACCOUNTING_OPTIONS_PARENT 03066 (elemAccounting->getNodeName(), OPTIONS_NODE_AI_HARD_LIMIT); 03067 03068 if (getDOMChildByName 03069 (elemAccounting, OPTIONS_NODE_AI_HARD_LIMIT, elemAIHardLimit, false) != E_SUCCESS) 03070 { 03071 LOG_NODE_NOT_FOUND(OPTIONS_NODE_AI_HARD_LIMIT); 03072 return E_UNKNOWN; 03073 } 03074 if(getDOMElementValue(elemAIHardLimit, &tmp)==E_SUCCESS) 03075 { 03076 m_iPaymentHardLimit = tmp; 03077 } 03078 else 03079 { 03080 //or better set default values? 03081 LOG_NODE_EMPTY_OR_INVALID(OPTIONS_NODE_AI_HARD_LIMIT); 03082 return E_UNKNOWN; 03083 } 03084 return E_SUCCESS; 03085 } 03086 03087 03088 SINT32 CACmdLnOptions::setPrepaidInterval(DOMElement *elemAccounting) 03089 { 03090 03091 DOMElement* elemPrepaidIval = NULL; 03092 UINT32 tmp = 0; 03093 03094 if(elemAccounting == NULL) return E_UNKNOWN; 03095 ASSERT_ACCOUNTING_OPTIONS_PARENT 03096 (elemAccounting->getNodeName(), OPTIONS_NODE_PREPAID_IVAL); 03097 03098 if (getDOMChildByName 03099 (elemAccounting, OPTIONS_NODE_PREPAID_IVAL, elemPrepaidIval, false) != E_SUCCESS) 03100 { 03101 LOG_NODE_NOT_FOUND(OPTIONS_NODE_PREPAID_IVAL); 03102 03103 if (getDOMChildByName 03104 (elemAccounting, OPTIONS_NODE_PREPAID_IVAL_KB, elemPrepaidIval, false) != E_SUCCESS) 03105 { 03106 LOG_NODE_NOT_FOUND(OPTIONS_NODE_PREPAID_IVAL_KB); 03107 } 03108 else 03109 { 03110 if(getDOMElementValue(elemPrepaidIval, &tmp)==E_SUCCESS) 03111 { 03112 m_iPrepaidInterval = tmp * 1000; 03113 } 03114 } 03115 } 03116 else if(getDOMElementValue(elemPrepaidIval, &tmp) == E_SUCCESS) 03117 { 03118 m_iPrepaidInterval = tmp; 03119 } 03120 else 03121 { 03122 CAMsg::printMsg(LOG_INFO,"Node \"%s\" is empty! Setting default...\n", 03123 OPTIONS_NODE_PREPAID_IVAL); 03124 m_iPrepaidInterval = OPTIONS_DEFAULT_PREPAID_IVAL; 03125 } 03126 if (m_iPrepaidInterval > OPTIONS_DEFAULT_PREPAID_IVAL ) 03127 { 03128 CAMsg::printMsg(LOG_WARNING,"Prepaid interval is higher than %u! " 03129 "No JAP will pay more in advance!\n", OPTIONS_DEFAULT_PREPAID_IVAL); 03130 } 03131 else if (m_iPrepaidInterval < 5000) 03132 { 03133 CAMsg::printMsg(LOG_WARNING,"Prepaid interval of %u is far too low! " 03134 "Performance will be critical and clients will lose connection!\n", m_iPrepaidInterval); 03135 } 03136 03137 //insert prepaid interval 03138 DOMElement* elemInterval = createDOMElement(m_docMixInfo, OPTIONS_NODE_PREPAID_IVAL_KB); 03139 setDOMElementValue(elemInterval, (m_iPrepaidInterval / 1000) ); 03140 //TODO: handle exceptional cases */ 03141 m_docMixInfo->getDocumentElement()->appendChild(elemInterval); 03142 return E_SUCCESS; 03143 } 03144 03145 03146 SINT32 CACmdLnOptions::setSettleInterval(DOMElement *elemAccounting) 03147 { 03148 03149 DOMElement* elemSettleIval = NULL; 03150 UINT32 tmp = 0; 03151 03152 if(elemAccounting == NULL) return E_UNKNOWN; 03153 ASSERT_ACCOUNTING_OPTIONS_PARENT 03154 (elemAccounting->getNodeName(), OPTIONS_NODE_SETTLE_IVAL); 03155 03156 if (getDOMChildByName 03157 (elemAccounting, OPTIONS_NODE_SETTLE_IVAL, elemSettleIval, false) != E_SUCCESS) 03158 { 03159 LOG_NODE_NOT_FOUND(OPTIONS_NODE_SETTLE_IVAL); 03160 return E_UNKNOWN; 03161 } 03162 if(getDOMElementValue(elemSettleIval, &tmp)==E_SUCCESS) 03163 { 03164 m_iPaymentSettleInterval = tmp; 03165 } 03166 else 03167 { 03168 LOG_NODE_EMPTY_OR_INVALID(OPTIONS_NODE_SETTLE_IVAL); 03169 return E_UNKNOWN; 03170 } 03171 return E_SUCCESS; 03172 } 03173 03174 03175 SINT32 CACmdLnOptions::setAccountingDatabase(DOMElement *elemAccounting) 03176 { 03177 03178 DOMElement* elem = NULL; 03179 DOMElement* elemDatabase = NULL; 03180 UINT8 tmpBuff[TMP_BUFF_SIZE]; 03181 UINT32 tmpLen = TMP_BUFF_SIZE, tmp = 0; 03182 03183 /* DDB is only configured for first payment mix */ 03184 if (!m_bFirstMix) 03185 { 03186 return E_SUCCESS; 03187 } 03188 03189 if(elemAccounting == NULL) return E_UNKNOWN; 03190 ASSERT_ACCOUNTING_OPTIONS_PARENT 03191 (elemAccounting->getNodeName(), OPTIONS_NODE_AI_DB); 03192 03193 CAMsg::printMsg(LOG_DEBUG, "Parsing AI values.\n"); 03194 03195 if (getDOMChildByName(elemAccounting, OPTIONS_NODE_AI_DB, elemDatabase, false) != E_SUCCESS) 03196 { 03197 LOG_NODE_NOT_FOUND(OPTIONS_NODE_AI_DB); 03198 return E_UNKNOWN; 03199 } 03200 03201 // get DB Hostname 03202 if (getDOMChildByName(elemDatabase, OPTIONS_NODE_AI_DB_HOST, elem, false) != E_SUCCESS) 03203 { 03204 LOG_NODE_NOT_FOUND(OPTIONS_NODE_AI_DB_HOST); 03205 return E_UNKNOWN; 03206 } 03207 03208 if(getDOMElementValue(elem, tmpBuff, &tmpLen) != E_SUCCESS) 03209 { 03210 LOG_NODE_EMPTY_OR_INVALID(OPTIONS_NODE_AI_DB_HOST); 03211 return E_UNKNOWN; 03212 } 03213 strtrim(tmpBuff); 03214 m_strDatabaseHost = new UINT8[strlen((char*)tmpBuff)+1]; 03215 strcpy((char *)m_strDatabaseHost, (char *) tmpBuff); 03216 03217 // get Database Port 03218 if (getDOMChildByName 03219 (elemDatabase, OPTIONS_NODE_AI_DB_PORT, elem, false) != E_SUCCESS) 03220 { 03221 LOG_NODE_NOT_FOUND(OPTIONS_NODE_AI_DB_PORT); 03222 return E_UNKNOWN; 03223 } 03224 if(getDOMElementValue(elem, &tmp) != E_SUCCESS) 03225 { 03226 LOG_NODE_EMPTY_OR_INVALID(OPTIONS_NODE_AI_DB_PORT); 03227 return E_UNKNOWN; 03228 } 03229 m_iDatabasePort = tmp; 03230 03231 // get DB Name 03232 if (getDOMChildByName 03233 (elemDatabase, OPTIONS_NODE_AI_DB_NAME, elem, false) != E_SUCCESS) 03234 { 03235 LOG_NODE_NOT_FOUND(OPTIONS_NODE_AI_DB_NAME); 03236 return E_UNKNOWN; 03237 } 03238 03239 tmpLen = TMP_BUFF_SIZE; 03240 memset(tmpBuff, 0, tmpLen); 03241 03242 if(getDOMElementValue 03243 (elem, tmpBuff, &tmpLen) != E_SUCCESS) 03244 { 03245 LOG_NODE_EMPTY_OR_INVALID(OPTIONS_NODE_AI_DB_NAME); 03246 return E_UNKNOWN; 03247 } 03248 strtrim(tmpBuff); 03249 m_strDatabaseName = new UINT8[strlen((char*)tmpBuff)+1]; 03250 strcpy((char *)m_strDatabaseName, (char *) tmpBuff); 03251 03252 // get DB Username 03253 if (getDOMChildByName 03254 (elemDatabase, OPTIONS_NODE_AI_DB_USER, elem, false) != E_SUCCESS) 03255 { 03256 LOG_NODE_NOT_FOUND(OPTIONS_NODE_AI_DB_USER); 03257 return E_UNKNOWN; 03258 } 03259 03260 tmpLen = TMP_BUFF_SIZE; 03261 memset(tmpBuff, 0, tmpLen); 03262 03263 if(getDOMElementValue 03264 (elem, tmpBuff, &tmpLen) != E_SUCCESS) 03265 { 03266 LOG_NODE_EMPTY_OR_INVALID(OPTIONS_NODE_AI_DB_USER); 03267 return E_UNKNOWN; 03268 } 03269 strtrim(tmpBuff); 03270 m_strDatabaseUser = new UINT8[strlen((char*)tmpBuff)+1]; 03271 strcpy((char *)m_strDatabaseUser, (char *) tmpBuff); 03272 03273 //get DB password from xml 03274 getDOMChildByName(elemDatabase, OPTIONS_NODE_AI_DB_PASSW, elem, false); 03275 03276 tmpLen = TMP_BUFF_SIZE; 03277 memset(tmpBuff, 0, tmpLen); 03278 03279 //read password from xml if given 03280 if(getDOMElementValue(elem, tmpBuff, &tmpLen) != E_SUCCESS) 03281 { 03282 //read password from stdin: 03283 UINT8 dbpass[500]; 03284 dbpass[0] = 0; 03285 printf("Please enter password for postgresql user %s at %s: ",m_strDatabaseUser, m_strDatabaseHost); 03286 scanf("%400[^\n]%*1[\n]",(char*)dbpass); 03287 int len = strlen((char *)dbpass); 03288 if(len>0) 03289 { 03290 m_strDatabasePassword = new UINT8[len+1]; 03291 strcpy((char *)m_strDatabasePassword, (char *)dbpass); 03292 } 03293 else 03294 { 03295 m_strDatabasePassword = new UINT8[1]; 03296 m_strDatabasePassword[0] = '\0'; 03297 } 03298 } 03299 else 03300 { 03301 strtrim(tmpBuff); 03302 m_strDatabasePassword = new UINT8[strlen((char*)tmpBuff)+1]; 03303 strcpy((char *)m_strDatabasePassword, (char *) tmpBuff); 03304 } 03305 CAMsg::printMsg(LOG_DEBUG, "Accounting database information parsed successfully.\n"); 03306 03307 // just for testing the connection to the database 03308 if(CAAccountingDBInterface::init() != E_SUCCESS) 03309 { 03310 exit(EXIT_FAILURE); 03311 } 03312 CAAccountingDBInterface::cleanup(); 03313 03314 return E_SUCCESS; 03315 } 03316 #endif //PAYMENT 03317 /*********************************** 03318 * network option setter functions * 03319 ***********************************/ 03320 SINT32 CACmdLnOptions::setNetworkOptions(DOMElement *elemRoot) 03321 { 03322 DOMElement* elemNetwork = NULL; 03323 if (getDOMChildByName 03324 (elemRoot, OPTIONS_NODE_NETWORK, elemNetwork, false) != E_SUCCESS) 03325 { 03326 LOG_NODE_NOT_FOUND(OPTIONS_NODE_NETWORK); 03327 return E_UNKNOWN; 03328 } 03329 03330 return invokeOptionSetters 03331 (networkOptionSetters, elemNetwork, NETWORK_OPTIONS_NR); 03332 } 03333 03334 SINT32 CACmdLnOptions::setInfoServices(DOMElement *elemNetwork) 03335 { 03336 UINT8 tmpBuff[TMP_BUFF_SIZE]; 03337 UINT32 tmpLen = TMP_BUFF_SIZE; 03338 DOMElement* elemInfoServiceContainer=NULL; 03339 03340 if(elemNetwork == NULL) return E_UNKNOWN; 03341 ASSERT_NETWORK_OPTIONS_PARENT 03342 (elemNetwork->getNodeName(), OPTIONS_NODE_INFOSERVICE_LIST); 03343 03344 getDOMChildByName 03345 (elemNetwork, OPTIONS_NODE_INFOSERVICE_LIST, elemInfoServiceContainer,false); 03346 if (elemInfoServiceContainer == NULL) 03347 { 03348 // old configuration version <= 0.61 03349 DOMElement* elemInfoService=NULL; 03350 DOMElement* elemAllowReconfig=NULL; 03351 if (getDOMChildByName 03352 (elemNetwork, OPTIONS_NODE_INFOSERVICE, elemInfoService, false) != E_SUCCESS) 03353 { 03354 LOG_NODE_NOT_FOUND(OPTIONS_NODE_INFOSERVICE); 03355 } 03356 /* LERNGRUPPE: There might not be any InfoService configuration in the file, but in infoservices.xml, so check this */ 03357 if(elemInfoService != NULL) 03358 { 03359 getDOMChildByName 03360 (elemInfoService, OPTIONS_NODE_ALLOW_AUTO_CONF, elemAllowReconfig, false); 03361 CAListenerInterface* isListenerInterface = CAListenerInterface::getInstance(elemInfoService); 03362 if (!isListenerInterface) 03363 { 03364 LOG_NODE_EMPTY_OR_INVALID(OPTIONS_NODE_INFOSERVICE); 03365 } 03366 else 03367 { 03368 m_addrInfoServicesSize = 1; 03369 m_addrInfoServices = new CAListenerInterface*[m_addrInfoServicesSize]; 03370 m_addrInfoServices[0] = isListenerInterface; 03371 if(getDOMElementValue(elemAllowReconfig,tmpBuff,&tmpLen)==E_SUCCESS) 03372 { 03373 m_bAcceptReconfiguration = (strcmp("True",(char*)tmpBuff) == 0); 03374 } 03375 } 03376 } 03377 } 03378 else 03379 { 03380 // Refactored 03381 parseInfoServices(elemInfoServiceContainer); 03382 } 03383 03384 return E_SUCCESS; 03385 } 03386 03387 SINT32 CACmdLnOptions::setListenerInterfaces(DOMElement *elemNetwork) 03388 { 03389 DOMElement* elemListenerInterfaces=NULL; 03390 03391 if(elemNetwork == NULL) return E_UNKNOWN; 03392 ASSERT_NETWORK_OPTIONS_PARENT 03393 (elemNetwork->getNodeName(), OPTIONS_NODE_LISTENER_INTERFACES); 03394 03395 getDOMChildByName 03396 (elemNetwork, OPTIONS_NODE_LISTENER_INTERFACES, elemListenerInterfaces, false); 03397 m_arListenerInterfaces = CAListenerInterface::getInstance( 03398 elemListenerInterfaces, m_cnListenerInterfaces); 03399 03400 #ifndef DYNAMIC_MIX 03401 /* LERNGRUPPE: ListenerInterfaces may be configured dynamically */ 03402 if (m_cnListenerInterfaces == 0) 03403 { 03404 CAMsg::printMsg(LOG_CRIT, "No listener interfaces found!\n"); 03405 return E_UNKNOWN; 03406 } 03407 #endif 03408 if(elemListenerInterfaces != NULL) 03409 { 03410 // import listener interfaces element; this is needed for cascade auto configuration 03411 // -- inserted by ronin <ronin2@web.de> 2004-08-16 03412 appendMixInfo_internal(elemListenerInterfaces, WITH_SUBTREE); 03413 } 03414 03415 UINT32 i; 03416 SINT32 ret; 03417 CASocket** arrSocketsIn=new CASocket*[getListenerInterfaceCount()]; 03418 for (i = 0; i < getListenerInterfaceCount(); i++) 03419 { 03420 arrSocketsIn[i] = NULL; 03421 } 03422 03423 ret = createSockets(false, arrSocketsIn, getListenerInterfaceCount()); 03424 03425 for(i=0;i<getListenerInterfaceCount();i++) 03426 { 03427 if (arrSocketsIn[i] != NULL) 03428 { 03429 arrSocketsIn[i]->close(); 03430 delete arrSocketsIn[i]; 03431 arrSocketsIn[i] = NULL; 03432 } 03433 } 03434 delete[] arrSocketsIn; 03435 arrSocketsIn=NULL; 03436 03437 03438 if (ret != E_SUCCESS && ret != E_UNSPECIFIED && ret != E_SPACE) 03439 { 03440 CAMsg::printMsg(LOG_CRIT, "Could not listen on at least one of the specified interfaces. Please check if another running mix or server process is blocking the listen addresses, and if you have sufficient system rights.\n"); 03441 } 03442 03443 return ret; 03444 } 03445 03446 03447 SINT32 CACmdLnOptions::createSockets(bool a_bMessages, CASocket** a_sockets, UINT32 a_socketsLen) 03448 { 03449 if (a_socketsLen <= 0) 03450 { 03451 CAMsg::printMsg(LOG_CRIT,"Could not create any listener sockets as we have no space reserved for them. This seems to be an implementation bug."); 03452 return E_SPACE; 03453 } 03454 03455 03456 UINT32 aktSocket; 03457 UINT8 buff[255]; 03458 SINT32 ret = E_UNKNOWN; 03459 UINT32 currentInterface; 03460 CASocketAddr* pAddr; 03461 UINT32* arrayVirtualPorts = new UINT32[a_socketsLen]; 03462 UINT32 iVirtualPortsLen = 0; 03463 UINT32 iHiddenPortsLen = 0; 03464 UINT32* arrayHiddenPorts = new UINT32[a_socketsLen]; 03465 03466 03467 aktSocket = 0; 03468 for(currentInterface=0;currentInterface < getListenerInterfaceCount(); currentInterface++) 03469 { 03470 CAListenerInterface* pListener=NULL; 03471 pListener=getListenerInterface(currentInterface+1); 03472 if(pListener==NULL) 03473 { 03474 CAMsg::printMsg(LOG_CRIT,"Error: Listener interface %d is invalid.\n", currentInterface+1); 03475 03476 delete[] arrayVirtualPorts; 03477 delete[] arrayHiddenPorts; 03478 03479 return E_UNKNOWN; 03480 } 03481 03482 pAddr=pListener->getAddr(); 03483 pAddr->toString(buff,255); 03484 03485 if(pAddr->getType()==AF_INET) 03486 { 03487 if (pListener->isVirtual()) 03488 { 03489 arrayVirtualPorts[iVirtualPortsLen] = ((CASocketAddrINet*)pAddr)->getPort(); 03490 iVirtualPortsLen++; 03491 } 03492 else if (pListener->isHidden()) 03493 { 03494 arrayHiddenPorts[iHiddenPortsLen] = ((CASocketAddrINet*)pAddr)->getPort(); 03495 iHiddenPortsLen++; 03496 } 03497 } 03498 03499 if(pListener->isVirtual()) 03500 { 03501 delete pListener; 03502 pListener = NULL; 03503 delete pAddr; 03504 pAddr = NULL; 03505 continue; 03506 } 03507 03508 if (a_socketsLen < aktSocket ) 03509 { 03510 CAMsg::printMsg(LOG_CRIT, 03511 "Found %d listener sockets, but we have only reserved memory for %d sockets. This seems to be an implementation error in the code.\n", 03512 (aktSocket + 1), a_socketsLen); 03513 03514 delete[] arrayVirtualPorts; 03515 delete[] arrayHiddenPorts; 03516 delete pAddr; 03517 03518 return E_SPACE; 03519 } 03520 03521 ret = E_SUCCESS; 03522 a_sockets[aktSocket] = new CASocket(); 03523 a_sockets[aktSocket]->create(pAddr->getType()); 03524 a_sockets[aktSocket]->setReuseAddr(true); 03525 03526 delete pListener; 03527 pListener = NULL; 03528 #ifndef _WIN32 03529 //we have to be a temporary superuser if port <1024... 03530 int old_uid=geteuid(); 03531 if(pAddr->getType()==AF_INET&&((CASocketAddrINet*)pAddr)->getPort()<1024) 03532 { 03533 if(seteuid(0)==-1) //changing to root 03534 { 03535 CAMsg::printMsg(LOG_CRIT,"Setuid failed! We might not be able to listen on interface %d (%s) as we cannot change to the root user.\n", 03536 currentInterface+1, buff); 03537 } 03538 } 03539 #endif 03540 ret=a_sockets[aktSocket]->listen(*pAddr); 03541 delete pAddr; 03542 pAddr = NULL; 03543 03544 if(ret!=E_SUCCESS) 03545 { 03546 CAMsg::printMsg(LOG_CRIT,"Socket error while listening on interface %d (%s). Reason: %s (%i)\n",currentInterface+1, buff, 03547 GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR); 03548 } 03549 03550 #ifndef _WIN32 03551 seteuid(old_uid); 03552 #endif 03553 if(ret!=E_SUCCESS) 03554 { 03555 delete[] arrayVirtualPorts; 03556 delete[] arrayHiddenPorts; 03557 return E_UNKNOWN; 03558 } 03559 03560 if (a_bMessages) 03561 { 03562 CAMsg::printMsg(LOG_DEBUG,"Listening on Interface: %s\n",buff); 03563 } 03564 aktSocket++; 03565 } //END FOR 03566 03567 if (ret == E_UNKNOWN) 03568 { 03569 CAMsg::printMsg(LOG_CRIT,"Could not find any valid (non-virtual) listener interface!\n"); 03570 } 03571 else if (ret == E_SUCCESS) 03572 { 03573 for (UINT32 iHiddenPort = 0; iHiddenPort < iHiddenPortsLen; iHiddenPort++) 03574 { 03575 bool bVirtualFound = false; 03576 for (UINT32 iVirtualPort = 0; iVirtualPort < iVirtualPortsLen; iVirtualPort++) 03577 { 03578 if (arrayHiddenPorts[iHiddenPort] == arrayVirtualPorts[iVirtualPort]) 03579 { 03580 bVirtualFound = true; 03581 arrayVirtualPorts[iVirtualPort] = 0; 03582 } 03583 } 03584 if (!bVirtualFound) 03585 { 03586 CAMsg::printMsg(LOG_CRIT,"No virtuel listener interface found for the hidden interface %d with port %d. Please remove the hidden interface, add the corresponding virtual interface or remove the 'hidden' attribute from the interface.\n", iHiddenPort, arrayHiddenPorts[iHiddenPort]); 03587 ret = E_UNSPECIFIED; 03588 break; 03589 } 03590 } 03591 03592 if (ret == E_SUCCESS) 03593 { 03594 for (UINT32 iVirtualPort = 0; iVirtualPort < iVirtualPortsLen; iVirtualPort++) 03595 { 03596 if (arrayVirtualPorts[iVirtualPort] != 0) 03597 { 03598 CAMsg::printMsg(LOG_CRIT,"No hidden listener interface found for the virtual interface %d with port %d. Please remove the virtual interface, add the corresponding hidden interface or remove the 'virtual' attribute from the interface.\n", iVirtualPort, arrayVirtualPorts[iVirtualPort]); 03599 ret = E_UNSPECIFIED; 03600 break; 03601 } 03602 } 03603 } 03604 } 03605 03606 if (ret == E_SUCCESS && a_bMessages) 03607 { 03608 CAMsg::printMsg(LOG_DEBUG,"Listening on all interfaces.\n"); 03609 } 03610 03611 delete[] arrayVirtualPorts; 03612 delete[] arrayHiddenPorts; 03613 arrayVirtualPorts = NULL; 03614 03615 return ret; 03616 } 03617 03618 03619 /* Proxy settings and next mix settings */ 03620 SINT32 CACmdLnOptions::setTargetInterfaces(DOMElement *elemNetwork) 03621 { 03622 UINT8 tmpBuff[TMP_BUFF_SIZE]; 03623 UINT32 tmpLen = TMP_BUFF_SIZE; 03624 DOMElement* elemNextMix = NULL; 03625 DOMElement* elemProxies=NULL; 03626 CATargetInterface* targetInterfaceNextMix = NULL; 03627 //get TargetInterfaces 03628 m_cnTargets=0; 03629 03630 if(elemNetwork == NULL) return E_UNKNOWN; 03631 ASSERT_NETWORK_OPTIONS_PARENT 03632 (elemNetwork->getNodeName(), OPTIONS_NODE_NEXT_MIX); 03633 03634 //NextMix --> only one!! 03635 getDOMChildByName 03636 (elemNetwork, OPTIONS_NODE_NEXT_MIX, elemNextMix, false); 03637 if(elemNextMix != NULL) 03638 { 03639 NetworkType type=RAW_TCP; 03640 CASocketAddr* addr = NULL; 03641 DOMElement* elemType = NULL; 03642 getDOMChildByName 03643 (elemNextMix, OPTIONS_NODE_NETWORK_PROTOCOL, elemType, false); 03644 03645 bool bAddrIsSet = false; 03646 03647 if(getDOMElementValue(elemType, tmpBuff, &tmpLen) == E_SUCCESS) 03648 { 03649 strtrim(tmpBuff); 03650 if(strcmp((char*)tmpBuff, "RAW/TCP") == 0) 03651 { 03652 type=RAW_TCP; 03653 } 03654 else if(strcmp((char*)tmpBuff, "RAW/UNIX") == 0) 03655 { 03656 type=RAW_UNIX; 03657 } 03658 else if(strcmp((char*)tmpBuff, "SSL/TCP") == 0) 03659 { 03660 type=SSL_TCP; 03661 } 03662 else if(strcmp((char*)tmpBuff, "SSL/UNIX") == 0) 03663 { 03664 type=SSL_UNIX; 03665 } 03666 03667 if( (type == SSL_TCP) || (type == RAW_TCP) ) 03668 { 03669 DOMElement* elemPort = NULL; 03670 DOMElement* elemHost = NULL; 03671 DOMElement* elemIP = NULL; 03672 UINT8 buffHost[TMP_BUFF_SIZE]; 03673 UINT32 buffHostLen = TMP_BUFF_SIZE; 03674 UINT16 port; 03675 getDOMChildByName 03676 (elemNextMix, OPTIONS_NODE_PORT, elemPort, false); 03677 if(getDOMElementValue(elemPort,&port) == E_SUCCESS) 03678 { 03679 addr = new CASocketAddrINet; 03680 //bool bAddrIsSet=false; 03681 getDOMChildByName 03682 (elemNextMix, OPTIONS_NODE_HOST, elemHost, false); 03683 /* The rules for <Host> and <IP> are as follows: 03684 * 1. if <Host> is given and not empty take the <Host> value for the address of the next mix; if not go to 2 03685 * 2. if <IP> if given and not empty take <IP> value for the address of the next mix; if not goto 3. 03686 * 3. this entry for the next mix is invalid!*/ 03687 if(elemHost != NULL) 03688 { 03689 if(getDOMElementValue(elemHost,buffHost,&buffHostLen)==E_SUCCESS && 03690 ((CASocketAddrINet*)addr)->setAddr(buffHost,port)==E_SUCCESS) 03691 { 03692 bAddrIsSet = true; 03693 } 03694 } 03695 if(!bAddrIsSet)//now try <IP> 03696 { 03697 getDOMChildByName(elemNextMix, OPTIONS_NODE_IP, elemIP, false); 03698 if(elemIP == NULL || getDOMElementValue(elemIP,buffHost,&buffHostLen) == E_SUCCESS) 03699 { 03700 ((CASocketAddrINet*)addr)->setAddr(buffHost,port); 03701 bAddrIsSet = true; 03702 } 03703 } 03704 CAMsg::printMsg(LOG_INFO, "Setting target interface: %s:%d\n", buffHost, port); 03705 } 03706 } 03707 #ifdef HAVE_UNIX_DOMAIN_PROTOCOL 03708 else if( (type == SSL_UNIX) || (type == RAW_UNIX) ) 03709 { 03710 DOMElement* elemFile=NULL; 03711 getDOMChildByName(elemNextMix, OPTIONS_NODE_FILE, elemFile, false); 03712 tmpLen = TMP_BUFF_SIZE; 03713 if(getDOMElementValue(elemFile, tmpBuff, &tmpLen) == E_SUCCESS) 03714 { 03715 tmpBuff[tmpLen]=0; 03716 strtrim(tmpBuff); 03717 addr=new CASocketAddrUnix; 03718 if(((CASocketAddrUnix*)addr)->setPath((char*)tmpBuff) == E_SUCCESS) 03719 { 03720 bAddrIsSet = true; 03721 } 03722 } 03723 } 03724 #endif 03725 } 03726 03727 if(bAddrIsSet) 03728 { 03729 targetInterfaceNextMix=new CATargetInterface(TARGET_MIX,type,addr->clone()); 03730 m_cnTargets=1; 03731 } 03732 03733 delete addr; 03734 addr = NULL; 03735 } 03736 03737 //Next Proxies and visible adresses 03738 SINT32 ret; 03739 UINT8 buff[255]; 03740 UINT32 buffLen = 255; 03741 CASocket* tmpSocket; 03742 03743 clearVisibleAddresses(); 03744 getDOMChildByName(elemNetwork, OPTIONS_NODE_PROXY_LIST, elemProxies, false); 03745 if(elemProxies != NULL) 03746 { 03747 DOMNodeList* nlTargetInterfaces=NULL; 03748 nlTargetInterfaces=getElementsByTagName(elemProxies, OPTIONS_NODE_PROXY); 03749 m_cnTargets+=nlTargetInterfaces->getLength(); 03750 03751 if(nlTargetInterfaces->getLength()>0) 03752 { 03753 m_arTargetInterfaces=new CATargetInterface[m_cnTargets]; 03754 UINT32 aktInterface=0; 03755 NetworkType type=UNKNOWN_NETWORKTYPE; 03756 TargetType proxy_type=TARGET_UNKNOWN; 03757 CASocketAddr* addr=NULL; 03758 UINT16 port; 03759 bool bHttpProxyFound = false; 03760 for(UINT32 i=0; i < nlTargetInterfaces->getLength(); i++) 03761 { 03762 delete addr; 03763 addr=NULL; 03764 DOMNode* elemTargetInterface=NULL; 03765 elemTargetInterface=nlTargetInterfaces->item(i); 03766 DOMElement* elemType; 03767 getDOMChildByName 03768 (elemTargetInterface, OPTIONS_NODE_NETWORK_PROTOCOL, elemType,false); 03769 tmpLen = TMP_BUFF_SIZE; 03770 if(getDOMElementValue(elemType,tmpBuff,&tmpLen)!=E_SUCCESS) 03771 continue; 03772 strtrim(tmpBuff); 03773 if(strcmp((char*)tmpBuff,"RAW/TCP") == 0) 03774 { 03775 type=RAW_TCP; 03776 } 03777 else if(strcmp((char*)tmpBuff,"RAW/UNIX") == 0) 03778 { 03779 type=RAW_UNIX; 03780 } 03781 else if(strcmp((char*)tmpBuff,"SSL/TCP") == 0) 03782 { 03783 type=SSL_TCP; 03784 } 03785 else if(strcmp((char*)tmpBuff,"SSL/UNIX") == 0) 03786 { 03787 type=SSL_UNIX; 03788 } 03789 else 03790 { 03791 continue; 03792 } 03793 //ProxyType 03794 elemType=NULL; 03795 getDOMChildByName 03796 (elemTargetInterface, OPTIONS_NODE_PROXY_TYPE, elemType, false); 03797 tmpLen = TMP_BUFF_SIZE; 03798 if(getDOMElementValue(elemType,tmpBuff,&tmpLen)!=E_SUCCESS) 03799 continue; 03800 strtrim(tmpBuff); 03801 if(strcmp((char*)tmpBuff,"SOCKS")==0) 03802 { 03803 proxy_type=TARGET_SOCKS_PROXY; 03804 } 03805 else if(strcmp((char*)tmpBuff,"HTTP")==0) 03806 { 03807 proxy_type=TARGET_HTTP_PROXY; 03808 } 03809 else 03810 { 03811 continue; 03812 } 03813 03814 if( (type==SSL_TCP) || (type == RAW_TCP) ) 03815 { 03816 DOMElement* elemPort; 03817 DOMElement* elemHost; 03818 getDOMChildByName 03819 (elemTargetInterface, OPTIONS_NODE_PORT, elemPort, false); 03820 if(getDOMElementValue(elemPort,&port)!=E_SUCCESS) 03821 { 03822 continue; 03823 } 03824 addr=new CASocketAddrINet; 03825 getDOMChildByName 03826 (elemTargetInterface, OPTIONS_NODE_HOST, elemHost, false); 03827 if(elemHost != NULL) 03828 { 03829 UINT8 buffHost[TMP_BUFF_SIZE]; 03830 UINT32 buffHostLen = TMP_BUFF_SIZE; 03831 if(getDOMElementValue(elemHost, buffHost, &buffHostLen) != E_SUCCESS) 03832 { 03833 continue; 03834 } 03835 if(((CASocketAddrINet*)addr)->setAddr(buffHost, port) != E_SUCCESS) 03836 { 03837 continue; 03838 } 03839 } 03840 else 03841 { 03842 continue; 03843 } 03844 } 03845 else 03846 #ifdef HAVE_UNIX_DOMAIN_PROTOCOL 03847 { 03848 DOMElement* elemFile; 03849 getDOMChildByName 03850 (elemTargetInterface, OPTIONS_NODE_FILE, elemFile, false); 03851 tmpLen = TMP_BUFF_SIZE; 03852 if(getDOMElementValue(elemFile, tmpBuff, &tmpLen) != E_SUCCESS) 03853 { 03854 continue; 03855 } 03856 tmpBuff[tmpLen]=0; 03857 strtrim(tmpBuff); 03858 addr=new CASocketAddrUnix; 03859 if(((CASocketAddrUnix*)addr)->setPath((char*)tmpBuff) != E_SUCCESS) 03860 { 03861 continue; 03862 } 03863 } 03864 #else 03865 continue; 03866 #endif 03867 03868 03869 03870 // check connection to proxy 03871 tmpSocket = new CASocket; 03872 tmpSocket->setRecvBuff(50000); 03873 tmpSocket->setSendBuff(5000); 03874 ret = tmpSocket->connect(*addr,LAST_MIX_TO_PROXY_CONNECT_TIMEOUT); 03875 if (ret != E_SUCCESS) 03876 { 03877 if (addr->toString(buff, buffLen) != E_SUCCESS) 03878 { 03879 buff[0] = 0; 03880 } 03881 if (ret != E_UNKNOWN) 03882 { 03883 CAMsg::printMsg(LOG_WARNING, "Could not connect to proxy %s! Reason: %s (%i) Please check if the proxy is running.\n", 03884 buff, GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR); 03885 } 03886 else 03887 { 03888 CAMsg::printMsg(LOG_WARNING, "Could not connect to proxy %s! Please check if the proxy is running.\n", buff); 03889 } 03890 } 03891 03892 if (ret == E_SUCCESS) 03893 { 03894 if (proxy_type == TARGET_HTTP_PROXY) 03895 { 03896 // TODO: we should not send an HTTP request to a non-existing address, for example to test:9999; if squid runs, we will get an HTTP error response 03897 //if(tmpSocket->sendTimeOut(pMixPacket->payload.data,payLen,LAST_MIX_TO_PROXY_SEND_TIMEOUT)==SOCKET_ERROR) ... 03898 // else ... tmpSocket->receive(pMixPacket->payload.data,PAYLOAD_SIZE); 03899 // if we get no response or an invalid response, we set ret = E_UNKNOWN 03900 03901 bHttpProxyFound = true; 03902 } 03903 else if (proxy_type == TARGET_SOCKS_PROXY) 03904 { 03905 // TODO maybe there is also a possibility to check the response of the SOCKS proxy? 03906 m_bSocksSupport = true; 03907 } 03908 } 03909 03910 tmpSocket->close(); 03911 delete tmpSocket; 03912 03913 03914 if (ret == E_SUCCESS) 03915 { 03916 addVisibleAddresses(elemTargetInterface); 03917 m_arTargetInterfaces[aktInterface].set(proxy_type,type,addr->clone()); 03918 aktInterface++; 03919 } 03920 03921 03922 delete addr; 03923 addr=NULL; 03924 } 03925 03926 if (!bHttpProxyFound) 03927 { 03928 CAMsg::printMsg(LOG_CRIT, "No valid HTTP proxy was specified! Please install and configure an HTTP proxy like Squid before starting the mix.\n"); 03929 for (UINT32 i = 0; i < aktInterface; i++) 03930 { 03931 m_arTargetInterfaces[aktInterface].cleanAddr(); 03932 } 03933 03934 03935 return E_UNKNOWN; 03936 } 03937 03938 m_cnTargets=aktInterface; 03939 } 03940 } //end if elemProxies!=null 03941 //add NextMixInterface to the End of the List... 03942 if(targetInterfaceNextMix != NULL) 03943 { 03944 if(m_arTargetInterfaces == NULL) 03945 { 03946 m_cnTargets=0; 03947 m_arTargetInterfaces=new CATargetInterface[1]; 03948 } 03949 m_arTargetInterfaces[m_cnTargets++].set(targetInterfaceNextMix); 03950 delete targetInterfaceNextMix; 03951 targetInterfaceNextMix = NULL; 03952 } 03953 else if(m_arTargetInterfaces == NULL) 03954 { 03955 CAMsg::printMsg(LOG_CRIT, "Neither proxy nor next mix target interfaces are specified!\n"); 03956 return E_UNKNOWN; 03957 } 03958 03959 //Set Proxy Visible Addresses if Last Mix and given 03960 if(isLastMix() && (m_docMixInfo != NULL) ) 03961 { 03962 DOMElement* elemMix = m_docMixInfo->getDocumentElement(); 03963 if(elemMix != NULL) 03964 { 03965 DOMElement* elemProxies=createDOMElement(m_docMixInfo,"Proxies"); 03966 if (m_bSocksSupport) 03967 { 03968 setDOMElementAttribute(elemProxies, "socks5Support", (UINT8*)"true"); 03969 } 03970 DOMElement* elemProxy=createDOMElement(m_docMixInfo,"Proxy"); 03971 DOMElement* elemVisAddresses=createDOMElement(m_docMixInfo,"VisibleAddresses"); 03972 elemMix->appendChild(elemProxies); 03973 elemProxies->appendChild(elemProxy); 03974 elemProxy->appendChild(elemVisAddresses); 03975 for(UINT32 i=1;i<=getVisibleAddressesCount();i++) 03976 { 03977 UINT8 tmp[255]; 03978 UINT32 tmplen=255; 03979 if(getVisibleAddress(tmp,tmplen,i)==E_SUCCESS) 03980 { 03981 DOMElement* elemVisAddress=createDOMElement(m_docMixInfo,"VisibleAddress"); 03982 DOMElement* elemHost=createDOMElement(m_docMixInfo,"Host"); 03983 elemVisAddress->appendChild(elemHost); 03984 setDOMElementValue(elemHost,tmp); 03985 elemVisAddresses->appendChild(elemVisAddress); 03986 } 03987 } 03988 } 03989 } 03990 03991 return E_SUCCESS; 03992 } 03993 03994 SINT32 CACmdLnOptions::setServerMonitoring(DOMElement *elemNetwork) 03995 { 03996 #ifdef SERVER_MONITORING 03997 03998 UINT8 tmpBuff[TMP_BUFF_SIZE]; 03999 UINT32 tmpLen = TMP_BUFF_SIZE; 04000 04001 DOMElement* elemServerMonitoringRoot = NULL; 04002 DOMElement* elemServerMonitoringHost = NULL; 04003 DOMElement* elemServerMonitoringPort = NULL; 04004 04005 if(elemNetwork == NULL) return E_UNKNOWN; 04006 ASSERT_NETWORK_OPTIONS_PARENT 04007 (elemNetwork->getNodeName(), OPTIONS_NODE_SERVER_MONITORING); 04008 04009 m_strMonitoringListenerHost = NULL; 04010 m_iMonitoringListenerPort = 0xFFFF; 04011 04012 if (getDOMChildByName 04013 (elemNetwork, OPTIONS_NODE_SERVER_MONITORING, elemServerMonitoringRoot,false) == E_SUCCESS) 04014 { 04015 if(getDOMChildByName 04016 (elemServerMonitoringRoot, OPTIONS_NODE_HOST, elemServerMonitoringHost, false) == E_SUCCESS) 04017 { 04018 if(getDOMElementValue(elemServerMonitoringHost, 04019 (UINT8 *)tmpBuff,&tmpLen)==E_SUCCESS) 04020 { 04021 m_strMonitoringListenerHost = new char[tmpLen+1]; 04022 strncpy(m_strMonitoringListenerHost, (const char*) tmpBuff, tmpLen); 04023 m_strMonitoringListenerHost[tmpLen] = 0; 04024 } 04025 } 04026 if(getDOMChildByName 04027 (elemServerMonitoringRoot, OPTIONS_NODE_PORT, 04028 elemServerMonitoringPort, false) == E_SUCCESS) 04029 { 04030 UINT16 port = 0xFFFF; 04031 if(getDOMElementValue(elemServerMonitoringPort, &port)==E_SUCCESS) 04032 { 04033 m_iMonitoringListenerPort = port; 04034 } 04035 } 04036 04037 /* only non-local ListnerInterfaces are showed in Mix status info */ 04038 if( (elemServerMonitoringRoot != NULL) && 04039 (m_strMonitoringListenerHost != NULL)) 04040 { 04041 if( (strncmp("localhost", m_strMonitoringListenerHost, 9) != 0) && 04042 (strncmp("127.0.0.1", m_strMonitoringListenerHost, 9) != 0) ) 04043 { 04044 appendMixInfo_internal(elemServerMonitoringRoot, WITH_SUBTREE); 04045 } 04046 } 04047 } 04048 else 04049 { 04050 CAMsg::printMsg(LOG_DEBUG, "Server Monitoring Config not found\n"); 04051 } 04052 #endif /* SERVER_MONITORING */ 04053 return E_SUCCESS; 04054 } 04055 04056 /* Read Configuration of KeepAliveTraffic */ 04057 SINT32 CACmdLnOptions::setKeepAliveTraffic(DOMElement *elemNetwork) 04058 { 04059 DOMElement* elemKeepAlive = NULL; 04060 DOMElement* elemKeepAliveSendInterval = NULL; 04061 DOMElement* elemKeepAliveRecvInterval = NULL; 04062 04063 if(elemNetwork == NULL) return E_UNKNOWN; 04064 ASSERT_NETWORK_OPTIONS_PARENT 04065 (elemNetwork->getNodeName(), OPTIONS_NODE_SERVER_MONITORING); 04066 04067 getDOMChildByName(elemNetwork, OPTIONS_NODE_KEEP_ALIVE, elemKeepAlive, false); 04068 getDOMChildByName(elemKeepAlive, OPTIONS_NODE_KEEP_ALIVE_SEND_IVAL, elemKeepAliveSendInterval, false); 04069 getDOMChildByName(elemKeepAlive, OPTIONS_NODE_KEEP_ALIVE_RECV_IVAL, elemKeepAliveRecvInterval, false); 04070 getDOMElementValue(elemKeepAliveSendInterval, m_u32KeepAliveSendInterval, KEEP_ALIVE_TRAFFIC_SEND_WAIT_TIME); 04071 getDOMElementValue(elemKeepAliveRecvInterval, m_u32KeepAliveRecvInterval, KEEP_ALIVE_TRAFFIC_RECV_WAIT_TIME); 04072 return E_SUCCESS; 04073 } 04074 04075 04076 /*************************************** 04077 * ressource option setter function(s) * 04078 * (delay options) * 04079 ***************************************/ 04080 SINT32 CACmdLnOptions::setRessourceOptions(DOMElement *elemRoot) 04081 { 04082 #if defined (DELAY_CHANNELS) ||defined(DELAY_USERS)||defined(DELAY_CHANNELS_LATENCY) 04083 04084 //this is at the moment: 04085 //<Ressources> 04086 //<UnlimitTraffic></UnlimitTraffic> #Number of bytes/packets without resource limitation 04087 //<BytesPerIntervall></BytesPerIntervall> #upper limit of number of bytes/packets which are processed per channel/per user per time intervall 04088 //<Intervall></Intervall> #duration of one intervall in ms 04089 //<Latency></Latency> #minimum Latency per channel in ms 04090 //</Ressources> 04091 CAMsg::printMsg(LOG_INFO,"Loading Parameters for traffic shaping / resource limitation....\n"); 04092 UINT32 u32 = 0; 04093 DOMElement *elemRessources=NULL; 04094 DOMElement *elem = NULL; 04095 04096 if(elemRoot == NULL) 04097 { 04098 return E_UNKNOWN; 04099 } 04100 04101 getDOMChildByName(elemRoot, OPTIONS_NODE_RESSOURCES, elemRessources,false); 04102 if(elemRessources!=NULL) 04103 { 04104 #if defined (DELAY_CHANNELS) || defined(DELAY_USERS) 04105 if( getDOMChildByName 04106 (elemRessources, OPTIONS_NODE_UNLIMIT_TRAFFIC, elem, false) == E_SUCCESS && 04107 getDOMElementValue(elem, &u32) == E_SUCCESS ) 04108 { 04109 m_u32DelayChannelUnlimitTraffic = u32; 04110 } 04111 if( getDOMChildByName 04112 (elemRessources, OPTIONS_NODE_BYTES_PER_IVAL, elem, false) == E_SUCCESS && 04113 getDOMElementValue(elem, &u32) == E_SUCCESS) 04114 { 04115 m_u32DelayChannelBucketGrow = u32; 04116 } 04117 if( getDOMChildByName 04118 (elemRessources, OPTIONS_NODE_DELAY_IVAL, elem, false) == E_SUCCESS && 04119 getDOMElementValue(elem, &u32) == E_SUCCESS) 04120 { 04121 m_u32DelayChannelBucketGrowIntervall = u32; 04122 } 04123 #endif 04124 #if defined (DELAY_CHANNELS_LATENCY) 04125 if( getDOMChildByName 04126 (elemRessources, OPTIONS_NODE_LATENCY, elem, false) == E_SUCCESS && 04127 getDOMElementValue(elem, &u32) == E_SUCCESS) 04128 { 04129 m_u32DelayChannelLatency = u32; 04130 } 04131 #endif 04132 } 04133 #endif 04134 return E_SUCCESS; 04135 } 04136 04137 /************************************************* 04138 * terms and condition option setter function(s) * 04139 *************************************************/ 04140 SINT32 CACmdLnOptions::setTermsAndConditions(DOMElement *elemRoot) 04141 { 04142 SINT32 ret = E_SUCCESS; 04143 DOMElement *elemTnCs = NULL; 04144 04145 if(elemRoot == NULL) 04146 { 04147 return E_UNKNOWN; 04148 } 04149 04150 ret = getDOMChildByName(elemRoot, OPTIONS_NODE_TNCS_OPTS, elemTnCs, true); 04151 if(elemTnCs != NULL) 04152 { 04153 return invokeOptionSetters 04154 (termsAndConditionsOptionSetters, elemTnCs, TERMS_AND_CONDITIONS_OPTIONS_NR); 04155 } 04156 else 04157 { 04158 CAMsg::printMsg(LOG_WARNING,"No Terms & Conditions for Operator specified!\n"); 04159 return E_SUCCESS; 04160 } 04161 } 04162 04163 SINT32 CACmdLnOptions::setTermsAndConditionsTemplates(DOMElement *elemTnCs) 04164 { 04165 if(elemTnCs == NULL) 04166 { 04167 CAMsg::printMsg(LOG_CRIT,"Terms And Conditions root element is null!\n"); 04168 return E_UNKNOWN; 04169 } 04170 DOMElement *elemTnCsTemplates = NULL; 04171 DOMNodeList *templateList = NULL; 04172 bool nothingFound = true; 04173 getDOMChildByName(elemTnCs, OPTIONS_NODE_TNCS_TEMPLATES, elemTnCsTemplates); 04174 04175 UINT8** loadedTemplateRefIds = NULL; 04176 bool templateError = false; 04177 04178 if(elemTnCsTemplates != NULL) 04179 { 04180 templateList = getElementsByTagName(elemTnCsTemplates, OPTIONS_NODE_TNCS_TEMPLATE); 04181 if(templateList->getLength() > 0) 04182 { 04183 nothingFound = false; 04184 m_nrOfTermsAndConditionsTemplates = templateList->getLength(); 04185 m_termsAndConditionsTemplates = new XERCES_CPP_NAMESPACE::DOMDocument*[m_nrOfTermsAndConditionsTemplates]; 04186 loadedTemplateRefIds = new UINT8*[m_nrOfTermsAndConditionsTemplates]; 04187 memset(loadedTemplateRefIds, 0, (sizeof(UINT8*)*m_nrOfTermsAndConditionsTemplates) ); 04188 04189 UINT8 currentTemplateURL[TMP_BUFF_SIZE]; 04190 UINT32 len = TMP_BUFF_SIZE; 04191 memset(currentTemplateURL, 0, len); 04192 04193 for (XMLSize_t i = 0; i < templateList->getLength(); i++) 04194 { 04195 getDOMElementValue(templateList->item(i), currentTemplateURL, &len); 04196 m_termsAndConditionsTemplates[i] = parseDOMDocument(currentTemplateURL); 04197 if(m_termsAndConditionsTemplates[i] == NULL) 04198 { 04199 CAMsg::printMsg(LOG_WARNING, "Cannot load Terms And Conditions template '%s'.\n", 04200 currentTemplateURL); 04201 return E_UNKNOWN; 04202 } 04203 UINT8* refId = getTermsAndConditionsTemplateRefId(m_termsAndConditionsTemplates[i]->getDocumentElement()); 04204 if(refId != NULL) 04205 { 04206 loadedTemplateRefIds[i] = refId; 04207 for(XMLSize_t j = 0; j < i; j++) 04208 { 04209 if(strncmp((char *)refId, (char *) loadedTemplateRefIds[j], TEMPLATE_REFID_MAXLEN) == 0 ) 04210 { 04211 templateError = true; 04212 CAMsg::printMsg(LOG_ERR, "duplicate Terms And Conditions template '%s'.\n",refId); 04213 break; 04214 } 04215 } 04216 } 04217 else 04218 { 04219 templateError = true; 04220 CAMsg::printMsg(LOG_ERR, "Terms And Conditions template with invalid refid found.\n"); 04221 break; 04222 } 04223 04224 if(!templateError) 04225 { 04226 CAMsg::printMsg(LOG_INFO, "loaded Terms And Conditions template '%s'.\n",refId); 04227 } 04228 else 04229 { 04230 break; 04231 } 04232 len = TMP_BUFF_SIZE; 04233 } 04234 } 04235 if(loadedTemplateRefIds != NULL) 04236 { 04237 for(XMLSize_t j = 0; j < m_nrOfTermsAndConditionsTemplates; j++) 04238 { 04239 delete [] loadedTemplateRefIds[j]; 04240 loadedTemplateRefIds[j] = NULL; 04241 } 04242 delete [] loadedTemplateRefIds; 04243 loadedTemplateRefIds = NULL; 04244 } 04245 if(templateError) 04246 { 04247 return E_UNKNOWN; 04248 } 04249 } 04250 04251 if(nothingFound) 04252 { 04253 CAMsg::printMsg(LOG_INFO,"No Terms And Conditions templates found.\n"); 04254 } 04255 04256 return E_SUCCESS; 04257 } 04258 SINT32 CACmdLnOptions::setTermsAndConditionsList(DOMElement *elemTnCs) 04259 { 04260 if(elemTnCs == NULL) 04261 { 04262 CAMsg::printMsg(LOG_CRIT,"Terms And Conditions root element is null!\n"); 04263 return E_UNKNOWN; 04264 } 04265 DOMElement *elemTnCsList = NULL; 04266 getDOMChildByName(elemTnCs, OPTIONS_NODE_TNCS, elemTnCsList); 04267 04268 if(elemTnCsList == NULL) 04269 { 04270 CAMsg::printMsg(LOG_CRIT,"No definitions for Terms And Conditions found!\n"); 04271 return E_UNKNOWN; 04272 } 04273 04274 UINT32 attrCheckLen = TMP_BUFF_SIZE; 04275 UINT8 attrCheck[TMP_BUFF_SIZE]; 04276 memset(attrCheck, 0, attrCheckLen); 04277 04278 UINT32 localeLen = TMP_LOCALE_SIZE; 04279 UINT8 locale[TMP_LOCALE_SIZE]; 04280 memset(locale, 0, localeLen); 04281 04282 UINT32 dateLen = TMP_DATE_SIZE; 04283 UINT8 date[TMP_DATE_SIZE]; 04284 memset(date, 0, dateLen); 04285 04286 if( (getDOMElementAttribute(elemTnCsList, OPTIONS_ATTRIBUTE_TNC_DATE, date, &dateLen) != E_SUCCESS) || 04287 (strlen((char *)date) != ((TMP_DATE_SIZE) - 1) ) ) 04288 { 04289 CAMsg::printMsg(LOG_CRIT,"Attribute '%s' is not properly set for the global definition of Terms And Conditions!\n", 04290 OPTIONS_ATTRIBUTE_TNC_DATE); 04291 return E_UNKNOWN; 04292 } 04293 04294 m_docOpTnCs = createDOMDocument(); 04295 04296 DOMElement *currentTnCEntry = NULL; 04297 DOMNodeList *tncDefEntryList = getElementsByTagName(elemTnCsList, OPTIONS_NODE_TNCS_TRANSLATION); 04298 04299 if(tncDefEntryList->getLength() < 1) 04300 { 04301 CAMsg::printMsg(LOG_CRIT,"No Terms And Conditions entries found!\n"); 04302 return E_UNKNOWN; 04303 } 04304 04305 DOMElement *tncTranslationImports = NULL; 04306 DOMElement *tncOperatorNode = NULL; 04307 getDOMChildByName(elemTnCsList, OPTIONS_NODE_TNCS_TRANSLATION_IMPORTS, tncTranslationImports, false); 04308 if(tncTranslationImports != NULL) 04309 { 04310 getDOMChildByName(tncTranslationImports, OPTIONS_NODE_TNCS_OPERATOR, tncOperatorNode, false); 04311 } 04312 bool defaultLangValue = false; 04313 bool defaultLangFound = false; 04314 bool operatorImportNodeFound = (tncOperatorNode != NULL); 04315 04316 /* validity check for every definition: are all necessary attributes set (referenceId, locale), length ok 04317 * and is there EXACTLY ONE default language specified? 04318 */ 04319 for (XMLSize_t j = 0; j < tncDefEntryList->getLength(); j++) 04320 { 04321 attrCheckLen = TMP_BUFF_SIZE; 04322 localeLen = TMP_LOCALE_SIZE; 04323 defaultLangValue = false; 04324 currentTnCEntry = (DOMElement *) tncDefEntryList->item(j); 04325 04326 if( (getDOMElementAttribute(currentTnCEntry, OPTIONS_ATTRIBUTE_TNC_TEMPLATE_REFID, attrCheck, &attrCheckLen) != E_SUCCESS) || 04327 (strlen((char *)attrCheck) < 1) ) 04328 { 04329 CAMsg::printMsg(LOG_CRIT,"Attribute '%s' is not proper set for definition %u of Terms And Conditions!\n", 04330 OPTIONS_ATTRIBUTE_TNC_TEMPLATE_REFID, (j+1)); 04331 return E_UNKNOWN; 04332 } 04333 else if( (getDOMElementAttribute(currentTnCEntry, OPTIONS_ATTRIBUTE_TNC_LOCALE, locale, &localeLen) != E_SUCCESS) || 04334 (strlen((char *)locale) != ((TMP_LOCALE_SIZE) - 1) ) ) 04335 { 04336 CAMsg::printMsg(LOG_CRIT,"Attribute '%s' is not proper set for definition %u of Terms And Conditions!\n", 04337 OPTIONS_ATTRIBUTE_TNC_LOCALE, (j+1)); 04338 return E_UNKNOWN; 04339 } 04340 04341 if(!operatorImportNodeFound) 04342 { 04343 tncOperatorNode = NULL; 04344 getDOMChildByName(currentTnCEntry, OPTIONS_NODE_TNCS_OPERATOR, tncOperatorNode, false); 04345 if(tncOperatorNode == NULL) 04346 { 04347 CAMsg::printMsg(LOG_CRIT,"No Node '%s' defined for the translation [%s]. Either define it in '%s' or" 04348 " in this %s.\n", OPTIONS_NODE_TNCS_OPERATOR, locale, OPTIONS_NODE_TNCS_TRANSLATION_IMPORTS, 04349 OPTIONS_NODE_TNCS_TRANSLATION); 04350 return E_UNKNOWN; 04351 } 04352 } 04353 04354 //setDOMElementAttribute(currentTnCEntry, OPTIONS_ATTRIBUTE_TNC_DATE, date); 04355 getDOMElementAttribute(currentTnCEntry, 04356 OPTIONS_ATTRIBUTE_TNC_DEFAULT_LANG_DEFINED, defaultLangValue); 04357 04358 if(defaultLangValue && defaultLangFound) 04359 { 04360 CAMsg::printMsg(LOG_CRIT,"exactly ONE default language must be specified for the Terms And Conditions!\n"); 04361 return E_UNKNOWN; 04362 } 04363 04364 //import nodes global for all translations 04365 if(tncTranslationImports != NULL) 04366 { 04367 if(integrateDOMNode(tncTranslationImports, currentTnCEntry, true, false) != E_SUCCESS) 04368 { 04369 CAMsg::printMsg(LOG_CRIT,"Integrating imports failed!\n"); 04370 return E_UNKNOWN; 04371 } 04372 } 04373 defaultLangFound = (defaultLangFound || defaultLangValue); 04374 } 04375 04376 if(!defaultLangFound) 04377 { 04378 CAMsg::printMsg(LOG_CRIT,"There is no default language specified for the Terms And Conditions!\n"); 04379 return E_UNKNOWN; 04380 } 04381 if(tncTranslationImports != NULL) 04382 { 04383 elemTnCsList->removeChild(tncTranslationImports); 04384 } 04385 m_docOpTnCs->appendChild(m_docOpTnCs->importNode(elemTnCsList, WITH_SUBTREE)); 04386 04387 return E_SUCCESS; 04388 } 04389 04390 /******************************************* 04391 * crime detection option setter functions * 04392 *******************************************/ 04393 #ifdef LOG_CRIME 04394 SINT32 CACmdLnOptions::setCrimeDetectionOptions(DOMElement *elemRoot) 04395 { 04396 DOMElement* elemCrimeDetection = NULL; 04397 if (getDOMChildByName 04398 (elemRoot, OPTIONS_NODE_CRIME_DETECTION, elemCrimeDetection, false) != E_SUCCESS) 04399 { 04400 LOG_NODE_NOT_FOUND(OPTIONS_NODE_CRIME_DETECTION); 04401 return E_SUCCESS; 04402 } 04403 04404 CAMsg::printMsg(LOG_INFO,"Loading Crime Detection Data....\n"); 04405 04406 if(elemCrimeDetection != NULL) 04407 { 04408 if( getDOMElementAttribute(elemCrimeDetection, 04409 OPTIONS_ATTRIBUTE_LOG_PAYLOAD, m_logPayload) != E_SUCCESS) 04410 { 04411 m_logPayload = false; 04412 } 04413 return invokeOptionSetters 04414 (crimeDetectionOptionSetters, elemCrimeDetection, CRIME_DETECTION_OPTIONS_NR); 04415 } 04416 return E_SUCCESS; 04417 } 04418 04419 SINT32 CACmdLnOptions::setCrimeURLRegExp(DOMElement *elemCrimeDetection) 04420 { 04421 04422 if(elemCrimeDetection == NULL) return E_UNKNOWN; 04423 ASSERT_CRIME_DETECTION_OPTIONS_PARENT 04424 (elemCrimeDetection->getNodeName(), OPTIONS_NODE_CRIME_REGEXP_URL); 04425 04426 return setRegExpressions(elemCrimeDetection, OPTIONS_NODE_CRIME_REGEXP_URL, 04427 &m_arCrimeRegExpsURL, &m_nCrimeRegExpsURL); 04428 04429 /*DOM_NodeList nlRegExp = elemCrimeDetection.getElementsByTagName("RegExpURL"); 04430 m_arCrimeRegExpsURL=new regex_t[nlRegExp.getLength()]; 04431 for(UINT32 i=0;i<nlRegExp.getLength();i++) 04432 { 04433 DOM_Node tmpChild=nlRegExp.item(i); 04434 UINT32 lenRegExp=4096; 04435 UINT8 buffRegExp[4096]; 04436 if(getDOMElementValue(tmpChild,buffRegExp,&lenRegExp)==E_SUCCESS) 04437 { 04438 if(regcomp(&m_arCrimeRegExpsURL[m_nCrimeRegExpsURL],(char*)buffRegExp,REG_EXTENDED|REG_ICASE|REG_NOSUB)!=0) 04439 { 04440 CAMsg::printMsg(LOG_CRIT,"Could not compile URL regexp: %s\n",buffRegExp); 04441 exit(-1); 04442 } 04443 CAMsg::printMsg(LOG_DEBUG,"Looking for crime URL RegExp: %s\n",buffRegExp); 04444 04445 m_nCrimeRegExpsURL++; 04446 } 04447 }*/ 04448 04449 return E_SUCCESS; 04450 } 04451 04452 SINT32 CACmdLnOptions::setCrimePayloadRegExp(DOMElement *elemCrimeDetection) 04453 { 04454 04455 if(elemCrimeDetection == NULL) return E_UNKNOWN; 04456 ASSERT_CRIME_DETECTION_OPTIONS_PARENT 04457 (elemCrimeDetection->getNodeName(), OPTIONS_NODE_CRIME_REGEXP_PAYLOAD); 04458 04459 return setRegExpressions(elemCrimeDetection, OPTIONS_NODE_CRIME_REGEXP_PAYLOAD, 04460 &m_arCrimeRegExpsPayload, &m_nCrimeRegExpsPayload); 04461 04462 /*DOMNodeList *nlRegExp = 04463 getElementsByTagName(elemCrimeDetection, OPTIONS_NODE_CRIME_REGEXP_PAYLOAD); 04464 04465 if(nlRegExp != NULL) 04466 { 04467 m_arCrimeRegExpsPayload = new regex_t[nlRegExp->getLength()]; 04468 for(UINT32 i = 0; i < nlRegExp->getLength(); i++) 04469 { 04470 DOMNode *tmpChild = nlRegExp->item(i); 04471 04472 UINT32 lenRegExp = REGEXP_BUFF_SIZE; 04473 UINT8 buffRegExp[REGEXP_BUFF_SIZE]; 04474 04475 if(getDOMElementValue(tmpChild, buffRegExp, &lenRegExp)==E_SUCCESS) 04476 { 04477 if(regcomp(&m_arCrimeRegExpsPayload[m_nCrimeRegExpsPayload],(char*)buffRegExp,REG_EXTENDED|REG_ICASE|REG_NOSUB)!=0) 04478 { 04479 CAMsg::printMsg(LOG_CRIT,"Could not compile payload regexp: %s\n",buffRegExp); 04480 exit(-1); 04481 } 04482 CAMsg::printMsg(LOG_DEBUG,"Looking for crime Payload RegExp: %s\n",buffRegExp); 04483 04484 m_nCrimeRegExpsPayload++; 04485 } 04486 } 04487 }*/ 04488 return E_SUCCESS; 04489 } 04490 04491 SINT32 CACmdLnOptions::setCrimeSurveillanceIP(DOMElement *elemCrimeDetection) 04492 { 04493 if(elemCrimeDetection == NULL) return E_UNKNOWN; 04494 ASSERT_CRIME_DETECTION_OPTIONS_PARENT (elemCrimeDetection->getNodeName(), OPTIONS_NODE_CRIME_SURVEILLANCE_IP); 04495 04496 UINT8 ipBuff[TMP_BUFF_SIZE]; 04497 04498 DOMNodeList *surveillanceIPNodes =getElementsByTagName(elemCrimeDetection, OPTIONS_NODE_CRIME_SURVEILLANCE_IP); 04499 m_nrOfSurveillanceIPs = (UINT32) surveillanceIPNodes->getLength(); 04500 04501 if (m_nrOfSurveillanceIPs == 0) 04502 { 04503 CAMsg::printMsg(LOG_INFO,"No surveillance IP specified.\n"); 04504 return E_SUCCESS; 04505 } 04506 04507 m_surveillanceIPs = new CAIPAddrWithNetmask[m_nrOfSurveillanceIPs]; 04508 for (UINT32 i = 0; i < m_nrOfSurveillanceIPs; i++) 04509 { 04510 UINT32 ipBuffSize = TMP_BUFF_SIZE; 04511 DOMNode* pelemCurrentIP=surveillanceIPNodes->item(i); 04512 if(getDOMElementValue(pelemCurrentIP, ipBuff,&ipBuffSize) == E_SUCCESS ) 04513 { 04514 m_surveillanceIPs[i].setAddr(ipBuff); 04515 ipBuffSize = TMP_BUFF_SIZE; 04516 if(getDOMElementAttribute(pelemCurrentIP,OPTIONS_NODE_CRIME_SURVEILLANCE_IP_NETMASK,ipBuff,&ipBuffSize)==E_SUCCESS) 04517 { 04518 m_surveillanceIPs[i].setNetmask(ipBuff); 04519 } 04520 ipBuffSize = TMP_BUFF_SIZE; 04521 m_surveillanceIPs[i].toString(ipBuff,&ipBuffSize); 04522 CAMsg::printMsg(LOG_INFO,"Found Surveillance IP %s\n", ipBuff); 04523 } 04524 else 04525 { 04526 CAMsg::printMsg(LOG_INFO,"Could not read surveillance IP!\n"); 04527 delete[] m_surveillanceIPs; 04528 m_surveillanceIPs = NULL; 04529 m_nrOfSurveillanceIPs = 0; 04530 return E_UNKNOWN; 04531 } 04532 } 04533 04534 04535 return E_SUCCESS; 04536 } 04537 04538 04539 SINT32 CACmdLnOptions::setCrimeSurveillanceAccounts(DOMElement *elemCrimeDetection) 04540 { 04541 04542 if(elemCrimeDetection == NULL) return E_UNKNOWN; 04543 04544 ASSERT_CRIME_DETECTION_OPTIONS_PARENT 04545 (elemCrimeDetection->getNodeName(), OPTIONS_NODE_CRIME_SURVEILLANCE_ACCOUNT); 04546 04547 04548 UINT64 accountNumber; 04549 04550 DOMNodeList *surveillanceIPNodes =getElementsByTagName(elemCrimeDetection, OPTIONS_NODE_CRIME_SURVEILLANCE_ACCOUNT); 04551 m_nrOfSurveillanceAccounts = (UINT32) surveillanceIPNodes->getLength(); 04552 04553 if (m_nrOfSurveillanceAccounts == 0) 04554 { 04555 CAMsg::printMsg(LOG_INFO,"No surveillance accounts specified.\n"); 04556 return E_SUCCESS; 04557 } 04558 04559 DOMNode* node=NULL; 04560 m_surveillanceAccounts = new UINT64[m_nrOfSurveillanceAccounts]; 04561 for (UINT32 i = 0; i < m_nrOfSurveillanceAccounts; i++) 04562 { 04563 node = surveillanceIPNodes->item(i); 04564 if(getDOMElementValue(node, accountNumber) == E_SUCCESS) 04565 { 04566 m_surveillanceAccounts[i] = accountNumber; 04567 CAMsg::printMsg(LOG_INFO,"Found surveillance account %llu.\n", accountNumber); 04568 } 04569 else 04570 { 04571 CAMsg::printMsg(LOG_INFO,"Could not read surveillance account number!\n"); 04572 delete[] m_surveillanceAccounts; 04573 m_surveillanceAccounts = NULL; 04574 m_nrOfSurveillanceAccounts = 0; 04575 return E_UNKNOWN; 04576 } 04577 } 04578 04579 04580 04581 return E_SUCCESS; 04582 } 04583 04584 SINT32 setRegExpressions(DOMElement *rootElement, const char* const childElementName, 04585 regex_t **regExContainer, UINT32* regExNr) 04586 { 04587 if( (rootElement == NULL) || (childElementName == NULL) || 04588 (regExNr == NULL) || (regExContainer == NULL) ) 04589 { 04590 return E_UNKNOWN; 04591 } 04592 04593 (*regExNr) = 0; 04594 04595 DOMNodeList *nlRegExp = 04596 getElementsByTagName(rootElement, childElementName); 04597 04598 if(nlRegExp != NULL) 04599 { 04600 (*regExContainer) = new regex_t[nlRegExp->getLength()]; 04601 04602 for(UINT32 i = 0; i < nlRegExp->getLength(); i++) 04603 { 04604 DOMNode *tmpChild = nlRegExp->item(i); 04605 04606 UINT32 lenRegExp = REGEXP_BUFF_SIZE; 04607 UINT8 buffRegExp[REGEXP_BUFF_SIZE]; 04608 04609 if(getDOMElementValue(tmpChild, buffRegExp, &lenRegExp)==E_SUCCESS) 04610 { 04611 if(regcomp( &((*regExContainer)[(*regExNr)]), 04612 ((char*) buffRegExp), 04613 REG_EXTENDED | REG_ICASE | REG_NOSUB) != 0 ) 04614 { 04615 CAMsg::printMsg(LOG_CRIT,"Could not compile regexp: %s\n",buffRegExp); 04616 return E_UNKNOWN; 04617 } 04618 CAMsg::printMsg(LOG_DEBUG,"Looking for RegExp: %s\n",buffRegExp); 04619 (*regExNr)++; 04620 } 04621 } 04622 } 04623 return E_SUCCESS; 04624 } 04625 #endif //LOG_CRIME 04626 04627 04628 04629 04637 SINT32 CACmdLnOptions::processXmlConfiguration(XERCES_CPP_NAMESPACE::DOMDocument* docConfig) 04638 { 04639 SINT32 ret = E_SUCCESS; 04640 if(docConfig==NULL) 04641 { 04642 return E_UNKNOWN; 04643 } 04644 DOMElement* elemRoot=docConfig->getDocumentElement(); 04645 04646 /* Initialize Mixinfo DOM structure so that neccessary 04647 * option can be appended to it. 04648 */ 04649 DOMElement* elemMix=createDOMElement(m_docMixInfo, MIXINFO_NODE_PARENT); 04650 m_docMixInfo->appendChild(elemMix); 04651 04652 /* invoke all main option setters 04653 * which then invoke their own specific 04654 * option setters 04655 */ 04656 ret = invokeOptionSetters(mainOptionSetters, elemRoot, MAIN_OPTION_SETTERS_NR); 04657 if(ret != E_SUCCESS) 04658 { 04659 return E_UNKNOWN; 04660 } 04661 04662 //Set Software-Version... 04663 DOMElement* elemSoftware=createDOMElement(m_docMixInfo, MIXINFO_NODE_SOFTWARE); 04664 DOMElement* elemVersion=createDOMElement(m_docMixInfo, MIXINFO_NODE_VERSION); 04665 setDOMElementValue(elemVersion,(UINT8*)MIX_VERSION); 04666 elemSoftware->appendChild(elemVersion); 04667 elemMix->appendChild(elemSoftware); 04668 04669 /* Add the payment reminder */ 04670 DOMElement* elemPaymentReminder=createDOMElement(m_docMixInfo, MIXINFO_NODE_PAYMENTREMINDER); 04671 setDOMElementValue(elemPaymentReminder, m_PaymentReminderProbability); 04672 elemMix->appendChild(elemPaymentReminder); 04673 04674 #ifdef COUNTRY_STATS 04675 DOMElement* elemCountryStats=NULL; 04676 getDOMChildByName(elemRoot,"CountryStatsDB",elemCountryStats,false); 04677 UINT8 db_tmp_buff[4096]; 04678 UINT32 db_tmp_buff_len=4096; 04679 if(getDOMElementAttribute(elemCountryStats,"host",db_tmp_buff,&db_tmp_buff_len)==E_SUCCESS) 04680 { 04681 m_dbCountryStatsHost=new char[db_tmp_buff_len+1]; 04682 memcpy(m_dbCountryStatsHost,db_tmp_buff,db_tmp_buff_len); 04683 m_dbCountryStatsHost[db_tmp_buff_len]=0; 04684 } 04685 db_tmp_buff_len=4096; 04686 if(getDOMElementAttribute(elemCountryStats,"user",db_tmp_buff,&db_tmp_buff_len)==E_SUCCESS) 04687 { 04688 m_dbCountryStatsUser=new char[db_tmp_buff_len+1]; 04689 memcpy(m_dbCountryStatsUser,db_tmp_buff,db_tmp_buff_len); 04690 m_dbCountryStatsUser[db_tmp_buff_len]=0; 04691 } 04692 db_tmp_buff_len=4096; 04693 if(getDOMElementAttribute(elemCountryStats,"passwd",db_tmp_buff,&db_tmp_buff_len)==E_SUCCESS) 04694 { 04695 m_dbCountryStatsPasswd=new char[db_tmp_buff_len+1]; 04696 memcpy(m_dbCountryStatsPasswd,db_tmp_buff,db_tmp_buff_len); 04697 m_dbCountryStatsPasswd[db_tmp_buff_len]=0; 04698 } 04699 #endif 04700 04701 DOMElement* elemCascade; 04702 SINT32 haveCascade = getDOMChildByName(elemRoot,"MixCascade",elemCascade,false); 04703 04704 #ifndef DYNAMIC_MIX 04705 /* LERNGRUPPE: This is no error in the fully dynamic model */ 04706 if(isLastMix() && haveCascade != E_SUCCESS && !hasPrevMixTestCertificate() && !verifyMixCertificates()) 04707 { 04708 CAMsg::printMsg(LOG_CRIT,"Error in configuration: You must either specify cascade info or the previous mix's certificate.\n"); 04709 return E_UNKNOWN; 04710 } 04711 #endif 04712 if(isLastMix() && haveCascade == E_SUCCESS) 04713 { 04714 getDOMChildByName(elemRoot,"MixCascade",m_pCascadeXML,false); 04715 04716 DOMNodeList* nl = getElementsByTagName(m_pCascadeXML,"Mix"); 04717 UINT16 len = (UINT16)nl->getLength(); 04718 if(len == 0) 04719 { 04720 CAMsg::printMsg(LOG_CRIT,"Error in configuration: Empty cascade specified.\n"); 04721 return E_UNKNOWN; 04722 } 04723 } 04724 #ifdef DATA_RETENTION_LOG 04725 DOMElement* elemDataRetention=NULL; 04726 getDOMChildByName(elemRoot,"DataRetention",elemDataRetention,false); 04727 DOMElement* elemDataRetentionLogDir=NULL; 04728 getDOMChildByName(elemDataRetention,"LogDir",elemDataRetentionLogDir,false); 04729 UINT8 log_dir[4096]; 04730 UINT32 log_dir_len=4096; 04731 if(getDOMElementValue(elemDataRetentionLogDir,log_dir,&log_dir_len)==E_SUCCESS) 04732 { 04733 m_strDataRetentionLogDir=new UINT8[log_dir_len+1]; 04734 memcpy(m_strDataRetentionLogDir,log_dir,log_dir_len); 04735 m_strDataRetentionLogDir[log_dir_len]=0; 04736 } 04737 CAMsg::printMsg(LOG_CRIT,"Data retention log dir in config file: %s\n",log_dir); 04738 04739 this->m_pDataRetentionPublicEncryptionKey=new CAASymCipher(); 04740 DOMElement* elemDataRetentionPublicKey=NULL; 04741 getDOMChildByName(elemDataRetention,"PublicEncryptionKey",elemDataRetentionPublicKey,false); 04742 DOMElement* elemDataRetentionPublicRSAKey=NULL; 04743 getDOMChildByName(elemDataRetentionPublicKey,"RSAKeyValue",elemDataRetentionPublicRSAKey,false); 04744 m_pDataRetentionPublicEncryptionKey->setPublicKeyAsDOMNode(elemDataRetentionPublicRSAKey); 04745 04746 //Add info to MixInfo structure... 04747 elemDataRetention=createDOMElement(m_docMixInfo, "DataRetention"); 04748 elemMix->appendChild(elemDataRetention); 04749 DOMElement* elemLoggedElements=createDOMElement(m_docMixInfo,"LoggedElements"); 04750 elemDataRetention->appendChild(elemLoggedElements); 04751 DOMElement* elemTemp=createDOMElement(m_docMixInfo,"InputTime"); 04752 elemLoggedElements->appendChild(elemTemp); 04753 setDOMElementValue(elemTemp,true); 04754 elemTemp=createDOMElement(m_docMixInfo,"OutputTime"); 04755 elemLoggedElements->appendChild(elemTemp); 04756 setDOMElementValue(elemTemp,true); 04757 elemTemp=createDOMElement(m_docMixInfo,"InputChannelID"); 04758 elemLoggedElements->appendChild(elemTemp); 04759 setDOMElementValue(elemTemp,true); 04760 elemTemp=createDOMElement(m_docMixInfo,"OutputChannelID"); 04761 elemLoggedElements->appendChild(elemTemp); 04762 setDOMElementValue(elemTemp,true); 04763 elemTemp=createDOMElement(m_docMixInfo,"InputSourceIPAddress"); 04764 elemLoggedElements->appendChild(elemTemp); 04765 setDOMElementValue(elemTemp,true); 04766 elemTemp=createDOMElement(m_docMixInfo,"OutputSourceIPAddress"); 04767 elemLoggedElements->appendChild(elemTemp); 04768 setDOMElementValue(elemTemp,true); 04769 elemTemp=createDOMElement(m_docMixInfo,"InputSourceIPPort"); 04770 elemLoggedElements->appendChild(elemTemp); 04771 setDOMElementValue(elemTemp,true); 04772 elemTemp=createDOMElement(m_docMixInfo,"OutputSourceIPPort"); 04773 elemLoggedElements->appendChild(elemTemp); 04774 setDOMElementValue(elemTemp,true); 04775 elemTemp=createDOMElement(m_docMixInfo,"RetentionPeriod"); 04776 elemDataRetention->appendChild(elemTemp); 04777 setDOMElementValue(elemTemp,(UINT8*)"P6M"); 04778 #endif //DATA_RETENTION_LOG 04779 04780 return E_SUCCESS; 04781 } 04782 #endif //ONLY_LOCAL_PROXY 04783 04784 #ifndef ONLY_LOCAL_PROXY 04785 04793 SINT32 CACmdLnOptions::parseInfoServices(DOMElement* a_infoServiceNode) 04794 { 04795 DOMElement* elemAllowReconfig; 04796 getDOMChildByName(a_infoServiceNode, OPTIONS_NODE_ALLOW_AUTO_CONF, elemAllowReconfig, false); 04797 DOMNodeList* isList = getElementsByTagName(a_infoServiceNode, OPTIONS_NODE_INFOSERVICE); 04798 /* If there are no InfoServices in the file, keep the (hopefully) previously configured InfoServices */ 04799 if(isList->getLength() == 0) 04800 { 04801 return E_SUCCESS; 04802 } 04803 /* If there are already InfoServices, delete them */ 04805 if(m_addrInfoServices!=NULL) 04806 { 04807 for(UINT32 i=0;i<m_addrInfoServicesSize;i++) 04808 { 04809 delete m_addrInfoServices[i]; 04810 m_addrInfoServices[i] = NULL; 04811 } 04812 delete[] m_addrInfoServices; 04813 } 04814 m_addrInfoServicesSize=0; 04815 m_addrInfoServices=NULL; 04816 04817 UINT32 nrListenerInterfaces; 04818 m_addrInfoServices = new CAListenerInterface*[isList->getLength()]; 04819 CAListenerInterface** isListenerInterfaces; 04820 for (UINT32 i = 0; i < isList->getLength(); i++) 04821 { 04822 //get ListenerInterfaces 04823 DOMElement* elemListenerInterfaces; 04824 getDOMChildByName(isList->item(i),CAListenerInterface::XML_ELEMENT_CONTAINER_NAME,elemListenerInterfaces,false); 04825 isListenerInterfaces = CAListenerInterface::getInstance(elemListenerInterfaces, nrListenerInterfaces); 04826 if (nrListenerInterfaces > 0) 04827 { 04829 m_addrInfoServices[m_addrInfoServicesSize] = isListenerInterfaces[0]; 04830 m_addrInfoServicesSize++; 04831 for (UINT32 j = 1; j < nrListenerInterfaces; j++) 04832 { 04833 // the other interfaces are not needed... 04834 delete isListenerInterfaces[j]; 04835 isListenerInterfaces[j] = NULL; 04836 } 04837 } 04838 } 04839 UINT8 tmpBuff[255]; 04840 UINT32 tmpLen=255; 04841 if(getDOMElementValue(elemAllowReconfig,tmpBuff,&tmpLen)==E_SUCCESS) 04842 { 04843 m_bAcceptReconfiguration = (strcmp("True",(char*)tmpBuff) == 0); 04844 } 04845 04846 return E_SUCCESS; 04847 } 04848 04849 04853 SINT32 CACmdLnOptions::createMixOnCDConfiguration(const UINT8* strFileName) 04854 { 04855 XERCES_CPP_NAMESPACE::DOMDocument* doc = createDOMDocument(); 04856 //Neasty but cool... 04857 bool bForLast=false; 04858 if(strFileName!=NULL&&strncmp((char*)strFileName,"last",4)==0) 04859 bForLast=true; 04860 buildDefaultConfig(doc,bForLast); 04861 saveToFile(doc, strFileName); 04862 return E_SUCCESS; 04863 } 04864 04870 SINT32 CACmdLnOptions::buildDefaultConfig(XERCES_CPP_NAMESPACE::DOMDocument* doc,bool bForLastMix=false) 04871 { 04872 CASignature* pSignature=new CASignature(); 04873 pSignature->generateSignKey(1024); 04874 DOMElement* elemRoot=createDOMElement(doc,"MixConfiguration"); 04875 doc->appendChild(elemRoot); 04876 setDOMElementAttribute(elemRoot,"version",(UINT8*)"0.5"); 04877 DOMElement* elemGeneral=createDOMElement(doc,"General"); 04878 elemRoot->appendChild(elemGeneral); 04879 04883 DOMElement* elemTmp=createDOMElement(doc,"MixType"); 04884 if(bForLastMix) 04885 setDOMElementValue(elemTmp,(UINT8*)"LastMix"); 04886 else 04887 setDOMElementValue(elemTmp,(UINT8*)"FirstMix"); 04888 elemGeneral->appendChild(elemTmp); 04889 04891 elemTmp=createDOMElement(doc,"MixID"); 04892 CACertificate* pCert; 04893 pSignature->getVerifyKey(&pCert); 04894 UINT8 buf[255]; 04895 UINT32 len = 255; 04896 pCert->getSubjectKeyIdentifier( buf, &len); 04897 setDOMElementValue(elemTmp,buf); 04898 elemGeneral->appendChild(elemTmp); 04899 elemTmp=createDOMElement(doc,"Dynamic"); 04900 setDOMElementValue(elemTmp,(UINT8*)"True"); 04901 elemGeneral->appendChild(elemTmp); 04902 04903 elemTmp=createDOMElement(doc,"Daemon"); 04904 setDOMElementValue(elemTmp,(UINT8*)"True"); 04905 elemGeneral->appendChild(elemTmp); 04906 04907 elemTmp=createDOMElement(doc,"CascadeName"); 04908 setDOMElementValue(elemTmp,(UINT8*)"Dynamic Cascade"); 04909 elemGeneral->appendChild(elemTmp); 04910 elemTmp=createDOMElement(doc,"MixName"); 04911 setDOMElementValue(elemTmp,(UINT8*)"Dynamic Mix"); 04912 elemGeneral->appendChild(elemTmp); 04913 elemTmp=createDOMElement(doc,"UserID"); 04914 setDOMElementValue(elemTmp,(UINT8*)"mix"); 04915 elemGeneral->appendChild(elemTmp); 04916 DOMElement* elemLogging=createDOMElement(doc,"Logging"); 04917 elemGeneral->appendChild(elemLogging); 04918 elemTmp=createDOMElement(doc,"SysLog"); 04919 setDOMElementValue(elemTmp,(UINT8*)"True"); 04920 elemLogging->appendChild(elemTmp); 04921 DOMElement* elemNet=createDOMElement(doc,"Network"); 04922 elemRoot->appendChild(elemNet); 04923 04925 DOMElement*elemISs=createDOMElement(doc,"InfoServices"); 04926 elemNet->appendChild(elemISs); 04927 elemTmp=createDOMElement(doc,"AllowAutoConfiguration"); 04928 setDOMElementValue(elemTmp,(UINT8*)"True"); 04929 elemISs->appendChild(elemTmp); 04930 04931 DOMElement* elemIS=createDOMElement(doc,"InfoService"); 04932 elemISs->appendChild(elemIS); 04933 DOMElement* elemISListeners=createDOMElement(doc,"ListenerInterfaces"); 04934 elemIS->appendChild(elemISListeners); 04935 DOMElement* elemISLi=createDOMElement(doc,"ListenerInterface"); 04936 elemISListeners->appendChild(elemISLi); 04937 elemTmp=createDOMElement(doc,"Host"); 04938 setDOMElementValue(elemTmp,(UINT8*)DEFAULT_INFOSERVICE); 04939 elemISLi->appendChild(elemTmp); 04940 elemTmp=createDOMElement(doc,"Port"); 04941 setDOMElementValue(elemTmp,6543U); 04942 elemISLi->appendChild(elemTmp); 04943 elemTmp=createDOMElement(doc,"AllowAutoConfiguration"); 04944 setDOMElementValue(elemTmp,(UINT8*)"True"); 04945 elemISs->appendChild(elemTmp); 04946 04948 /* DOM_Element elemListeners=doc.createElement("ListenerInterfaces"); 04949 elemNet.appendChild(elemListeners); 04950 DOM_Element elemListener=doc.createElement("ListenerInterface"); 04951 elemListeners.appendChild(elemListener); 04952 elemTmp=doc.createElement("Port"); 04953 setDOMElementValue(elemTmp,6544U); 04954 elemListener.appendChild(elemTmp); 04955 elemTmp=doc.createElement("NetworkProtocol"); 04956 setDOMElementValue(elemTmp,(UINT8*)"RAW/TCP"); 04957 elemListener.appendChild(elemTmp); 04958 */ 04959 if(bForLastMix) 04960 { 04961 DOMElement* elemProxies=createDOMElement(doc,"Proxies"); 04962 DOMElement* elemProxy=createDOMElement(doc,"Proxy"); 04963 elemProxies->appendChild(elemProxy); 04964 elemTmp=createDOMElement(doc,"ProxyType"); 04965 setDOMElementValue(elemTmp,(UINT8*)"HTTP"); 04966 elemProxy->appendChild(elemTmp); 04967 elemTmp=createDOMElement(doc,"Host"); 04968 setDOMElementValue(elemTmp,(UINT8*)"127.0.0.1"); 04969 elemProxy->appendChild(elemTmp); 04970 elemTmp=createDOMElement(doc,"Port"); 04971 setDOMElementValue(elemTmp,3128U); 04972 elemProxy->appendChild(elemTmp); 04973 elemTmp=createDOMElement(doc,"NetworkProtocol"); 04974 setDOMElementValue(elemTmp,(UINT8*)"RAW/TCP"); 04975 elemProxy->appendChild(elemTmp); 04976 elemNet->appendChild(elemProxies); 04977 } 04978 DOMElement* elemCerts=createDOMElement(doc,"Certificates"); 04979 elemRoot->appendChild(elemCerts); 04980 DOMElement* elemOwnCert=createDOMElement(doc,"OwnCertificate"); 04981 elemCerts->appendChild(elemOwnCert); 04982 DOMElement* tmpElemSigKey=NULL; 04983 pSignature->getSignKey(tmpElemSigKey,doc); 04984 elemOwnCert->appendChild(tmpElemSigKey); 04985 04986 DOMElement* elemTmpCert=NULL; 04987 pCert->encode(elemTmpCert,doc); 04988 elemOwnCert->appendChild(elemTmpCert); 04989 04991 delete pCert; 04992 pCert = NULL; 04993 delete pSignature; 04994 pSignature = NULL; 04995 return E_SUCCESS; 04996 } 04997 05004 SINT32 CACmdLnOptions::saveToFile(XERCES_CPP_NAMESPACE::DOMDocument* p_doc, const UINT8* p_strFileName) 05005 { 05007 UINT32 len; 05008 UINT8* buff = DOM_Output::dumpToMem(p_doc,&len); 05009 if(p_strFileName!=NULL) 05010 { 05011 FILE *handle; 05012 handle=fopen((const char*)p_strFileName, "w"); 05013 fwrite(buff,len,1,handle); 05014 fflush(handle); 05015 fclose(handle); 05016 } 05017 else 05018 { 05019 fwrite(buff,len,1,stdout); 05020 fflush(stdout); 05021 } 05022 delete[] buff; 05023 buff = NULL; 05024 return E_SUCCESS; 05025 } 05026 05027 05028 #ifdef DYNAMIC_MIX 05029 05037 SINT32 CACmdLnOptions::createDefaultConfiguration() 05038 { 05039 m_docMixXml = DOM_Document::createDocument(); 05040 buildDefaultConfig(m_docMixXml); 05041 saveToFile(m_docMixXml, (const UINT8*)DEFAULT_CONFIG_FILE); 05042 05043 char *configfile = (char*) malloc(sizeof(char) * (strlen(DEFAULT_CONFIG_FILE))); 05044 strcpy(configfile, DEFAULT_CONFIG_FILE); 05045 05046 // Set default config file for possible reread attempt 05047 m_strConfigFile=new UINT8[ strlen(DEFAULT_CONFIG_FILE)+1 ]; 05048 memcpy(m_strConfigFile,DEFAULT_CONFIG_FILE, strlen(DEFAULT_CONFIG_FILE)+1); 05049 return E_SUCCESS; 05050 } 05051 05058 SINT32 CACmdLnOptions::addListenerInterface(DOM_Element a_elem) 05059 { 05060 CAListenerInterface *pListener = CAListenerInterface::getInstance(a_elem); 05061 if(pListener == NULL) 05062 return E_UNKNOWN; 05063 05064 if(m_arListenerInterfaces != NULL && m_cnListenerInterfaces > 0) 05065 { 05066 CAListenerInterface **tmp = new CAListenerInterface*[m_cnListenerInterfaces + 1]; 05067 for(unsigned int i = 0; i < m_cnListenerInterfaces; i++) 05068 { 05069 tmp[i] = m_arListenerInterfaces[i]; 05070 } 05071 delete[] m_arListenerInterfaces; 05072 m_arListenerInterfaces=NULL; 05073 m_arListenerInterfaces = tmp; 05074 m_cnListenerInterfaces++; 05075 } 05076 else 05077 { 05078 m_arListenerInterfaces = new CAListenerInterface*[1]; 05079 m_cnListenerInterfaces = 1; 05080 } 05081 05082 m_arListenerInterfaces[m_cnListenerInterfaces-1] = pListener; 05083 return E_SUCCESS; 05084 05085 } 05086 05092 SINT32 CACmdLnOptions::resetNetworkConfiguration() 05093 { 05094 DOM_Element elemRoot = m_docMixInfo.getDocumentElement(); 05095 if(elemRoot != NULL) 05096 { 05097 DOM_Element elemListeners; 05098 getDOMChildByName(elemRoot,(UINT8*)"ListenerInterfaces",elemListeners,false); 05099 if(elemListeners != NULL) 05100 { 05101 elemRoot.removeChild( elemListeners ); 05102 } 05103 } 05104 clearListenerInterfaces(); 05105 return E_SUCCESS; 05106 } 05107 05114 SINT32 CACmdLnOptions::checkListenerInterfaces() 05115 { 05116 SINT32 result = E_UNKNOWN; 05117 05118 UINT32 interfaces = getListenerInterfaceCount(); 05119 CAListenerInterface *pListener = NULL; 05120 CADynaNetworking *dyn = new CADynaNetworking(); 05121 05122 for( UINT32 i = 1; i <= interfaces; i++ ) 05123 { 05124 pListener = getListenerInterface(i); 05125 if(!pListener->isVirtual()) 05126 { 05127 result = E_SUCCESS; 05128 break; 05129 } 05130 delete pListener; 05131 pListener=NULL; 05132 } 05133 if( pListener == NULL ) 05134 { 05136 result = dyn->updateNetworkConfiguration(DEFAULT_TARGET_PORT); 05137 if( result != E_SUCCESS ) 05138 goto error; 05139 } 05140 if( dyn->verifyConnectivity() != E_SUCCESS ) 05141 { 05142 CAMsg::printMsg( LOG_CRIT, "Your mix is not reachable from the internet.\n Please make sure that your open port %i in your firewall and forward this port to this machine.\n", DEFAULT_TARGET_PORT); 05143 result = E_UNKNOWN; 05144 } 05145 error: 05146 delete dyn; 05147 dyn = NULL; 05148 return result; 05149 } 05150 05159 SINT32 CACmdLnOptions::checkInfoServices(UINT32 *r_runningInfoServices) 05160 { 05161 UINT32 i; 05162 *r_runningInfoServices = 0; 05163 if(m_addrInfoServicesSize == 0 ) // WTH? 05164 return E_UNKNOWN; 05165 05167 for(i = 0; i < m_addrInfoServicesSize; i++) 05168 { 05169 CASocket socket; 05170 socket.setSendTimeOut(1000); 05171 if(socket.connect( *m_addrInfoServices[i]->getAddr() )== E_SUCCESS ) 05172 { 05173 (*r_runningInfoServices)++; 05174 } 05175 socket.close(); 05176 } 05177 if((*r_runningInfoServices) < MIN_INFOSERVICES) 05178 return E_UNKNOWN; 05179 return E_SUCCESS; 05180 } 05181 05187 SINT32 CACmdLnOptions::checkCertificates() 05188 { 05192 return E_SUCCESS; 05193 } 05194 05201 SINT32 CACmdLnOptions::checkMixId() 05202 { 05203 UINT8 ski[255]; 05204 UINT32 len = 255; 05205 if( m_pOwnCertificate->getSubjectKeyIdentifier( ski, &len ) != E_SUCCESS ) 05206 return E_UNKNOWN; 05207 05208 CAMsg::printMsg( LOG_DEBUG, "\nID : (%s)\n SKI: (%s)\n", m_strMixID, ski); 05209 if( strcmp( (const char*)m_strMixID, (const char*)ski ) != 0 ) 05210 return E_UNKNOWN; 05211 return E_SUCCESS; 05212 } 05213 05221 SINT32 CACmdLnOptions::getRandomInfoService(CASocketAddrINet *&r_address) 05222 { 05223 UINT32 nrAddresses; 05224 CAListenerInterface** socketAddresses = pglobalOptions->getInfoServices(nrAddresses); 05225 if( socketAddresses == NULL ) 05226 { 05227 CAMsg::printMsg( LOG_ERR, "Unable to get a list of InfoServices from the options, check your configuration!\n"); 05228 return E_UNKNOWN; 05229 } 05230 UINT32 index = getRandom(nrAddresses); 05231 // Search for a runnung infoservice from the random index on overlapping at nrAddresses 05232 UINT32 i = (index+1) % nrAddresses; 05233 while(true) 05234 { 05235 CASocket socket; 05236 socket.setSendTimeOut(1000); 05237 r_address = (CASocketAddrINet*)m_addrInfoServices[i]->getAddr(); 05238 if(socket.connect( *r_address )== E_SUCCESS ) 05239 { 05240 #ifdef DEBUG 05241 UINT8 buf[2048]; 05242 UINT32 len=2047; 05243 r_address->getHostName( buf, len ); 05244 CAMsg::printMsg( LOG_DEBUG, "getRandomInfoService: Chose InfoService server %s:%i\n", buf, r_address->getPort()); 05245 #endif 05246 socket.close(); 05247 return E_SUCCESS; 05248 } 05249 else 05250 { 05251 socket.close(); 05252 delete r_address; 05253 r_address = NULL; 05254 } 05255 if(i == index) break; 05256 i = (i+1) % nrAddresses; 05257 } 05258 return E_UNKNOWN; 05259 } 05260 05266 UINT32 CACmdLnOptions::getRandom(UINT32 a_max) 05267 { 05268 UINT32 result = (UINT32) (a_max * (rand() / (RAND_MAX + 1.0))); 05269 return result; 05270 } 05271 05280 SINT32 CACmdLnOptions::changeMixType(CAMix::tMixType a_newMixType) 05281 { 05282 if( a_newMixType == CAMix::LAST_MIX ) 05283 { 05284 CAMsg::printMsg( LOG_ERR,"Trying to reconfigure a dynamic mix to LastMix, that is evil!\n"); 05285 return E_UNKNOWN; 05286 } 05287 05288 if( a_newMixType == CAMix::MIDDLE_MIX && isFirstMix()) 05289 { 05290 CAMsg::printMsg( LOG_DEBUG,"Reconfiguring a FirstMix to MiddleMix.\n"); 05291 m_bFirstMix = false; 05292 m_bMiddleMix = true; 05293 DOM_Element elemRoot = m_docMixInfo.getDocumentElement(); 05294 if(elemRoot != NULL) 05295 { 05296 DOM_Element elemMixType; 05297 getDOMChildByName(elemRoot,(UINT8*)"MixType",elemMixType,false); 05298 if(elemMixType != NULL) 05299 { 05300 setDOMElementValue(elemMixType,(UINT8*)"MiddleMix"); 05301 } 05302 } 05303 } 05304 else if( a_newMixType == CAMix::FIRST_MIX && isMiddleMix()) 05305 { 05306 CAMsg::printMsg( LOG_DEBUG,"Reconfiguring a MiddleMix to FirstMix.\n"); 05307 m_bFirstMix = true; 05308 m_bMiddleMix = false; 05309 DOM_Element elemRoot = m_docMixInfo.getDocumentElement(); 05310 if(elemRoot != NULL) 05311 { 05312 DOM_Element elemMixType; 05313 getDOMChildByName(elemRoot,(UINT8*)"MixType",elemMixType,false); 05314 if(elemMixType != NULL) 05315 { 05316 setDOMElementValue(elemMixType,(UINT8*)"FirstMix"); 05317 } 05318 } 05319 } 05320 else 05321 { 05322 CAMsg::printMsg( LOG_ERR, "Error reconfiguring the mix, some strange combination of existing and new type happened\n"); 05323 return E_UNKNOWN; 05324 } 05325 return E_SUCCESS; 05326 } 05327 05328 #endif //DYNAMIC_MIX 05329 05330 #ifdef COUNTRY_STATS 05331 SINT32 CACmdLnOptions::getCountryStatsDBConnectionLoginData(char** db_host,char**db_user,char**db_passwd) 05332 { 05333 *db_host=*db_user=*db_passwd=NULL; 05334 if(m_dbCountryStatsHost!=NULL) 05335 { 05336 *db_host=new char[strlen(m_dbCountryStatsHost)+1]; 05337 strcpy(*db_host,m_dbCountryStatsHost); 05338 } 05339 if(m_dbCountryStatsUser!=NULL) 05340 { 05341 *db_user=new char[strlen(m_dbCountryStatsUser)+1]; 05342 strcpy(*db_user,m_dbCountryStatsUser); 05343 } 05344 if(m_dbCountryStatsPasswd!=NULL) 05345 { 05346 *db_passwd=new char[strlen(m_dbCountryStatsPasswd)+1]; 05347 strcpy(*db_passwd,m_dbCountryStatsPasswd); 05348 } 05349 return E_SUCCESS; 05350 } 05351 #endif 05352 05353 #ifdef DATA_RETENTION_LOG 05354 SINT32 CACmdLnOptions::getDataRetentionLogDir(UINT8* strLogDir,UINT32 len) 05355 { 05356 if(strLogDir==NULL||m_strDataRetentionLogDir==NULL) 05357 return E_UNKNOWN; 05358 if(len<=(UINT32)strlen((char*)m_strDataRetentionLogDir)) 05359 { 05360 return E_UNKNOWN; 05361 } 05362 strcpy((char*)strLogDir,(char*)m_strDataRetentionLogDir); 05363 return E_SUCCESS; 05364 } 05365 #endif// DATA_RETENTION_LOG 05366 05367 #endif //ONLY_LOCAL_PROXY
1.7.6.1