00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
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 "CASocket.hpp"
00036 #include "CAXMLBI.hpp"
00037 #include "xml/DOM_Output.hpp"
00038 #include "CABase64.hpp"
00039 #include "CADynaNetworking.hpp"
00040 #ifdef PAYMENT
00041 #include "CAAccountingDBInterface.hpp"
00042 #endif
00043
00044 #include "tre/regex.h"
00045
00046
00047 CACmdLnOptions::CACmdLnOptions()
00048 {
00049 m_bDaemon=false;
00050 m_bSyslog=false;
00051 m_bLogConsole = false;
00052 m_bSocksSupport = false;
00053 m_bLocalProxy=m_bFirstMix=m_bLastMix=m_bMiddleMix=false;
00054 #ifndef ONLY_LOCAL_PROXY
00055 m_bIsRunReConfigure=false;
00056 m_addrInfoServices = NULL;
00057 m_addrInfoServicesSize=0;
00058 m_pcsReConfigure=new CAMutex();
00059
00060
00061 m_OpCert=NULL;
00062 m_pMultiSignature=NULL;
00063 m_pPrevMixCertificate=NULL;
00064 m_pNextMixCertificate=NULL;
00065 m_pTrustedRootCertificates=NULL;
00066 m_bVerifyMixCerts=false;
00067 m_bCompressedLogs=false;
00068 m_pLogEncryptionCertificate=NULL;
00069 m_bIsEncryptedLogEnabled=false;
00070 m_docMixInfo= createDOMDocument();
00071 m_docMixXml=NULL;
00072 m_pCascadeXML=NULL;
00073 m_docOpTnCs=NULL;
00074 m_bAcceptReconfiguration=false;
00075 m_maxNrOfUsers = 0;
00076 #ifdef COUNTRY_STATS
00077 m_dbCountryStatsHost=m_dbCountryStatsPasswd=m_dbCountryStatsUser=NULL;
00078 #endif
00079 #endif //ONLY_LOCAL_PROXY
00080 m_iTargetPort=m_iSOCKSPort=m_iSOCKSServerPort=0xFFFF;
00081 m_strTargetHost=m_strSOCKSHost=NULL;
00082 m_strUser=NULL;
00083 m_strCascadeName=NULL;
00084 m_strLogDir=NULL;
00085 setZero64(m_maxLogFileSize);
00086 m_strEncryptedLogDir=NULL;
00087 m_arTargetInterfaces=NULL;
00088 m_cnTargets=0;
00089 m_arListenerInterfaces=NULL;
00090 m_cnListenerInterfaces=0;
00091 m_arStrVisibleAddresses=NULL;
00092 m_cnVisibleAddresses=0;
00093 m_nrOfOpenFiles=-1;
00094 m_strMixID=NULL;
00095 m_strMixName=NULL;
00096 m_bAutoReconnect=false;
00097 m_strConfigFile=NULL;
00098 m_strPidFile=NULL;
00099 #ifdef PAYMENT
00100 m_pBI=NULL;
00101 m_strDatabaseHost=NULL;
00102 m_strDatabaseName=NULL;
00103 m_strDatabaseUser=NULL;
00104 m_strDatabasePassword=NULL;
00105 m_strAiID=NULL;
00106 #endif
00107 #ifdef SERVER_MONITORING
00108 m_strMonitoringListenerHost = NULL;
00109 m_iMonitoringListenerPort = 0xFFFF;
00110 #endif
00111 m_termsAndConditionsTemplates = NULL;
00112 m_nrOfTermsAndConditionsTemplates = 0;
00113
00114 #ifdef LOG_CRIME
00115 m_logPayload = false;
00116 m_arCrimeRegExpsURL=NULL;
00117 m_nCrimeRegExpsURL=0;
00118 m_arCrimeRegExpsPayload=NULL;
00119 m_nCrimeRegExpsPayload=0;
00120 m_nrOfSurveillanceIPs = 0;
00121 m_surveillanceIPs = NULL;
00122 m_nrOfSurveillanceAccounts = 0;
00123 m_surveillanceAccounts = NULL;
00124 #endif
00125
00126 #ifdef DATA_RETENTION_LOG
00127 m_strDataRetentionLogDir=NULL;
00128 #endif
00129
00130 #ifdef DYNAMIC_MIX
00131 m_strLastCascadeProposal = NULL;
00132 #endif
00133
00134 #if defined(DELAY_CHANNELS) && defined(DELAY_USERS)
00135 if(isFirstMix())
00136 {
00137 m_u32DelayChannelUnlimitTraffic=DELAY_USERS_TRAFFIC;
00138 m_u32DelayChannelBucketGrow=DELAY_USERS_BUCKET_GROW;
00139 m_u32DelayChannelBucketGrowIntervall=DELAY_USERS_BUCKET_GROW_INTERVALL;
00140 }
00141 else
00142 {
00143 m_u32DelayChannelUnlimitTraffic=DELAY_CHANNEL_TRAFFIC;
00144 m_u32DelayChannelBucketGrow=DELAY_BUCKET_GROW;
00145 m_u32DelayChannelBucketGrowIntervall=DELAY_BUCKET_GROW_INTERVALL;
00146 }
00147 #elif defined(DELAY_CHANNELS)
00148 m_u32DelayChannelUnlimitTraffic=DELAY_CHANNEL_TRAFFIC;
00149 m_u32DelayChannelBucketGrow=DELAY_BUCKET_GROW;
00150 m_u32DelayChannelBucketGrowIntervall=DELAY_BUCKET_GROW_INTERVALL;
00151 #elif defined (DELAY_USERS)
00152 m_u32DelayChannelUnlimitTraffic=DELAY_USERS_TRAFFIC;
00153 m_u32DelayChannelBucketGrow=DELAY_USERS_BUCKET_GROW;
00154 m_u32DelayChannelBucketGrowIntervall=DELAY_USERS_BUCKET_GROW_INTERVALL;
00155 #endif
00156
00157 #if defined(DELAY_CHANNELS_LATENCY)
00158 m_u32DelayChannelLatency = DELAY_CHANNEL_LATENCY;
00159 #endif
00160
00161
00162 initMainOptionSetters();
00163 initGeneralOptionSetters();
00164 initCertificateOptionSetters();
00165 initAccountingOptionSetters();
00166 initNetworkOptionSetters();
00167 initTermsAndConditionsOptionSetters();
00168 initCrimeDetectionOptionSetters();
00169 }
00170
00171 CACmdLnOptions::~CACmdLnOptions()
00172 {
00173 cleanup();
00174 }
00175
00176 void CACmdLnOptions::initMainOptionSetters()
00177 {
00178 mainOptionSetters = new optionSetter_pt[MAIN_OPTION_SETTERS_NR];
00179 int count = -1;
00180
00181 mainOptionSetters[++count]=
00182 &CACmdLnOptions::setGeneralOptions;
00183 mainOptionSetters[++count]=
00184 &CACmdLnOptions::setMixDescription;
00185 mainOptionSetters[++count]=
00186 &CACmdLnOptions::setCertificateOptions;
00187 mainOptionSetters[++count]=
00188 &CACmdLnOptions::setAccountingOptions;
00189 mainOptionSetters[++count]=
00190 &CACmdLnOptions::setNetworkOptions;
00191 mainOptionSetters[++count]=
00192 &CACmdLnOptions::setRessourceOptions;
00193 mainOptionSetters[++count]=
00194 &CACmdLnOptions::setTermsAndConditions;
00195 mainOptionSetters[++count]=
00196 &CACmdLnOptions::setCrimeDetectionOptions;
00197 }
00198
00199 void CACmdLnOptions::initGeneralOptionSetters()
00200 {
00201 generalOptionSetters = new optionSetter_pt[GENERAL_OPTIONS_NR];
00202 int count = -1;
00203
00204 generalOptionSetters[++count]=
00205 &CACmdLnOptions::setDaemonMode;
00206 generalOptionSetters[++count]=
00207 &CACmdLnOptions::setNrOfFileDescriptors;
00208 generalOptionSetters[++count]=
00209 &CACmdLnOptions::setUserID;
00210 generalOptionSetters[++count]=
00211 &CACmdLnOptions::setLoggingOptions;
00212 generalOptionSetters[++count]=
00213 &CACmdLnOptions::setMixType;
00214 generalOptionSetters[++count]=
00215 &CACmdLnOptions::setMixName;
00216 generalOptionSetters[++count]=
00217 &CACmdLnOptions::setMixID;
00218 generalOptionSetters[++count]=
00219 &CACmdLnOptions::setDynamicMix;
00220 generalOptionSetters[++count]=
00221 &CACmdLnOptions::setMinCascadeLength;
00222 generalOptionSetters[++count]=
00223 &CACmdLnOptions::setCascadeNameFromOptions;
00224
00225 generalOptionSetters[++count]=
00226 &CACmdLnOptions::setMaxUsers;
00227 }
00228
00229 void CACmdLnOptions::initCertificateOptionSetters()
00230 {
00231 certificateOptionSetters = new optionSetter_pt[MAX_CERTIFICATE_OPTIONS_NR];
00232 m_nCertificateOptionsSetters = 0;
00233
00234 certificateOptionSetters[m_nCertificateOptionsSetters++]=&CACmdLnOptions::setOwnOperatorCertificate;
00235 certificateOptionSetters[m_nCertificateOptionsSetters++]=&CACmdLnOptions::setOwnCertificate;
00236 certificateOptionSetters[m_nCertificateOptionsSetters++]=&CACmdLnOptions::setNextMixCertificate;
00237 certificateOptionSetters[m_nCertificateOptionsSetters++]=&CACmdLnOptions::setPrevMixCertificate;
00238 }
00239
00240 void CACmdLnOptions::initAccountingOptionSetters()
00241 {
00242 accountingOptionSetters = new optionSetter_pt[ACCOUNTING_OPTIONS_NR];
00243 int count = -1;
00244
00245 accountingOptionSetters[++count]=
00246 &CACmdLnOptions::setPaymentInstance;
00247 accountingOptionSetters[++count]=
00248 &CACmdLnOptions::setPriceCertificate;
00249 accountingOptionSetters[++count]=
00250 &CACmdLnOptions::setAccountingSoftLimit;
00251 accountingOptionSetters[++count]=
00252 &CACmdLnOptions::setAccountingHardLimit;
00253 accountingOptionSetters[++count]=
00254 &CACmdLnOptions::setPrepaidInterval;
00255 accountingOptionSetters[++count]=
00256 &CACmdLnOptions::setSettleInterval;
00257 accountingOptionSetters[++count]=
00258 &CACmdLnOptions::setAccountingDatabase;
00259 }
00260
00261 void CACmdLnOptions::initNetworkOptionSetters()
00262 {
00263 networkOptionSetters = new optionSetter_pt[NETWORK_OPTIONS_NR];
00264 int count = -1;
00265
00266 networkOptionSetters[++count]=
00267 &CACmdLnOptions::setInfoServices;
00268 networkOptionSetters[++count]=
00269 &CACmdLnOptions::setListenerInterfaces;
00270 networkOptionSetters[++count]=
00271 &CACmdLnOptions::setTargetInterfaces;
00272 networkOptionSetters[++count]=
00273 &CACmdLnOptions::setServerMonitoring;
00274 networkOptionSetters[++count]=
00275 &CACmdLnOptions::setKeepAliveTraffic;
00276 }
00277
00278 void CACmdLnOptions::initTermsAndConditionsOptionSetters()
00279 {
00280
00281 termsAndConditionsOptionSetters = new optionSetter_pt[TERMS_AND_CONDITIONS_OPTIONS_NR];
00282 int count = -1;
00283
00284 termsAndConditionsOptionSetters[++count]=
00285 &CACmdLnOptions::setTermsAndConditionsTemplates;
00286 termsAndConditionsOptionSetters[++count]=
00287 &CACmdLnOptions::setTermsAndConditionsList;
00288 }
00289
00290 void CACmdLnOptions::initCrimeDetectionOptionSetters()
00291 {
00292 crimeDetectionOptionSetters = new optionSetter_pt[CRIME_DETECTION_OPTIONS_NR];
00293 int count = -1;
00294
00295 crimeDetectionOptionSetters[++count]=
00296 &CACmdLnOptions::setCrimeURLRegExp;
00297 crimeDetectionOptionSetters[++count]=
00298 &CACmdLnOptions::setCrimePayloadRegExp;
00299 crimeDetectionOptionSetters[++count]=
00300 &CACmdLnOptions::setCrimeSurveillanceAccounts;
00301 crimeDetectionOptionSetters[++count]=
00302 &CACmdLnOptions::setCrimeSurveillanceIP;
00303 }
00306 SINT32 CACmdLnOptions::cleanup()
00307 {
00308 clean();
00309 #ifndef ONLY_LOCAL_PROXY
00310 delete m_pcsReConfigure;
00311 m_pcsReConfigure=NULL;
00312 #endif
00313 return E_SUCCESS;
00314 }
00315
00318 SINT32 CACmdLnOptions::clearTargetInterfaces()
00319 {
00320 if(m_arTargetInterfaces!=NULL)
00321 {
00322 for(UINT32 i=0;i<m_cnTargets;i++)
00323 {
00324 delete m_arTargetInterfaces[i].addr;
00325 m_arTargetInterfaces[i].addr = NULL;
00326 }
00327 delete[] m_arTargetInterfaces;
00328 m_arTargetInterfaces = NULL;
00329 }
00330 m_cnTargets=0;
00331 m_arTargetInterfaces=NULL;
00332 return E_SUCCESS;
00333 }
00334
00337 SINT32 CACmdLnOptions::clearListenerInterfaces()
00338 {
00339 if(m_arListenerInterfaces!=NULL)
00340 {
00341 for(UINT32 i=0;i<m_cnListenerInterfaces;i++)
00342 {
00343 delete m_arListenerInterfaces[i];
00344 m_arListenerInterfaces[i] = NULL;
00345 }
00346 delete[] m_arListenerInterfaces;
00347 }
00348 m_cnListenerInterfaces=0;
00349 m_arListenerInterfaces=NULL;
00350 return E_SUCCESS;
00351 }
00352
00353 #ifndef ONLY_LOCAL_PROXY
00354
00356 SINT32 CACmdLnOptions::clearVisibleAddresses()
00357 {
00358 if(m_arStrVisibleAddresses!=NULL)
00359 {
00360 for(UINT32 i=0;i<m_cnVisibleAddresses;i++)
00361 {
00362 delete[] m_arStrVisibleAddresses[i];
00363 m_arStrVisibleAddresses[i] = NULL;
00364 }
00365 delete[] m_arStrVisibleAddresses;
00366 }
00367 m_cnVisibleAddresses=0;
00368 m_arStrVisibleAddresses=NULL;
00369 return E_SUCCESS;
00370 }
00371
00386 SINT32 CACmdLnOptions::addVisibleAddresses(DOMNode* nodeProxy)
00387 {
00388 if(nodeProxy==NULL) return E_UNKNOWN;
00389 ASSERT_PARENT_NODE_NAME
00390 (nodeProxy->getNodeName(), OPTIONS_NODE_PROXY, OPTIONS_NODE_VISIBLE_ADDRESS_LIST);
00391 DOMNode* elemVisAdresses=NULL;
00392 getDOMChildByName(nodeProxy, OPTIONS_NODE_VISIBLE_ADDRESS_LIST, elemVisAdresses);
00393 DOMNode* elemVisAddress=NULL;
00394 getDOMChildByName(elemVisAdresses, OPTIONS_NODE_VISIBLE_ADDRESS ,elemVisAddress);
00395 while(elemVisAddress!=NULL)
00396 {
00397 if(equals(elemVisAddress->getNodeName(), OPTIONS_NODE_VISIBLE_ADDRESS))
00398 {
00399 DOMElement* elemHost;
00400 if(getDOMChildByName(elemVisAddress, OPTIONS_NODE_HOST ,elemHost)==E_SUCCESS)
00401 {
00402 UINT8 tmp[TMP_BUFF_SIZE];
00403 UINT32 len = TMP_BUFF_SIZE;
00404 if(getDOMElementValue(elemHost,tmp,&len)==E_SUCCESS)
00405 {
00406 UINT8** tmpAr=new UINT8*[m_cnVisibleAddresses+1];
00407 if(m_arStrVisibleAddresses!=NULL)
00408 {
00409 memcpy(tmpAr,m_arStrVisibleAddresses,m_cnVisibleAddresses*sizeof(UINT8*));
00410 delete[] m_arStrVisibleAddresses;
00411 m_arStrVisibleAddresses = NULL;
00412 }
00413 tmpAr[m_cnVisibleAddresses]=new UINT8[len+1];
00414 memcpy(tmpAr[m_cnVisibleAddresses],tmp,len+1);
00415 m_cnVisibleAddresses++;
00416 m_arStrVisibleAddresses=tmpAr;
00417 }
00418 }
00419 }
00420 elemVisAddress=elemVisAddress->getNextSibling();
00421 }
00422 return E_SUCCESS;
00423 }
00424
00425 SINT32 CACmdLnOptions::getVisibleAddress(UINT8* strAddressBuff, UINT32 len,UINT32 nr)
00426 {
00427 if(strAddressBuff==NULL||nr==0||nr>m_cnVisibleAddresses)
00428 {
00429 return E_UNKNOWN;
00430 }
00431 if(strlen((char*)m_arStrVisibleAddresses[nr-1] )>=len)
00432 {
00433 return E_SPACE;
00434 }
00435 strcpy((char*)strAddressBuff,(char*)m_arStrVisibleAddresses[nr-1]);
00436 return E_SUCCESS;
00437 }
00438 #endif //ONLY_LOCAL_PROXY
00439
00441 void CACmdLnOptions::clean()
00442 {
00443 delete[] m_strConfigFile;
00444 m_strConfigFile=NULL;
00445
00446 delete[] m_strTargetHost;
00447 m_strTargetHost=NULL;
00448
00449 delete[] m_strSOCKSHost;
00450 m_strSOCKSHost=NULL;
00451
00452 #ifndef ONLY_LOCAL_PROXY
00453 if (m_addrInfoServices != NULL)
00454 {
00455 for (UINT32 i = 0; i < m_addrInfoServicesSize; i++)
00456 {
00457 delete m_addrInfoServices[i];
00458 m_addrInfoServices[i] = NULL;
00459 }
00460 delete[] m_addrInfoServices;
00461 m_addrInfoServices=NULL;
00462 m_addrInfoServicesSize = 0;
00463 }
00464 #endif //ONLY_LOCAL_PROXY
00465
00466
00467 delete[] m_strCascadeName;
00468 m_strCascadeName=NULL;
00469
00470 delete[] m_strLogDir;
00471 m_strLogDir=NULL;
00472
00473 delete[] m_strPidFile;
00474 m_strPidFile=NULL;
00475
00476 delete[] m_strEncryptedLogDir;
00477 m_strEncryptedLogDir=NULL;
00478
00479 delete[] m_strUser;
00480 m_strUser=NULL;
00481
00482 delete[] m_strMixID;
00483 m_strMixID=NULL;
00484
00485 delete[] m_strMixName;
00486 m_strMixName=NULL;
00487
00488 clearTargetInterfaces();
00489 clearListenerInterfaces();
00490 #ifndef ONLY_LOCAL_PROXY
00491 if(m_docMixInfo!=NULL)
00492 m_docMixInfo=NULL;
00493 clearVisibleAddresses();
00494
00495
00496
00497
00498
00499
00500
00501 delete m_pMultiSignature;
00502 m_pMultiSignature = NULL;
00503
00504 delete m_OpCert;
00505 m_OpCert=NULL;
00506
00507 delete m_pNextMixCertificate;
00508 m_pNextMixCertificate=NULL;
00509
00510 delete m_pPrevMixCertificate;
00511 m_pPrevMixCertificate=NULL;
00512
00513 delete m_pLogEncryptionCertificate;
00514 m_pLogEncryptionCertificate=NULL;
00515
00516 if(m_docMixInfo!=NULL)
00517 {
00518 m_docMixInfo->release();
00519 m_docMixInfo=NULL;
00520 }
00521
00522 if(m_docMixXml!=NULL)
00523 {
00524 m_docMixXml->release();
00525 m_docMixXml=NULL;
00526 }
00527
00528 if(m_docOpTnCs!=NULL)
00529 {
00530 m_docOpTnCs->release();
00531 m_docOpTnCs=NULL;
00532 }
00533
00534 #ifdef COUNTRY_STATS
00535 delete[] m_dbCountryStatsHost;
00536 m_dbCountryStatsHost = NULL;
00537 delete[] m_dbCountryStatsUser;
00538 m_dbCountryStatsUser = NULL;
00539 delete[] m_dbCountryStatsPasswd;
00540 m_dbCountryStatsPasswd = NULL;
00541 #endif
00542
00543 #ifdef DATA_RETENTION_LOG
00544 delete[] m_strDataRetentionLogDir;
00545 m_strDataRetentionLogDir=NULL;
00546 #endif
00547
00548 #endif //ONLY_LOCAL_PROXY
00549 #ifdef SERVER_MONITORING
00550 if(m_strMonitoringListenerHost != NULL)
00551 {
00552 delete[] m_strMonitoringListenerHost;
00553 m_strMonitoringListenerHost = NULL;
00554 }
00555 #endif
00556 delete [] mainOptionSetters;
00557 mainOptionSetters = NULL;
00558 delete [] generalOptionSetters;
00559 generalOptionSetters = NULL;
00560 delete certificateOptionSetters;
00561 certificateOptionSetters = NULL;
00562 delete [] accountingOptionSetters;
00563 accountingOptionSetters = NULL;
00564 delete [] networkOptionSetters;
00565 networkOptionSetters = NULL;
00566 }
00567
00568 SINT32 CACmdLnOptions::parse(int argc,const char** argv)
00569 {
00570 int iDaemon=0;
00571 char* target=NULL;
00572 int iLocalProxy=0;
00573 int SOCKSport=-1;
00574 char* socks=NULL;
00575 char* logdir=NULL;
00576 int iCompressedLogs=0;
00577 char* serverPort=NULL;
00578 int iVersion=0;
00579 char* configfile=NULL;
00580 int iAutoReconnect=0;
00581 char* strPidFile=NULL;
00582 char* strCreateConf=0;
00583
00584 poptOption theOptions[]=
00585 {
00586 {"localproxy",'j',POPT_ARG_NONE,&iLocalProxy,0,"act as local proxy",NULL},
00587 {"daemon",'d',POPT_ARG_NONE,&iDaemon,0,"start as daemon [only for local proxy]",NULL},
00588 {"next",'n',POPT_ARG_STRING,&target,0,"first mix of cascade [only for local proxy]","<ip:port>"},
00589 {"autoreconnect",'a',POPT_ARG_NONE,&iAutoReconnect,0,"auto reconnects if connection to first mix was lost [only for local proxy]",NULL},
00590 {"port",'p',POPT_ARG_STRING,&serverPort,0,"listening on [host:]port|path [only for local proxy]","<[host:]port|path>"},
00591 {"socksport",'s',POPT_ARG_INT,&SOCKSport,0,"listening port for socks","<portnumber>"},
00592 {"logdir",'l',POPT_ARG_STRING,&logdir,0,"directory where log files go to [only for local proxy]","<dir>"},
00593 #ifdef COMPRESSED_LOGS
00594 {"gzip",'z',POPT_ARG_NONE,&iCompressedLogs,0,"create gziped logs",NULL},
00595 #endif
00596 {"config",'c',POPT_ARG_STRING,&configfile,0,"config file to use [for a real Mix in a cascade]","<file>"},
00597 {"version",'v',POPT_ARG_NONE,&iVersion,0,"show version",NULL},
00598 {"pidfile",'r',POPT_ARG_STRING,&strPidFile,0,"file where the PID will be stored","<file>"},
00599 {"createConf",0,POPT_ARG_STRING,&strCreateConf,0,"creates a generic configuration for MixOnCD","[<file>]"},
00600 POPT_AUTOHELP
00601 {NULL,0,0,
00602 NULL,0,NULL,NULL}
00603 };
00604 poptContext ctx=poptGetContext(NULL,argc,argv,theOptions,0);
00605 SINT32 ret=poptGetNextOpt(ctx);
00606 while(ret==POPT_ERROR_BADOPT)
00607 ret=poptGetNextOpt(ctx);
00608 poptFreeContext(ctx);
00609 if(iVersion!=0)
00610 {
00611 printf(MIX_VERSION_INFO);
00612 for(UINT32 t=0;t<10000;t++)
00613 {
00614 CASocket* pSocket=new CASocket;
00615 if(pSocket->create(false)!=E_SUCCESS)
00616 {
00617 printf("Max open sockets: %u\n",t);
00618 exit(0);
00619 }
00620 }
00621 printf("Max open sockets: >10000\n");
00622 exit(0);
00623 }
00624
00625 if (MIX_VERSION_TESTING)
00626 {
00627 CAMsg::printMsg(LOG_WARNING, MIX_VERSION_TESTING_TEXT);
00628 }
00629
00630 #ifndef ONLY_LOCAL_PROXY
00631 if(strCreateConf!=NULL)
00632 {
00633 createMixOnCDConfiguration((UINT8*)strCreateConf);
00634 exit(0);
00635 }
00636 #endif
00637 if(iLocalProxy!=0)
00638 m_bLocalProxy=true;
00639 if(m_bLocalProxy&&iAutoReconnect!=0)
00640 m_bAutoReconnect=true;
00641
00642
00643 if(configfile == NULL)
00644 {
00645 configfile = (char*) malloc(sizeof(char) * (strlen(DEFAULT_CONFIG_FILE)+1));
00646 strncpy(configfile, DEFAULT_CONFIG_FILE, (strlen(DEFAULT_CONFIG_FILE)+1));
00647
00648 #if defined (_WIN32) &&!defined(__CYGWIN__)
00649
00650 #define R_OK 4
00651 #endif
00652
00653 int err = access(configfile, R_OK);
00654 if( err )
00655 {
00656 if(configfile != NULL)
00657 {
00658 free(configfile);
00659 configfile = NULL;
00660 }
00661 }
00662 }
00663
00664
00665
00666 if(configfile!=NULL)
00667 {
00668 #ifndef ONLY_LOCAL_PROXY
00669 ret=readXmlConfiguration(m_docMixXml,(UINT8*)configfile);
00670 if(ret==E_FILE_OPEN)
00671 CAMsg::printMsg(LOG_CRIT,"Could not open config file: %s\n",configfile);
00672 else if(ret==E_FILE_READ)
00673 CAMsg::printMsg(LOG_CRIT,"Could not read config file: %s\n",configfile);
00674 else if(ret==E_XML_PARSE)
00675 CAMsg::printMsg(LOG_CRIT,"Could not parse config file: %s\n",configfile);
00676 else
00677 {
00678 m_strConfigFile=new UINT8[strlen(configfile)+1];
00679 memcpy(m_strConfigFile,configfile,strlen(configfile)+1);
00680 }
00681 #endif
00682 free(configfile);
00683 }
00684 if(iDaemon!=0)
00685 m_bDaemon=true;
00686 if(target!=NULL)
00687 {
00688 if(target[0]=='/')
00689 {
00690 m_strTargetHost=new char[strlen(target)+1];
00691 strcpy(m_strTargetHost,target);
00692 }
00693 else
00694 {
00695 char tmpHostname[TMP_BUFF_SIZE];
00696 SINT32 tmpPort;
00697 char* tmpStr1=strchr(target,':');
00698 if(tmpStr1!=NULL)
00699 {
00700 memcpy(tmpHostname,target,tmpStr1-target);
00701 tmpHostname[tmpStr1-target]=0;
00702 tmpPort=(SINT32)atol(tmpStr1+1);
00703 }
00704 else
00705 {
00706
00707
00708 tmpPort=(SINT32)atol(target);
00709 if(tmpPort!=0)
00710 {
00711 strcpy(tmpHostname,"localhost");
00712 }
00713 else
00714 {
00715
00716
00717 tmpPort=DEFAULT_TARGET_PORT;
00718 strcpy(tmpHostname,target);
00719 }
00720 }
00721 m_strTargetHost=new char[strlen(tmpHostname)+1];
00722 strcpy(m_strTargetHost,tmpHostname);
00723 m_iTargetPort=(UINT16)tmpPort;
00724 }
00725 free(target);
00726 }
00727 if(socks!=NULL)
00728 {
00729 char* tmpStr;
00730 if((tmpStr=strchr(socks,':'))!=NULL)
00731 {
00732 m_strSOCKSHost=new char[tmpStr-socks+1];
00733 (*tmpStr)=0;
00734 strcpy(m_strSOCKSHost,socks);
00735 m_iSOCKSPort=(UINT16)atol(tmpStr+1);
00736 }
00737 free(socks);
00738 }
00739 if(logdir!=NULL)
00740 {
00741 m_strLogDir=new char[strlen(logdir)+1];
00742 strcpy(m_strLogDir,logdir);
00743 free(logdir);
00744 }
00745 if(strPidFile!=NULL)
00746 {
00747 m_strPidFile=new char[strlen(strPidFile)+1];
00748 strcpy(m_strPidFile,strPidFile);
00749 free(strPidFile);
00750 }
00751 if(iCompressedLogs!=0)
00752 m_bCompressedLogs=true;
00753
00754 if(serverPort!=NULL&&m_bLocalProxy)
00755 {
00756 m_arListenerInterfaces=new CAListenerInterface*[1];
00757 m_arListenerInterfaces[0]=NULL;
00758 m_cnListenerInterfaces=0;
00759 char* tmpStr;
00760 if(serverPort[0]=='/')
00761 {
00762 m_arListenerInterfaces[0]=CAListenerInterface::getInstance(RAW_UNIX,(UINT8*)serverPort);
00763 }
00764 else
00765 {
00766 char* strServerHost=NULL;
00767 SINT32 iServerPort;
00768 if((tmpStr=strchr(serverPort,':'))!=NULL)
00769 {
00770 strServerHost=new char[tmpStr-serverPort+1];
00771 (*tmpStr)=0;
00772 strcpy(strServerHost,serverPort);
00773 iServerPort=(SINT32)atol(tmpStr+1);
00774 }
00775 else
00776 {
00777 iServerPort=(SINT32)atol(serverPort);
00778 }
00779 m_arListenerInterfaces[0]=CAListenerInterface::getInstance(RAW_TCP,(UINT8*)strServerHost,(UINT16)iServerPort);
00780 delete [] strServerHost;
00781 strServerHost = NULL;
00782 }
00783 free(serverPort);
00784 if(m_arListenerInterfaces[0]!=0)
00785 m_cnListenerInterfaces=1;
00786 }
00787
00788 m_iSOCKSServerPort=(UINT16)SOCKSport;
00789 #ifndef ONLY_LOCAL_PROXY
00790 if(!m_bLocalProxy)
00791 {
00792 ret=processXmlConfiguration(m_docMixXml);
00793 #ifndef DYNAMIC_MIX
00794 if(ret!=E_SUCCESS)
00795 return ret;
00796 }
00797 #else
00798
00799 if(ret!=E_SUCCESS)
00800 {
00801 createDefaultConfiguration();
00802 ret=processXmlConfiguration(m_docMixXml);
00803 if(ret!=E_SUCCESS)
00804 return ret;
00805 }
00806 }
00807 #endif
00808
00809
00810 XERCES_CPP_NAMESPACE::DOMDocument* infoservices;
00811 if( readXmlConfiguration(infoservices,(UINT8*)"infoservices.xml") == E_SUCCESS )
00812 {
00813 CAMsg::printMsg(LOG_DEBUG, "Will now get InfoServices from infoservices.xml (this overrides the InfoServices from the default config!)\n");
00814 DOMElement* elemIs=infoservices->getDocumentElement();
00815 parseInfoServices(elemIs);
00816 }
00817
00818 #ifdef DYNAMIC_MIX
00819
00820
00821 if( checkCertificates() != E_SUCCESS )
00822 {
00823 CAMsg::printMsg(LOG_CRIT, "I was not able to get a working certificate, please check the configuration! Exiting now\n");
00824 exit(0);
00825 }
00826 UINT32 running = 0;
00827 CAMsg::printMsg( LOG_INFO, "I will now test if I have enough information about InfoServices...\n");
00828 if( checkInfoServices(&running) != E_SUCCESS )
00829 {
00831 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);
00832 exit(0);
00833 }
00834 CAMsg::printMsg( LOG_INFO, "InfoService information ok\n");
00835 if( checkListenerInterfaces() != E_SUCCESS )
00836 {
00837 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");
00838 exit(0);
00839 }
00840 if( checkMixId() != E_SUCCESS)
00841 {
00842 CAMsg::printMsg(LOG_CRIT, "ARGS, I don't have an unique ID, cannot create one! Exiting now\n");
00843 exit(0);
00844 }
00845 #endif // DYNAMIC_MIX
00846 #endif //ONLY_LOCAL_PROXY
00847 return E_SUCCESS;
00848 }
00849
00850 #ifndef ONLY_LOCAL_PROXY
00851 struct t_CMNDLN_REREAD_PARAMS
00852 {
00853 CACmdLnOptions* pCmdLnOptions;
00854 CAMix* pMix;
00855 };
00856 #endif //ONLY_LOCAL_PROXY
00857
00865 SINT32 CACmdLnOptions::setNewValues(CACmdLnOptions& newOptions)
00866 {
00867
00868 if(newOptions.getTargetInterfaceCount()>0)
00869 {
00870 clearTargetInterfaces();
00871 m_cnTargets=newOptions.getTargetInterfaceCount();
00872 m_arTargetInterfaces=new TargetInterface[m_cnTargets];
00873 for(UINT32 i=0;i<m_cnTargets;i++)
00874 newOptions.getTargetInterface(m_arTargetInterfaces[i],i+1);
00875 }
00876 #if defined( DELAY_CHANNELS)||defined(DELAY_USERS)
00877
00878 m_u32DelayChannelUnlimitTraffic=newOptions.getDelayChannelUnlimitTraffic();
00879 m_u32DelayChannelBucketGrow=newOptions.getDelayChannelBucketGrow();
00880 m_u32DelayChannelBucketGrowIntervall=newOptions.getDelayChannelBucketGrowIntervall();
00881 #endif
00882 #if defined( DELAY_CHANNELS_LATENCY)
00883
00884 m_u32DelayChannelLatency=newOptions.getDelayChannelLatency();
00885 #endif
00886 if(newOptions.getMaxNrOfUsers()>0)
00887 m_maxNrOfUsers=newOptions.getMaxNrOfUsers();
00888 return E_SUCCESS;
00889 }
00890
00891 #ifndef ONLY_LOCAL_PROXY
00892
00897 #ifndef DYNAMIC_MIX
00898 SINT32 CACmdLnOptions::setNextMix(XERCES_CPP_NAMESPACE::DOMDocument* doc)
00899 {
00900 CAMsg::printMsg(LOG_DEBUG,"setNextMix() - start\n");
00901 DOMElement* elemRoot = doc->getDocumentElement();
00902
00903
00904 DOMElement* elemSig;
00905 getDOMChildByName(elemRoot, OPTIONS_NODE_SIGNATURE, elemSig, false);
00906
00907
00908 DOMElement* elemCert;
00909 getDOMChildByName(elemSig, OPTIONS_NODE_X509DATA, elemCert,true);
00910 if(elemSig!=NULL)
00911 m_pNextMixCertificate = CACertificate::decode(elemCert->getFirstChild(),CERT_X509CERTIFICATE);
00912
00913 DOMElement* elemOptionsRoot = m_docMixXml->getDocumentElement();
00914 DOMElement* elemOptionsCerts;
00915 getDOMChildByName(elemOptionsRoot, OPTIONS_NODE_CERTIFICATE_LIST, elemOptionsCerts, false);
00916 DOMElement* elemOptionsNextMixCert;
00917
00918 if(getDOMChildByName(elemOptionsRoot, OPTIONS_NODE_NEXT_MIX_CERTIFICATE, elemOptionsNextMixCert, false) != E_SUCCESS)
00919 {
00920 elemOptionsNextMixCert = createDOMElement(m_docMixXml, OPTIONS_NODE_NEXT_MIX_CERTIFICATE);
00921 elemOptionsCerts->appendChild(elemOptionsNextMixCert);
00922 elemOptionsNextMixCert->appendChild(m_docMixXml->importNode(elemCert->getFirstChild(),true));
00923 }
00924 else
00925 {
00926 if(elemOptionsNextMixCert->hasChildNodes())
00927 {
00928 elemOptionsNextMixCert->replaceChild(m_docMixXml->importNode(elemCert->getFirstChild(),true),
00929 elemOptionsNextMixCert->getFirstChild());
00930 }
00931 else
00932 {
00933 elemOptionsNextMixCert->appendChild(m_docMixXml->importNode(elemCert->getFirstChild(),true));
00934 }
00935 }
00936 CAMsg::printMsg(LOG_DEBUG,"setNextMix() - certificates done\n");
00937 DOMElement* elemNextMix;
00938 getDOMChildByName(elemRoot, OPTIONS_NODE_LISTENER_INTERFACE, elemNextMix,true);
00939
00940 DOMElement* elemOptionsNetwork;
00941 DOMElement* elemOptionsNextMixInterface;
00942
00943 if(getDOMChildByName(elemOptionsRoot, OPTIONS_NODE_NETWORK, elemOptionsNetwork, false) != E_SUCCESS)
00944 {
00945 elemOptionsNetwork = createDOMElement(m_docMixXml, OPTIONS_NODE_NETWORK);
00946 elemOptionsRoot->appendChild(elemOptionsNetwork);
00947 }
00948
00949 if(getDOMChildByName(elemOptionsNetwork, OPTIONS_NODE_NEXT_MIX, elemOptionsNextMixInterface, false) != E_SUCCESS)
00950 {
00951 elemOptionsNextMixInterface = createDOMElement(m_docMixXml, OPTIONS_NODE_NEXT_MIX);
00952 elemOptionsNetwork->appendChild(elemOptionsNextMixInterface);
00953 }
00954 else
00955 {
00956 while(elemOptionsNextMixInterface->hasChildNodes())
00957 {
00958 elemOptionsNextMixInterface->removeChild(elemOptionsNextMixInterface->getFirstChild());
00959 }
00960 }
00961
00962 DOMNode* interfaceData = elemNextMix->getFirstChild();
00963 while(interfaceData != NULL)
00964 {
00965 elemOptionsNextMixInterface->appendChild(m_docMixXml->importNode(interfaceData,true));
00966 interfaceData = interfaceData->getNextSibling();
00967 }
00968
00969 CAMsg::printMsg(LOG_DEBUG,"setNextMix() - end\n");
00970 return processXmlConfiguration(m_docMixXml);
00971 }
00972
00973 #else //DYNAMIC_MIX
00974
00975 SINT32 CACmdLnOptions::setNextMix(DOM_Document& doc)
00976 {
00977 resetNextMix();
00979 DOM_Element elemRoot = doc.getDocumentElement();
00980
00981 DOM_Element elemSig;
00982 getDOMChildByName(elemRoot,(UINT8*) OPTIONS_NODE_SIGNATURE, elemSig, false);
00983 DOM_Element elemCert;
00984 getDOMChildByName(elemSig,(UINT8*) OPTIONS_NODE_X509DATA, elemCert, true);
00985 if(elemCert!=NULL)
00986 m_pNextMixCertificate = CACertificate::decode(elemCert.getFirstChild(),CERT_X509CERTIFICATE);
00988 DOM_Node elemNextMix;
00989 DOM_Element elemListeners;
00990
00991 getDOMChildByName(elemRoot,(UINT8*) OPTIONS_NODE_LISTENER_INTERFACE_LIST, elemListeners, true);
00992 DOM_NodeList nlListenerInterfaces = elemListeners.getElementsByTagName(CAListenerInterface::XML_ELEMENT_NAME);
00993 UINT32 len = nlListenerInterfaces.getLength();
00994 bool foundNonHiddenInterface = false;
00995 for(UINT32 i=0;i<len;i++)
00996 {
00997 elemNextMix=nlListenerInterfaces.item(i);
00998 SINT32 ret = E_SUCCESS;
00999 ret = getDOMElementAttribute(elemNextMix,"hidden",foundNonHiddenInterface);
01000
01001 if(foundNonHiddenInterface || ret == E_UNSPECIFIED)
01002 {
01003 foundNonHiddenInterface = true;
01004 break;
01005 }
01006 }
01007 if(!foundNonHiddenInterface)
01008 {
01009 CAMsg::printMsg(LOG_ERR, "NEXT MIX HAS NO REAL LISTENERINTERFACES!\n");
01010 exit(0);
01011 return E_UNKNOWN;
01012 }
01014 clearTargetInterfaces();
01015
01016 m_cnTargets=0;
01017 TargetInterface* targetInterfaceNextMix=NULL;
01018 if(elemNextMix!=NULL)
01019 {
01020 NetworkType type;
01021 CASocketAddr* addr=NULL;
01022 DOM_Element elemType;
01023 getDOMChildByName(elemNextMix,(UINT8*) OPTIONS_NODE_NETWORK, elemType, false);
01024 UINT8 tmpBuff[TMP_BUFF_SIZE];
01025 UINT32 tmpLen = TMP_BUFF_SIZE;
01026 if(getDOMElementValue(elemType,tmpBuff,&tmpLen)!=E_SUCCESS)
01027 goto SKIP_NEXT_MIX;
01028 strtrim(tmpBuff);
01029 if(strcmp((char*)tmpBuff,"RAW/TCP")==0)
01030 type=RAW_TCP;
01031 else if(strcmp((char*)tmpBuff,"RAW/UNIX")==0)
01032 type=RAW_UNIX;
01033 else if(strcmp((char*)tmpBuff,"SSL/TCP")==0)
01034 type=SSL_TCP;
01035 else if(strcmp((char*)tmpBuff,"SSL/UNIX")==0)
01036 type=SSL_UNIX;
01037 else
01038 goto SKIP_NEXT_MIX;
01039 if(type==SSL_TCP||type==RAW_TCP)
01040 {
01041 DOM_Element elemPort;
01042 DOM_Element elemHost;
01043 DOM_Element elemIP;
01044 UINT8 buffHost[255];
01045 UINT32 buffHostLen=255;
01046 UINT16 port;
01047 getDOMChildByName(elemNextMix,(UINT8*) OPTIONS_NODE_PORT, elemPort, false);
01048 if(getDOMElementValue(elemPort,&port)!=E_SUCCESS)
01049 goto SKIP_NEXT_MIX;
01050 addr=new CASocketAddrINet;
01051 bool bAddrIsSet=false;
01052 getDOMChildByName(elemNextMix,(UINT8*) OPTIONS_NODE_HOST, elemHost, false);
01053
01054
01055
01056
01057 if(elemHost!=NULL)
01058 {
01059 if(getDOMElementValue(elemHost,buffHost,&buffHostLen)==E_SUCCESS&&((CASocketAddrINet*)addr)->setAddr(buffHost,port)==E_SUCCESS)
01060 {
01061 bAddrIsSet=true;
01062 }
01063 }
01064 if(!bAddrIsSet)
01065 {
01066 getDOMChildByName(elemNextMix,(UINT8*) OPTIONS_NODE_IP, elemIP, false);
01067 if(elemIP == NULL || getDOMElementValue(elemIP,buffHost,&buffHostLen)!=E_SUCCESS)
01068 goto SKIP_NEXT_MIX;
01069 if(((CASocketAddrINet*)addr)->setAddr(buffHost,port)!=E_SUCCESS)
01070 goto SKIP_NEXT_MIX;
01071 }
01072 CAMsg::printMsg(LOG_INFO, "Setting target interface: %s:%d\n", buffHost, port);
01073 }
01074 else
01075 #ifdef HAVE_UNIX_DOMAIN_PROTOCOL
01076
01077 {
01078 DOM_Element elemFile;
01079 getDOMChildByName(elemNextMix,(UINT8*) OPTIONS_NODE_FILE, elemFile, false);
01080 tmpLen=255;
01081 if(getDOMElementValue(elemFile,tmpBuff,&tmpLen)!=E_SUCCESS)
01082 goto SKIP_NEXT_MIX;
01083 tmpBuff[tmpLen]=0;
01084 strtrim(tmpBuff);
01085 addr=new CASocketAddrUnix;
01086 if(((CASocketAddrUnix*)addr)->setPath((char*)tmpBuff)!=E_SUCCESS)
01087 goto SKIP_NEXT_MIX;
01088 }
01089 #else
01090 goto SKIP_NEXT_MIX;
01091 #endif
01092 targetInterfaceNextMix=new TargetInterface;
01093 targetInterfaceNextMix->target_type=TARGET_MIX;
01094 targetInterfaceNextMix->net_type=type;
01095 targetInterfaceNextMix->addr=addr->clone();
01096 m_cnTargets=1;
01097 if(targetInterfaceNextMix!=NULL)
01098 {
01099 if(m_arTargetInterfaces==NULL)
01100 {
01101 m_cnTargets=0;
01102 m_arTargetInterfaces=new TargetInterface[1];
01103 }
01104 m_arTargetInterfaces[m_cnTargets].net_type=targetInterfaceNextMix->net_type;
01105 m_arTargetInterfaces[m_cnTargets].target_type=targetInterfaceNextMix->target_type;
01106 m_arTargetInterfaces[m_cnTargets++].addr=targetInterfaceNextMix->addr;
01107 delete targetInterfaceNextMix;
01108 targetInterfaceNextMix = NULL;
01109 }
01110
01111 SKIP_NEXT_MIX:
01112 delete addr;
01113 addr = NULL;
01114 }
01115
01116 CAMsg::printMsg(LOG_DEBUG,"setNextMix() - end\n");
01117 return E_SUCCESS;
01118 }
01119 #endif //DYNAMIC_MIX
01120
01121 #endif //ONLY_LOCAL_PROXY
01122
01123 #ifndef ONLY_LOCAL_PROXY
01124
01129 #ifndef DYNAMIC_MIX
01130 SINT32 CACmdLnOptions::setPrevMix(XERCES_CPP_NAMESPACE::DOMDocument* doc)
01131 {
01132 CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - start\n");
01133 DOMElement* elemRoot = doc->getDocumentElement();
01134
01135
01136 DOMElement* elemSig;
01137 getDOMChildByName(elemRoot, OPTIONS_NODE_SIGNATURE, elemSig, false);
01138
01139
01140 DOMElement* elemCert;
01141 getDOMChildByName(elemSig, OPTIONS_NODE_X509DATA, elemCert, true);
01142 if(elemCert!=NULL)
01143 {
01144 CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - elem cert found in data from infoservice\n");
01145 DOMElement* elemOptionsRoot = m_docMixXml->getDocumentElement();
01146 CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - got current options root element\n");
01147 DOMElement* elemOptionsCerts;
01148 getDOMChildByName
01149 (elemOptionsRoot, OPTIONS_NODE_CERTIFICATE_LIST, elemOptionsCerts, false);
01150 DOMElement* elemOptionsPrevMixCert;
01151
01152 if(getDOMChildByName
01153 (elemOptionsRoot,OPTIONS_NODE_PREV_MIX_CERTIFICATE, elemOptionsPrevMixCert, false) != E_SUCCESS)
01154 {
01155 CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - no prev cert set at the moment\n");
01156 elemOptionsPrevMixCert =createDOMElement( m_docMixXml,"PrevMixCertificate");
01157 elemOptionsCerts->appendChild(elemOptionsPrevMixCert);
01158 CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - try to import the one we got from infoservice\n");
01159 getDOMChildByName
01160 (elemCert, OPTIONS_NODE_X509_CERTIFICATE, elemCert, false);
01161
01162 CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - Cert to be imported:\n");
01163 UINT8 buff[8192];
01164 UINT32 len=8192;
01165 DOM_Output::dumpToMem(elemCert,buff,&len);
01166 CAMsg::printMsg(LOG_DEBUG,(char*)buff);
01167
01168 elemOptionsPrevMixCert->appendChild(m_docMixXml->importNode(elemCert,true));
01169 CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - MixConf now:\n");
01170 len=8192;
01171 DOM_Output::dumpToMem(m_docMixXml,buff,&len);
01172 buff[len]=0;
01173 CAMsg::printMsg(LOG_DEBUG,(char*)buff);
01174 }
01175 else
01176 {
01177 if(elemOptionsPrevMixCert->hasChildNodes())
01178 {
01179 elemOptionsPrevMixCert->replaceChild(m_docMixXml->importNode(elemCert->getFirstChild(),true),
01180 elemOptionsPrevMixCert->getFirstChild());
01181 }
01182 else
01183 {
01184 elemOptionsPrevMixCert->appendChild(m_docMixXml->importNode(elemCert->getFirstChild(),true));
01185 }
01186 }
01187 CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - end\n");
01188 return processXmlConfiguration(m_docMixXml);
01189 }
01190 CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - end with error\n");
01191 return E_UNKNOWN;
01192 }
01193
01194 #else //DYNAMIC_MIX
01195
01196 SINT32 CACmdLnOptions::setPrevMix(DOM_Document& doc)
01197 {
01198 resetPrevMix();
01199 CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - start\n");
01200 DOM_Element elemRoot = doc.getDocumentElement();
01201 DOM_Element elemSig;
01202 getDOMChildByName(elemRoot,(UINT8*) OPTIONS_NODE_SIGNATURE, elemSig, false);
01203 DOM_Element elemCert;
01204 getDOMChildByName(elemSig,(UINT8*) OPTIONS_NODE_X509DATA, elemCert,true);
01205
01206 if(elemCert!=NULL)
01207 {
01208 m_pPrevMixCertificate=CACertificate::decode(elemCert.getFirstChild(),CERT_X509CERTIFICATE);
01209 return E_SUCCESS;
01210 }
01211 CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - end with error\n");
01212 return E_UNKNOWN;
01213 }
01214 #endif //DYNAMIC_MIX
01215 #endif //ONLY_LOCAL_PROXY
01216
01217 #ifndef ONLY_LOCAL_PROXY
01218 #ifdef DYNAMIC_MIX
01219 SINT32 CACmdLnOptions::resetNextMix()
01220 {
01221 if(m_pNextMixCertificate != NULL)
01222 {
01223 delete m_pNextMixCertificate;
01224 m_pNextMixCertificate = NULL;
01225 }
01226 DOM_Element elemOptionsRoot = m_docMixXml.getDocumentElement();
01227 DOM_Element elemOptionsCerts;
01228 getDOMChildByName(elemOptionsRoot, (UINT8*) OPTIONS_NODE_CERTIFICATE_LIST, elemOptionsCerts, false);
01229 DOM_Element elemTmp;
01230
01231 if(getDOMChildByName(elemOptionsCerts, (UINT8*) OPTIONS_NODE_PREV_MIX_CERTIFICATE, elemTmp, false) == E_SUCCESS)
01232 {
01233
01234 elemOptionsCerts.removeChild(elemTmp);
01235 }
01236 if(getDOMChildByName(elemOptionsCerts, (UINT8*) OPTIONS_NODE_PREV_OPERATOR_CERTIFICATE, elemTmp, false) == E_SUCCESS)
01237 {
01238
01239 elemOptionsCerts.removeChild(elemTmp);
01240 }
01241 clearTargetInterfaces();
01242 return E_SUCCESS;
01243 }
01244
01245 SINT32 CACmdLnOptions::resetPrevMix()
01246 {
01247 if(m_pPrevMixCertificate != NULL)
01248 {
01249 delete m_pPrevMixCertificate;
01250 m_pPrevMixCertificate = NULL;
01251 }
01252 DOM_Element elemOptionsRoot = m_docMixXml.getDocumentElement();
01253 DOM_Element elemOptionsCerts;
01254 getDOMChildByName(elemOptionsRoot, (UINT8*) OPTIONS_NODE_CERTIFICATE_LIST, elemOptionsCerts, false);
01255 DOM_Element elemTmp;
01256
01257 if(getDOMChildByName(elemOptionsCerts, (UINT8*) OPTIONS_NODE_NEXT_MIX_CERTIFICATE, elemTmp, false) == E_SUCCESS)
01258 {
01259
01260 elemOptionsCerts.removeChild(elemTmp);
01261 }
01262 if(getDOMChildByName(elemOptionsCerts, (UINT8*) OPTIONS_NODE_NEXT_OPERATOR_CERTIFICATE, elemTmp, false) == E_SUCCESS)
01263 {
01264
01265 elemOptionsCerts.removeChild(elemTmp);
01266 }
01267 return E_SUCCESS;
01268
01269 }
01270 #endif //DYNAMIC_MIX
01271 #endif //ONLY_LOCAL_PROXY
01272
01273 #ifndef ONLY_LOCAL_PROXY
01274
01281 SINT32 CACmdLnOptions::reread(CAMix* pMix)
01282 {
01283 if(m_bIsRunReConfigure)
01284 return E_UNKNOWN;
01285 m_bIsRunReConfigure=true;
01286 m_threadReConfigure.setMainLoop(threadReConfigure);
01287 t_CMNDLN_REREAD_PARAMS* param=new t_CMNDLN_REREAD_PARAMS;
01288 param->pCmdLnOptions=this;
01289 param->pMix=pMix;
01290 m_threadReConfigure.start(param,true,false);
01291 return E_SUCCESS;
01292 }
01293
01298 THREAD_RETURN threadReConfigure(void *param)
01299 {
01300 CACmdLnOptions* pOptions=((t_CMNDLN_REREAD_PARAMS*)param)->pCmdLnOptions;
01301 CAMix* pMix=((t_CMNDLN_REREAD_PARAMS*)param)->pMix;
01302
01303 CAMsg::printMsg(LOG_DEBUG,"ReConfiguration of the Mix is under way....\n");
01304 CACmdLnOptions otmpOptions;
01305 XERCES_CPP_NAMESPACE::DOMDocument* docConfig=NULL;
01306 if(otmpOptions.readXmlConfiguration(docConfig,pOptions->m_strConfigFile)!=E_SUCCESS)
01307 {
01308 CAMsg::printMsg(LOG_DEBUG,"Could not re-read the config file!\n");
01309 goto REREAD_FINISH;
01310 }
01311 CAMsg::printMsg(LOG_DEBUG,"Re-readed config file -- start processing config file!\n");
01312 if(otmpOptions.processXmlConfiguration(docConfig)!=E_SUCCESS)
01313 {
01314 CAMsg::printMsg(LOG_DEBUG,"Re-readed config file -- could not process configuration!\n");
01315 goto REREAD_FINISH;
01316 }
01317 pOptions->setNewValues(otmpOptions);
01318 if(pMix!=NULL)
01319 pMix->reconfigure();
01320
01321 REREAD_FINISH:
01322 CAMsg::printMsg(LOG_DEBUG,"ReConfiguration of the Mix finished!\n");
01323
01324 pOptions->m_bIsRunReConfigure=false;
01325 THREAD_RETURN_SUCCESS;
01326 }
01327 #endif //ONLY_LOCAL_PROXY
01328
01329 bool CACmdLnOptions::getDaemon()
01330 {
01331 return m_bDaemon;
01332 }
01333
01334 SINT32 CACmdLnOptions::getMixId(UINT8* id,UINT32 len)
01335 {
01336 if(len<24||m_strMixID==NULL)
01337 return E_UNKNOWN;
01338 strcpy((char*)id,m_strMixID);
01339 return E_SUCCESS;
01340 }
01341
01342
01343 UINT16 CACmdLnOptions::getSOCKSServerPort()
01344 {
01345 return m_iSOCKSServerPort;
01346 }
01347
01348 UINT16 CACmdLnOptions::getMixPort()
01349 {
01350 return m_iTargetPort;
01351 }
01352
01353
01354 SINT32 CACmdLnOptions::getMixHost(UINT8* host,UINT32 len)
01355 {
01356 if(m_strTargetHost==NULL)
01357 return E_UNKNOWN;
01358 if(len<=(UINT32)strlen(m_strTargetHost))
01359 {
01360 return E_UNKNOWN;
01361 }
01362 strcpy((char*)host,m_strTargetHost);
01363 return E_SUCCESS;
01364 }
01365
01366 #ifndef ONLY_LOCAL_PROXY
01367 UINT16 CACmdLnOptions::getSOCKSPort()
01368 {
01369 return m_iSOCKSPort;
01370 }
01371
01372 SINT32 CACmdLnOptions::getSOCKSHost(UINT8* host,UINT32 len)
01373 {
01374 if(m_strSOCKSHost==NULL)
01375 return E_UNKNOWN;
01376 if(len<=(UINT32)strlen(m_strSOCKSHost))
01377 {
01378 return E_UNKNOWN;
01379 }
01380 strcpy((char*)host,m_strSOCKSHost);
01381 return (SINT32)strlen(m_strSOCKSHost);
01382 }
01383 #endif //ONLY_LOCAL_PROXY
01384
01385 #ifdef PAYMENT
01386
01391 CAXMLBI* CACmdLnOptions::getBI()
01392 {
01393 return m_pBI;
01394 }
01395
01396 SINT32 CACmdLnOptions::getDatabaseHost(UINT8 * host, UINT32 len)
01397 {
01398 if(m_strDatabaseHost==NULL)
01399 return E_UNKNOWN;
01400 if(len<=(UINT32)strlen((char *)m_strDatabaseHost))
01401 {
01402 return E_UNKNOWN;
01403 }
01404 strcpy((char*)host,(char *)m_strDatabaseHost);
01405 return E_SUCCESS;
01406 }
01407
01408 UINT16 CACmdLnOptions::getDatabasePort()
01409 {
01410 return m_iDatabasePort;
01411 }
01412
01413 SINT32 CACmdLnOptions::getDatabaseName(UINT8 * name, UINT32 len)
01414 {
01415 if(m_strDatabaseName==NULL)
01416 return E_UNKNOWN;
01417 if(len<=(UINT32)strlen((char *)m_strDatabaseName))
01418 {
01419 return E_UNKNOWN;
01420 }
01421 strcpy((char*)name,(char *)m_strDatabaseName);
01422 return E_SUCCESS;
01423 }
01424
01425 SINT32 CACmdLnOptions::getDatabaseUsername(UINT8 * user, UINT32 len)
01426 {
01427 if(m_strDatabaseUser==NULL)
01428 return E_UNKNOWN;
01429 if(len<=(UINT32)strlen((char *)m_strDatabaseUser))
01430 {
01431 return E_UNKNOWN;
01432 }
01433 strcpy((char*)user,(char *)m_strDatabaseUser);
01434 return E_SUCCESS;
01435 }
01436
01437 SINT32 CACmdLnOptions::getDatabasePassword(UINT8 * pass, UINT32 len)
01438 {
01439 if(m_strDatabasePassword==NULL)
01440 return E_UNKNOWN;
01441 if(len<=(UINT32)strlen((char *)m_strDatabasePassword))
01442 {
01443 return E_UNKNOWN;
01444 }
01445 strcpy((char*)pass,(char *)m_strDatabasePassword);
01446 return E_SUCCESS;
01447 }
01448
01449 SINT32 CACmdLnOptions::getAiID(UINT8 * id, UINT32 len)
01450 {
01451 if(m_strAiID==NULL)
01452 return E_UNKNOWN;
01453 if(len<=(UINT32)strlen((char *)m_strAiID))
01454 {
01455 return E_UNKNOWN;
01456 }
01457 strcpy((char*)id,(char *)m_strAiID);
01458 return E_SUCCESS;
01459 }
01460
01461 UINT32 CACmdLnOptions::getPaymentHardLimit()
01462 {
01463 return m_iPaymentHardLimit;
01464 }
01465
01466 UINT32 CACmdLnOptions::getPrepaidInterval()
01467 {
01468 return m_iPrepaidInterval;
01469 }
01470
01471 UINT32 CACmdLnOptions::getPaymentSoftLimit()
01472 {
01473 return m_iPaymentSoftLimit;
01474 }
01475
01476 UINT32 CACmdLnOptions::getPaymentSettleInterval()
01477 {
01478 return m_iPaymentSettleInterval;
01479 }
01480
01481 #endif
01482
01483 SINT32 CACmdLnOptions::getOperatorSubjectKeyIdentifier(UINT8 *buffer, UINT32 *length)
01484 {
01485 if(m_OpCert == NULL)
01486 {
01487 (*length) = 0;
01488 return E_UNKNOWN;
01489 }
01490 return m_OpCert->getSubjectKeyIdentifier(buffer, length);
01491
01492 }
01493
01494 #ifndef ONLY_LOCAL_PROXY
01495 CAListenerInterface** CACmdLnOptions::getInfoServices(UINT32& r_size)
01496 {
01497 r_size = m_addrInfoServicesSize;
01498 return m_addrInfoServices;
01499 }
01500
01501 SINT32 CACmdLnOptions::getCascadeName(UINT8* name,UINT32 len) const
01502 {
01503 if(m_strCascadeName==NULL)
01504 return E_UNKNOWN;
01505 if(len<=(UINT32)strlen((char*)m_strCascadeName))
01506 {
01507 return E_UNKNOWN;
01508 }
01509 strcpy((char*)name,(char*)m_strCascadeName);
01510 return E_SUCCESS;
01511 }
01512
01513
01514 SINT32 CACmdLnOptions::getEncryptedLogDir(UINT8* name,UINT32 len)
01515 {
01516 if(m_strEncryptedLogDir==NULL||name==NULL)
01517 return E_UNKNOWN;
01518 if(len<=(UINT32)strlen(m_strEncryptedLogDir))
01519 return E_UNKNOWN;
01520 strcpy((char*)name,m_strEncryptedLogDir);
01521 return E_SUCCESS;
01522 }
01523 #endif //ONLY_LOCAL_PROXY
01524
01525 SINT32 CACmdLnOptions::getLogDir(UINT8* name,UINT32 len)
01526 {
01527 if(m_strLogDir==NULL||name==NULL)
01528 return E_UNKNOWN;
01529 if(len<=(UINT32)strlen(m_strLogDir))
01530 {
01531 return E_SPACE;
01532 }
01533 strcpy((char*)name,m_strLogDir);
01534 return E_SUCCESS;
01535 }
01536
01537 SINT32 CACmdLnOptions::setLogDir(const UINT8* name,UINT32 len)
01538 {
01539 if(m_strLogDir!=NULL)
01540 {
01541 delete[] m_strLogDir;
01542 m_strLogDir = NULL;
01543 }
01544 m_strLogDir=new char[len+1];
01545 memcpy(m_strLogDir,name,len);
01546 m_strLogDir[len]=0;
01547 return E_SUCCESS;
01548 }
01549
01550 SINT32 CACmdLnOptions::getPidFile(UINT8* pidfile,UINT32 len)
01551 {
01552 if(m_strPidFile==NULL||pidfile==NULL)
01553 return E_UNKNOWN;
01554 if(len<=(UINT32)strlen(m_strPidFile))
01555 {
01556 return E_SPACE;
01557 }
01558 strcpy((char*)pidfile,m_strPidFile);
01559 return E_SUCCESS;
01560 }
01561
01562
01563 SINT32 CACmdLnOptions::getUser(UINT8* user,UINT32 len)
01564 {
01565 if(m_strUser==NULL||user==NULL)
01566 {
01567 return E_UNKNOWN;
01568 }
01569 if(len<=(UINT32)strlen(m_strUser))
01570 {
01571 return E_UNKNOWN;
01572 }
01573 strcpy((char*)user,m_strUser);
01574 return E_SUCCESS;
01575 }
01576
01577 bool CACmdLnOptions::isFirstMix()
01578 {
01579 return m_bFirstMix;
01580 }
01581
01582 bool CACmdLnOptions::isMiddleMix()
01583 {
01584 return m_bMiddleMix;
01585 }
01586
01587 bool CACmdLnOptions::isLastMix()
01588 {
01589 return m_bLastMix;
01590 }
01591
01592 bool CACmdLnOptions::isLocalProxy()
01593 {
01594 return m_bLocalProxy;
01595 }
01596
01597
01598 #ifdef SERVER_MONITORING
01599 char *CACmdLnOptions::getMonitoringListenerHost()
01600 {
01601 return m_strMonitoringListenerHost;
01602 }
01603
01604 UINT16 CACmdLnOptions::getMonitoringListenerPort()
01605 {
01606 return m_iMonitoringListenerPort;
01607 }
01608 #endif
01609
01610 #ifndef ONLY_LOCAL_PROXY
01611
01617 SINT32 CACmdLnOptions::getMixXml(XERCES_CPP_NAMESPACE::DOMDocument* & docMixInfo)
01618 {
01619 if(m_docMixInfo == NULL)
01620 {
01621 CAMsg::printMsg(LOG_CRIT,"No mixinfo document initialized!\n");
01622 return E_UNKNOWN;
01623 }
01624 docMixInfo=m_docMixInfo;
01625
01626 DOMElement* elemTimeStamp=NULL;
01627 DOMElement* elemRoot=docMixInfo->getDocumentElement();
01628 if(getDOMChildByName(elemRoot, UNIVERSAL_NODE_LAST_UPDATE, elemTimeStamp, false)!=E_SUCCESS)
01629 {
01630 elemTimeStamp=createDOMElement(docMixInfo, UNIVERSAL_NODE_LAST_UPDATE);
01631 elemRoot->appendChild(elemTimeStamp);
01632 }
01633 UINT64 currentMillis;
01634 getcurrentTimeMillis(currentMillis);
01635 UINT8 tmpStrCurrentMillis[50];
01636 print64(tmpStrCurrentMillis,currentMillis);
01637 setDOMElementValue(elemTimeStamp,tmpStrCurrentMillis);
01638 return E_SUCCESS;
01639 }
01640
01641 UINT32 CACmdLnOptions::getNumberOfTermsAndConditionsTemplates()
01642 {
01643 return m_nrOfTermsAndConditionsTemplates;
01644 }
01645 XERCES_CPP_NAMESPACE::DOMDocument **CACmdLnOptions::getAllTermsAndConditionsTemplates()
01646 {
01647 return m_termsAndConditionsTemplates;
01648 }
01649
01650
01651
01652
01653 XERCES_CPP_NAMESPACE::DOMElement* CACmdLnOptions::getTermsAndConditions()
01654 {
01655
01656 if(m_docOpTnCs == NULL)
01657 {
01658 return NULL;
01659 }
01660 UINT8 tmpBuff[TMP_BUFF_SIZE];
01661 UINT32 tmpLen = TMP_BUFF_SIZE;
01662 memset(tmpBuff, 0, tmpLen);
01663 getOperatorSubjectKeyIdentifier(tmpBuff, &tmpLen);
01664 setDOMElementAttribute(m_docOpTnCs->getDocumentElement(), OPTIONS_ATTRIBUTE_TNC_ID, tmpBuff);
01665 return m_docOpTnCs->getDocumentElement();
01666
01667
01668 }
01669
01679 SINT32 CACmdLnOptions::readXmlConfiguration(XERCES_CPP_NAMESPACE::DOMDocument* & docConfig,const UINT8* const configFile)
01680 {
01681 int handle;
01682 handle=open((char*)configFile,O_BINARY|O_RDONLY);
01683 if(handle==-1)
01684 return E_FILE_OPEN;
01685 SINT32 len=filesize32(handle);
01686 UINT8* tmpChar=new UINT8[len];
01687 int ret=read(handle,tmpChar,len);
01688 close(handle);
01689 if(ret!=len)
01690 return E_FILE_READ;
01691 SINT32 retVal = readXmlConfiguration(docConfig, tmpChar, len);
01692 delete[] tmpChar;
01693 tmpChar = NULL;
01694 return retVal;
01695 }
01696
01706 SINT32 CACmdLnOptions::readXmlConfiguration(XERCES_CPP_NAMESPACE::DOMDocument* & docConfig,const UINT8* const buf, UINT32 len)
01707 {
01708 docConfig=parseDOMDocument(buf,len);
01709 if(docConfig==NULL)
01710 {
01711 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");
01712 return E_UNKNOWN;
01713 }
01714 return E_SUCCESS;
01715 }
01716
01717
01718
01719
01720
01721
01722
01723 SINT32 CACmdLnOptions::appendMixInfo_internal(DOMNode* a_node, bool with_subtree)
01724 {
01725 DOMNode *importedNode = NULL;
01726 DOMNode *appendedNode = NULL;
01727
01728 if(a_node == NULL)
01729 {
01730 CAMsg::printMsg(LOG_CRIT,"No node specified!\n");
01731 return E_UNKNOWN;
01732 }
01733 if(m_docMixInfo == NULL)
01734 {
01735 CAMsg::printMsg(LOG_CRIT,"No mixinfo document initialized!\n");
01736 return E_UNKNOWN;
01737 }
01738 if(m_docMixInfo->getDocumentElement() == NULL)
01739 {
01740 CAMsg::printMsg(LOG_CRIT,"No mixinfo dom structure initialized!\n");
01741 return E_UNKNOWN;
01742 }
01743
01744 importedNode = m_docMixInfo->importNode(a_node, with_subtree);
01745
01746 if(importedNode != NULL)
01747 {
01749 if (importedNode->getNodeType() == DOMNode::ELEMENT_NODE)
01750 {
01751 DOMNodeList* nodesMail = getElementsByTagName((DOMElement*)importedNode, "EMail");
01752 for (UINT32 i = 0; i < nodesMail->getLength (); i++)
01753 {
01754 nodesMail->item(i)->getParentNode()->removeChild(nodesMail->item(i));
01755 }
01756 }
01757
01758 appendedNode = m_docMixInfo->getDocumentElement()->appendChild(importedNode);
01759 if( appendedNode != NULL )
01760 {
01761 return E_SUCCESS;
01762 }
01763 }
01764 CAMsg::printMsg(LOG_CRIT,"Could not append Node \"%s\" to Mixinfo!\n", a_node->getNodeName());
01765 return E_UNKNOWN;
01766 }
01767
01771 inline SINT32 CACmdLnOptions::addMixIdToMixInfo()
01772 {
01773 if( (m_docMixInfo != NULL) && (m_strMixID != NULL) )
01774 {
01775 return setDOMElementAttribute
01776 (m_docMixInfo->getDocumentElement(), MIXINFO_ATTRIBUTE_MIX_ID, (UINT8*) m_strMixID);
01777 }
01778 CAMsg::printMsg(LOG_CRIT,"No mixinfo document initialized!\n");
01779 return E_UNKNOWN;
01780 }
01781
01782
01788 SINT32 CACmdLnOptions::invokeOptionSetters (const optionSetter_pt *optionsSetters, DOMElement* optionsSource, SINT32 optionsSettersLength)
01789 {
01790 SINT32 i = 0;
01791 SINT32 ret = E_SUCCESS;
01792
01793 if( optionsSetters == NULL )
01794 {
01795 CAMsg::printMsg(LOG_CRIT,"Error parsing config file: OptionSetters not initialized!\n");
01796 return E_UNKNOWN;
01797 }
01798
01799 if( optionsSettersLength < 0)
01800 {
01801 CAMsg::printMsg(LOG_CRIT,"Error parsing config file: Negative number of option setters specified!\n");
01802 return E_UNKNOWN;
01803 }
01804
01805
01806 if( optionsSource == NULL )
01807 {
01808 CAMsg::printMsg(LOG_INFO, "Found NULL DOM element. "
01809 "NULL element handling is delegated to the specified setter method!\n");
01810 }
01811
01812 for(i=0; i < optionsSettersLength; i++ )
01813 {
01814 ret = (this->*(optionsSetters[i]))(optionsSource);
01815 if(ret != E_SUCCESS)
01816 {
01817 return ret;
01818 }
01819 }
01820 return E_SUCCESS;
01821 }
01822
01823
01824
01825
01826 SINT32 CACmdLnOptions::setGeneralOptions(DOMElement* elemRoot)
01827 {
01828 DOMElement* elemGeneral=NULL;
01829
01830 if (getDOMChildByName(elemRoot, OPTIONS_NODE_GENERAL,
01831 elemGeneral,false) != E_SUCCESS)
01832 {
01833 LOG_NODE_NOT_FOUND(OPTIONS_NODE_GENERAL);
01834 return E_UNKNOWN;
01835 }
01836
01837 return invokeOptionSetters
01838 (generalOptionSetters, elemGeneral, GENERAL_OPTIONS_NR);
01839 }
01840
01845 SINT32 CACmdLnOptions::setMixType(DOMElement* elemGeneral)
01846 {
01847 DOMElement* elemMixType=NULL;
01848 UINT8 tmpBuff[TMP_BUFF_SIZE];
01849 UINT32 tmpLen = TMP_BUFF_SIZE;
01850
01851 if(elemGeneral == NULL) return E_UNKNOWN;
01852 ASSERT_GENERAL_OPTIONS_PARENT
01853 (elemGeneral->getNodeName(), OPTIONS_NODE_MIX_TYPE);
01854
01855
01856 if (getDOMChildByName(elemGeneral, OPTIONS_NODE_MIX_TYPE,
01857 elemMixType,false) != E_SUCCESS)
01858 {
01859 LOG_NODE_NOT_FOUND(OPTIONS_NODE_MIX_TYPE);
01860 return E_UNKNOWN;
01861 }
01862
01863 if( getDOMElementValue(elemMixType,tmpBuff,&tmpLen) == E_SUCCESS )
01864 {
01865 if(memcmp(tmpBuff,"FirstMix",8) == 0)
01866 {
01867 m_bFirstMix = true;
01868 }
01869 else if (memcmp(tmpBuff,"MiddleMix",9) == 0)
01870 {
01871 m_bMiddleMix = true;
01872 }
01873 else if (memcmp(tmpBuff,"LastMix",7) == 0)
01874 {
01875 m_bLastMix = true;
01876 }
01877 if ( appendMixInfo_internal(elemMixType, WITH_SUBTREE) != E_SUCCESS )
01878 {
01879 return E_UNKNOWN;
01880 }
01881 }
01882 else
01883 {
01884 LOG_NODE_EMPTY_OR_INVALID(OPTIONS_NODE_MIX_TYPE);
01885 return E_UNKNOWN;
01886 }
01887 return E_SUCCESS;
01888 }
01889
01890 SINT32 CACmdLnOptions::setMixName(DOMElement* elemGeneral)
01891 {
01892 DOMElement *elemMixName = NULL, *elemMixInfoName = NULL;
01893 UINT8 tmpBuff[TMP_BUFF_SIZE];
01894 UINT32 tmpLen = TMP_BUFF_SIZE;
01895 UINT8 *typeValue = NULL;
01896
01897
01898 if(elemGeneral == NULL) return E_UNKNOWN;
01899 ASSERT_GENERAL_OPTIONS_PARENT
01900 (elemGeneral->getNodeName(), OPTIONS_NODE_MIX_NAME);
01901
01902
01903 getDOMChildByName(elemGeneral, OPTIONS_NODE_MIX_NAME, elemMixName, false);
01904 if(elemMixName != NULL)
01905 {
01906 if(getDOMElementValue(elemMixName, tmpBuff, &tmpLen) == E_SUCCESS)
01907 {
01908 m_strMixName = new char[tmpLen+1];
01909 memset(m_strMixName, 0, tmpLen+1);
01910 memcpy(m_strMixName, tmpBuff, tmpLen);
01911 }
01912 tmpLen = TMP_BUFF_SIZE;
01913 getDOMElementAttribute(elemMixName, OPTIONS_ATTRIBUTE_NAME_FOR_CASCADE, tmpBuff, &tmpLen);
01914 }
01915 else
01916 {
01917 tmpLen = 0;
01918 m_strMixName = NULL;
01919 }
01920
01921
01922
01923
01924
01925
01926 elemMixInfoName = createDOMElement(m_docMixInfo, MIXINFO_NODE_MIX_NAME);
01927
01928
01929 if(m_strMixName != NULL)
01930 {
01931 setDOMElementValue(elemMixInfoName, (UINT8*) m_strMixName);
01932 }
01933
01934 if( tmpLen != 0 )
01935 {
01936 if( strncasecmp( ((char *)tmpBuff),
01937 OPTIONS_VALUE_OPERATOR_NAME,
01938 strlen(OPTIONS_VALUE_OPERATOR_NAME)) == 0 )
01939 {
01940 typeValue = (UINT8 *) OPTIONS_VALUE_OPERATOR_NAME;
01941 }
01942 else if( strncasecmp( ((char *)tmpBuff),
01943 OPTIONS_VALUE_MIX_NAME,
01944 strlen(OPTIONS_VALUE_MIX_NAME)) == 0 )
01945 {
01946 typeValue = (UINT8 *) OPTIONS_VALUE_MIX_NAME;
01947 }
01948 }
01949 if(typeValue != NULL)
01950 {
01951 setDOMElementAttribute(elemMixInfoName,
01952 OPTIONS_ATTRIBUTE_NAME_FOR_CASCADE, typeValue);
01953 }
01954
01955 if(m_docMixInfo->getDocumentElement() != NULL)
01956 {
01957 m_docMixInfo->getDocumentElement()->appendChild(elemMixInfoName);
01958 }
01959 else
01960 {
01961
01962 return E_UNKNOWN;
01963 }
01964 return E_SUCCESS;
01965 }
01966
01967 SINT32 CACmdLnOptions::setMixID(DOMElement* elemGeneral)
01968 {
01969 DOMElement* elemMixID=NULL;
01970 UINT8 tmpBuff[TMP_BUFF_SIZE];
01971 UINT32 tmpLen = TMP_BUFF_SIZE;
01972 size_t mixID_strlen = 0;
01973
01974 if(elemGeneral == NULL) return E_UNKNOWN;
01975 ASSERT_GENERAL_OPTIONS_PARENT
01976 (elemGeneral->getNodeName(), OPTIONS_NODE_MIX_NAME);
01977
01978 getDOMChildByName(elemGeneral, OPTIONS_NODE_MIX_ID, elemMixID, false);
01979 if(elemMixID != NULL)
01980 {
01981 if(getDOMElementValue(elemMixID,tmpBuff,&tmpLen) == E_SUCCESS)
01982 {
01983 strtrim(tmpBuff);
01984 mixID_strlen = strlen((char*)tmpBuff)+1;
01985 m_strMixID = new char[strlen((char*)tmpBuff)+1];
01986 memset(m_strMixID, 0, mixID_strlen);
01987 memcpy(m_strMixID, tmpBuff, mixID_strlen);
01988
01989 return addMixIdToMixInfo();
01990 }
01991 }
01992 return E_SUCCESS;
01993
01994 }
01999 SINT32 CACmdLnOptions::setDynamicMix(DOMElement* elemGeneral)
02000 {
02001
02002
02003 DOMElement* elemDynamic=NULL;
02004 UINT8 tmpBuff[TMP_BUFF_SIZE];
02005 UINT32 tmpLen = TMP_BUFF_SIZE;
02006 m_bDynamic = false;
02007
02008 if(elemGeneral == NULL) return E_UNKNOWN;
02009 ASSERT_GENERAL_OPTIONS_PARENT
02010 (elemGeneral->getNodeName(), OPTIONS_NODE_DYNAMIC_MIX);
02011
02012 getDOMChildByName(elemGeneral, OPTIONS_NODE_DYNAMIC_MIX, elemDynamic, false);
02013 if(elemDynamic != NULL)
02014 {
02015 if(getDOMElementValue(elemDynamic, tmpBuff, &tmpLen)==E_SUCCESS)
02016 {
02017 m_bDynamic = (strcmp("True",(char*)tmpBuff) == 0);
02018 }
02019 }
02020 if(m_bDynamic)
02021 {
02022 CAMsg::printMsg( LOG_DEBUG, "I am a dynamic mix\n");
02023 }
02024 return E_SUCCESS;
02025 }
02026
02027 SINT32 CACmdLnOptions::setMinCascadeLength(DOMElement* elemGeneral)
02028 {
02029 DOMElement* elemMinCascadeLength = NULL;
02030 if(elemGeneral == NULL) return E_UNKNOWN;
02031 ASSERT_GENERAL_OPTIONS_PARENT
02032 (elemGeneral->getNodeName(), OPTIONS_NODE_MIN_CASCADE_LENGTH);
02033
02034 getDOMChildByName
02035 (elemGeneral, OPTIONS_NODE_MIN_CASCADE_LENGTH, elemMinCascadeLength, false);
02036 if(elemMinCascadeLength != NULL)
02037 {
02038 appendMixInfo_internal(elemMinCascadeLength, WITH_SUBTREE);
02039 }
02040 return E_SUCCESS;
02041 }
02042
02043 SINT32 CACmdLnOptions::setCascadeNameFromOptions(DOMElement* elemGeneral)
02044 {
02045 DOMElement* elemCascadeName=NULL;
02046 UINT8 tmpBuff[TMP_BUFF_SIZE];
02047 UINT32 tmpLen = TMP_BUFF_SIZE;
02048
02049 if(elemGeneral == NULL) return E_UNKNOWN;
02050 ASSERT_GENERAL_OPTIONS_PARENT
02051 (elemGeneral->getNodeName(), OPTIONS_NODE_CASCADE_NAME);
02052
02053
02054 getDOMChildByName(elemGeneral, OPTIONS_NODE_CASCADE_NAME, elemCascadeName, false);
02055
02056 #ifdef DYNAMIC_MIX
02057 bool bNeedCascadeNameFromMixID=false;
02058 #endif
02059 if(getDOMElementValue(elemCascadeName,tmpBuff,&tmpLen)==E_SUCCESS)
02060 {
02061 setCascadeName(tmpBuff);
02062 }
02063 #ifdef DYNAMIC_MIX
02064
02065 else
02066 {
02067 bNeedCascadeNameFromMixID=true;
02068 setCascadeName(m_strMixID);
02069 }
02070 #endif
02071 return E_SUCCESS;
02072 }
02073
02074 SINT32 CACmdLnOptions::setUserID(DOMElement* elemGeneral)
02075 {
02076 DOMElement* elemUID=NULL;
02077 UINT8 tmpBuff[TMP_BUFF_SIZE];
02078 UINT32 tmpLen = TMP_BUFF_SIZE;
02079 UINT8 buff[255];
02080
02081 if(elemGeneral == NULL) return E_UNKNOWN;
02082 ASSERT_GENERAL_OPTIONS_PARENT
02083 (elemGeneral->getNodeName(), OPTIONS_NODE_USER_ID);
02084
02085
02086 getDOMChildByName(elemGeneral, OPTIONS_NODE_USER_ID, elemUID,false);
02087
02088 if(getDOMElementValue(elemUID,tmpBuff,&tmpLen)==E_SUCCESS)
02089 {
02090 m_strUser=new char[tmpLen+1];
02091 memcpy(m_strUser,tmpBuff,tmpLen);
02092 m_strUser[tmpLen]=0;
02093 }
02094
02095 #ifndef WIN32
02096 if(getUser(buff,255)==E_SUCCESS)
02097 {
02098 struct passwd* pwd=getpwnam((char*)buff);
02099 if(pwd==NULL || (setegid(pwd->pw_gid)==-1) || (seteuid(pwd->pw_uid)==-1) )
02100 {
02101 if (pwd==NULL)
02102 {
02103 CAMsg::printMsg(LOG_ERR,
02104 "Could not switch to effective user '%s'! Reason: User '%s' does not exist on this system. Create this user first.\n",
02105 buff, buff);
02106 }
02107 else
02108 {
02109 CAMsg::printMsg(LOG_ERR,"Could not switch to effective user '%s'! Reason: %s (%i)\n",
02110 buff, GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR);
02111 }
02112 }
02113 else
02114 CAMsg::printMsg(LOG_INFO,"Switched to effective user '%s'!\n",buff);
02115 }
02116
02117 if(geteuid()==0)
02118 CAMsg::printMsg(LOG_WARNING,"Mix is running as root/superuser!\n");
02119 #endif
02120
02121
02122
02123 return E_SUCCESS;
02124 }
02125
02126 SINT32 CACmdLnOptions::setNrOfFileDescriptors(DOMElement* elemGeneral)
02127 {
02128 DOMElement* elemNrFd=NULL;
02129 UINT32 tmp = 0;
02130
02131 if(elemGeneral == NULL) return E_UNKNOWN;
02132 ASSERT_GENERAL_OPTIONS_PARENT
02133 (elemGeneral->getNodeName(), OPTIONS_NODE_FD_NR);
02134
02135
02136 getDOMChildByName(elemGeneral, OPTIONS_NODE_FD_NR, elemNrFd, false);
02137
02138 if(getDOMElementValue(elemNrFd,&tmp) == E_SUCCESS)
02139 {
02140 m_nrOfOpenFiles=tmp;
02141 }
02142
02143 #ifndef WIN32
02144
02145 struct rlimit coreLimit;
02146 coreLimit.rlim_cur = coreLimit.rlim_max = RLIM_INFINITY;
02147 if (setrlimit(RLIMIT_CORE, &coreLimit) != 0)
02148 {
02149 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);
02150 }
02151
02152 if(m_nrOfOpenFiles>0)
02153 {
02154 struct rlimit lim;
02155
02156 lim.rlim_cur = lim.rlim_max = m_nrOfOpenFiles;
02157 if (setrlimit(RLIMIT_NOFILE, &lim) != 0)
02158 {
02159 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",
02160 m_nrOfOpenFiles, GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR);
02161 exit(EXIT_FAILURE);
02162 }
02163 }
02164 #endif
02165
02166 return E_SUCCESS;
02167 }
02168
02169 SINT32 CACmdLnOptions::setDaemonMode(DOMElement* elemGeneral)
02170 {
02171 DOMElement* elemDaemonMode = NULL;
02172 UINT8 tmpBuff[TMP_BUFF_SIZE];
02173 UINT32 tmpLen = TMP_BUFF_SIZE;
02174
02175 if(elemGeneral == NULL) return E_UNKNOWN;
02176 ASSERT_GENERAL_OPTIONS_PARENT
02177 (elemGeneral->getNodeName(), OPTIONS_NODE_DAEMON);
02178
02179
02180 getDOMChildByName(elemGeneral, OPTIONS_NODE_DAEMON, elemDaemonMode,false);
02181
02182 if(getDOMElementValue(elemDaemonMode, tmpBuff, &tmpLen) == E_SUCCESS &&
02183 memcmp(tmpBuff,"True",4)==0)
02184 {
02185 m_bDaemon=true;
02186 }
02187 return E_SUCCESS;
02188 }
02189
02190 SINT32 CACmdLnOptions::setMaxUsers(DOMElement* elemGeneral)
02191 {
02192 DOMElement* elemMaxUsers=NULL;
02193 UINT32 tmp = 0;
02194
02195 if(elemGeneral == NULL) return E_UNKNOWN;
02196 ASSERT_GENERAL_OPTIONS_PARENT
02197 (elemGeneral->getNodeName(), OPTIONS_NODE_MAX_USERS);
02198
02199
02200 getDOMChildByName(elemGeneral, OPTIONS_NODE_MAX_USERS, elemMaxUsers, false);
02201 if(elemMaxUsers!=NULL)
02202 {
02203 if(getDOMElementValue(elemMaxUsers, &tmp)==E_SUCCESS)
02204 {
02205 m_maxNrOfUsers = tmp;
02206 }
02207 }
02208 return E_SUCCESS;
02209 }
02210
02211
02212 SINT32 CACmdLnOptions::initLogging()
02213 {
02214 SINT32 ret = E_SUCCESS;
02215 UINT8 buff[2000];
02216 UINT32 iLogOptions = 0;
02217
02218 CAMsg::init();
02219
02220
02221 #ifndef ONLY_LOCAL_PROXY
02222 if(isSyslogEnabled())
02223 {
02224 iLogOptions |= MSG_LOG;
02225 }
02226 #endif
02227 if(getLogDir((UINT8*)buff,2000)==E_SUCCESS)
02228 {
02229 if(getCompressLogs())
02230 iLogOptions |= MSG_COMPRESSED_FILE;
02231 else
02232 iLogOptions |= MSG_FILE;
02233 }
02234 #ifndef ONLY_LOCAL_PROXY
02235
02236 if (m_bLogConsole || iLogOptions == 0)
02237 {
02238 iLogOptions |= MSG_STDOUT;
02239 }
02240 ret = CAMsg::setLogOptions(iLogOptions);
02241
02242 if (strcmp(m_strLogLevel,"info") == 0)
02243 {
02244 CAMsg::setLogLevel(LOG_INFO);
02245 }
02246 else if (strcmp(m_strLogLevel,"warning") == 0)
02247 {
02248 CAMsg::setLogLevel(LOG_WARNING);
02249 }
02250 else if (strcmp(m_strLogLevel,"error") == 0)
02251 {
02252 CAMsg::setLogLevel(LOG_ERR);
02253 }
02254 else if (strcmp(m_strLogLevel,"critical") == 0)
02255 {
02256 CAMsg::setLogLevel(LOG_CRIT);
02257 }
02258
02259 if(isEncryptedLogEnabled())
02260 {
02261 SINT32 retEncr;
02262 if ((retEncr = CAMsg::openEncryptedLog()) != E_SUCCESS)
02263 {
02264 CAMsg::printMsg(LOG_ERR,"Could not open encrypted log - exiting!\n");
02265 return retEncr;
02266 }
02267 }
02268 #endif
02269
02270 if(getDaemon() && ret != E_SUCCESS)
02271 {
02272 CAMsg::printMsg(LOG_CRIT, "We need a log file in daemon mode in order to get any messages! Exiting...\n");
02273 return ret;
02274 }
02275
02276 return E_SUCCESS;
02277 }
02278
02279 SINT32 CACmdLnOptions::setLoggingOptions(DOMElement* elemGeneral)
02280 {
02281
02282 DOMElement* elemLogging=NULL;
02283 DOMElement* elemEncLog=NULL;
02284 DOMElement* elem=NULL;
02285
02286 UINT8 tmpBuff[TMP_BUFF_SIZE];
02287 UINT32 tmpLen = TMP_BUFF_SIZE;
02288
02289 SINT32 maxLogFilesTemp = 0;
02290 if(elemGeneral == NULL) return E_UNKNOWN;
02291 ASSERT_GENERAL_OPTIONS_PARENT
02292 (elemGeneral->getNodeName(), OPTIONS_NODE_LOGGING);
02293
02294 getDOMChildByName(elemGeneral, OPTIONS_NODE_LOGGING, elemLogging, false);
02295 if(elemLogging != NULL)
02296 {
02297 if (getDOMElementAttribute(elemLogging, "level", tmpBuff, &tmpLen) == E_SUCCESS)
02298 {
02299 strtrim(tmpBuff);
02300 toLower(tmpBuff);
02301 m_strLogLevel = new char[strlen((char*)tmpBuff)+1];
02302 strcpy(m_strLogLevel, (char*)tmpBuff);
02303 }
02304 else
02305 {
02306 m_strLogLevel = new char[strlen("debug")+1];
02307 strcpy(m_strLogLevel, "debug");
02308 }
02309
02310
02311
02312 getDOMChildByName(elemLogging, OPTIONS_NODE_LOGGING_FILE, elem, false);
02313 tmpLen = TMP_BUFF_SIZE;
02314 if(getDOMElementValue(elem, tmpBuff, &tmpLen) == E_SUCCESS)
02315 {
02316 strtrim(tmpBuff);
02317 m_strLogDir = new char[strlen((char*)tmpBuff)+1];
02318 strcpy(m_strLogDir, (char*)tmpBuff);
02319 getDOMElementAttribute
02320 (elem, OPTIONS_ATTRIBUTE_LOGGING_MAXFILESIZE, m_maxLogFileSize);
02321
02322
02323 if((getDOMElementAttribute
02324 (elem, OPTIONS_ATTRIBUTE_LOGGING_MAXFILES, &maxLogFilesTemp) != E_SUCCESS) ||
02325 (maxLogFilesTemp == 0) )
02326 {
02327 m_maxLogFiles = LOGGING_MAXFILES_DEFAULT;
02328 }
02329 else
02330 {
02331 if(maxLogFilesTemp < 0)
02332 {
02333
02334 return E_UNKNOWN;
02335 }
02336 m_maxLogFiles = (UINT32) maxLogFilesTemp;
02337
02338 }
02339 }
02340 getDOMChildByName(elemLogging, OPTIONS_NODE_SYSLOG, elem, false);
02341 tmpLen = TMP_BUFF_SIZE;
02342 memset(tmpBuff, 0, tmpLen);
02343 if( (getDOMElementValue(elem, tmpBuff, &tmpLen) == E_SUCCESS) &&
02344 (memcmp(tmpBuff,"True",4) == 0) )
02345 {
02346 m_bSyslog = true;
02347 }
02348
02349 getDOMChildByName(elemLogging, OPTIONS_NODE_LOGGING_CONSOLE, elem, false);
02350 tmpLen = TMP_BUFF_SIZE;
02351 memset(tmpBuff, 0, tmpLen);
02352 if( (getDOMElementValue(elem, tmpBuff, &tmpLen) == E_SUCCESS) &&
02353 (memcmp(tmpBuff,"True",4) == 0) )
02354 {
02355 m_bLogConsole = true;
02356 }
02357
02358
02359 if( getDOMChildByName
02360 (elemLogging, OPTIONS_NODE_ENCRYPTED_LOG, elemEncLog,false) == E_SUCCESS )
02361 {
02362 m_bIsEncryptedLogEnabled = true;
02363 getDOMChildByName(elemEncLog, OPTIONS_NODE_LOGGING_FILE, elem, false);
02364
02365 tmpLen = TMP_BUFF_SIZE;
02366 memset(tmpBuff, 0, tmpLen);
02367 if( getDOMElementValue(elem, tmpBuff, &tmpLen) == E_SUCCESS )
02368 {
02369 strtrim(tmpBuff);
02370 m_strEncryptedLogDir = new char[strlen((char*)tmpBuff)+1];
02371 strcpy(m_strEncryptedLogDir, (char*)tmpBuff);
02372 }
02373 DOMElement* elemKeyInfo;
02374 DOMElement* elemX509Data;
02375 if(getDOMChildByName
02376 (elemEncLog, OPTIONS_NODE_LOGGING_KEYINFO, elemKeyInfo, false) == E_SUCCESS &&
02377 getDOMChildByName
02378 (elemKeyInfo, OPTIONS_NODE_X509DATA, elemX509Data, false) == E_SUCCESS )
02379 {
02380 m_pLogEncryptionCertificate =
02381 CACertificate::decode(elemX509Data->getFirstChild(), CERT_X509CERTIFICATE);
02382 }
02383 }
02384 else
02385 {
02386 m_bIsEncryptedLogEnabled=false;
02387 }
02388
02389 }
02390
02391 SINT32 ret = initLogging();
02392 if (ret == E_SUCCESS)
02393 {
02394 CAMsg::printMsg(LOG_INFO,MIX_VERSION_INFO);
02395 if (MIX_VERSION_TESTING)
02396 {
02397 CAMsg::printMsg(LOG_WARNING, MIX_VERSION_TESTING_TEXT);
02398 }
02399 }
02400
02401 return ret;
02402 }
02403
02404
02405
02406
02407 SINT32 CACmdLnOptions::setMixDescription(DOMElement* elemRoot)
02408 {
02409 SINT32 ret = E_SUCCESS;
02410 DOMElement* elemMixDescription = NULL;
02411 if(elemRoot == NULL)
02412 {
02413 return E_UNKNOWN;
02414 }
02415 ret = getDOMChildByName
02416 (elemRoot, OPTIONS_NODE_DESCRIPTION, elemMixDescription, false);
02417
02418 if(elemMixDescription != NULL )
02419 {
02420 DOMNode* tmpChild = elemMixDescription->getFirstChild();
02421 while( (tmpChild != NULL) && (ret == E_SUCCESS) )
02422 {
02423 ret = appendMixInfo_internal(tmpChild, WITH_SUBTREE);
02424 tmpChild=tmpChild->getNextSibling();
02425 }
02426 }
02427 return ret;
02428 }
02429
02430
02431
02432
02433 SINT32 CACmdLnOptions::setCertificateOptions(DOMElement* elemRoot)
02434 {
02435
02436 DOMElement* elemCertificates;
02437
02438 if (getDOMChildByName
02439 (elemRoot, OPTIONS_NODE_CERTIFICATE_LIST, elemCertificates, false) != E_SUCCESS)
02440 {
02441 LOG_NODE_NOT_FOUND(OPTIONS_NODE_CERTIFICATE_LIST);
02442 return E_UNKNOWN;
02443 }
02444
02445 return invokeOptionSetters(certificateOptionSetters, elemCertificates, m_nCertificateOptionsSetters);
02446 }
02447
02448 SINT32 CACmdLnOptions::setOwnCertificate(DOMElement *elemCertificates)
02449 {
02450 DOMElement* elemOwnCert=NULL;
02451 UINT8 tmpBuff[TMP_BUFF_SIZE];
02452 UINT32 tmpLen = TMP_BUFF_SIZE;
02453
02454 UINT8 passwd[500];
02455 passwd[0] = 0;
02456
02457 if(elemCertificates == NULL) return E_UNKNOWN;
02458 ASSERT_CERTIFICATES_OPTIONS_PARENT
02459 (elemCertificates->getNodeName(), OPTIONS_NODE_OWN_CERTIFICATE);
02460
02461
02462 getDOMChildByName(elemCertificates, OPTIONS_NODE_OWN_CERTIFICATE, elemOwnCert, false);
02463 if (elemOwnCert == NULL)
02464 {
02465 LOG_NODE_NOT_FOUND(OPTIONS_NODE_OWN_CERTIFICATE);
02466 return E_UNKNOWN;
02467 }
02468
02469
02470
02471
02472
02473
02474
02475
02476
02477
02478
02479
02480
02481
02482
02483
02484
02485
02486
02487
02488
02489
02490
02491
02492
02493
02494
02495
02496
02497
02498
02499
02500
02501 UINT32 opCertsLen = m_opCertList->getLength();
02502 CACertificate** opCerts=new CACertificate*[opCertsLen];
02503 for(UINT32 j=0; j<opCertsLen; j++)
02504 {
02505 DOMNode* a_opCert = m_opCertList->item(j);
02506 opCerts[j] = CACertificate::decode(a_opCert,CERT_X509CERTIFICATE);
02507 if(opCerts[j] == NULL)
02508 {
02509 CAMsg::printMsg(LOG_CRIT, "Error while decoding operator certificates!");
02510 delete[] opCerts;
02511 return E_UNKNOWN;
02512 }
02513 }
02514
02515 DOMNodeList* ownCertList = getElementsByTagName(elemOwnCert, OPTIONS_NODE_X509_PKCS12);
02516
02517 m_pMultiSignature = new CAMultiSignature();
02518 for (UINT32 i=0; i<ownCertList->getLength(); i++)
02519 {
02520 DOMNode* a_cert = ownCertList->item(i);
02521 CASignature* signature = new CASignature();
02522 CACertStore* certs = new CACertStore();
02523
02524
02525 if(signature->setSignKey(a_cert, SIGKEY_PKCS12, (char*)passwd) != E_SUCCESS)
02526 {
02527
02528 printf("I need a password for the private Mix certificate nr. %d: ", i+1);
02529 fflush(stdout);
02530 readPasswd(passwd,500);
02531 printf("\n");
02532 if(signature->setSignKey(a_cert, SIGKEY_PKCS12, (char*)passwd) != E_SUCCESS)
02533 {
02534 CAMsg::printMsg(LOG_CRIT,"Unable to load private Mix certificate nr. %d! Please check your password.\n", i+1);
02535 delete signature;
02536 delete[] opCerts;
02537 signature = NULL;
02538 return E_UNKNOWN;
02539 }
02540 }
02541
02542 CACertificate* tmpCert = CACertificate::decode(a_cert, CERT_PKCS12, (char*)passwd);
02543 if(tmpCert== NULL)
02544 {
02545 CAMsg::printMsg(LOG_CRIT, "Error while getting own certificate %d!\n", i+1);
02546 delete[] opCerts;
02547 return E_UNKNOWN;
02548 }
02549
02550
02551 UINT32 tmpSKIlen = 255;
02552 UINT8 tmpSKI[255];
02553 if(tmpCert->getSubjectKeyIdentifier(tmpSKI, &tmpSKIlen) != E_SUCCESS)
02554 {
02555 CAMsg::printMsg(LOG_CRIT, "Error while getting SKI of own certificate %d!\n", i+1);
02556 delete[] opCerts;
02557 return E_UNKNOWN;
02558 }
02559
02560
02561 UINT32 tmpAKIlen = 255;
02562 UINT8 tmpAKI[255];
02563 if(tmpCert->getAuthorityKeyIdentifier(tmpAKI, &tmpAKIlen) != E_SUCCESS)
02564 {
02565 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");
02566 }
02567 else
02568 {
02569
02570 }
02571
02572 for(UINT32 j=0; j<opCertsLen; j++)
02573 {
02574 if(tmpCert->verify(opCerts[j]) == E_SUCCESS)
02575 {
02576
02577
02578 certs->add(opCerts[j]);
02579 break;
02580 }
02581 }
02582 if(certs->getNumber() == 0)
02583 {
02584 CAMsg::printMsg(LOG_CRIT, "Could not find operator cert for sign key %d! Please check your configuration. Exiting...\n", i+1);
02585 exit(EXIT_FAILURE);
02586 }
02587
02588 certs->add(tmpCert);
02589
02590 UINT32 tmpRawSKIlen = 255;
02591 UINT8 tmpRawSKI[255];
02592 if(tmpCert->getRawSubjectKeyIdentifier(tmpRawSKI, &tmpRawSKIlen) != E_SUCCESS)
02593 {
02594 delete[] opCerts;
02595 return E_UNKNOWN;
02596 }
02597 if (certs->getNumber() < 2)
02598 {
02599 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());
02600 exit(EXIT_FAILURE);
02601 }
02602 CAMsg::printMsg(LOG_DEBUG, "Adding Sign-Key %d with %d certificate(s).\n", i+1, certs->getNumber());
02603 m_pMultiSignature->addSignature(signature, certs, tmpRawSKI, tmpRawSKIlen);
02604 }
02605 if (m_pMultiSignature->getSignatureCount() == 0)
02606 {
02607 CAMsg::printMsg(LOG_CRIT, "Could not set a signature key for MultiCert!\n");
02608 delete m_pMultiSignature;
02609 m_pMultiSignature = NULL;
02610 delete[] opCerts;
02611 return E_UNKNOWN;
02612 }
02613
02614
02615
02616
02617
02618
02619
02620
02621 if(m_pMultiSignature->getXORofSKIs(tmpBuff, tmpLen) != E_SUCCESS)
02622 {
02623 delete[] opCerts;
02624 return E_UNKNOWN;
02625 }
02626
02627 if(m_strMixID != NULL )
02628 {
02629 if(strncmp(m_strMixID, (char*)tmpBuff, strlen((char*)tmpBuff) ) != 0)
02630 {
02631 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);
02632 delete[] opCerts;
02633 return E_UNKNOWN;
02634 }
02635 }
02636 else
02637 {
02638 m_strMixID=new char[strlen((char*)tmpBuff)+1];
02639 m_strMixID[strlen((char*)tmpBuff)]= (char) 0;
02640 strcpy(m_strMixID,(char*) tmpBuff);
02641 delete[] opCerts;
02642 return addMixIdToMixInfo();
02643 }
02644
02645 #ifdef PAYMENT
02646 if (m_strAiID != NULL && m_pMultiSignature->findSKI(m_strAiID) != E_SUCCESS)
02647 {
02648 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");
02649 }
02650 #endif
02651
02652 #ifdef DYNAMIC_MIX
02653
02654 if(bNeedCascadeNameFromMixID)
02655 {
02656 m_strCascadeName = new char[strlen(m_strMixID) + 1];
02657 memset(m_strCascadeName, 0, strlen(m_strMixID) + 1);
02658 strncpy(m_strCascadeName, m_strMixID, strlen(m_strMixID)+1);
02659 }
02660 #endif
02661 delete[] opCerts;
02662 return E_SUCCESS;
02663 }
02664
02665 SINT32 CACmdLnOptions::setOwnOperatorCertificate(DOMElement *elemCertificates)
02666 {
02667 DOMElement* elemOpCert = NULL;
02668 DOMElement *opCertX509 = NULL;
02669
02670 if(elemCertificates == NULL) return E_UNKNOWN;
02671 ASSERT_CERTIFICATES_OPTIONS_PARENT
02672 (elemCertificates->getNodeName(), OPTIONS_NODE_OWN_OPERATOR_CERTIFICATE);
02673
02674
02675 if (getDOMChildByName
02676 (elemCertificates, OPTIONS_NODE_OWN_OPERATOR_CERTIFICATE,
02677 elemOpCert, false) != E_SUCCESS)
02678 {
02679 LOG_NODE_NOT_FOUND(OPTIONS_NODE_OWN_OPERATOR_CERTIFICATE);
02680 return E_UNKNOWN;
02681 }
02682
02683 if (elemOpCert != NULL)
02684 {
02685 m_opCertList = getElementsByTagName(elemOpCert, "X509Certificate");
02686
02687 getDOMChildByName(elemOpCert, OPTIONS_NODE_X509_CERTIFICATE, opCertX509, true);
02688 if( opCertX509 != NULL)
02689 {
02690 m_OpCert = CACertificate::decode(opCertX509, CERT_X509CERTIFICATE);
02691 }
02692 else
02693 {
02694 LOG_NODE_NOT_FOUND(OPTIONS_NODE_X509_CERTIFICATE);
02695 return E_UNKNOWN;
02696 }
02697 }
02698 return E_SUCCESS;
02699 }
02700
02701 SINT32 CACmdLnOptions::setMixCertificateVerification(DOMElement *elemCertificates)
02702 {
02703 DOMElement *elemMixVerify;
02704 UINT8 tmpBuff[TMP_BUFF_SIZE];
02705 UINT32 tmpLen = TMP_BUFF_SIZE;
02706
02707 if(elemCertificates == NULL) return E_UNKNOWN;
02708 ASSERT_CERTIFICATES_OPTIONS_PARENT
02709 (elemCertificates->getNodeName(), OPTIONS_NODE_MIX_CERTIFICATE_VERIFICATION);
02710
02711 getDOMChildByName(elemCertificates, OPTIONS_NODE_MIX_CERTIFICATE_VERIFICATION, elemMixVerify, false);
02712 if(elemMixVerify != NULL)
02713 {
02714 if(getDOMElementValue(elemMixVerify, tmpBuff, &tmpLen) == E_SUCCESS &&
02715 memcmp(tmpBuff,"True",4)==0)
02716 {
02717 m_bVerifyMixCerts = true;
02718 m_pTrustedRootCertificates = new CACertStore();
02719 CAMsg::printMsg(LOG_INFO, "Mix certificate verification is enabled.\n");
02720 }
02721 }
02722 return E_SUCCESS;
02723 }
02724
02725 SINT32 CACmdLnOptions::setNextMixCertificate(DOMElement *elemCertificates)
02726 {
02727 DOMElement* elemNextCert = NULL;
02728
02729 if(!m_bVerifyMixCerts)
02730 {
02731 if(elemCertificates == NULL) return E_UNKNOWN;
02732 ASSERT_CERTIFICATES_OPTIONS_PARENT
02733 (elemCertificates->getNodeName(), OPTIONS_NODE_NEXT_MIX_CERTIFICATE);
02734
02735
02736 getDOMChildByName(elemCertificates, OPTIONS_NODE_NEXT_MIX_CERTIFICATE, elemNextCert,false);
02737 if(elemNextCert!=NULL)
02738 {
02739 m_pNextMixCertificate=
02740 CACertificate::decode(elemNextCert->getFirstChild(),CERT_X509CERTIFICATE);
02741 if(m_pNextMixCertificate == NULL)
02742 {
02743 CAMsg::printMsg(LOG_CRIT,"Could not decode the certificate of the next mix!\n");
02744 return E_UNKNOWN;
02745 }
02746 }
02747 }
02748 return E_SUCCESS;
02749
02750 }
02751
02752 SINT32 CACmdLnOptions::setPrevMixCertificate(DOMElement *elemCertificates)
02753 {
02754
02755 DOMElement* elemPrevCert=NULL;
02756
02757 if(!m_bVerifyMixCerts)
02758 {
02759 if(elemCertificates == NULL) return E_UNKNOWN;
02760 ASSERT_CERTIFICATES_OPTIONS_PARENT
02761 (elemCertificates->getNodeName(), OPTIONS_NODE_PREV_MIX_CERTIFICATE);
02762
02763 getDOMChildByName(elemCertificates, OPTIONS_NODE_PREV_MIX_CERTIFICATE, elemPrevCert, false);
02764 if(elemPrevCert!=NULL)
02765 {
02766 m_pPrevMixCertificate=
02767 CACertificate::decode(elemPrevCert->getFirstChild(),CERT_X509CERTIFICATE);
02768 }
02769 }
02770 return E_SUCCESS;
02771
02772 }
02773
02774 SINT32 CACmdLnOptions::setTrustedRootCertificates(DOMElement *elemCertificates)
02775 {
02776 DOMElement* elemTrustedCerts=NULL;
02777 DOMNodeList* trustedCerts=NULL;
02778 CACertificate* cert;
02779
02780 if(m_bVerifyMixCerts)
02781 {
02782 if(elemCertificates == NULL) return E_UNKNOWN;
02783 ASSERT_CERTIFICATES_OPTIONS_PARENT
02784 (elemCertificates->getNodeName(), OPTIONS_NODE_TRUSTED_ROOT_CERTIFICATES);
02785
02786 getDOMChildByName(elemCertificates, OPTIONS_NODE_TRUSTED_ROOT_CERTIFICATES, elemTrustedCerts, false);
02787 if(elemTrustedCerts!=NULL)
02788 {
02789 trustedCerts = getElementsByTagName(elemTrustedCerts, OPTIONS_NODE_X509_CERTIFICATE);
02790
02791 for(UINT32 i=0; i<trustedCerts->getLength(); i++)
02792 {
02793 cert = CACertificate::decode(trustedCerts->item(i), CERT_X509CERTIFICATE);
02794 if(cert != NULL)
02795 {
02796 m_pTrustedRootCertificates->add(cert);
02797 }
02798 else
02799 {
02800 CAMsg::printMsg(LOG_WARNING, "Root certificate could not be decoded\n");
02801 }
02802 }
02803 }
02804 else
02805 {
02806 LOG_NODE_NOT_FOUND(OPTIONS_NODE_TRUSTED_ROOT_CERTIFICATES);
02807 return E_UNKNOWN;
02808 }
02809 if(m_pTrustedRootCertificates->getNumber() == 0)
02810 {
02811 CAMsg::printMsg(LOG_CRIT, "No trusted root certificates found.\n");
02812 return E_UNKNOWN;
02813 }
02814 CAMsg::printMsg(LOG_INFO, "Loaded %d trusted root certificates.\n", m_pTrustedRootCertificates->getNumber());
02815 }
02816 return E_SUCCESS;
02817 }
02818
02819
02820
02821
02822 SINT32 CACmdLnOptions::setAccountingOptions(DOMElement *elemRoot)
02823 {
02824
02825 #ifdef PAYMENT
02826 DOMElement* elemAccounting=NULL;
02827 if (getDOMChildByName
02828 (elemRoot, OPTIONS_NODE_ACCOUNTING, elemAccounting, false) != E_SUCCESS)
02829 {
02830 LOG_NODE_NOT_FOUND(OPTIONS_NODE_ACCOUNTING);
02831 return E_UNKNOWN;
02832 }
02833
02834 return invokeOptionSetters
02835 (accountingOptionSetters, elemAccounting, ACCOUNTING_OPTIONS_NR);
02836 #endif
02837
02838 return E_SUCCESS;
02839 }
02840
02841 SINT32 CACmdLnOptions::setPriceCertificate(DOMElement *elemAccounting)
02842 {
02843
02844 #ifdef PAYMENT
02845 DOMElement* elemPriceCert = NULL;
02846
02847 if(elemAccounting == NULL) return E_UNKNOWN;
02848 ASSERT_ACCOUNTING_OPTIONS_PARENT
02849 (elemAccounting->getNodeName(), OPTIONS_NODE_PRICE_CERTIFICATE);
02850
02851
02852 getDOMChildByName
02853 (elemAccounting, OPTIONS_NODE_PRICE_CERTIFICATE, elemPriceCert, false);
02854 if (elemPriceCert == NULL)
02855 {
02856 CAMsg::printMsg(LOG_CRIT, "Did you really want to compile the mix with payment support?\n");
02857 LOG_NODE_NOT_FOUND(OPTIONS_NODE_PRICE_CERTIFICATE);
02858 return E_UNKNOWN;
02859 }
02860 else
02861 {
02862
02863
02864
02865
02866
02867
02868
02869
02870
02871
02872
02873
02874
02875
02876
02877
02878
02879
02880
02881 m_pPriceCertificate = CAXMLPriceCert::getInstance(elemPriceCert);
02882 if (m_pPriceCertificate == NULL)
02883 {
02884 CAMsg::printMsg(LOG_CRIT, "Could not parse price certificate!");
02885 return E_UNKNOWN;
02886 }
02887 m_strAiID = m_pPriceCertificate->getSubjectKeyIdentifier();
02888
02889 if (m_pMultiSignature != NULL && m_pMultiSignature->findSKI(m_strAiID) != E_SUCCESS)
02890 {
02891 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");
02892 return E_UNKNOWN;
02893 }
02894
02895 if (m_pBI == NULL)
02896 {
02897 CAMsg::printMsg(LOG_CRIT,"Could not verify price certificate, as no payment instance was found!\n");
02898 return E_UNKNOWN;
02899 }
02900
02901
02902 if (CAMultiSignature::verifyXML(elemPriceCert, m_pBI->getCertificate()) != E_SUCCESS)
02903 {
02904 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");
02905 return E_UNKNOWN;
02906 }
02907
02908 }
02909
02910
02911 return appendMixInfo_internal(elemPriceCert, WITH_SUBTREE);
02912
02913 #endif
02914 return E_SUCCESS;
02915 }
02916
02917 SINT32 CACmdLnOptions::setPaymentInstance(DOMElement *elemAccounting)
02918 {
02919
02920 #ifdef PAYMENT
02921 DOMElement* elemJPI = NULL;
02922
02923 if(elemAccounting == NULL) return E_UNKNOWN;
02924 ASSERT_ACCOUNTING_OPTIONS_PARENT
02925 (elemAccounting->getNodeName(), OPTIONS_NODE_PAYMENT_INSTANCE);
02926
02927 CAMsg::printMsg(LOG_DEBUG, "Parsing JPI values.\n");
02928
02929 getDOMChildByName(elemAccounting, OPTIONS_NODE_PAYMENT_INSTANCE, elemJPI, false);
02930 m_pBI = CAXMLBI::getInstance(elemJPI);
02931 if (m_pBI == NULL)
02932 {
02933 CAMsg::printMsg(LOG_CRIT,"Could not instantiate payment instance interface. Did you really want to compile the mix with payment support?\n");
02934 return E_UNKNOWN;
02935 }
02936 #endif
02937 return E_SUCCESS;
02938 }
02939
02940
02941 SINT32 CACmdLnOptions::setAccountingSoftLimit(DOMElement *elemAccounting)
02942 {
02943
02944 #ifdef PAYMENT
02945 DOMElement* elemAISoftLimit = NULL;
02946 UINT32 tmp = 0;
02947
02948 if(elemAccounting == NULL) return E_UNKNOWN;
02949 ASSERT_ACCOUNTING_OPTIONS_PARENT
02950 (elemAccounting->getNodeName(), OPTIONS_NODE_AI_SOFT_LIMIT);
02951
02952 if (getDOMChildByName
02953 (elemAccounting, OPTIONS_NODE_AI_SOFT_LIMIT, elemAISoftLimit, false) != E_SUCCESS)
02954 {
02955 LOG_NODE_NOT_FOUND(OPTIONS_NODE_AI_SOFT_LIMIT);
02956 return E_UNKNOWN;
02957 }
02958 if(getDOMElementValue(elemAISoftLimit, &tmp)==E_SUCCESS)
02959 {
02960 m_iPaymentSoftLimit = tmp;
02961 }
02962 else
02963 {
02964
02965 LOG_NODE_EMPTY_OR_INVALID(OPTIONS_NODE_AI_SOFT_LIMIT);
02966 return E_UNKNOWN;
02967 }
02968 #endif
02969 return E_SUCCESS;
02970 }
02971
02972
02973 SINT32 CACmdLnOptions::setAccountingHardLimit(DOMElement *elemAccounting)
02974 {
02975
02976 #ifdef PAYMENT
02977 DOMElement* elemAIHardLimit = NULL;
02978 UINT32 tmp = 0;
02979
02980 if(elemAccounting == NULL) return E_UNKNOWN;
02981 ASSERT_ACCOUNTING_OPTIONS_PARENT
02982 (elemAccounting->getNodeName(), OPTIONS_NODE_AI_HARD_LIMIT);
02983
02984 if (getDOMChildByName
02985 (elemAccounting, OPTIONS_NODE_AI_HARD_LIMIT, elemAIHardLimit, false) != E_SUCCESS)
02986 {
02987 LOG_NODE_NOT_FOUND(OPTIONS_NODE_AI_HARD_LIMIT);
02988 return E_UNKNOWN;
02989 }
02990 if(getDOMElementValue(elemAIHardLimit, &tmp)==E_SUCCESS)
02991 {
02992 m_iPaymentHardLimit = tmp;
02993 }
02994 else
02995 {
02996
02997 LOG_NODE_EMPTY_OR_INVALID(OPTIONS_NODE_AI_HARD_LIMIT);
02998 return E_UNKNOWN;
02999 }
03000 #endif
03001 return E_SUCCESS;
03002 }
03003
03004
03005 SINT32 CACmdLnOptions::setPrepaidInterval(DOMElement *elemAccounting)
03006 {
03007
03008 #ifdef PAYMENT
03009 DOMElement* elemPrepaidIval = NULL;
03010 UINT32 tmp = 0;
03011
03012 if(elemAccounting == NULL) return E_UNKNOWN;
03013 ASSERT_ACCOUNTING_OPTIONS_PARENT
03014 (elemAccounting->getNodeName(), OPTIONS_NODE_PREPAID_IVAL);
03015
03016 if (getDOMChildByName
03017 (elemAccounting, OPTIONS_NODE_PREPAID_IVAL, elemPrepaidIval, false) != E_SUCCESS)
03018 {
03019 LOG_NODE_NOT_FOUND(OPTIONS_NODE_PREPAID_IVAL);
03020
03021 if (getDOMChildByName
03022 (elemAccounting, OPTIONS_NODE_PREPAID_IVAL_KB, elemPrepaidIval, false) != E_SUCCESS)
03023 {
03024 LOG_NODE_NOT_FOUND(OPTIONS_NODE_PREPAID_IVAL_KB);
03025 }
03026 else
03027 {
03028 if(getDOMElementValue(elemPrepaidIval, &tmp)==E_SUCCESS)
03029 {
03030 m_iPrepaidInterval = tmp * 1000;
03031 }
03032 }
03033 }
03034 else if(getDOMElementValue(elemPrepaidIval, &tmp) == E_SUCCESS)
03035 {
03036 m_iPrepaidInterval = tmp;
03037 }
03038 else
03039 {
03040 CAMsg::printMsg(LOG_INFO,"Node \"%s\" is empty! Setting default...\n",
03041 OPTIONS_NODE_PREPAID_IVAL);
03042 m_iPrepaidInterval = OPTIONS_DEFAULT_PREPAID_IVAL;
03043 }
03044 if (m_iPrepaidInterval > OPTIONS_DEFAULT_PREPAID_IVAL )
03045 {
03046 CAMsg::printMsg(LOG_WARNING,"Prepaid interval is higher than %u! "
03047 "No JAP will pay more in advance!\n", OPTIONS_DEFAULT_PREPAID_IVAL);
03048 }
03049 else if (m_iPrepaidInterval < 5000)
03050 {
03051 CAMsg::printMsg(LOG_WARNING,"Prepaid interval of %u is far too low! "
03052 "Performance will be critical and clients will lose connection!\n", m_iPrepaidInterval);
03053 }
03054
03055
03056 DOMElement* elemInterval = createDOMElement(m_docMixInfo, OPTIONS_NODE_PREPAID_IVAL_KB);
03057 setDOMElementValue(elemInterval, (m_iPrepaidInterval / 1000) );
03058
03059 m_docMixInfo->getDocumentElement()->appendChild(elemInterval);
03060 #endif
03061 return E_SUCCESS;
03062 }
03063
03064
03065 SINT32 CACmdLnOptions::setSettleInterval(DOMElement *elemAccounting)
03066 {
03067
03068 #ifdef PAYMENT
03069 DOMElement* elemSettleIval = NULL;
03070 UINT32 tmp = 0;
03071
03072 if(elemAccounting == NULL) return E_UNKNOWN;
03073 ASSERT_ACCOUNTING_OPTIONS_PARENT
03074 (elemAccounting->getNodeName(), OPTIONS_NODE_SETTLE_IVAL);
03075
03076 if (getDOMChildByName
03077 (elemAccounting, OPTIONS_NODE_SETTLE_IVAL, elemSettleIval, false) != E_SUCCESS)
03078 {
03079 LOG_NODE_NOT_FOUND(OPTIONS_NODE_SETTLE_IVAL);
03080 return E_UNKNOWN;
03081 }
03082 if(getDOMElementValue(elemSettleIval, &tmp)==E_SUCCESS)
03083 {
03084 m_iPaymentSettleInterval = tmp;
03085 }
03086 else
03087 {
03088 LOG_NODE_EMPTY_OR_INVALID(OPTIONS_NODE_SETTLE_IVAL);
03089 return E_UNKNOWN;
03090 }
03091 #endif
03092 return E_SUCCESS;
03093 }
03094
03095
03096 SINT32 CACmdLnOptions::setAccountingDatabase(DOMElement *elemAccounting)
03097 {
03098 #ifdef PAYMENT
03099
03100 DOMElement* elem = NULL;
03101 DOMElement* elemDatabase = NULL;
03102 UINT8 tmpBuff[TMP_BUFF_SIZE];
03103 UINT32 tmpLen = TMP_BUFF_SIZE, tmp = 0;
03104
03105
03106 if (!m_bFirstMix)
03107 {
03108 return E_SUCCESS;
03109 }
03110
03111 if(elemAccounting == NULL) return E_UNKNOWN;
03112 ASSERT_ACCOUNTING_OPTIONS_PARENT
03113 (elemAccounting->getNodeName(), OPTIONS_NODE_AI_DB);
03114
03115 CAMsg::printMsg(LOG_DEBUG, "Parsing AI values.\n");
03116
03117 if (getDOMChildByName(elemAccounting, OPTIONS_NODE_AI_DB, elemDatabase, false) != E_SUCCESS)
03118 {
03119 LOG_NODE_NOT_FOUND(OPTIONS_NODE_AI_DB);
03120 return E_UNKNOWN;
03121 }
03122
03123
03124 if (getDOMChildByName(elemDatabase, OPTIONS_NODE_AI_DB_HOST, elem, false) != E_SUCCESS)
03125 {
03126 LOG_NODE_NOT_FOUND(OPTIONS_NODE_AI_DB_HOST);
03127 return E_UNKNOWN;
03128 }
03129
03130 if(getDOMElementValue(elem, tmpBuff, &tmpLen) != E_SUCCESS)
03131 {
03132 LOG_NODE_EMPTY_OR_INVALID(OPTIONS_NODE_AI_DB_HOST);
03133 return E_UNKNOWN;
03134 }
03135 strtrim(tmpBuff);
03136 m_strDatabaseHost = new UINT8[strlen((char*)tmpBuff)+1];
03137 strcpy((char *)m_strDatabaseHost, (char *) tmpBuff);
03138
03139
03140 if (getDOMChildByName
03141 (elemDatabase, OPTIONS_NODE_AI_DB_PORT, elem, false) != E_SUCCESS)
03142 {
03143 LOG_NODE_NOT_FOUND(OPTIONS_NODE_AI_DB_PORT);
03144 return E_UNKNOWN;
03145 }
03146 if(getDOMElementValue(elem, &tmp) != E_SUCCESS)
03147 {
03148 LOG_NODE_EMPTY_OR_INVALID(OPTIONS_NODE_AI_DB_PORT);
03149 return E_UNKNOWN;
03150 }
03151 m_iDatabasePort = tmp;
03152
03153
03154 if (getDOMChildByName
03155 (elemDatabase, OPTIONS_NODE_AI_DB_NAME, elem, false) != E_SUCCESS)
03156 {
03157 LOG_NODE_NOT_FOUND(OPTIONS_NODE_AI_DB_NAME);
03158 return E_UNKNOWN;
03159 }
03160
03161 tmpLen = TMP_BUFF_SIZE;
03162 memset(tmpBuff, 0, tmpLen);
03163
03164 if(getDOMElementValue
03165 (elem, tmpBuff, &tmpLen) != E_SUCCESS)
03166 {
03167 LOG_NODE_EMPTY_OR_INVALID(OPTIONS_NODE_AI_DB_NAME);
03168 return E_UNKNOWN;
03169 }
03170 strtrim(tmpBuff);
03171 m_strDatabaseName = new UINT8[strlen((char*)tmpBuff)+1];
03172 strcpy((char *)m_strDatabaseName, (char *) tmpBuff);
03173
03174
03175 if (getDOMChildByName
03176 (elemDatabase, OPTIONS_NODE_AI_DB_USER, elem, false) != E_SUCCESS)
03177 {
03178 LOG_NODE_NOT_FOUND(OPTIONS_NODE_AI_DB_USER);
03179 return E_UNKNOWN;
03180 }
03181
03182 tmpLen = TMP_BUFF_SIZE;
03183 memset(tmpBuff, 0, tmpLen);
03184
03185 if(getDOMElementValue
03186 (elem, tmpBuff, &tmpLen) != E_SUCCESS)
03187 {
03188 LOG_NODE_EMPTY_OR_INVALID(OPTIONS_NODE_AI_DB_USER);
03189 return E_UNKNOWN;
03190 }
03191 strtrim(tmpBuff);
03192 m_strDatabaseUser = new UINT8[strlen((char*)tmpBuff)+1];
03193 strcpy((char *)m_strDatabaseUser, (char *) tmpBuff);
03194
03195
03196 getDOMChildByName(elemDatabase, OPTIONS_NODE_AI_DB_PASSW, elem, false);
03197
03198 tmpLen = TMP_BUFF_SIZE;
03199 memset(tmpBuff, 0, tmpLen);
03200
03201
03202 if(getDOMElementValue(elem, tmpBuff, &tmpLen) != E_SUCCESS)
03203 {
03204
03205 UINT8 dbpass[500];
03206 dbpass[0] = 0;
03207 printf("Please enter password for postgresql user %s at %s: ",m_strDatabaseUser, m_strDatabaseHost);
03208 scanf("%400[^\n]%*1[\n]",(char*)dbpass);
03209 int len = strlen((char *)dbpass);
03210 if(len>0)
03211 {
03212 m_strDatabasePassword = new UINT8[len+1];
03213 strcpy((char *)m_strDatabasePassword, (char *)dbpass);
03214 }
03215 else
03216 {
03217 m_strDatabasePassword = new UINT8[1];
03218 m_strDatabasePassword[0] = '\0';
03219 }
03220 }
03221 else
03222 {
03223 strtrim(tmpBuff);
03224 m_strDatabasePassword = new UINT8[strlen((char*)tmpBuff)+1];
03225 strcpy((char *)m_strDatabasePassword, (char *) tmpBuff);
03226 }
03227 CAMsg::printMsg(LOG_DEBUG, "Accounting database information parsed successfully.\n");
03228
03229
03230 if(CAAccountingDBInterface::init() != E_SUCCESS)
03231 {
03232 exit(EXIT_FAILURE);
03233 }
03234 CAAccountingDBInterface::cleanup();
03235
03236 #endif
03237 return E_SUCCESS;
03238 }
03239
03240
03241
03242
03243 SINT32 CACmdLnOptions::setNetworkOptions(DOMElement *elemRoot)
03244 {
03245 DOMElement* elemNetwork = NULL;
03246 if (getDOMChildByName
03247 (elemRoot, OPTIONS_NODE_NETWORK, elemNetwork, false) != E_SUCCESS)
03248 {
03249 LOG_NODE_NOT_FOUND(OPTIONS_NODE_NETWORK);
03250 return E_UNKNOWN;
03251 }
03252
03253 return invokeOptionSetters
03254 (networkOptionSetters, elemNetwork, NETWORK_OPTIONS_NR);
03255 }
03256
03257 SINT32 CACmdLnOptions::setInfoServices(DOMElement *elemNetwork)
03258 {
03259 UINT8 tmpBuff[TMP_BUFF_SIZE];
03260 UINT32 tmpLen = TMP_BUFF_SIZE;
03261 DOMElement* elemInfoServiceContainer=NULL;
03262
03263 if(elemNetwork == NULL) return E_UNKNOWN;
03264 ASSERT_NETWORK_OPTIONS_PARENT
03265 (elemNetwork->getNodeName(), OPTIONS_NODE_INFOSERVICE_LIST);
03266
03267 getDOMChildByName
03268 (elemNetwork, OPTIONS_NODE_INFOSERVICE_LIST, elemInfoServiceContainer,false);
03269 if (elemInfoServiceContainer == NULL)
03270 {
03271
03272 DOMElement* elemInfoService=NULL;
03273 DOMElement* elemAllowReconfig=NULL;
03274 if (getDOMChildByName
03275 (elemNetwork, OPTIONS_NODE_INFOSERVICE, elemInfoService, false) != E_SUCCESS)
03276 {
03277 LOG_NODE_NOT_FOUND(OPTIONS_NODE_INFOSERVICE);
03278 }
03279
03280 if(elemInfoService != NULL)
03281 {
03282 getDOMChildByName
03283 (elemInfoService, OPTIONS_NODE_ALLOW_AUTO_CONF, elemAllowReconfig, false);
03284 CAListenerInterface* isListenerInterface = CAListenerInterface::getInstance(elemInfoService);
03285 if (!isListenerInterface)
03286 {
03287 LOG_NODE_EMPTY_OR_INVALID(OPTIONS_NODE_INFOSERVICE);
03288 }
03289 else
03290 {
03291 m_addrInfoServicesSize = 1;
03292 m_addrInfoServices = new CAListenerInterface*[m_addrInfoServicesSize];
03293 m_addrInfoServices[0] = isListenerInterface;
03294 if(getDOMElementValue(elemAllowReconfig,tmpBuff,&tmpLen)==E_SUCCESS)
03295 {
03296 m_bAcceptReconfiguration = (strcmp("True",(char*)tmpBuff) == 0);
03297 }
03298 }
03299 }
03300 }
03301 else
03302 {
03303
03304 parseInfoServices(elemInfoServiceContainer);
03305 }
03306
03307 return E_SUCCESS;
03308 }
03309
03310 SINT32 CACmdLnOptions::setListenerInterfaces(DOMElement *elemNetwork)
03311 {
03312 DOMElement* elemListenerInterfaces=NULL;
03313
03314 if(elemNetwork == NULL) return E_UNKNOWN;
03315 ASSERT_NETWORK_OPTIONS_PARENT
03316 (elemNetwork->getNodeName(), OPTIONS_NODE_LISTENER_INTERFACES);
03317
03318 getDOMChildByName
03319 (elemNetwork, OPTIONS_NODE_LISTENER_INTERFACES, elemListenerInterfaces, false);
03320 m_arListenerInterfaces = CAListenerInterface::getInstance(
03321 elemListenerInterfaces, m_cnListenerInterfaces);
03322
03323 #ifndef DYNAMIC_MIX
03324
03325 if (m_cnListenerInterfaces == 0)
03326 {
03327 CAMsg::printMsg(LOG_CRIT, "No listener interfaces found!\n");
03328 return E_UNKNOWN;
03329 }
03330 #endif
03331 if(elemListenerInterfaces != NULL)
03332 {
03333
03334
03335 appendMixInfo_internal(elemListenerInterfaces, WITH_SUBTREE);
03336 }
03337
03338 UINT32 i;
03339 SINT32 ret;
03340 CASocket** arrSocketsIn=new CASocket*[getListenerInterfaceCount()];
03341 for (i = 0; i < getListenerInterfaceCount(); i++)
03342 {
03343 arrSocketsIn[i] = NULL;
03344 }
03345
03346 ret = createSockets(false, arrSocketsIn, getListenerInterfaceCount());
03347
03348 for(i=0;i<getListenerInterfaceCount();i++)
03349 {
03350 if (arrSocketsIn[i] != NULL)
03351 {
03352 arrSocketsIn[i]->close();
03353 delete arrSocketsIn[i];
03354 arrSocketsIn[i] = NULL;
03355 }
03356 }
03357 delete[] arrSocketsIn;
03358 arrSocketsIn=NULL;
03359
03360
03361 if (ret != E_SUCCESS && ret != E_UNSPECIFIED && ret != E_SPACE)
03362 {
03363 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");
03364 }
03365
03366 return ret;
03367 }
03368
03369
03370 SINT32 CACmdLnOptions::createSockets(bool a_bMessages, CASocket** a_sockets, UINT32 a_socketsLen)
03371 {
03372 if (a_socketsLen <= 0)
03373 {
03374 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.");
03375 return E_SPACE;
03376 }
03377
03378
03379 UINT32 aktSocket;
03380 UINT8 buff[255];
03381 SINT32 ret = E_UNKNOWN;
03382 UINT32 currentInterface;
03383 CASocketAddr* pAddr;
03384 UINT32* arrayVirtualPorts = new UINT32[a_socketsLen];
03385 UINT32 iVirtualPortsLen = 0;
03386 UINT32 iHiddenPortsLen = 0;
03387 UINT32* arrayHiddenPorts = new UINT32[a_socketsLen];
03388
03389
03390 aktSocket = -1;
03391 for(currentInterface=0;currentInterface < getListenerInterfaceCount(); currentInterface++)
03392 {
03393 CAListenerInterface* pListener=NULL;
03394 pListener=getListenerInterface(currentInterface+1);
03395 if(pListener==NULL)
03396 {
03397 CAMsg::printMsg(LOG_CRIT,"Error: Listener interface %d is invalid.\n", currentInterface+1);
03398
03399 delete[] arrayVirtualPorts;
03400 delete[] arrayHiddenPorts;
03401
03402 return E_UNKNOWN;
03403 }
03404
03405 pAddr=pListener->getAddr();
03406 pAddr->toString(buff,255);
03407
03408 if(pAddr->getType()==AF_INET)
03409 {
03410 if (pListener->isVirtual())
03411 {
03412 arrayVirtualPorts[iVirtualPortsLen] = ((CASocketAddrINet*)pAddr)->getPort();
03413 iVirtualPortsLen++;
03414 }
03415 else if (pListener->isHidden())
03416 {
03417 arrayHiddenPorts[iHiddenPortsLen] = ((CASocketAddrINet*)pAddr)->getPort();
03418 iHiddenPortsLen++;
03419 }
03420 }
03421
03422 if(pListener->isVirtual())
03423 {
03424 delete pListener;
03425 pListener = NULL;
03426 delete pAddr;
03427 pAddr = NULL;
03428 continue;
03429 }
03430 aktSocket++;
03431
03432 if (a_socketsLen < (aktSocket + 1))
03433 {
03434 CAMsg::printMsg(LOG_CRIT,
03435 "Found %d listener sockets, but we have only reserved memory for %d sockets. This seems to be an implementation error in the code.\n",
03436 (aktSocket + 1), a_socketsLen);
03437
03438 delete[] arrayVirtualPorts;
03439 delete[] arrayHiddenPorts;
03440 delete pAddr;
03441
03442 return E_SPACE;
03443 }
03444
03445 ret = E_SUCCESS;
03446 a_sockets[aktSocket] = new CASocket();
03447 a_sockets[aktSocket]->create(pAddr->getType());
03448 a_sockets[aktSocket]->setReuseAddr(true);
03449
03450 delete pListener;
03451 pListener = NULL;
03452 #ifndef _WIN32
03453
03454 int old_uid=geteuid();
03455 if(pAddr->getType()==AF_INET&&((CASocketAddrINet*)pAddr)->getPort()<1024)
03456 {
03457 if(seteuid(0)==-1)
03458 {
03459 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",
03460 currentInterface+1, buff);
03461 }
03462 }
03463 #endif
03464 ret=a_sockets[aktSocket]->listen(*pAddr);
03465 delete pAddr;
03466 pAddr = NULL;
03467
03468 if(ret!=E_SUCCESS)
03469 {
03470 CAMsg::printMsg(LOG_CRIT,"Socket error while listening on interface %d (%s). Reason: %s (%i)\n",currentInterface+1, buff,
03471 GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR);
03472 }
03473
03474 #ifndef _WIN32
03475 seteuid(old_uid);
03476 #endif
03477 if(ret!=E_SUCCESS)
03478 {
03479 delete[] arrayVirtualPorts;
03480 delete[] arrayHiddenPorts;
03481 return E_UNKNOWN;
03482 }
03483
03484 if (a_bMessages)
03485 {
03486 CAMsg::printMsg(LOG_DEBUG,"Listening on Interface: %s\n",buff);
03487 }
03488 }
03489
03490 if (ret == E_UNKNOWN)
03491 {
03492 CAMsg::printMsg(LOG_CRIT,"Could not find any valid (non-virtual) listener interface!\n");
03493 }
03494 else if (ret == E_SUCCESS)
03495 {
03496 for (UINT32 iHiddenPort = 0; iHiddenPort < iHiddenPortsLen; iHiddenPort++)
03497 {
03498 bool bVirtualFound = false;
03499 for (UINT32 iVirtualPort = 0; iVirtualPort < iVirtualPortsLen; iVirtualPort++)
03500 {
03501 if (arrayHiddenPorts[iHiddenPort] == arrayVirtualPorts[iVirtualPort])
03502 {
03503 bVirtualFound = true;
03504 arrayVirtualPorts[iVirtualPort] = 0;
03505 }
03506 }
03507 if (!bVirtualFound)
03508 {
03509 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]);
03510 ret = E_UNSPECIFIED;
03511 break;
03512 }
03513 }
03514
03515 if (ret == E_SUCCESS)
03516 {
03517 for (UINT32 iVirtualPort = 0; iVirtualPort < iVirtualPortsLen; iVirtualPort++)
03518 {
03519 if (arrayVirtualPorts[iVirtualPort] != 0)
03520 {
03521 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]);
03522 ret = E_UNSPECIFIED;
03523 break;
03524 }
03525 }
03526 }
03527 }
03528
03529 if (ret == E_SUCCESS && a_bMessages)
03530 {
03531 CAMsg::printMsg(LOG_DEBUG,"Listening on all interfaces.\n");
03532 }
03533
03534 delete[] arrayVirtualPorts;
03535 delete[] arrayHiddenPorts;
03536 arrayVirtualPorts = NULL;
03537
03538 return ret;
03539 }
03540
03541
03542
03543 SINT32 CACmdLnOptions::setTargetInterfaces(DOMElement *elemNetwork)
03544 {
03545 UINT8 tmpBuff[TMP_BUFF_SIZE];
03546 UINT32 tmpLen = TMP_BUFF_SIZE;
03547 DOMElement* elemNextMix = NULL;
03548 DOMElement* elemProxies=NULL;
03549 TargetInterface* targetInterfaceNextMix = NULL;
03550
03551 m_cnTargets=0;
03552
03553 if(elemNetwork == NULL) return E_UNKNOWN;
03554 ASSERT_NETWORK_OPTIONS_PARENT
03555 (elemNetwork->getNodeName(), OPTIONS_NODE_NEXT_MIX);
03556
03557
03558 getDOMChildByName
03559 (elemNetwork, OPTIONS_NODE_NEXT_MIX, elemNextMix, false);
03560 if(elemNextMix != NULL)
03561 {
03562 NetworkType type;
03563 CASocketAddr* addr = NULL;
03564 DOMElement* elemType = NULL;
03565 getDOMChildByName
03566 (elemNextMix, OPTIONS_NODE_NETWORK_PROTOCOL, elemType, false);
03567
03568 bool bAddrIsSet = false;
03569
03570 if(getDOMElementValue(elemType, tmpBuff, &tmpLen) == E_SUCCESS)
03571 {
03572 strtrim(tmpBuff);
03573 if(strcmp((char*)tmpBuff, "RAW/TCP") == 0)
03574 {
03575 type=RAW_TCP;
03576 }
03577 else if(strcmp((char*)tmpBuff, "RAW/UNIX") == 0)
03578 {
03579 type=RAW_UNIX;
03580 }
03581 else if(strcmp((char*)tmpBuff, "SSL/TCP") == 0)
03582 {
03583 type=SSL_TCP;
03584 }
03585 else if(strcmp((char*)tmpBuff, "SSL/UNIX") == 0)
03586 {
03587 type=SSL_UNIX;
03588 }
03589
03590 if( (type == SSL_TCP) || (type == RAW_TCP) )
03591 {
03592 DOMElement* elemPort = NULL;
03593 DOMElement* elemHost = NULL;
03594 DOMElement* elemIP = NULL;
03595 UINT8 buffHost[TMP_BUFF_SIZE];
03596 UINT32 buffHostLen = TMP_BUFF_SIZE;
03597 UINT16 port;
03598 getDOMChildByName
03599 (elemNextMix, OPTIONS_NODE_PORT, elemPort, false);
03600 if(getDOMElementValue(elemPort,&port) == E_SUCCESS)
03601 {
03602 addr = new CASocketAddrINet;
03603
03604 getDOMChildByName
03605 (elemNextMix, OPTIONS_NODE_HOST, elemHost, false);
03606
03607
03608
03609
03610 if(elemHost != NULL)
03611 {
03612 if(getDOMElementValue(elemHost,buffHost,&buffHostLen)==E_SUCCESS &&
03613 ((CASocketAddrINet*)addr)->setAddr(buffHost,port)==E_SUCCESS)
03614 {
03615 bAddrIsSet = true;
03616 }
03617 }
03618 if(!bAddrIsSet)
03619 {
03620 getDOMChildByName(elemNextMix, OPTIONS_NODE_IP, elemIP, false);
03621 if(elemIP == NULL || getDOMElementValue(elemIP,buffHost,&buffHostLen) == E_SUCCESS)
03622 {
03623 ((CASocketAddrINet*)addr)->setAddr(buffHost,port);
03624 bAddrIsSet = true;
03625 }
03626 }
03627 CAMsg::printMsg(LOG_INFO, "Setting target interface: %s:%d\n", buffHost, port);
03628 }
03629 }
03630 #ifdef HAVE_UNIX_DOMAIN_PROTOCOL
03631 else if( (type == SSL_UNIX) || (type == RAW_UNIX) )
03632 {
03633 DOMElement* elemFile=NULL;
03634 getDOMChildByName(elemNextMix, OPTIONS_NODE_FILE, elemFile, false);
03635 tmpLen = TMP_BUFF_SIZE;
03636 if(getDOMElementValue(elemFile, tmpBuff, &tmpLen) == E_SUCCESS)
03637 {
03638 tmpBuff[tmpLen]=0;
03639 strtrim(tmpBuff);
03640 addr=new CASocketAddrUnix;
03641 if(((CASocketAddrUnix*)addr)->setPath((char*)tmpBuff) == E_SUCCESS)
03642 {
03643 bAddrIsSet = true;
03644 }
03645 }
03646 }
03647 #endif
03648 }
03649
03650 if(bAddrIsSet)
03651 {
03652 targetInterfaceNextMix=new TargetInterface;
03653 targetInterfaceNextMix->target_type=TARGET_MIX;
03654 targetInterfaceNextMix->net_type=type;
03655 targetInterfaceNextMix->addr=addr->clone();
03656 m_cnTargets=1;
03657 }
03658
03659 delete addr;
03660 addr = NULL;
03661 }
03662
03663
03664 SINT32 ret;
03665 UINT8 buff[255];
03666 UINT32 buffLen = 255;
03667 CASocket* tmpSocket;
03668
03669 clearVisibleAddresses();
03670 getDOMChildByName(elemNetwork, OPTIONS_NODE_PROXY_LIST, elemProxies, false);
03671 if(elemProxies != NULL)
03672 {
03673 DOMNodeList* nlTargetInterfaces=NULL;
03674 nlTargetInterfaces=getElementsByTagName(elemProxies, OPTIONS_NODE_PROXY);
03675 m_cnTargets+=nlTargetInterfaces->getLength();
03676
03677 if(nlTargetInterfaces->getLength()>0)
03678 {
03679 m_arTargetInterfaces=new TargetInterface[m_cnTargets];
03680 UINT32 aktInterface=0;
03681 NetworkType type=UNKNOWN_NETWORKTYPE;
03682 UINT32 proxy_type=0;
03683 CASocketAddr* addr=NULL;
03684 UINT16 port;
03685 bool bHttpProxyFound = false;
03686 for(UINT32 i=0; i < nlTargetInterfaces->getLength(); i++)
03687 {
03688 delete addr;
03689 addr=NULL;
03690 DOMNode* elemTargetInterface=NULL;
03691 elemTargetInterface=nlTargetInterfaces->item(i);
03692 DOMElement* elemType;
03693 getDOMChildByName
03694 (elemTargetInterface, OPTIONS_NODE_NETWORK_PROTOCOL, elemType,false);
03695 tmpLen = TMP_BUFF_SIZE;
03696 if(getDOMElementValue(elemType,tmpBuff,&tmpLen)!=E_SUCCESS)
03697 continue;
03698 strtrim(tmpBuff);
03699 if(strcmp((char*)tmpBuff,"RAW/TCP") == 0)
03700 {
03701 type=RAW_TCP;
03702 }
03703 else if(strcmp((char*)tmpBuff,"RAW/UNIX") == 0)
03704 {
03705 type=RAW_UNIX;
03706 }
03707 else if(strcmp((char*)tmpBuff,"SSL/TCP") == 0)
03708 {
03709 type=SSL_TCP;
03710 }
03711 else if(strcmp((char*)tmpBuff,"SSL/UNIX") == 0)
03712 {
03713 type=SSL_UNIX;
03714 }
03715 else
03716 {
03717 continue;
03718 }
03719
03720 elemType=NULL;
03721 getDOMChildByName
03722 (elemTargetInterface, OPTIONS_NODE_PROXY_TYPE, elemType, false);
03723 tmpLen = TMP_BUFF_SIZE;
03724 if(getDOMElementValue(elemType,tmpBuff,&tmpLen)!=E_SUCCESS)
03725 continue;
03726 strtrim(tmpBuff);
03727 if(strcmp((char*)tmpBuff,"SOCKS")==0)
03728 {
03729 proxy_type=TARGET_SOCKS_PROXY;
03730 }
03731 else if(strcmp((char*)tmpBuff,"HTTP")==0)
03732 {
03733 proxy_type=TARGET_HTTP_PROXY;
03734 }
03735 else
03736 {
03737 continue;
03738 }
03739
03740 if( (type==SSL_TCP) || (type == RAW_TCP) )
03741 {
03742 DOMElement* elemPort;
03743 DOMElement* elemHost;
03744 getDOMChildByName
03745 (elemTargetInterface, OPTIONS_NODE_PORT, elemPort, false);
03746 if(getDOMElementValue(elemPort,&port)!=E_SUCCESS)
03747 {
03748 continue;
03749 }
03750 addr=new CASocketAddrINet;
03751 getDOMChildByName
03752 (elemTargetInterface, OPTIONS_NODE_HOST, elemHost, false);
03753 if(elemHost != NULL)
03754 {
03755 UINT8 buffHost[TMP_BUFF_SIZE];
03756 UINT32 buffHostLen = TMP_BUFF_SIZE;
03757 if(getDOMElementValue(elemHost, buffHost, &buffHostLen) != E_SUCCESS)
03758 {
03759 continue;
03760 }
03761 if(((CASocketAddrINet*)addr)->setAddr(buffHost, port) != E_SUCCESS)
03762 {
03763 continue;
03764 }
03765 }
03766 else
03767 {
03768 continue;
03769 }
03770 }
03771 else
03772 #ifdef HAVE_UNIX_DOMAIN_PROTOCOL
03773 {
03774 DOMElement* elemFile;
03775 getDOMChildByName
03776 (elemTargetInterface, OPTIONS_NODE_FILE, elemFile, false);
03777 tmpLen = TMP_BUFF_SIZE;
03778 if(getDOMElementValue(elemFile, tmpBuff, &tmpLen) != E_SUCCESS)
03779 {
03780 continue;
03781 }
03782 tmpBuff[tmpLen]=0;
03783 strtrim(tmpBuff);
03784 addr=new CASocketAddrUnix;
03785 if(((CASocketAddrUnix*)addr)->setPath((char*)tmpBuff) != E_SUCCESS)
03786 {
03787 continue;
03788 }
03789 }
03790 #else
03791 continue;
03792 #endif
03793
03794
03795
03796
03797 tmpSocket = new CASocket;
03798 tmpSocket->setRecvBuff(50000);
03799 tmpSocket->setSendBuff(5000);
03800 ret = tmpSocket->connect(*addr,LAST_MIX_TO_PROXY_CONNECT_TIMEOUT);
03801 if (ret != E_SUCCESS)
03802 {
03803 if (addr->toString(buff, buffLen) != E_SUCCESS)
03804 {
03805 buff[0] = 0;
03806 }
03807 if (ret != E_UNKNOWN)
03808 {
03809 CAMsg::printMsg(LOG_WARNING, "Could not connect to proxy %s! Reason: %s (%i) Please check if the proxy is running.\n",
03810 buff, GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR);
03811 }
03812 else
03813 {
03814 CAMsg::printMsg(LOG_WARNING, "Could not connect to proxy %s! Please check if the proxy is running.\n", buff);
03815 }
03816 }
03817
03818 if (ret == E_SUCCESS)
03819 {
03820 if (proxy_type == TARGET_HTTP_PROXY)
03821 {
03822
03823
03824
03825
03826
03827 bHttpProxyFound = true;
03828 }
03829 else if (proxy_type == TARGET_SOCKS_PROXY)
03830 {
03831
03832 m_bSocksSupport = true;
03833 }
03834 }
03835
03836 tmpSocket->close();
03837 delete tmpSocket;
03838
03839
03840 if (ret == E_SUCCESS)
03841 {
03842 addVisibleAddresses(elemTargetInterface);
03843 m_arTargetInterfaces[aktInterface].net_type=type;
03844 m_arTargetInterfaces[aktInterface].target_type=proxy_type;
03845 m_arTargetInterfaces[aktInterface].addr=addr->clone();
03846 aktInterface++;
03847 }
03848
03849
03850 delete addr;
03851 addr=NULL;
03852 }
03853
03854 if (!bHttpProxyFound)
03855 {
03856 CAMsg::printMsg(LOG_CRIT, "No valid HTTP proxy was specified! Please install and configure an HTTP proxy like Squid before starting the mix.\n");
03857 for (UINT32 i = 0; i < aktInterface; i++)
03858 {
03859 delete m_arTargetInterfaces[aktInterface].addr;
03860 }
03861
03862
03863 return E_UNKNOWN;
03864 }
03865
03866 m_cnTargets=aktInterface;
03867 }
03868 }
03869
03870 if(targetInterfaceNextMix != NULL)
03871 {
03872 if(m_arTargetInterfaces == NULL)
03873 {
03874 m_cnTargets=0;
03875 m_arTargetInterfaces=new TargetInterface[1];
03876 }
03877 m_arTargetInterfaces[m_cnTargets].net_type=targetInterfaceNextMix->net_type;
03878 m_arTargetInterfaces[m_cnTargets].target_type=targetInterfaceNextMix->target_type;
03879 m_arTargetInterfaces[m_cnTargets++].addr=targetInterfaceNextMix->addr;
03880 delete targetInterfaceNextMix;
03881 targetInterfaceNextMix = NULL;
03882 }
03883 else if(m_arTargetInterfaces == NULL)
03884 {
03885 CAMsg::printMsg(LOG_CRIT, "Neither proxy nor next mix target interfaces are specified!\n");
03886 return E_UNKNOWN;
03887 }
03888
03889
03890 if(isLastMix() && (m_docMixInfo != NULL) )
03891 {
03892 DOMElement* elemMix = m_docMixInfo->getDocumentElement();
03893 if(elemMix != NULL)
03894 {
03895 DOMElement* elemProxies=createDOMElement(m_docMixInfo,"Proxies");
03896 if (m_bSocksSupport)
03897 {
03898 setDOMElementAttribute(elemProxies, "socks5Support", (UINT8*)"true");
03899 }
03900 DOMElement* elemProxy=createDOMElement(m_docMixInfo,"Proxy");
03901 DOMElement* elemVisAddresses=createDOMElement(m_docMixInfo,"VisibleAddresses");
03902 elemMix->appendChild(elemProxies);
03903 elemProxies->appendChild(elemProxy);
03904 elemProxy->appendChild(elemVisAddresses);
03905 for(UINT32 i=1;i<=getVisibleAddressesCount();i++)
03906 {
03907 UINT8 tmp[255];
03908 UINT32 tmplen=255;
03909 if(getVisibleAddress(tmp,tmplen,i)==E_SUCCESS)
03910 {
03911 DOMElement* elemVisAddress=createDOMElement(m_docMixInfo,"VisibleAddress");
03912 DOMElement* elemHost=createDOMElement(m_docMixInfo,"Host");
03913 elemVisAddress->appendChild(elemHost);
03914 setDOMElementValue(elemHost,tmp);
03915 elemVisAddresses->appendChild(elemVisAddress);
03916 }
03917 }
03918 }
03919 }
03920
03921 return E_SUCCESS;
03922 }
03923
03924 SINT32 CACmdLnOptions::setServerMonitoring(DOMElement *elemNetwork)
03925 {
03926 #ifdef SERVER_MONITORING
03927
03928 UINT8 tmpBuff[TMP_BUFF_SIZE];
03929 UINT32 tmpLen = TMP_BUFF_SIZE;
03930
03931 DOMElement* elemServerMonitoringRoot = NULL;
03932 DOMElement* elemServerMonitoringHost = NULL;
03933 DOMElement* elemServerMonitoringPort = NULL;
03934
03935 if(elemNetwork == NULL) return E_UNKNOWN;
03936 ASSERT_NETWORK_OPTIONS_PARENT
03937 (elemNetwork->getNodeName(), OPTIONS_NODE_SERVER_MONITORING);
03938
03939 m_strMonitoringListenerHost = NULL;
03940 m_iMonitoringListenerPort = 0xFFFF;
03941
03942 if (getDOMChildByName
03943 (elemNetwork, OPTIONS_NODE_SERVER_MONITORING, elemServerMonitoringRoot,false) == E_SUCCESS)
03944 {
03945 if(getDOMChildByName
03946 (elemServerMonitoringRoot, OPTIONS_NODE_HOST, elemServerMonitoringHost, false) == E_SUCCESS)
03947 {
03948 if(getDOMElementValue(elemServerMonitoringHost,
03949 (UINT8 *)tmpBuff,&tmpLen)==E_SUCCESS)
03950 {
03951 m_strMonitoringListenerHost = new char[tmpLen+1];
03952 strncpy(m_strMonitoringListenerHost, (const char*) tmpBuff, tmpLen);
03953 m_strMonitoringListenerHost[tmpLen] = 0;
03954 }
03955 }
03956 if(getDOMChildByName
03957 (elemServerMonitoringRoot, OPTIONS_NODE_PORT,
03958 elemServerMonitoringPort, false) == E_SUCCESS)
03959 {
03960 UINT16 port = 0xFFFF;
03961 if(getDOMElementValue(elemServerMonitoringPort, &port)==E_SUCCESS)
03962 {
03963 m_iMonitoringListenerPort = port;
03964 }
03965 }
03966
03967
03968 if( (elemServerMonitoringRoot != NULL) &&
03969 (m_strMonitoringListenerHost != NULL))
03970 {
03971 if( (strncmp("localhost", m_strMonitoringListenerHost, 9) != 0) &&
03972 (strncmp("127.0.0.1", m_strMonitoringListenerHost, 9) != 0) )
03973 {
03974 appendMixInfo_internal(elemServerMonitoringRoot, WITH_SUBTREE);
03975 }
03976 }
03977 }
03978 else
03979 {
03980 CAMsg::printMsg(LOG_DEBUG, "Server Monitoring Config not found\n");
03981 }
03982 #endif
03983 return E_SUCCESS;
03984 }
03985
03986
03987 SINT32 CACmdLnOptions::setKeepAliveTraffic(DOMElement *elemNetwork)
03988 {
03989 DOMElement* elemKeepAlive = NULL;
03990 DOMElement* elemKeepAliveSendInterval = NULL;
03991 DOMElement* elemKeepAliveRecvInterval = NULL;
03992
03993 if(elemNetwork == NULL) return E_UNKNOWN;
03994 ASSERT_NETWORK_OPTIONS_PARENT
03995 (elemNetwork->getNodeName(), OPTIONS_NODE_SERVER_MONITORING);
03996
03997 getDOMChildByName(elemNetwork, OPTIONS_NODE_KEEP_ALIVE, elemKeepAlive, false);
03998 getDOMChildByName(elemKeepAlive, OPTIONS_NODE_KEEP_ALIVE_SEND_IVAL, elemKeepAliveSendInterval, false);
03999 getDOMChildByName(elemKeepAlive, OPTIONS_NODE_KEEP_ALIVE_RECV_IVAL, elemKeepAliveRecvInterval, false);
04000 getDOMElementValue(elemKeepAliveSendInterval, m_u32KeepAliveSendInterval, KEEP_ALIVE_TRAFFIC_SEND_WAIT_TIME);
04001 getDOMElementValue(elemKeepAliveRecvInterval, m_u32KeepAliveRecvInterval, KEEP_ALIVE_TRAFFIC_RECV_WAIT_TIME);
04002 return E_SUCCESS;
04003 }
04004
04005
04006
04007
04008
04009
04010 SINT32 CACmdLnOptions::setRessourceOptions(DOMElement *elemRoot)
04011 {
04012 #if defined (DELAY_CHANNELS) ||defined(DELAY_USERS)||defined(DELAY_CHANNELS_LATENCY)
04014 //this is at the moment:
04015
04016
04017
04018
04019
04020
04021 CAMsg::printMsg(LOG_INFO,"Loading Parameters for traffic shaping / resource limitation....\n");
04022 UINT32 u32 = 0;
04023 DOMElement *elemRessources=NULL;
04024 DOMElement *elem = NULL;
04025
04026 if(elemRoot == NULL)
04027 {
04028 return E_UNKNOWN;
04029 }
04030
04031 getDOMChildByName(elemRoot, OPTIONS_NODE_RESSOURCES, elemRessources,false);
04032 if(elemRessources!=NULL)
04033 {
04034 #if defined (DELAY_CHANNELS) || defined(DELAY_USERS)
04035 if( getDOMChildByName
04036 (elemRessources, OPTIONS_NODE_UNLIMIT_TRAFFIC, elem, false) == E_SUCCESS &&
04037 getDOMElementValue(elem, &u32) == E_SUCCESS )
04038 {
04039 m_u32DelayChannelUnlimitTraffic = u32;
04040 }
04041 if( getDOMChildByName
04042 (elemRessources, OPTIONS_NODE_BYTES_PER_IVAL, elem, false) == E_SUCCESS &&
04043 getDOMElementValue(elem, &u32) == E_SUCCESS)
04044 {
04045 m_u32DelayChannelBucketGrow = u32;
04046 }
04047 if( getDOMChildByName
04048 (elemRessources, OPTIONS_NODE_DELAY_IVAL, elem, false) == E_SUCCESS &&
04049 getDOMElementValue(elem, &u32) == E_SUCCESS)
04050 {
04051 m_u32DelayChannelBucketGrowIntervall = u32;
04052 }
04053 #endif
04054 #if defined (DELAY_CHANNELS_LATENCY)
04055 if( getDOMChildByName
04056 (elemRessources, OPTIONS_NODE_LATENCY, elem, false) == E_SUCCESS &&
04057 getDOMElementValue(elem, &u32) == E_SUCCESS)
04058 {
04059 m_u32DelayChannelLatency = u32;
04060 }
04061 #endif
04062 }
04063 #endif
04064 return E_SUCCESS;
04065 }
04066
04067
04068
04069
04070 SINT32 CACmdLnOptions::setTermsAndConditions(DOMElement *elemRoot)
04071 {
04072 SINT32 ret = E_SUCCESS;
04073 DOMElement *elemTnCs = NULL;
04074
04075 if(elemRoot == NULL)
04076 {
04077 return E_UNKNOWN;
04078 }
04079
04080 ret = getDOMChildByName(elemRoot, OPTIONS_NODE_TNCS_OPTS, elemTnCs, true);
04081 if(elemTnCs != NULL)
04082 {
04083 return invokeOptionSetters
04084 (termsAndConditionsOptionSetters, elemTnCs, TERMS_AND_CONDITIONS_OPTIONS_NR);
04085 }
04086 else
04087 {
04088 CAMsg::printMsg(LOG_WARNING,"No Terms & Conditions for Operator specified!\n");
04089 return E_SUCCESS;
04090 }
04091 }
04092
04093 SINT32 CACmdLnOptions::setTermsAndConditionsTemplates(DOMElement *elemTnCs)
04094 {
04095 if(elemTnCs == NULL)
04096 {
04097 CAMsg::printMsg(LOG_CRIT,"Terms And Conditions root element is null!\n");
04098 return E_UNKNOWN;
04099 }
04100 DOMElement *elemTnCsTemplates = NULL;
04101 DOMNodeList *templateList = NULL;
04102 bool nothingFound = true;
04103 getDOMChildByName(elemTnCs, OPTIONS_NODE_TNCS_TEMPLATES, elemTnCsTemplates);
04104
04105 UINT8** loadedTemplateRefIds = NULL;
04106 bool templateError = false;
04107
04108 if(elemTnCsTemplates != NULL)
04109 {
04110 templateList = getElementsByTagName(elemTnCsTemplates, OPTIONS_NODE_TNCS_TEMPLATE);
04111 if(templateList->getLength() > 0)
04112 {
04113 nothingFound = false;
04114 m_nrOfTermsAndConditionsTemplates = templateList->getLength();
04115 m_termsAndConditionsTemplates = new XERCES_CPP_NAMESPACE::DOMDocument*[m_nrOfTermsAndConditionsTemplates];
04116 loadedTemplateRefIds = new UINT8*[m_nrOfTermsAndConditionsTemplates];
04117 memset(loadedTemplateRefIds, 0, (sizeof(UINT8*)*m_nrOfTermsAndConditionsTemplates) );
04118
04119 UINT8 currentTemplateURL[TMP_BUFF_SIZE];
04120 UINT32 len = TMP_BUFF_SIZE;
04121 memset(currentTemplateURL, 0, len);
04122
04123 for (XMLSize_t i = 0; i < templateList->getLength(); i++)
04124 {
04125 getDOMElementValue(templateList->item(i), currentTemplateURL, &len);
04126 m_termsAndConditionsTemplates[i] = parseDOMDocument(currentTemplateURL);
04127 if(m_termsAndConditionsTemplates[i] == NULL)
04128 {
04129 CAMsg::printMsg(LOG_WARNING, "Cannot load Terms And Conditions template '%s'.\n",
04130 currentTemplateURL);
04131 return E_UNKNOWN;
04132 }
04133 UINT8* refId = getTermsAndConditionsTemplateRefId(m_termsAndConditionsTemplates[i]->getDocumentElement());
04134 if(refId != NULL)
04135 {
04136 loadedTemplateRefIds[i] = refId;
04137 for(XMLSize_t j = 0; j < i; j++)
04138 {
04139 if(strncmp((char *)refId, (char *) loadedTemplateRefIds[j], TEMPLATE_REFID_MAXLEN) == 0 )
04140 {
04141 templateError = true;
04142 CAMsg::printMsg(LOG_ERR, "duplicate Terms And Conditions template '%s'.\n",refId);
04143 break;
04144 }
04145 }
04146 }
04147 else
04148 {
04149 templateError = true;
04150 CAMsg::printMsg(LOG_ERR, "Terms And Conditions template with invalid refid found.\n");
04151 break;
04152 }
04153
04154 if(!templateError)
04155 {
04156 CAMsg::printMsg(LOG_INFO, "loaded Terms And Conditions template '%s'.\n",refId);
04157 }
04158 else
04159 {
04160 break;
04161 }
04162 len = TMP_BUFF_SIZE;
04163 }
04164 }
04165 if(loadedTemplateRefIds != NULL)
04166 {
04167 for(XMLSize_t j = 0; j < m_nrOfTermsAndConditionsTemplates; j++)
04168 {
04169 delete [] loadedTemplateRefIds[j];
04170 loadedTemplateRefIds[j] = NULL;
04171 }
04172 delete [] loadedTemplateRefIds;
04173 loadedTemplateRefIds = NULL;
04174 }
04175 if(templateError)
04176 {
04177 return E_UNKNOWN;
04178 }
04179 }
04180
04181 if(nothingFound)
04182 {
04183 CAMsg::printMsg(LOG_INFO,"No Terms And Conditions templates found.\n");
04184 }
04185
04186 return E_SUCCESS;
04187 }
04188 SINT32 CACmdLnOptions::setTermsAndConditionsList(DOMElement *elemTnCs)
04189 {
04190 if(elemTnCs == NULL)
04191 {
04192 CAMsg::printMsg(LOG_CRIT,"Terms And Conditions root element is null!\n");
04193 return E_UNKNOWN;
04194 }
04195 DOMElement *elemTnCsList = NULL;
04196 getDOMChildByName(elemTnCs, OPTIONS_NODE_TNCS, elemTnCsList);
04197
04198 if(elemTnCsList == NULL)
04199 {
04200 CAMsg::printMsg(LOG_CRIT,"No definitions for Terms And Conditions found!\n");
04201 return E_UNKNOWN;
04202 }
04203
04204 UINT32 attrCheckLen = TMP_BUFF_SIZE;
04205 UINT8 attrCheck[TMP_BUFF_SIZE];
04206 memset(attrCheck, 0, attrCheckLen);
04207
04208 UINT32 localeLen = TMP_LOCALE_SIZE;
04209 UINT8 locale[TMP_LOCALE_SIZE];
04210 memset(locale, 0, localeLen);
04211
04212 UINT32 dateLen = TMP_DATE_SIZE;
04213 UINT8 date[TMP_DATE_SIZE];
04214 memset(date, 0, dateLen);
04215
04216 if( (getDOMElementAttribute(elemTnCsList, OPTIONS_ATTRIBUTE_TNC_DATE, date, &dateLen) != E_SUCCESS) ||
04217 (strlen((char *)date) != ((TMP_DATE_SIZE) - 1) ) )
04218 {
04219 CAMsg::printMsg(LOG_CRIT,"Attribute '%s' is not properly set for the global definition of Terms And Conditions!\n",
04220 OPTIONS_ATTRIBUTE_TNC_DATE);
04221 return E_UNKNOWN;
04222 }
04223
04224 m_docOpTnCs = createDOMDocument();
04225
04226 DOMElement *currentTnCEntry = NULL;
04227 DOMNodeList *tncDefEntryList = getElementsByTagName(elemTnCsList, OPTIONS_NODE_TNCS_TRANSLATION);
04228
04229 if(tncDefEntryList->getLength() < 1)
04230 {
04231 CAMsg::printMsg(LOG_CRIT,"No Terms And Conditions entries found!\n");
04232 return E_UNKNOWN;
04233 }
04234
04235 DOMElement *tncTranslationImports = NULL;
04236 DOMElement *tncOperatorNode = NULL;
04237 getDOMChildByName(elemTnCsList, OPTIONS_NODE_TNCS_TRANSLATION_IMPORTS, tncTranslationImports, false);
04238 if(tncTranslationImports != NULL)
04239 {
04240 getDOMChildByName(tncTranslationImports, OPTIONS_NODE_TNCS_OPERATOR, tncOperatorNode, false);
04241 }
04242 bool defaultLangValue = false;
04243 bool defaultLangFound = false;
04244 bool operatorImportNodeFound = (tncOperatorNode != NULL);
04245
04246
04247
04248