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