Mixe for Privacy and Anonymity in the Internet
CACmdLnOptions.cpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2000, The JAP-Team
3 All rights reserved.
4 Redistribution and use in source and binary forms, with or without modification,
5 are permitted provided that the following conditions are met:
6 
7  - Redistributions of source code must retain the above copyright notice,
8  this list of conditions and the following disclaimer.
9 
10  - Redistributions in binary form must reproduce the above copyright notice,
11  this list of conditions and the following disclaimer in the documentation and/or
12  other materials provided with the distribution.
13 
14  - Neither the name of the University of Technology Dresden, Germany nor the names of its contributors
15  may be used to endorse or promote products derived from this software without specific
16  prior written permission.
17 
18 
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
20 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
21 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS
22 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
27 */
28 
29 #include "StdAfx.h"
30 #include "CACmdLnOptions.hpp"
31 #include "CAUtil.hpp"
32 #include "CAMix.hpp"
33 #include "CAMsg.hpp"
34 #include "CASocketAddrINet.hpp"
35 //#include "CAIPAddrWithNetmask.hpp"
36 #include "CASocket.hpp"
37 #include "CAXMLBI.hpp"
38 #include "xml/DOM_Output.hpp"
39 #include "CABase64.hpp"
40 #include "CADynaNetworking.hpp"
41 #ifdef PAYMENT
43 #endif
44 //#ifdef LOG_CRIME
45  #include "tre/tre.h"
46 //#endif
47 
48 
50  {
51  m_bDaemon=false;
52  m_bSyslog=false;
53  m_bLogConsole = false;
54  m_bSocksSupport = false;
55  m_bVPNSupport = false;
57 
58 #if !defined ONLY_LOCAL_PROXY || defined INCLUDE_MIDDLE_MIX
60  m_docMixXml=NULL;
61  m_addrInfoServices = NULL;
63  m_OpCert=NULL;
64  m_pMultiSignature=NULL;
68  m_bVerifyMixCerts=false;
70 #endif
71 
72 #ifndef ONLY_LOCAL_PROXY
73  m_bIsRunReConfigure=false;
75  //m_pSignKey=NULL;
76  //m_pOwnCertificate=NULL;
77  m_bCompressedLogs=false;
80  m_pCascadeXML=NULL;
81  m_docOpTnCs=NULL; //Operator Terms and Conditions (if any)
82  m_maxNrOfUsers = 0;
83  m_bSkipProxyCheck = false;
84 #ifdef PAYMENT
86 #else
88 #endif
89 
90 #ifdef COUNTRY_STATS
92 #endif
95 #endif //ONLY_LOCAL_PROXY
96 
97 #if !defined ONLY_LOCAL_PROXY || defined INCLUDE_FIRST_MIX
99 #endif
100 
103  m_strUser=NULL;
104  m_strCascadeName=NULL;
105  m_strLogDir=NULL;
106  m_strLogLevel=NULL;
110  m_cnTargets=0;
115  m_nrOfOpenFiles=-1;
116  m_strMixID=NULL;
117  m_strMixName=NULL;
118  m_bAutoReconnect=false;
119  m_strConfigFile=NULL;
120  m_strPidFile=NULL;
121  m_strCredential = NULL;
122 #ifdef PAYMENT
123  m_pBI=NULL;
124  m_strDatabaseHost=NULL;
125  m_strDatabaseName=NULL;
126  m_strDatabaseUser=NULL;
128  m_strAiID=NULL;
129 #endif
130 #ifdef SERVER_MONITORING
131  m_strMonitoringListenerHost = NULL;
132  m_iMonitoringListenerPort = 0xFFFF;
133 #endif
134 
135 #ifdef LOG_CRIME
136  m_logPayload = false;
137  m_arCrimeRegExpsURL=NULL;
138  m_nCrimeRegExpsURL=0;
139  m_arCrimeRegExpsPayload=NULL;
140  m_nCrimeRegExpsPayload=0;
141  m_nrOfSurveillanceIPs = 0;
142  m_surveillanceIPs = NULL;
143  m_nrOfSurveillanceAccounts = 0;
144  m_surveillanceAccounts = NULL;
145 #endif
146 
147 #ifdef DATA_RETENTION_LOG
148  m_strDataRetentionLogDir=NULL;
149 #endif
150 
151 #ifdef EXPORT_ASYM_PRIVATE_KEY
152  m_strImportKeyFile=NULL;
153  m_strExportKeyFile=NULL;
154 #endif
155 
156 #ifdef DYNAMIC_MIX
157  m_strLastCascadeProposal = NULL;
158 #endif
159 
160 #if defined(DELAY_CHANNELS) && defined(DELAY_USERS)
161  if(isFirstMix())
162  {
166  }
167  else
168  {
169  m_u32DelayChannelUnlimitTraffic=DELAY_CHANNEL_TRAFFIC;
170  m_u32DelayChannelBucketGrow=DELAY_BUCKET_GROW;
171  m_u32DelayChannelBucketGrowIntervall=DELAY_BUCKET_GROW_INTERVALL;
172  }
173 #elif defined(DELAY_CHANNELS)
174  m_u32DelayChannelUnlimitTraffic=DELAY_CHANNEL_TRAFFIC;
175  m_u32DelayChannelBucketGrow=DELAY_BUCKET_GROW;
176  m_u32DelayChannelBucketGrowIntervall=DELAY_BUCKET_GROW_INTERVALL;
177 #elif defined (DELAY_USERS)
181 #endif
182 
183 #if defined(DELAY_CHANNELS_LATENCY)
184  m_u32DelayChannelLatency = DELAY_CHANNEL_LATENCY;
185 #endif
186 
187 #if !defined ONLY_LOCAL_PROXY || defined INCLUDE_MIDDLE_MIX
188  // initialize pointer to option setter functions
192 #ifdef PAYMENT
194 #endif
196 #ifdef PAYMENT
198 #endif
199 #ifdef LOG_CRIME
200  initCrimeDetectionOptionSetters();
201 #endif
202 #endif //ONLY_LOCAL_PROXY
203 
204  }
205 
206 
208  {
209  cleanup();
210  }
211 
212 #ifndef ONLY_LOCAL_PROXY
213 
214 
215 #ifdef PAYMENT
217 {
218 
220  int count = -1;
221 
224 }
225 #endif
226 #ifdef LOG_CRIME
227 void CACmdLnOptions::initCrimeDetectionOptionSetters()
228 {
229  crimeDetectionOptionSetters = new optionSetter_pt[CRIME_DETECTION_OPTIONS_NR];
230  int count = -1;
231 
232  crimeDetectionOptionSetters[++count]=
233  &CACmdLnOptions::setCrimeURLRegExp;
234  crimeDetectionOptionSetters[++count]=
235  &CACmdLnOptions::setCrimePayloadRegExp;
236  crimeDetectionOptionSetters[++count]=
237  &CACmdLnOptions::setCrimeSurveillanceAccounts;
238  crimeDetectionOptionSetters[++count]=
239  &CACmdLnOptions::setCrimeSurveillanceIP;
240 }
241 #endif
242 
243 #endif //ONLY_LOCAL_PROXY
244 
245 // This is the final cleanup, which deletes every resource (including any locks necessary to synchronise read/write to properties).
246 //
248  {
249  clean();
250 #ifndef ONLY_LOCAL_PROXY
251  delete m_pcsReConfigure;
252  m_pcsReConfigure=NULL;
253 #endif
254  return E_SUCCESS;
255  }
256 
257 // Deletes all information about the target interfaces.
258  //
260  {
261  if(m_arTargetInterfaces!=NULL)
262  {
263  for(UINT32 i=0;i<m_cnTargets;i++)
264  {
266  }
267  delete[] m_arTargetInterfaces;
268  m_arTargetInterfaces = NULL;
269  }
270  m_cnTargets=0;
272  return E_SUCCESS;
273  }
274 
275 // Deletes all information about the listener interfaces.
276  //
278  {
279  if(m_arListenerInterfaces!=NULL)
280  {
281  for(UINT32 i=0;i<m_cnListenerInterfaces;i++)
282  {
283  delete m_arListenerInterfaces[i];
284  m_arListenerInterfaces[i] = NULL;
285  }
286  delete[] m_arListenerInterfaces;
287  }
290  return E_SUCCESS;
291  }
292 
293 #ifndef ONLY_LOCAL_PROXY
294 #endif //ONLY_LOCAL_PROXY
295 
296 
297 
300  {
301  delete[] m_strConfigFile;
302  m_strConfigFile=NULL;
303 
304  delete[] m_strTargetHost;
305  m_strTargetHost=NULL;
306 
307  delete[] m_strSOCKSHost;
308  m_strSOCKSHost=NULL;
309 
310 #if !defined ONLY_LOCAL_PROXY || defined INCLUDE_MIDDLE_MIX
311  if (m_addrInfoServices != NULL)
312  {
313  for (UINT32 i = 0; i < m_addrInfoServicesSize; i++)
314  {
315  delete m_addrInfoServices[i];
316  m_addrInfoServices[i] = NULL;
317  }
318  delete[] m_addrInfoServices;
319  m_addrInfoServices=NULL;
321  }
322 #endif //ONLY_LOCAL_PROXY
323 
324 
325  delete[] m_strCascadeName;
326  m_strCascadeName=NULL;
327 
328  delete[] m_strLogDir;
329  m_strLogDir=NULL;
330 
331  delete[] m_strCredential;
332  m_strCredential=NULL;
333 
334  delete[] m_strLogLevel;
335  m_strLogLevel=NULL;
336 
337  delete[] m_strPidFile;
338  m_strPidFile=NULL;
339 
340  delete[] m_strEncryptedLogDir;
342 
343  delete[] m_strUser;
344  m_strUser=NULL;
345 
346  delete[] m_strMixID;
347  m_strMixID=NULL;
348 
349  delete[] m_strMixName;
350  m_strMixName=NULL;
351 
354 #if !defined ONLY_LOCAL_PROXY || defined INCLUDE_MIDDLE_MIX
355  if(m_docMixInfo!=NULL)
356  {
357  m_docMixInfo->release();
358  m_docMixInfo=NULL;
359  }
360 
361  if(m_docMixXml!=NULL)
362  {
363  m_docMixXml->release();
364  m_docMixXml=NULL;
365  }
366 #endif
367 #ifndef ONLY_LOCAL_PROXY
369 
370  //delete m_pSignKey;
371  //m_pSignKey=NULL;
372 
373  //delete m_pOwnCertificate;
374  //m_pOwnCertificate=NULL;
375 
376  delete m_pMultiSignature;
377  m_pMultiSignature = NULL;
378 
379  delete m_OpCert;
380  m_OpCert=NULL;
381 
382  delete m_pNextMixCertificate;
384 
385  delete m_pPrevMixCertificate;
387 
390 
391  if(m_docOpTnCs!=NULL)
392  {
393  m_docOpTnCs->release();
394  m_docOpTnCs=NULL;
395  }
396 
397 
398 
399 #ifdef COUNTRY_STATS
400  delete[] m_dbCountryStatsHost;
401  m_dbCountryStatsHost = NULL;
402  delete[] m_dbCountryStatsUser;
403  m_dbCountryStatsUser = NULL;
404  delete[] m_dbCountryStatsPasswd;
405  m_dbCountryStatsPasswd = NULL;
406 #endif
407 
408 #ifdef DATA_RETENTION_LOG
409  delete[] m_strDataRetentionLogDir;
410  m_strDataRetentionLogDir=NULL;
411 #endif
412 
413 #ifdef EXPORT_ASYM_PRIVATE_KEY
414  if(m_strImportKeyFile!=NULL)
415  delete[] m_strImportKeyFile;
416  m_strImportKeyFile=NULL;
417  if(m_strExportKeyFile!=NULL)
418  delete[] m_strExportKeyFile;
419  m_strExportKeyFile=NULL;
420 #endif
421 
422 
423 #endif //ONLY_LOCAL_PROXY
424 
425 
426 #if !defined ONLY_LOCAL_PROXY || defined INCLUDE_FIRST_MIX
427  if (m_strAccessControlCredential != NULL)
428  {
431  }
432 #endif
433 #ifdef SERVER_MONITORING
434  if(m_strMonitoringListenerHost != NULL)
435  {
436  delete[] m_strMonitoringListenerHost;
437  m_strMonitoringListenerHost = NULL;
438  }
439 #endif
440  delete [] mainOptionSetters;
441  mainOptionSetters = NULL;
442  delete [] generalOptionSetters;
443  generalOptionSetters = NULL;
446 #ifdef PAYMENT
447  delete [] accountingOptionSetters;
449 #endif
450  delete [] networkOptionSetters;
451  networkOptionSetters = NULL;
452 #ifdef PAYMENT
455 #endif
456 }
457 
458 SINT32 CACmdLnOptions::parse(int argc,const char** argv)
459  {
460  int iDaemon=0;
461  char* target=NULL;
462  int iLocalProxy=0;
463  int SOCKSport=-1;
464  char* socks=NULL;
465  char* logdir=NULL;
466  int iCompressedLogs=0;
467  char* serverPort=NULL;
468  int iVersion=0;
469  int iCryptoBenchmark = 0;
470  int iSkipProxyCheck = 0;
471  char *configfile = NULL;
472  int iAutoReconnect=0;
473  char* strPidFile=NULL;
474  char* strCreateConf=NULL;
475  char* strCredential = NULL;
476 #ifdef EXPORT_ASYM_PRIVATE_KEY
477  char* strImportKey=NULL;
478  char* strExportKey=NULL;
479 #endif
480  //DOM_Document docMixXml;
481  poptOption theOptions[]=
482  {
483  {"localproxy",'j',POPT_ARG_NONE,&iLocalProxy,0,"act as local proxy",NULL},
484  {"daemon",'d',POPT_ARG_NONE,&iDaemon,0,"start as daemon [only for local proxy]",NULL},
485  {"next",'n',POPT_ARG_STRING,&target,0,"first mix of cascade [only for local proxy]","<ip:port>"},
486  {"autoreconnect",'a',POPT_ARG_NONE,&iAutoReconnect,0,"auto reconnects if connection to first mix was lost [only for local proxy]",NULL},
487  {"port",'p',POPT_ARG_STRING,&serverPort,0,"listening on [host:]port|path [only for local proxy]","<[host:]port|path>"},
488  {"socksport",'s',POPT_ARG_INT,&SOCKSport,0,"listening port for socks","<portnumber>"},
489  {"logdir",'l',POPT_ARG_STRING,&logdir,0,"directory where log files go to [only for local proxy]","<dir>"},
490 #ifdef COMPRESSED_LOGS
491  {"gzip",'z',POPT_ARG_NONE,&iCompressedLogs,0,"create gziped logs",NULL},
492 #endif
493  {"config",'c',POPT_ARG_STRING,&configfile,0,"config file to use [for a real Mix in a cascade]","<file>"},
494  {"version",'v',POPT_ARG_NONE,&iVersion,0,"show version",NULL},
495  {"pidfile",'r',POPT_ARG_STRING,&strPidFile,0,"file where the PID will be stored","<file>"},
496  {"createConf",0,POPT_ARG_STRING,&strCreateConf,0,"creates a generic configuration for MixOnCD","[<file>]"},
497  {"credential",0,POPT_ARG_STRING,&strCredential,0,"credential for connetion to cascade [only for local proxy]","<credential>"},
498  {"cryptobenchmark",0,POPT_ARG_NONE,&iCryptoBenchmark,0,"do a benchamrk of the cryptographic functions",NULL},
499  { "skip-proxy-check", 0, POPT_ARG_NONE, &iSkipProxyCheck, 0, "skip the proxy check (e.g if the proxies are started intentionally after the last mix)", NULL },
500 #ifdef EXPORT_ASYM_PRIVATE_KEY
501  {"exportKey",0,POPT_ARG_STRING,&strExportKey,0,"export private encryption key to file","<file>"},
502  {"importKey",0,POPT_ARG_STRING,&strImportKey,0,"import private encryption key from file","<file>"},
503 #endif
505  {NULL,0,0,
506  NULL,0,NULL,NULL}
507  };
508  poptContext ctx=poptGetContext(NULL,argc,argv,theOptions,0);
509  SINT32 ret=poptGetNextOpt(ctx);
510  while(ret==POPT_ERROR_BADOPT)
511  ret=poptGetNextOpt(ctx);
512  poptFreeContext(ctx);
513  if(iVersion!=0)
514  {
515  printf(MIX_VERSION_INFO);
516  for(UINT32 t=0;t<10000;t++)
517  {
518  CASocket* pSocket=new CASocket;
519  if(pSocket->create(false)!=E_SUCCESS)
520  {
521  printf("Max open sockets: %u\n",t);
522  exit(0);
523  }
524  }
525  printf("Max open sockets: >10000\n");
526  exit(0);
527  }
528 
529 #ifdef MIX_VERSION_TESTING
531 #endif
532 
533 #ifndef ONLY_LOCAL_PROXY
534  if(strCreateConf!=NULL)
535  {
536  createMixOnCDConfiguration((UINT8*)strCreateConf);
537  exit(0);
538  }
539 #endif
540  m_bLocalProxy=(iLocalProxy != 0);
541  m_bCryptoBenchmark = (iCryptoBenchmark != 0);
542  m_bSkipProxyCheck = (iSkipProxyCheck != 0);
543  m_bAutoReconnect = (m_bLocalProxy && iAutoReconnect != 0);
544 
545  /* LERNGRUPPE: Also try to use default config file for Mix Category 1 */
546  if(configfile == NULL)
547  {
548  configfile = (char*) malloc(sizeof(char) * (strlen(DEFAULT_CONFIG_FILE)+1));
549  strncpy(configfile, DEFAULT_CONFIG_FILE, (strlen(DEFAULT_CONFIG_FILE)+1));
550 
551 #if defined (_WIN32) &&!defined(__CYGWIN__)
552 // R_OK is not defined in Windows POSIX implementation
553 #define R_OK 4
554 #endif
555 
556  int err = access(configfile, R_OK);
557  if( err )
558  {
559  if(configfile != NULL)
560  {
561  free(configfile);
562  configfile = NULL;
563  }
564  }
565  }
566  /* END LERNGRUPPE */
567 
568 
569  if(configfile!=NULL)
570  {
571 #if !defined ONLY_LOCAL_PROXY || defined INCLUDE_MIDDLE_MIX
572  ret=readXmlConfiguration(m_docMixXml,(UINT8*)configfile);
573  if(ret==E_FILE_OPEN)
574  CAMsg::printMsg(LOG_CRIT,"Could not open config file: %s\n",configfile);
575  else if(ret==E_FILE_READ)
576  CAMsg::printMsg(LOG_CRIT,"Could not read config file: %s\n",configfile);
577  else if(ret==E_XML_PARSE)
578  CAMsg::printMsg(LOG_CRIT,"Could not parse config file: %s\n",configfile);
579  else
580  {
581  m_strConfigFile=new UINT8[strlen(configfile)+1];
582  memcpy(m_strConfigFile,configfile,strlen(configfile)+1);
583  }
584 #endif
585  free(configfile);
586  }
587  if(iDaemon!=0)
588  m_bDaemon=true;
589  if(target!=NULL)
590  {
591  if(target[0]=='/') //Unix Domain Sockaet
592  {
593  m_strTargetHost=new char[strlen(target)+1];
594  strcpy(m_strTargetHost,target);
595  }
596  else
597  {
598  char tmpHostname[TMP_BUFF_SIZE];
599  SINT32 tmpPort;
600  char* tmpStr1=strchr(target,':');
601  if(tmpStr1!=NULL)
602  {
603  memcpy(tmpHostname,target,tmpStr1-target);
604  tmpHostname[tmpStr1-target]=0;
605  tmpPort=(SINT32)atol(tmpStr1+1);
606  }
607  else
608  {//TODO what if not in right form ?
609  //try if it is a number --> use it as port
610  //and use 'localhost' as traget-host
611  tmpPort=(SINT32)atol(target);
612  if(tmpPort!=0) //we get it
613  {
614  strcpy(tmpHostname,"localhost");
615  }
616  else //we try to use it as host and use the default port
617  {
618 /* LERNGRUPPE moved the define to CACmdLnOption.hpp because we need it elsewhere too */
619 //#define DEFAULT_TARGET_PORT 6544
620  tmpPort=DEFAULT_TARGET_PORT;
621  strcpy(tmpHostname,target);
622  }
623  }
624  m_strTargetHost=new char[strlen(tmpHostname)+1];
625  strcpy(m_strTargetHost,tmpHostname);
626  m_iTargetPort=(UINT16)tmpPort;
627  }
628  free(target);
629  }
630  if(socks!=NULL)
631  {
632  char* tmpStr;
633  if((tmpStr=strchr(socks,':'))!=NULL)
634  {
635  m_strSOCKSHost=new char[tmpStr-socks+1];
636  (*tmpStr)=0;
637  strcpy(m_strSOCKSHost,socks);
638  m_iSOCKSPort=(UINT16)atol(tmpStr+1);
639  }
640  free(socks);
641  }
642  if(logdir!=NULL)
643  {
644  m_strLogDir=new char[strlen(logdir)+1];
645  strcpy(m_strLogDir,logdir);
646  free(logdir);
647  }
648  if(strPidFile!=NULL)
649  {
650  m_strPidFile=new char[strlen(strPidFile)+1];
651  strcpy(m_strPidFile,strPidFile);
652  free(strPidFile);
653  }
654 
655  if(strCredential!=NULL)
656  {
657  m_strCredential=new char[strlen(strCredential)+1];
658  strcpy(m_strCredential,strCredential);
659  free(strCredential);
660  }
661 
662 #ifdef EXPORT_ASYM_PRIVATE_KEY
663  if(strExportKey!=NULL)
664  {
665  m_strExportKeyFile=new UINT8[strlen(strExportKey)+1];
666  strcpy((char*)m_strExportKeyFile,strExportKey);
667  free(strExportKey);
668  }
669  if(strImportKey!=NULL)
670  {
671  m_strImportKeyFile=new UINT8[strlen(strImportKey)+1];
672  strcpy((char*)m_strImportKeyFile,strImportKey);
673  free(strImportKey);
674  }
675 #endif
676  if(iCompressedLogs!=0)
677  m_bCompressedLogs=true;
678 
679  if(serverPort!=NULL&&m_bLocalProxy)
680  {
682  m_arListenerInterfaces[0]=NULL;
684  char* tmpStr;
685  if(serverPort[0]=='/') //Unix Domain Socket
686  {
688  }
689  else //Internet Socket
690  {
691  char* strServerHost=NULL;
692  SINT32 iServerPort;
693  if((tmpStr=strchr(serverPort,':'))!=NULL) //host:port
694  {
695  strServerHost=new char[tmpStr-serverPort+1];
696  (*tmpStr)=0;
697  strcpy(strServerHost,serverPort);
698  iServerPort=(SINT32)atol(tmpStr+1);
699  }
700  else //port only ?
701  {
702  iServerPort=(SINT32)atol(serverPort);
703  }
705  delete [] strServerHost;
706  strServerHost = NULL;
707  }
708  free(serverPort);
709  if(m_arListenerInterfaces[0]!=0)
711  }
712 
713  m_iSOCKSServerPort=(UINT16)SOCKSport;
714 #if !defined ONLY_LOCAL_PROXY || defined INCLUDE_MIDDLE_MIX
716  {
718 #ifndef DYNAMIC_MIX
719  if(ret!=E_SUCCESS)
720  return ret;
721  }
722 #else
723  /* LERNGRUPPE: Let's try to recover and build a default configuration */
724  if(ret!=E_SUCCESS)
725  {
726  createDefaultConfiguration();
728  if(ret!=E_SUCCESS)
729  return ret;
730  }
731  }
732 #endif
733 #endif
734 #if !defined ONLY_LOCAL_PROXY
735 
736  /* Try to read InfoService configuration from external file infoservices.xml */
737  XERCES_CPP_NAMESPACE::DOMDocument* infoservices;
738  if( readXmlConfiguration(infoservices,(UINT8*)"infoservices.xml") == E_SUCCESS )
739  {
740  CAMsg::printMsg(LOG_DEBUG, "Will now get InfoServices from infoservices.xml (this overrides the InfoServices from the default config!)\n");
741  DOMElement* elemIs=infoservices->getDocumentElement();
742  parseInfoServices(elemIs);
743  }
744 
745 
746 
747 #ifdef DYNAMIC_MIX
748  /* Ok, at this point we should make sure that we have a minimal configuration.
749  If not we try to fill up the missing parameters with default values*/
750  if( checkCertificates() != E_SUCCESS )
751  {
752  CAMsg::printMsg(LOG_CRIT, "I was not able to get a working certificate, please check the configuration! Exiting now\n");
753  exit(0);
754  }
755  UINT32 running = 0;
756  CAMsg::printMsg( LOG_INFO, "I will now test if I have enough information about InfoServices...\n");
757  if( checkInfoServices(&running) != E_SUCCESS )
758  {
760  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);
761  exit(0);
762  }
763  CAMsg::printMsg( LOG_INFO, "InfoService information ok\n");
764  if( checkListenerInterfaces() != E_SUCCESS )
765  {
766  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");
767  exit(0);
768  }
769  if( checkMixId() != E_SUCCESS)
770  {
771  CAMsg::printMsg(LOG_CRIT, "ARGS, I don't have an unique ID, cannot create one! Exiting now\n");
772  exit(0);
773  }
774 #endif // DYNAMIC_MIX
775 #endif //ONLY_LOCAL_PROXY
776  return E_SUCCESS;
777  }
778 
779 #ifndef ONLY_LOCAL_PROXY
781  {
784  };
785 
794  {
795  //Copy Targets
796  if(newOptions.getTargetInterfaceCount()>0)
797  {
801  for(UINT32 i=0;i<m_cnTargets;i++)
802  newOptions.getTargetInterface(m_arTargetInterfaces[i],i+1);
803  }
804 #if defined( DELAY_CHANNELS)||defined(DELAY_USERS)
805  //Copy ressources limitation
809 #endif
810 #if defined( DELAY_CHANNELS_LATENCY)
811  //Copy ressources limitation
812  m_u32DelayChannelLatency=newOptions.getDelayChannelLatency();
813 #endif
814  if(newOptions.getMaxNrOfUsers()>0)
815  m_maxNrOfUsers=newOptions.getMaxNrOfUsers();
816 #ifdef LOG_CRIME
817 #endif
818  return E_SUCCESS;
819 }
820 #endif //ONLY_LOCAL_PROXY
821 
822 #ifndef ONLY_LOCAL_PROXY
828 #ifndef DYNAMIC_MIX
829 SINT32 CACmdLnOptions::setNextMix(XERCES_CPP_NAMESPACE::DOMDocument* doc)
830  {
831  CAMsg::printMsg(LOG_DEBUG,"setNextMix() - start\n");
832  DOMElement* elemRoot = doc->getDocumentElement();
833 
834  //getCertificates if given...
835  DOMElement* elemSig;
836  getDOMChildByName(elemRoot, OPTIONS_NODE_SIGNATURE, elemSig, false);
837  //Own Certiticate first
838  //nextMixCertificate if given
839  DOMElement* elemCert;
840  getDOMChildByName(elemSig, OPTIONS_NODE_X509DATA, elemCert,true);
841  if(elemSig!=NULL)
843 
844  DOMElement* elemOptionsRoot = m_docMixXml->getDocumentElement();
845  DOMElement* elemOptionsCerts;
846  getDOMChildByName(elemOptionsRoot, OPTIONS_NODE_CERTIFICATE_LIST, elemOptionsCerts, false);
847  DOMElement* elemOptionsNextMixCert;
848 
849  if(getDOMChildByName(elemOptionsRoot, OPTIONS_NODE_NEXT_MIX_CERTIFICATE, elemOptionsNextMixCert, false) != E_SUCCESS)
850  {
852  elemOptionsCerts->appendChild(elemOptionsNextMixCert);
853  elemOptionsNextMixCert->appendChild(m_docMixXml->importNode(elemCert->getFirstChild(),true));
854  }
855  else
856  {
857  if(elemOptionsNextMixCert->hasChildNodes())
858  {
859  elemOptionsNextMixCert->replaceChild(m_docMixXml->importNode(elemCert->getFirstChild(),true),
860  elemOptionsNextMixCert->getFirstChild());
861  }
862  else
863  {
864  elemOptionsNextMixCert->appendChild(m_docMixXml->importNode(elemCert->getFirstChild(),true));
865  }
866  }
867  CAMsg::printMsg(LOG_DEBUG,"setNextMix() - certificates done\n");
868  DOMElement* elemNextMix;
869  getDOMChildByName(elemRoot, OPTIONS_NODE_LISTENER_INTERFACE, elemNextMix,true);
870 
871  DOMElement* elemOptionsNetwork;
872  DOMElement* elemOptionsNextMixInterface;
873 
874  if(getDOMChildByName(elemOptionsRoot, OPTIONS_NODE_NETWORK, elemOptionsNetwork, false) != E_SUCCESS)
875  {
876  elemOptionsNetwork = createDOMElement(m_docMixXml, OPTIONS_NODE_NETWORK);
877  elemOptionsRoot->appendChild(elemOptionsNetwork);
878  }
879 
880  if(getDOMChildByName(elemOptionsNetwork, OPTIONS_NODE_NEXT_MIX, elemOptionsNextMixInterface, false) != E_SUCCESS)
881  {
882  elemOptionsNextMixInterface = createDOMElement(m_docMixXml, OPTIONS_NODE_NEXT_MIX);
883  elemOptionsNetwork->appendChild(elemOptionsNextMixInterface);
884  }
885  else
886  {
887  while(elemOptionsNextMixInterface->hasChildNodes())
888  {
889  elemOptionsNextMixInterface->removeChild(elemOptionsNextMixInterface->getFirstChild());
890  }
891  }
892 
893  DOMNode* interfaceData = elemNextMix->getFirstChild();
894  while(interfaceData != NULL)
895  {
896  elemOptionsNextMixInterface->appendChild(m_docMixXml->importNode(interfaceData,true));
897  interfaceData = interfaceData->getNextSibling();
898  }
899 
900  CAMsg::printMsg(LOG_DEBUG,"setNextMix() - end\n");
902 }
903 
904 #else //DYNAMIC_MIX
905 
906 SINT32 CACmdLnOptions::setNextMix(DOM_Document& doc)
907 {
908  resetNextMix();
910  DOM_Element elemRoot = doc.getDocumentElement();
911  //getCertificates if given...
912  DOM_Element elemSig;
913  getDOMChildByName(elemRoot,(UINT8*) OPTIONS_NODE_SIGNATURE, elemSig, false);
914  DOM_Element elemCert;
915  getDOMChildByName(elemSig,(UINT8*) OPTIONS_NODE_X509DATA, elemCert, true);
916  if(elemCert!=NULL)
919  DOM_Node elemNextMix;
920  DOM_Element elemListeners;
921  // Search through the ListenerInterfaces an use a non-hidden one!
922  getDOMChildByName(elemRoot,(UINT8*) OPTIONS_NODE_LISTENER_INTERFACE_LIST, elemListeners, true);
923  DOM_NodeList nlListenerInterfaces = elemListeners.getElementsByTagName(CAListenerInterface::XML_ELEMENT_NAME);
924  UINT32 len = nlListenerInterfaces.getLength();
925  bool foundNonHiddenInterface = false;
926  for(UINT32 i=0;i<len;i++)
927  {
928  elemNextMix=nlListenerInterfaces.item(i);
929  SINT32 ret = E_SUCCESS;
930  ret = getDOMElementAttribute(elemNextMix,"hidden",foundNonHiddenInterface);
931  // Interface was not hidden or "hidden"-Attribute was not specified
932  if(foundNonHiddenInterface || ret == E_UNSPECIFIED)
933  {
934  foundNonHiddenInterface = true;
935  break;
936  }
937  }
938  if(!foundNonHiddenInterface)
939  {
940  CAMsg::printMsg(LOG_ERR, "NEXT MIX HAS NO REAL LISTENERINTERFACES!\n");
941  exit(0);
942  return E_UNKNOWN;
943  }
946  //get TargetInterfaces
947  m_cnTargets=0;
948  TargetInterface* targetInterfaceNextMix=NULL;
949  if(elemNextMix!=NULL)
950 {
952  CASocketAddr* addr=NULL;
953  DOM_Element elemType;
954  getDOMChildByName(elemNextMix,(UINT8*) OPTIONS_NODE_NETWORK, elemType, false);
955  UINT8 tmpBuff[TMP_BUFF_SIZE];
956  UINT32 tmpLen = TMP_BUFF_SIZE;
957  if(getDOMElementValue(elemType,tmpBuff,&tmpLen)!=E_SUCCESS)
958  goto SKIP_NEXT_MIX;
959  strtrim(tmpBuff);
960  if(strcmp((char*)tmpBuff,"RAW/TCP")==0)
961  type=RAW_TCP;
962  else if(strcmp((char*)tmpBuff,"RAW/UNIX")==0)
963  type=RAW_UNIX;
964  else if(strcmp((char*)tmpBuff,"SSL/TCP")==0)
965  type=SSL_TCP;
966  else if(strcmp((char*)tmpBuff,"SSL/UNIX")==0)
967  type=SSL_UNIX;
968  else
969  goto SKIP_NEXT_MIX;
970  if(type==SSL_TCP||type==RAW_TCP)
971  {
972  DOM_Element elemPort;
973  DOM_Element elemHost;
974  DOM_Element elemIP;
975  UINT8 buffHost[255];
976  UINT32 buffHostLen=255;
977  UINT16 port;
978  getDOMChildByName(elemNextMix,(UINT8*) OPTIONS_NODE_PORT, elemPort, false);
979  if(getDOMElementValue(elemPort,&port)!=E_SUCCESS)
980  goto SKIP_NEXT_MIX;
981  addr=new CASocketAddrINet;
982  bool bAddrIsSet=false;
983  getDOMChildByName(elemNextMix,(UINT8*) OPTIONS_NODE_HOST, elemHost, false);
984  /* The rules for <Host> and <IP> are as follows:
985  * 1. if <Host> is given and not empty take the <Host> value for the address of the next mix; if not go to 2
986  * 2. if <IP> if given and not empty take <IP> value for the address of the next mix; if not goto 3.
987  * 3. this entry for the next mix is invalid!*/
988  if(elemHost!=NULL)
989  {
990  if(getDOMElementValue(elemHost,buffHost,&buffHostLen)==E_SUCCESS&&((CASocketAddrINet*)addr)->setAddr(buffHost,port)==E_SUCCESS)
991  {
992  bAddrIsSet=true;
993  }
994  }
995  if(!bAddrIsSet)//now try <IP>
996  {
997  getDOMChildByName(elemNextMix,(UINT8*) OPTIONS_NODE_IP, elemIP, false);
998  if(elemIP == NULL || getDOMElementValue(elemIP,buffHost,&buffHostLen)!=E_SUCCESS)
999  goto SKIP_NEXT_MIX;
1000  if(((CASocketAddrINet*)addr)->setAddr(buffHost,port)!=E_SUCCESS)
1001  goto SKIP_NEXT_MIX;
1002  }
1003  CAMsg::printMsg(LOG_INFO, "Setting target interface: %s:%d\n", buffHost, port);
1004  }
1005  else
1006 #ifdef HAVE_UNIX_DOMAIN_PROTOCOL
1007 
1008  {
1009  DOM_Element elemFile;
1010  getDOMChildByName(elemNextMix,(UINT8*) OPTIONS_NODE_FILE, elemFile, false);
1011  tmpLen=255;
1012  if(getDOMElementValue(elemFile,tmpBuff,&tmpLen)!=E_SUCCESS)
1013  goto SKIP_NEXT_MIX;
1014  tmpBuff[tmpLen]=0;
1015  strtrim(tmpBuff);
1016  addr=new CASocketAddrUnix;
1017  if(((CASocketAddrUnix*)addr)->setPath((char*)tmpBuff)!=E_SUCCESS)
1018  goto SKIP_NEXT_MIX;
1019  }
1020 #else
1021  goto SKIP_NEXT_MIX;
1022 #endif
1023  targetInterfaceNextMix=new TargetInterface;
1024  targetInterfaceNextMix->target_type=TARGET_MIX;
1025  targetInterfaceNextMix->net_type=type;
1026  targetInterfaceNextMix->addr=addr->clone();
1027  m_cnTargets=1;
1028  if(targetInterfaceNextMix!=NULL)
1029  {
1030  if(m_arTargetInterfaces==NULL)
1031  {
1032  m_cnTargets=0;
1033  m_arTargetInterfaces=new TargetInterface[1];
1034  }
1035  m_arTargetInterfaces[m_cnTargets].net_type=targetInterfaceNextMix->net_type;
1036  m_arTargetInterfaces[m_cnTargets].target_type=targetInterfaceNextMix->target_type;
1037  m_arTargetInterfaces[m_cnTargets++].addr=targetInterfaceNextMix->addr;
1038  delete targetInterfaceNextMix;
1039  targetInterfaceNextMix = NULL;
1040  }
1041 
1042  SKIP_NEXT_MIX:
1043  delete addr;
1044  addr = NULL;
1045 }
1046 
1047  CAMsg::printMsg(LOG_DEBUG,"setNextMix() - end\n");
1048  return E_SUCCESS;
1049 }
1050 #endif //DYNAMIC_MIX
1051 
1052 #endif //ONLY_LOCAL_PROXY
1053 
1054 #ifndef ONLY_LOCAL_PROXY
1060 #ifndef DYNAMIC_MIX
1061 SINT32 CACmdLnOptions::setPrevMix(XERCES_CPP_NAMESPACE::DOMDocument* doc)
1062 {
1063  CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - start\n");
1064  DOMElement* elemRoot = doc->getDocumentElement();
1065 
1066  //getCertificates if given...
1067  DOMElement* elemSig;
1068  getDOMChildByName(elemRoot, OPTIONS_NODE_SIGNATURE, elemSig, false);
1069  //Own Certiticate first
1070  //nextMixCertificate if given
1071  DOMElement* elemCert;
1072  getDOMChildByName(elemSig, OPTIONS_NODE_X509DATA, elemCert, true);
1073  if(elemCert!=NULL)
1074  {
1075  CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - elem cert found in data from infoservice\n");
1076  DOMElement* elemOptionsRoot = m_docMixXml->getDocumentElement();
1077  CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - got current options root element\n");
1078  DOMElement* elemOptionsCerts;
1080  (elemOptionsRoot, OPTIONS_NODE_CERTIFICATE_LIST, elemOptionsCerts, false);
1081  DOMElement* elemOptionsPrevMixCert;
1082 
1084  (elemOptionsRoot,OPTIONS_NODE_PREV_MIX_CERTIFICATE, elemOptionsPrevMixCert, false) != E_SUCCESS)
1085  {
1086  CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - no prev cert set at the moment\n");
1087  elemOptionsPrevMixCert =createDOMElement( m_docMixXml,"PrevMixCertificate");
1088  elemOptionsCerts->appendChild(elemOptionsPrevMixCert);
1089  CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - try to import the one we got from infoservice\n");
1091  (elemCert, OPTIONS_NODE_X509_CERTIFICATE, elemCert, false);
1092 
1093  CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - Cert to be imported:\n");
1094  UINT8 buff[8192];
1095  UINT32 len=8192;
1096  DOM_Output::dumpToMem(elemCert,buff,&len);
1097  CAMsg::printMsg(LOG_DEBUG,(char*)buff);
1098 
1099  elemOptionsPrevMixCert->appendChild(m_docMixXml->importNode(elemCert,true));
1100  CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - MixConf now:\n");
1101  len=8192;
1103  buff[len]=0;
1104  CAMsg::printMsg(LOG_DEBUG,(char*)buff);
1105  }
1106  else
1107  {
1108  if(elemOptionsPrevMixCert->hasChildNodes())
1109  {
1110  elemOptionsPrevMixCert->replaceChild(m_docMixXml->importNode(elemCert->getFirstChild(),true),
1111  elemOptionsPrevMixCert->getFirstChild());
1112  }
1113  else
1114  {
1115  elemOptionsPrevMixCert->appendChild(m_docMixXml->importNode(elemCert->getFirstChild(),true));
1116  }
1117  }
1118  CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - end\n");
1120  }
1121  CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - end with error\n");
1122  return E_UNKNOWN;
1123 }
1124 
1125 #else //DYNAMIC_MIX
1126 
1127 SINT32 CACmdLnOptions::setPrevMix(DOM_Document& doc)
1128 {
1129  resetPrevMix();
1130  CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - start\n");
1131  DOM_Element elemRoot = doc.getDocumentElement();
1132  DOM_Element elemSig;
1133  getDOMChildByName(elemRoot,(UINT8*) OPTIONS_NODE_SIGNATURE, elemSig, false);
1134  DOM_Element elemCert;
1135  getDOMChildByName(elemSig,(UINT8*) OPTIONS_NODE_X509DATA, elemCert,true);
1136 
1137  if(elemCert!=NULL)
1138  {
1140  return E_SUCCESS; //processXmlConfiguration(m_docMixXml);
1141  }
1142  CAMsg::printMsg(LOG_DEBUG,"setPrevMix() - end with error\n");
1143  return E_UNKNOWN;
1144 }
1145 #endif //DYNAMIC_MIX
1146 #endif //ONLY_LOCAL_PROXY
1147 
1148 #ifndef ONLY_LOCAL_PROXY
1149 #ifdef DYNAMIC_MIX
1150 SINT32 CACmdLnOptions::resetNextMix()
1151 {
1152  if(m_pNextMixCertificate != NULL)
1153  {
1154  delete m_pNextMixCertificate;
1155  m_pNextMixCertificate = NULL;
1156  }
1157  DOM_Element elemOptionsRoot = m_docMixXml.getDocumentElement();
1158  DOM_Element elemOptionsCerts;
1159  getDOMChildByName(elemOptionsRoot, (UINT8*) OPTIONS_NODE_CERTIFICATE_LIST, elemOptionsCerts, false);
1160  DOM_Element elemTmp;
1161  // Remove existing certificates
1162  if(getDOMChildByName(elemOptionsCerts, (UINT8*) OPTIONS_NODE_PREV_MIX_CERTIFICATE, elemTmp, false) == E_SUCCESS)
1163  {
1164 
1165  elemOptionsCerts.removeChild(elemTmp);
1166  }
1167  if(getDOMChildByName(elemOptionsCerts, (UINT8*) OPTIONS_NODE_PREV_OPERATOR_CERTIFICATE, elemTmp, false) == E_SUCCESS)
1168  {
1169 
1170  elemOptionsCerts.removeChild(elemTmp);
1171  }
1173  return E_SUCCESS;
1174 }
1175 
1176 SINT32 CACmdLnOptions::resetPrevMix()
1177 {
1178  if(m_pPrevMixCertificate != NULL)
1179  {
1180  delete m_pPrevMixCertificate;
1181  m_pPrevMixCertificate = NULL;
1182  }
1183  DOM_Element elemOptionsRoot = m_docMixXml.getDocumentElement();
1184  DOM_Element elemOptionsCerts;
1185  getDOMChildByName(elemOptionsRoot, (UINT8*) OPTIONS_NODE_CERTIFICATE_LIST, elemOptionsCerts, false);
1186  DOM_Element elemTmp;
1187  // Remove existing certificates
1188  if(getDOMChildByName(elemOptionsCerts, (UINT8*) OPTIONS_NODE_NEXT_MIX_CERTIFICATE, elemTmp, false) == E_SUCCESS)
1189  {
1190 
1191  elemOptionsCerts.removeChild(elemTmp);
1192  }
1193  if(getDOMChildByName(elemOptionsCerts, (UINT8*) OPTIONS_NODE_NEXT_OPERATOR_CERTIFICATE, elemTmp, false) == E_SUCCESS)
1194  {
1195 
1196  elemOptionsCerts.removeChild(elemTmp);
1197  }
1198  return E_SUCCESS;
1199 
1200 }
1201 #endif //DYNAMIC_MIX
1202 #endif //ONLY_LOCAL_PROXY
1203 
1204 #ifndef ONLY_LOCAL_PROXY
1213  {
1215  return E_UNKNOWN;
1216  m_bIsRunReConfigure=true;
1219  param->pCmdLnOptions=this;
1220  param->pMix=pMix;
1221  m_threadReConfigure.start(param,true,false);
1222  return E_SUCCESS;
1223  }
1224 
1230  {
1231  CACmdLnOptions* pOptions=((t_CMNDLN_REREAD_PARAMS*)param)->pCmdLnOptions;
1232  CAMix* pMix=((t_CMNDLN_REREAD_PARAMS*)param)->pMix;
1233  //pOptions->m_pcsReConfigure->lock();
1234  CAMsg::printMsg(LOG_DEBUG,"ReConfiguration of the Mix is under way....\n");
1235  CACmdLnOptions otmpOptions;
1236  XERCES_CPP_NAMESPACE::DOMDocument* docConfig=NULL;
1237  if(otmpOptions.readXmlConfiguration(docConfig,pOptions->m_strConfigFile)!=E_SUCCESS)
1238  {
1239  CAMsg::printMsg(LOG_DEBUG,"Could not re-read the config file!\n");
1240  goto REREAD_FINISH;
1241  }
1242  CAMsg::printMsg(LOG_DEBUG,"Re-readed config file -- start processing config file!\n");
1243  if(otmpOptions.processXmlConfiguration(docConfig)!=E_SUCCESS)
1244  {
1245  CAMsg::printMsg(LOG_DEBUG,"Re-readed config file -- could not process configuration!\n");
1246  goto REREAD_FINISH;
1247  }
1248  pOptions->setNewValues(otmpOptions);
1249  if(pMix!=NULL)
1250  pMix->reconfigure();
1251 
1252 REREAD_FINISH:
1253  CAMsg::printMsg(LOG_DEBUG,"ReConfiguration of the Mix finished!\n");
1254  //pOptions->m_pcsReConfigure->unlock();
1255  pOptions->m_bIsRunReConfigure=false;
1257  }
1258 #endif //ONLY_LOCAL_PROXY
1259 
1261  {
1262  return m_bDaemon;
1263  }
1264 
1266  {
1267  if(len<24||m_strMixID==NULL) //we need 24 chars (including final \0)
1268  return E_UNKNOWN;
1269  strcpy((char*)id,m_strMixID);
1270  return E_SUCCESS;
1271  }
1272 
1273 
1275  {
1276  return m_iSOCKSServerPort;
1277  }
1278 
1280  {
1281  return m_iTargetPort;
1282  }
1283 
1284 
1286  {
1287  if(m_strTargetHost==NULL)
1288  return E_UNKNOWN;
1289  if(len<=(UINT32)strlen(m_strTargetHost))
1290  {
1291  return E_UNKNOWN;
1292  }
1293  strcpy((char*)host,m_strTargetHost);
1294  return E_SUCCESS;
1295  }
1296 
1297 #ifndef ONLY_LOCAL_PROXY
1299  {
1300  return m_iSOCKSPort;
1301  }
1302 
1304  {
1305  if(m_strSOCKSHost==NULL)
1306  return E_UNKNOWN;
1307  if(len<=(UINT32)strlen(m_strSOCKSHost))
1308  {
1309  return E_UNKNOWN;
1310  }
1311  strcpy((char*)host,m_strSOCKSHost);
1312  return (SINT32)strlen(m_strSOCKSHost);
1313  }
1314 #endif //ONLY_LOCAL_PROXY
1315 
1316 #ifdef PAYMENT
1323  {
1324  return m_pBI;
1325  }
1326 
1328  {
1329  if(m_strDatabaseHost==NULL)
1330  return E_UNKNOWN;
1331  if(len<=(UINT32)strlen((char *)m_strDatabaseHost))
1332  {
1333  return E_UNKNOWN;
1334  }
1335  strcpy((char*)host,(char *)m_strDatabaseHost);
1336  return E_SUCCESS;
1337 }
1338 
1340  {
1341  return m_iDatabasePort;
1342  }
1343 
1345  {
1346  if(m_strDatabaseName==NULL)
1347  return E_UNKNOWN;
1348  if(len<=(UINT32)strlen((char *)m_strDatabaseName))
1349  {
1350  return E_UNKNOWN;
1351  }
1352  strcpy((char*)name,(char *)m_strDatabaseName);
1353  return E_SUCCESS;
1354  }
1355 
1357  {
1358  if(m_strDatabaseUser==NULL)
1359  return E_UNKNOWN;
1360  if(len<=(UINT32)strlen((char *)m_strDatabaseUser))
1361  {
1362  return E_UNKNOWN;
1363  }
1364  strcpy((char*)user,(char *)m_strDatabaseUser);
1365  return E_SUCCESS;
1366  }
1367 
1369  {
1370  if(m_strDatabasePassword==NULL)
1371  return E_UNKNOWN;
1372  if(len<=(UINT32)strlen((char *)m_strDatabasePassword))
1373  {
1374  return E_UNKNOWN;
1375  }
1376  strcpy((char*)pass,(char *)m_strDatabasePassword);
1377  return E_SUCCESS;
1378  }
1379 
1381  {
1382  if(m_strAiID==NULL)
1383  return E_UNKNOWN;
1384  if(len<=(UINT32)strlen((char *)m_strAiID))
1385  {
1386  return E_UNKNOWN;
1387  }
1388  strcpy((char*)id,(char *)m_strAiID);
1389  return E_SUCCESS;
1390  }
1391 
1393 {
1394  return m_iPaymentHardLimit;
1395 }
1396 
1398 {
1399  return m_iPrepaidInterval;
1400 }
1401 
1403 {
1404  return m_iPaymentSoftLimit;
1405 }
1406 
1408 {
1409  return m_iPaymentSettleInterval;
1410 }
1411 
1412 #endif /* ifdef PAYMENT */
1413 
1414 #ifndef ONLY_LOCAL_PROXY
1416 {
1417  if(m_OpCert == NULL)
1418  {
1419  (*length) = 0;
1420  return E_UNKNOWN;
1421  }
1422  return m_OpCert->getSubjectKeyIdentifier(buffer, length);
1423 
1424 }
1425 
1426 
1427 
1428 
1430  {
1431  if(m_strEncryptedLogDir==NULL||name==NULL)
1432  return E_UNKNOWN;
1433  if(len<=(UINT32)strlen(m_strEncryptedLogDir))
1434  return E_UNKNOWN;
1435  strcpy((char*)name,m_strEncryptedLogDir);
1436  return E_SUCCESS;
1437  }
1438 #endif //ONLY_LOCAL_PROXY
1439 
1441  {
1442  if(m_strLogDir==NULL||name==NULL)
1443  return E_UNKNOWN;
1444  if(len<=(UINT32)strlen(m_strLogDir))
1445  {
1446  return E_SPACE;
1447  }
1448  strcpy((char*)name,m_strLogDir);
1449  return E_SUCCESS;
1450  }
1451 
1453  {
1454  if(m_strLogDir!=NULL)
1455  {
1456  delete[] m_strLogDir;
1457  m_strLogDir = NULL;
1458  }
1459  m_strLogDir=new char[len+1];
1460  memcpy(m_strLogDir,name,len);
1461  m_strLogDir[len]=0;
1462  return E_SUCCESS;
1463  }
1464 
1466  {
1467  if(m_strCredential==NULL||credential==NULL)
1468  return E_UNKNOWN;
1469  if(len<=(UINT32)strlen(m_strCredential))
1470  {
1471  return E_SPACE;
1472  }
1473  strcpy((char*)credential,m_strCredential);
1474  return E_SUCCESS;
1475  }
1476 
1478  {
1479  if(m_strPidFile==NULL||pidfile==NULL)
1480  return E_UNKNOWN;
1481  if(len<=(UINT32)strlen(m_strPidFile))
1482  {
1483  return E_SPACE;
1484  }
1485  strcpy((char*)pidfile,m_strPidFile);
1486  return E_SUCCESS;
1487  }
1488 
1489 
1491 {
1492  if(m_strUser==NULL||user==NULL)
1493  {
1494  return E_UNKNOWN;
1495  }
1496  if(len<=(UINT32)strlen(m_strUser))
1497  {
1498  return E_UNKNOWN;
1499  }
1500  strcpy((char*)user,m_strUser);
1501  return E_SUCCESS;
1502 }
1503 
1505 {
1506  return m_bFirstMix;
1507 }
1508 
1510 {
1511  return m_bMiddleMix;
1512 }
1513 
1515 {
1516  return m_bLastMix;
1517 }
1518 
1520 {
1521  return m_bLocalProxy;
1522 }
1523 
1524 
1525 #ifdef SERVER_MONITORING
1526 char *CACmdLnOptions::getMonitoringListenerHost()
1527 {
1528  return m_strMonitoringListenerHost;
1529 }
1530 
1531 UINT16 CACmdLnOptions::getMonitoringListenerPort()
1532 {
1533  return m_iMonitoringListenerPort;
1534 }
1535 #endif /* SERVER_MONITORING */
1536 
1538  {
1539  SINT32 ret = E_SUCCESS;
1540  UINT8 buff[2000];
1541  UINT32 iLogOptions = MSG_NOLOG;
1542 
1543  CAMsg::init();
1544 
1545 
1546 #ifndef ONLY_LOCAL_PROXY
1547  if(isSyslogEnabled())
1548  {
1549  iLogOptions |= MSG_LOG;
1550  }
1551 #endif
1552  if(getLogDir((UINT8*)buff,2000)==E_SUCCESS)
1553  {
1554  if(getCompressLogs())
1555  iLogOptions |= MSG_COMPRESSED_FILE;
1556  else
1557  iLogOptions |= MSG_FILE;
1558  }
1559 #if !defined ONLY_LOCAL_PROXY || defined INCLUDE_MIDDLE_MIX
1560 
1561  if (m_bLogConsole )
1562  {
1563  iLogOptions |= MSG_STDOUT;
1564  }
1565  ret = CAMsg::setLogOptions(iLogOptions);
1566 
1567  if(m_strLogLevel!=NULL)
1568  {
1569  if (strcmp(m_strLogLevel,"info") == 0)
1570  {
1571  CAMsg::setLogLevel(LOG_INFO);
1572  }
1573  else if (strcmp(m_strLogLevel,"warning") == 0)
1574  {
1575  CAMsg::setLogLevel(LOG_WARNING);
1576  }
1577  else if (strcmp(m_strLogLevel,"error") == 0)
1578  {
1579  CAMsg::setLogLevel(LOG_ERR);
1580  }
1581  else if (strcmp(m_strLogLevel,"critical") == 0)
1582  {
1583  CAMsg::setLogLevel(LOG_CRIT);
1584  }
1585  else if (strcmp(m_strLogLevel,"debug") == 0)
1586  {
1587  CAMsg::setLogLevel(LOG_DEBUG);
1588  }
1589  }
1590 #endif
1591 #if!defined ONLY_LOCAL_PROXY
1592  if(isEncryptedLogEnabled())
1593  {
1594  SINT32 retEncr;
1595  if ((retEncr = CAMsg::openEncryptedLog()) != E_SUCCESS)
1596  {
1597  CAMsg::printMsg(LOG_ERR,"Could not open encrypted log - exiting!\n");
1598  return retEncr;
1599  }
1600  }
1601 #endif
1602 
1603  if(getDaemon() && ret != E_SUCCESS)
1604  {
1605  CAMsg::printMsg(LOG_CRIT, "We need a log file in daemon mode in order to get any messages! Exiting...\n");
1606  return ret;
1607  }
1608 
1609  return E_SUCCESS;
1610  }
1611 
1612 
1613 #if !defined ONLY_LOCAL_PROXY || defined INCLUDE_FIRST_MIX
1615  {
1616  if (m_strAccessControlCredential != NULL)
1617  {
1620  }
1621 
1622  DOMElement* elemCredential = NULL;
1623  UINT8 tmpBuff[TMP_BUFF_SIZE];
1624  UINT32 tmpLen = TMP_BUFF_SIZE;
1625 
1626  if (elemGeneral == NULL)
1627  return E_UNKNOWN;
1628  ASSERT_GENERAL_OPTIONS_PARENT(elemGeneral->getNodeName(), OPTIONS_NODE_CREDENTIAL);
1629 
1630  //get Accesscontrol credential
1631  getDOMChildByName(elemGeneral, OPTIONS_NODE_CREDENTIAL, elemCredential, false);
1632 
1633  if (getDOMElementValue(elemCredential, tmpBuff, &tmpLen) == E_SUCCESS)
1634  {
1635  m_strAccessControlCredential = new UINT8[tmpLen + 1];
1636  memcpy(m_strAccessControlCredential,tmpBuff,tmpLen);
1637  m_strAccessControlCredential[tmpLen] = 0;
1638  DOMElement* elemMixType=NULL;
1639  getDOMChildByName(m_docMixInfo, "MixType", elemMixType, true);
1640  setDOMElementAttribute(elemMixType, "accessControlled", true);
1641  }
1642  return E_SUCCESS;
1643  }
1644 
1646  {
1647 
1648  if (outbuff== NULL || inoutsize == NULL || m_strAccessControlCredential==NULL || *inoutsize<=strlen((char*)m_strAccessControlCredential))
1649  return E_UNKNOWN;
1650  strcpy((char*)outbuff, (char*)m_strAccessControlCredential);
1651  *inoutsize = strlen((char*)m_strAccessControlCredential);
1652  return E_SUCCESS;
1653  }
1654 
1655 
1657  {
1658  m_algSymChannelCipher = cipherAlgorithm;
1659 
1660  //Append if to MixInfo
1661  DOMElement* elemRoot=m_docMixInfo->getDocumentElement();
1662  DOMElement* elemChannelSymmetricChipher=NULL;
1663  getDOMChildByName(elemRoot, "ChannelSymmetricChipher",elemChannelSymmetricChipher,false);
1664  if (elemChannelSymmetricChipher == NULL)
1665  {
1666  elemChannelSymmetricChipher = createDOMElement(m_docMixInfo, "ChannelSymmetricChipher");
1667  elemRoot->appendChild(elemChannelSymmetricChipher);
1668  }
1669  const UINT8* const algName=CASymChannelCipher::getAlgorithmName(cipherAlgorithm);
1670  setDOMElementValue(elemChannelSymmetricChipher, algName);
1671  return E_SUCCESS;
1672  }
1673 
1675  {
1676  return m_algSymChannelCipher;
1677  }
1678 
1679 #endif
1680 
1681 
1682 #ifndef ONLY_LOCAL_PROXY
1683 
1684 
1685 
1687 {
1689 }
1690 XERCES_CPP_NAMESPACE::DOMDocument **CACmdLnOptions::getAllTermsAndConditionsTemplates()
1691 {
1693 }
1694 
1695 /* a reference to the Terms and conditions document stored by this class.
1696  * this method does not return a copy of the doc so don't release it.
1697  */
1699 {
1700  //DOMElement *docElement = NULL;
1701  if(m_docOpTnCs == NULL)
1702  {
1703  return NULL;
1704  }
1705  UINT8 tmpBuff[TMP_BUFF_SIZE];
1706  UINT32 tmpLen = TMP_BUFF_SIZE;
1707  memset(tmpBuff, 0, tmpLen);
1708  getOperatorSubjectKeyIdentifier(tmpBuff, &tmpLen);
1709  setDOMElementAttribute(m_docOpTnCs->getDocumentElement(), OPTIONS_ATTRIBUTE_TNC_ID, tmpBuff);
1710  return m_docOpTnCs->getDocumentElement();
1711  //docElement = m_docOpTnCs->getDocumentElement();
1712  //return (docElement == NULL) ? NULL : getElementsByTagName(docElement, OPTION_NODE_TNCS);
1713 }
1714 
1715 
1716 
1717 
1718 SINT32 CACmdLnOptions::setMaxUsers(DOMElement* elemGeneral)
1719 {
1720  DOMElement* elemMaxUsers=NULL;
1721  UINT32 tmp = 0;
1722 
1723  if(elemGeneral == NULL) return E_UNKNOWN;
1725  (elemGeneral->getNodeName(), OPTIONS_NODE_MAX_USERS);
1726 
1727  // get max users
1728  getDOMChildByName(elemGeneral, OPTIONS_NODE_MAX_USERS, elemMaxUsers, false);
1729  if(elemMaxUsers!=NULL)
1730  {
1731  if(getDOMElementValue(elemMaxUsers, &tmp)==E_SUCCESS)
1732  {
1733  m_maxNrOfUsers = tmp;
1734  }
1735  }
1736  return E_SUCCESS;
1737 }
1738 
1740 {
1741  DOMElement* elemPaymentReminder=NULL;
1743 
1744  if(elemGeneral == NULL)
1745  return E_UNKNOWN;
1746  ASSERT_GENERAL_OPTIONS_PARENT (elemGeneral->getNodeName(), OPTIONS_NODE_PAYMENT_REMINDER);
1747 
1748  // get payment reminder probabilty
1749  getDOMChildByName(elemGeneral, OPTIONS_NODE_PAYMENT_REMINDER, elemPaymentReminder, false);
1750  bool bEnabled=false;
1751  getDOMElementAttribute(elemPaymentReminder, "enable", bEnabled);
1752  if (!bEnabled)
1753  {
1755  }
1756  else
1757  {
1758  getDOMElementValue(elemPaymentReminder, &m_PaymentReminderProbability);
1759  }
1760  return E_SUCCESS;
1761 }
1762 
1763 
1764 
1765 
1766 // **************************************
1767 // accounting option setter functions *
1768 // *************************************
1769 #ifdef PAYMENT
1771 {
1772  // the accoutning options are added by Bastian Voigt
1773  DOMElement* elemAccounting=NULL;
1774  if (getDOMChildByName
1775  (elemRoot, OPTIONS_NODE_ACCOUNTING, elemAccounting, false) != E_SUCCESS)
1776  {
1778  return E_UNKNOWN;
1779  }
1780 
1781  return invokeOptionSetters
1783  return E_SUCCESS;
1784 }
1785 
1786 
1787 SINT32 CACmdLnOptions::setPriceCertificate(DOMElement *elemAccounting)
1788 {
1789 
1790  DOMElement* elemPriceCert = NULL;
1791 
1792  if(elemAccounting == NULL) return E_UNKNOWN;
1794  (elemAccounting->getNodeName(), OPTIONS_NODE_PRICE_CERTIFICATE);
1795 
1796  //function in CAUtil, last param is "deep", needs to be set to include child elems
1798  (elemAccounting, OPTIONS_NODE_PRICE_CERTIFICATE, elemPriceCert, false);
1799  if (elemPriceCert == NULL)
1800  {
1801  CAMsg::printMsg(LOG_CRIT, "Did you really want to compile the mix with payment support?\n");
1803  return E_UNKNOWN;
1804  }
1805  else
1806  {
1807 // UINT8 digest[SHA_DIGEST_LENGTH];
1808 // UINT8* out=new UINT8[5000];
1809 // UINT32 outlen=5000;
1810 //
1811 // DOM_Output::makeCanonical(elemPriceCert,out,&outlen);
1812 // out[outlen] = 0;
1814 // CAMsg::printMsg(LOG_DEBUG, "price cert (%u bytes) to be hashed: %s\n",outlen, out);
1816 // SHA1(out,outlen,digest);
1817 // delete[] out;
1818 // out = NULL;
1819 //
1820 // UINT32 len2 = 1024;
1821 // UINT8* tmpBuff2 = new UINT8[len2+1];
1822 // memset(tmpBuff2, 0, len2+1);
1823 // CABase64::encode(digest,SHA_DIGEST_LENGTH, tmpBuff2, &len2);
1824 // CAMsg::printMsg(LOG_CRIT,"hash: %s\n", tmpBuff2);
1825 // exit(0);
1826  m_pPriceCertificate = CAXMLPriceCert::getInstance(elemPriceCert);
1827  if (m_pPriceCertificate == NULL)
1828  {
1829  CAMsg::printMsg(LOG_CRIT, "Could not parse price certificate!");
1830  return E_UNKNOWN;
1831  }
1832  m_strAiID = m_pPriceCertificate->getSubjectKeyIdentifier();
1833 
1835  {
1836  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");
1837  return E_UNKNOWN;
1838  }
1839 
1840  if (m_pBI == NULL)
1841  {
1842  CAMsg::printMsg(LOG_CRIT,"Could not verify price certificate, as no payment instance was found!\n");
1843  return E_UNKNOWN;
1844  }
1845 
1846 
1847  if (CAMultiSignature::verifyXML(elemPriceCert, m_pBI->getCertificate()) != E_SUCCESS)
1848  {
1849  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");
1850  return E_UNKNOWN;
1851  }
1852 
1853  }
1854 
1855  //insert price certificate
1856  return appendMixInfo_internal(elemPriceCert, WITH_SUBTREE);
1857 
1858  return E_SUCCESS;
1859 }
1860 
1861 SINT32 CACmdLnOptions::setPaymentInstance(DOMElement *elemAccounting)
1862 {
1863 
1864  DOMElement* elemJPI = NULL;
1865 
1866  if(elemAccounting == NULL) return E_UNKNOWN;
1868  (elemAccounting->getNodeName(), OPTIONS_NODE_PAYMENT_INSTANCE);
1869 
1870  CAMsg::printMsg(LOG_DEBUG, "Parsing JPI values.\n");
1871 
1872  getDOMChildByName(elemAccounting, OPTIONS_NODE_PAYMENT_INSTANCE, elemJPI, false);
1873  m_pBI = CAXMLBI::getInstance(elemJPI);
1874  if (m_pBI == NULL)
1875  {
1876  CAMsg::printMsg(LOG_CRIT,"Could not instantiate payment instance interface. Did you really want to compile the mix with payment support?\n");
1877  return E_UNKNOWN;
1878  }
1879  return E_SUCCESS;
1880 }
1881 
1882 
1884 {
1885 
1886  DOMElement* elemAISoftLimit = NULL;
1887  UINT32 tmp = 0;
1888 
1889  if(elemAccounting == NULL) return E_UNKNOWN;
1891  (elemAccounting->getNodeName(), OPTIONS_NODE_AI_SOFT_LIMIT);
1892 
1893  if (getDOMChildByName
1894  (elemAccounting, OPTIONS_NODE_AI_SOFT_LIMIT, elemAISoftLimit, false) != E_SUCCESS)
1895  {
1897  return E_UNKNOWN;
1898  }
1899  if(getDOMElementValue(elemAISoftLimit, &tmp)==E_SUCCESS)
1900  {
1901  m_iPaymentSoftLimit = tmp;
1902  }
1903  else
1904  {
1905  //or better set default values?
1907  return E_UNKNOWN;
1908  }
1909  return E_SUCCESS;
1910 }
1911 
1912 
1914 {
1915 
1916  DOMElement* elemAIHardLimit = NULL;
1917  UINT32 tmp = 0;
1918 
1919  if(elemAccounting == NULL) return E_UNKNOWN;
1921  (elemAccounting->getNodeName(), OPTIONS_NODE_AI_HARD_LIMIT);
1922 
1923  if (getDOMChildByName
1924  (elemAccounting, OPTIONS_NODE_AI_HARD_LIMIT, elemAIHardLimit, false) != E_SUCCESS)
1925  {
1927  return E_UNKNOWN;
1928  }
1929  if(getDOMElementValue(elemAIHardLimit, &tmp)==E_SUCCESS)
1930  {
1931  m_iPaymentHardLimit = tmp;
1932  }
1933  else
1934  {
1935  //or better set default values?
1937  return E_UNKNOWN;
1938  }
1939  return E_SUCCESS;
1940 }
1941 
1942 
1943 SINT32 CACmdLnOptions::setPrepaidInterval(DOMElement *elemAccounting)
1944 {
1945 
1946  DOMElement* elemPrepaidIval = NULL;
1947  UINT32 tmp = 0;
1948 
1949  if(elemAccounting == NULL) return E_UNKNOWN;
1951  (elemAccounting->getNodeName(), OPTIONS_NODE_PREPAID_IVAL);
1952 
1953  if (getDOMChildByName
1954  (elemAccounting, OPTIONS_NODE_PREPAID_IVAL, elemPrepaidIval, false) != E_SUCCESS)
1955  {
1957 
1958  if (getDOMChildByName
1959  (elemAccounting, OPTIONS_NODE_PREPAID_IVAL_KB, elemPrepaidIval, false) != E_SUCCESS)
1960  {
1962  }
1963  else
1964  {
1965  if(getDOMElementValue(elemPrepaidIval, &tmp)==E_SUCCESS)
1966  {
1967  m_iPrepaidInterval = tmp * 1000;
1968  }
1969  }
1970  }
1971  else if(getDOMElementValue(elemPrepaidIval, &tmp) == E_SUCCESS)
1972  {
1973  m_iPrepaidInterval = tmp;
1974  }
1975  else
1976  {
1977  CAMsg::printMsg(LOG_INFO,"Node \"%s\" is empty! Setting default...\n",
1980  }
1982  {
1983  CAMsg::printMsg(LOG_WARNING,"Prepaid interval is higher than %u! "
1984  "No JAP will pay more in advance!\n", OPTIONS_DEFAULT_PREPAID_IVAL);
1985  }
1986  else if (m_iPrepaidInterval < 5000)
1987  {
1988  CAMsg::printMsg(LOG_WARNING,"Prepaid interval of %u is far too low! "
1989  "Performance will be critical and clients will lose connection!\n", m_iPrepaidInterval);
1990  }
1991 
1992  //insert prepaid interval
1993  DOMElement* elemInterval = createDOMElement(m_docMixInfo, OPTIONS_NODE_PREPAID_IVAL_KB);
1994  setDOMElementValue(elemInterval, (m_iPrepaidInterval / 1000) );
1995  //TODO: handle exceptional cases
1996  m_docMixInfo->getDocumentElement()->appendChild(elemInterval);
1997  return E_SUCCESS;
1998 }
1999 
2000 
2001 SINT32 CACmdLnOptions::setSettleInterval(DOMElement *elemAccounting)
2002 {
2003 
2004  DOMElement* elemSettleIval = NULL;
2005  UINT32 tmp = 0;
2006 
2007  if(elemAccounting == NULL) return E_UNKNOWN;
2009  (elemAccounting->getNodeName(), OPTIONS_NODE_SETTLE_IVAL);
2010 
2011  if (getDOMChildByName
2012  (elemAccounting, OPTIONS_NODE_SETTLE_IVAL, elemSettleIval, false) != E_SUCCESS)
2013  {
2015  return E_UNKNOWN;
2016  }
2017  if(getDOMElementValue(elemSettleIval, &tmp)==E_SUCCESS)
2018  {
2020  }
2021  else
2022  {
2024  return E_UNKNOWN;
2025  }
2026  return E_SUCCESS;
2027 }
2028 
2029 
2031 {
2032 
2033  DOMElement* elem = NULL;
2034  DOMElement* elemDatabase = NULL;
2035  UINT8 tmpBuff[TMP_BUFF_SIZE];
2036  UINT32 tmpLen = TMP_BUFF_SIZE, tmp = 0;
2037 
2038  // DDB is only configured for first payment mix
2039  if (!m_bFirstMix)
2040  {
2041  return E_SUCCESS;
2042  }
2043 
2044  if(elemAccounting == NULL) return E_UNKNOWN;
2046  (elemAccounting->getNodeName(), OPTIONS_NODE_AI_DB);
2047 
2048  CAMsg::printMsg(LOG_DEBUG, "Parsing AI values.\n");
2049 
2050  if (getDOMChildByName(elemAccounting, OPTIONS_NODE_AI_DB, elemDatabase, false) != E_SUCCESS)
2051  {
2053  return E_UNKNOWN;
2054  }
2055 
2056  // get DB Hostname
2057  if (getDOMChildByName(elemDatabase, OPTIONS_NODE_AI_DB_HOST, elem, false) != E_SUCCESS)
2058  {
2060  return E_UNKNOWN;
2061  }
2062 
2063  if(getDOMElementValue(elem, tmpBuff, &tmpLen) != E_SUCCESS)
2064  {
2066  return E_UNKNOWN;
2067  }
2068  strtrim(tmpBuff);
2069  m_strDatabaseHost = new UINT8[strlen((char*)tmpBuff)+1];
2070  strcpy((char *)m_strDatabaseHost, (char *) tmpBuff);
2071 
2072  // get Database Port
2073  if (getDOMChildByName
2074  (elemDatabase, OPTIONS_NODE_AI_DB_PORT, elem, false) != E_SUCCESS)
2075  {
2077  return E_UNKNOWN;
2078  }
2079  if(getDOMElementValue(elem, &tmp) != E_SUCCESS)
2080  {
2082  return E_UNKNOWN;
2083  }
2084  m_iDatabasePort = tmp;
2085 
2086  // get DB Name
2087  if (getDOMChildByName
2088  (elemDatabase, OPTIONS_NODE_AI_DB_NAME, elem, false) != E_SUCCESS)
2089  {
2091  return E_UNKNOWN;
2092  }
2093 
2094  tmpLen = TMP_BUFF_SIZE;
2095  memset(tmpBuff, 0, tmpLen);
2096 
2098  (elem, tmpBuff, &tmpLen) != E_SUCCESS)
2099  {
2101  return E_UNKNOWN;
2102  }
2103  strtrim(tmpBuff);
2104  m_strDatabaseName = new UINT8[strlen((char*)tmpBuff)+1];
2105  strcpy((char *)m_strDatabaseName, (char *) tmpBuff);
2106 
2107  // get DB Username
2108  if (getDOMChildByName
2109  (elemDatabase, OPTIONS_NODE_AI_DB_USER, elem, false) != E_SUCCESS)
2110  {
2112  return E_UNKNOWN;
2113  }
2114 
2115  tmpLen = TMP_BUFF_SIZE;
2116  memset(tmpBuff, 0, tmpLen);
2117 
2119  (elem, tmpBuff, &tmpLen) != E_SUCCESS)
2120  {
2122  return E_UNKNOWN;
2123  }
2124  strtrim(tmpBuff);
2125  m_strDatabaseUser = new UINT8[strlen((char*)tmpBuff)+1];
2126  strcpy((char *)m_strDatabaseUser, (char *) tmpBuff);
2127 
2128  //get DB password from xml
2129  getDOMChildByName(elemDatabase, OPTIONS_NODE_AI_DB_PASSW, elem, false);
2130 
2131  tmpLen = TMP_BUFF_SIZE;
2132  memset(tmpBuff, 0, tmpLen);
2133 
2134  //read password from xml if given
2135  if(getDOMElementValue(elem, tmpBuff, &tmpLen) != E_SUCCESS)
2136  {
2137  //read password from stdin:
2138  UINT8 dbpass[500];
2139  dbpass[0] = 0;
2140  printf("Please enter password for postgresql user %s at %s: ",m_strDatabaseUser, m_strDatabaseHost);
2141  scanf("%400[^\n]%*1[\n]",(char*)dbpass);
2142  int len = strlen((char *)dbpass);
2143  if(len>0)
2144  {
2145  m_strDatabasePassword = new UINT8[len+1];
2146  strcpy((char *)m_strDatabasePassword, (char *)dbpass);
2147  }
2148  else
2149  {
2150  m_strDatabasePassword = new UINT8[1];
2151  m_strDatabasePassword[0] = '\0';
2152  }
2153  }
2154  else
2155  {
2156  strtrim(tmpBuff);
2157  m_strDatabasePassword = new UINT8[strlen((char*)tmpBuff)+1];
2158  strcpy((char *)m_strDatabasePassword, (char *) tmpBuff);
2159  }
2160  CAMsg::printMsg(LOG_DEBUG, "Accounting database information parsed successfully.\n");
2161 
2162  // just for testing the connection to the database
2164  {
2165  exit(EXIT_FAILURE);
2166  }
2168 
2169  return E_SUCCESS;
2170 }
2171 #endif //PAYMENT
2172 
2173 
2174 
2175 
2176 
2177 
2178 
2179 
2180 #ifdef PAYMENT
2181 // *************************************************
2182 // * terms and condition option setter function(s) *
2183 // *************************************************
2185 {
2186  DOMElement *elemTnCs = NULL;
2187 
2188  if(elemRoot == NULL)
2189  {
2190  return E_UNKNOWN;
2191  }
2192 
2193  getDOMChildByName(elemRoot, OPTIONS_NODE_TNCS_OPTS, elemTnCs, true);
2194  if(elemTnCs != NULL)
2195  {
2196  return invokeOptionSetters
2198  }
2199  else
2200  {
2201  CAMsg::printMsg(LOG_WARNING,"No Terms & Conditions for Operator specified!\n");
2202  return E_SUCCESS;
2203  }
2204 }
2205 
2207 {
2208  if(elemTnCs == NULL)
2209  {
2210  CAMsg::printMsg(LOG_CRIT,"Terms And Conditions root element is null!\n");
2211  return E_UNKNOWN;
2212  }
2213  DOMElement *elemTnCsTemplates = NULL;
2214  DOMNodeList *templateList = NULL;
2215  bool nothingFound = true;
2216  getDOMChildByName(elemTnCs, OPTIONS_NODE_TNCS_TEMPLATES, elemTnCsTemplates);
2217 
2218  UINT8** loadedTemplateRefIds = NULL;
2219  bool templateError = false;
2220 
2221  if(elemTnCsTemplates != NULL)
2222  {
2223  templateList = getElementsByTagName(elemTnCsTemplates, OPTIONS_NODE_TNCS_TEMPLATE);
2224  if(templateList->getLength() > 0)
2225  {
2226  nothingFound = false;
2227  m_nrOfTermsAndConditionsTemplates = templateList->getLength();
2228  m_termsAndConditionsTemplates = new XERCES_CPP_NAMESPACE::DOMDocument*[m_nrOfTermsAndConditionsTemplates];
2229  loadedTemplateRefIds = new UINT8*[m_nrOfTermsAndConditionsTemplates];
2230  memset(loadedTemplateRefIds, 0, (sizeof(UINT8*)*m_nrOfTermsAndConditionsTemplates) );
2231 
2232  UINT8 currentTemplateURL[TMP_BUFF_SIZE];
2234  memset(currentTemplateURL, 0, len);
2235 
2236  for (UINT32 i = 0; i < templateList->getLength(); i++)
2237  {
2238  getDOMElementValue(templateList->item(i), currentTemplateURL, &len);
2239  m_termsAndConditionsTemplates[i] = parseDOMDocument(currentTemplateURL);
2240  if(m_termsAndConditionsTemplates[i] == NULL)
2241  {
2242  CAMsg::printMsg(LOG_WARNING, "Cannot load Terms And Conditions template '%s'.\n",
2243  currentTemplateURL);
2244  return E_UNKNOWN;
2245  }
2246  UINT8* refId = getTermsAndConditionsTemplateRefId(m_termsAndConditionsTemplates[i]->getDocumentElement());
2247  if(refId != NULL)
2248  {
2249  loadedTemplateRefIds[i] = refId;
2250  for(UINT32 j = 0; j < i; j++)
2251  {
2252  if(strncmp((char *)refId, (char *) loadedTemplateRefIds[j], TEMPLATE_REFID_MAXLEN) == 0 )
2253  {
2254  templateError = true;
2255  CAMsg::printMsg(LOG_ERR, "duplicate Terms And Conditions template '%s'.\n",refId);
2256  break;
2257  }
2258  }
2259  }
2260  else
2261  {
2262  templateError = true;
2263  CAMsg::printMsg(LOG_ERR, "Terms And Conditions template with invalid refid found.\n");
2264  break;
2265  }
2266 
2267  if(!templateError)
2268  {
2269  CAMsg::printMsg(LOG_INFO, "loaded Terms And Conditions template '%s'.\n",refId);
2270  }
2271  else
2272  {
2273  break;
2274  }
2275  len = TMP_BUFF_SIZE;
2276  }
2277  }
2278  if(loadedTemplateRefIds != NULL)
2279  {
2280  for(UINT32 j = 0; j < m_nrOfTermsAndConditionsTemplates; j++)
2281  {
2282  delete [] loadedTemplateRefIds[j];
2283  loadedTemplateRefIds[j] = NULL;
2284  }
2285  delete [] loadedTemplateRefIds;
2286  loadedTemplateRefIds = NULL;
2287  }
2288  if(templateError)
2289  {
2290  return E_UNKNOWN;
2291  }
2292  }
2293 
2294  if(nothingFound)
2295  {
2296  CAMsg::printMsg(LOG_INFO,"No Terms And Conditions templates found.\n");
2297  }
2298 
2299  return E_SUCCESS;
2300 }
2302 {
2303  if(elemTnCs == NULL)
2304  {
2305  CAMsg::printMsg(LOG_CRIT,"Terms And Conditions root element is null!\n");
2306  return E_UNKNOWN;
2307  }
2308  DOMElement *elemTnCsList = NULL;
2309  getDOMChildByName(elemTnCs, OPTIONS_NODE_TNCS, elemTnCsList);
2310 
2311  if(elemTnCsList == NULL)
2312  {
2313  CAMsg::printMsg(LOG_CRIT,"No definitions for Terms And Conditions found!\n");
2314  return E_UNKNOWN;
2315  }
2316 
2317  UINT32 attrCheckLen = TMP_BUFF_SIZE;
2318  UINT8 attrCheck[TMP_BUFF_SIZE];
2319  memset(attrCheck, 0, attrCheckLen);
2320 
2321  UINT32 localeLen = TMP_LOCALE_SIZE;
2322  UINT8 locale[TMP_LOCALE_SIZE];
2323  memset(locale, 0, localeLen);
2324 
2325  UINT32 dateLen = TMP_DATE_SIZE;
2326  UINT8 date[TMP_DATE_SIZE];
2327  memset(date, 0, dateLen);
2328 
2329  if( (getDOMElementAttribute(elemTnCsList, OPTIONS_ATTRIBUTE_TNC_DATE, date, &dateLen) != E_SUCCESS) ||
2330  (strlen((char *)date) != ((TMP_DATE_SIZE) - 1) ) )
2331  {
2332  CAMsg::printMsg(LOG_CRIT,"Attribute '%s' is not properly set for the global definition of Terms And Conditions!\n",
2334  return E_UNKNOWN;
2335  }
2336 
2338 
2339  DOMElement *currentTnCEntry = NULL;
2340  DOMNodeList *tncDefEntryList = getElementsByTagName(elemTnCsList, OPTIONS_NODE_TNCS_TRANSLATION);
2341 
2342  if(tncDefEntryList->getLength() < 1)
2343  {
2344  CAMsg::printMsg(LOG_CRIT,"No Terms And Conditions entries found!\n");
2345  return E_UNKNOWN;
2346  }
2347 
2348  DOMElement *tncTranslationImports = NULL;
2349  DOMElement *tncOperatorNode = NULL;
2350  getDOMChildByName(elemTnCsList, OPTIONS_NODE_TNCS_TRANSLATION_IMPORTS, tncTranslationImports, false);
2351  if(tncTranslationImports != NULL)
2352  {
2353  getDOMChildByName(tncTranslationImports, OPTIONS_NODE_TNCS_OPERATOR, tncOperatorNode, false);
2354  }
2355  bool defaultLangValue = false;
2356  bool defaultLangFound = false;
2357  bool operatorImportNodeFound = (tncOperatorNode != NULL);
2358 
2359  // validity check for every definition: are all necessary attributes set (referenceId, locale), length ok
2360  // * and is there EXACTLY ONE default language specified?
2361  //
2362  for (UINT32 j = 0; j < tncDefEntryList->getLength(); j++)
2363  {
2364  attrCheckLen = TMP_BUFF_SIZE;
2365  localeLen = TMP_LOCALE_SIZE;
2366  defaultLangValue = false;
2367  currentTnCEntry = (DOMElement *) tncDefEntryList->item(j);
2368 
2369  if( (getDOMElementAttribute(currentTnCEntry, OPTIONS_ATTRIBUTE_TNC_TEMPLATE_REFID, attrCheck, &attrCheckLen) != E_SUCCESS) ||
2370  (strlen((char *)attrCheck) < 1) )
2371  {
2372  CAMsg::printMsg(LOG_CRIT,"Attribute '%s' is not proper set for definition %u of Terms And Conditions!\n",
2374  return E_UNKNOWN;
2375  }
2376  else if( (getDOMElementAttribute(currentTnCEntry, OPTIONS_ATTRIBUTE_TNC_LOCALE, locale, &localeLen) != E_SUCCESS) ||
2377  (strlen((char *)locale) != ((TMP_LOCALE_SIZE) - 1) ) )
2378  {
2379  CAMsg::printMsg(LOG_CRIT,"Attribute '%s' is not proper set for definition %u of Terms And Conditions!\n",
2381  return E_UNKNOWN;
2382  }
2383 
2384  if(!operatorImportNodeFound)
2385  {
2386  tncOperatorNode = NULL;
2387  getDOMChildByName(currentTnCEntry, OPTIONS_NODE_TNCS_OPERATOR, tncOperatorNode, false);
2388  if(tncOperatorNode == NULL)
2389  {
2390  CAMsg::printMsg(LOG_CRIT,"No Node '%s' defined for the translation [%s]. Either define it in '%s' or"
2393  return E_UNKNOWN;
2394  }
2395  }
2396 
2397  //setDOMElementAttribute(currentTnCEntry, OPTIONS_ATTRIBUTE_TNC_DATE, date);
2398  getDOMElementAttribute(currentTnCEntry,
2399  OPTIONS_ATTRIBUTE_TNC_DEFAULT_LANG_DEFINED, defaultLangValue);
2400 
2401  if(defaultLangValue && defaultLangFound)
2402  {
2403  CAMsg::printMsg(LOG_CRIT,"exactly ONE default language must be specified for the Terms And Conditions!\n");
2404  return E_UNKNOWN;
2405  }
2406 
2407  //import nodes global for all translations
2408  if(tncTranslationImports != NULL)
2409  {
2410  if(integrateDOMNode(tncTranslationImports, currentTnCEntry, true, false) != E_SUCCESS)
2411  {
2412  CAMsg::printMsg(LOG_CRIT,"Integrating imports failed!\n");
2413  return E_UNKNOWN;
2414  }
2415  }
2416  defaultLangFound = (defaultLangFound || defaultLangValue);
2417  }
2418 
2419  if(!defaultLangFound)
2420  {
2421  CAMsg::printMsg(LOG_CRIT,"There is no default language specified for the Terms And Conditions!\n");
2422  return E_UNKNOWN;
2423  }
2424  if(tncTranslationImports != NULL)
2425  {
2426  elemTnCsList->removeChild(tncTranslationImports);
2427  }
2428  m_docOpTnCs->appendChild(m_docOpTnCs->importNode(elemTnCsList, WITH_SUBTREE));
2429 
2430  return E_SUCCESS;
2431 }
2432 #endif
2433 // *******************************************
2434 // * crime detection option setter functions *
2435 // *******************************************
2436 #ifdef LOG_CRIME
2437 SINT32 CACmdLnOptions::setCrimeDetectionOptions(DOMElement *elemRoot)
2438 {
2439  DOMElement* elemCrimeDetection = NULL;
2440  if (getDOMChildByName
2441  (elemRoot, OPTIONS_NODE_CRIME_DETECTION, elemCrimeDetection, false) != E_SUCCESS)
2442  {
2444  return E_SUCCESS;
2445  }
2446 
2447  CAMsg::printMsg(LOG_INFO,"Loading Crime Detection Data....\n");
2448 
2449  if(elemCrimeDetection != NULL)
2450  {
2451  if( getDOMElementAttribute(elemCrimeDetection,
2452  OPTIONS_ATTRIBUTE_LOG_PAYLOAD, m_logPayload) != E_SUCCESS)
2453  {
2454  m_logPayload = false;
2455  }
2456  return invokeOptionSetters
2457  (crimeDetectionOptionSetters, elemCrimeDetection, CRIME_DETECTION_OPTIONS_NR);
2458  }
2459  return E_SUCCESS;
2460 }
2461 
2462 SINT32 CACmdLnOptions::setCrimeURLRegExp(DOMElement *elemCrimeDetection)
2463 {
2464 
2465  if(elemCrimeDetection == NULL) return E_UNKNOWN;
2467  (elemCrimeDetection->getNodeName(), OPTIONS_NODE_CRIME_REGEXP_URL);
2468 
2469  return setRegExpressions(elemCrimeDetection, OPTIONS_NODE_CRIME_REGEXP_URL,
2470  &m_arCrimeRegExpsURL, &m_nCrimeRegExpsURL);
2471 
2473  //m_arCrimeRegExpsURL=new regex_t[nlRegExp.getLength()];
2474  //for(UINT32 i=0;i<nlRegExp.getLength();i++)
2475  //{
2476  // DOM_Node tmpChild=nlRegExp.item(i);
2477  // UINT32 lenRegExp=4096;
2478  // UINT8 buffRegExp[4096];
2479  // if(getDOMElementValue(tmpChild,buffRegExp,&lenRegExp)==E_SUCCESS)
2480  // {
2481  // if(regcomp(&m_arCrimeRegExpsURL[m_nCrimeRegExpsURL],(char*)buffRegExp,REG_EXTENDED|REG_ICASE|REG_NOSUB)!=0)
2482  // {
2483  // CAMsg::printMsg(LOG_CRIT,"Could not compile URL regexp: %s\n",buffRegExp);
2484  // exit(-1);
2485  // }
2486  // CAMsg::printMsg(LOG_DEBUG,"Looking for crime URL RegExp: %s\n",buffRegExp);
2487 
2488  // m_nCrimeRegExpsURL++;
2489  // }
2490  //}
2491 
2492  return E_SUCCESS;
2493 }
2494 
2495 SINT32 CACmdLnOptions::setCrimePayloadRegExp(DOMElement *elemCrimeDetection)
2496 {
2497 
2498  if(elemCrimeDetection == NULL) return E_UNKNOWN;
2500  (elemCrimeDetection->getNodeName(), OPTIONS_NODE_CRIME_REGEXP_PAYLOAD);
2501 
2502  return setRegExpressions(elemCrimeDetection, OPTIONS_NODE_CRIME_REGEXP_PAYLOAD,
2503  &m_arCrimeRegExpsPayload, &m_nCrimeRegExpsPayload);
2504 
2506  // getElementsByTagName(elemCrimeDetection, OPTIONS_NODE_CRIME_REGEXP_PAYLOAD);
2507 
2508  //if(nlRegExp != NULL)
2509  //{
2510  // m_arCrimeRegExpsPayload = new regex_t[nlRegExp->getLength()];
2511  // for(UINT32 i = 0; i < nlRegExp->getLength(); i++)
2512  // {
2513  // DOMNode *tmpChild = nlRegExp->item(i);
2514 
2515  // UINT32 lenRegExp = REGEXP_BUFF_SIZE;
2516  // UINT8 buffRegExp[REGEXP_BUFF_SIZE];
2517 
2518  // if(getDOMElementValue(tmpChild, buffRegExp, &lenRegExp)==E_SUCCESS)
2519  // {
2520  // if(regcomp(&m_arCrimeRegExpsPayload[m_nCrimeRegExpsPayload],(char*)buffRegExp,REG_EXTENDED|REG_ICASE|REG_NOSUB)!=0)
2521  // {
2522  // CAMsg::printMsg(LOG_CRIT,"Could not compile payload regexp: %s\n",buffRegExp);
2523  // exit(-1);
2524  // }
2525  // CAMsg::printMsg(LOG_DEBUG,"Looking for crime Payload RegExp: %s\n",buffRegExp);
2526 
2527  // m_nCrimeRegExpsPayload++;
2528  // }
2529  // }
2530  //}
2531  return E_SUCCESS;
2532 }
2533 
2534 SINT32 CACmdLnOptions::setCrimeSurveillanceIP(DOMElement *elemCrimeDetection)
2535 {
2536  if(elemCrimeDetection == NULL) return E_UNKNOWN;
2538 
2539  UINT8 ipBuff[TMP_BUFF_SIZE];
2540 
2541  DOMNodeList *surveillanceIPNodes =getElementsByTagName(elemCrimeDetection, OPTIONS_NODE_CRIME_SURVEILLANCE_IP);
2542  m_nrOfSurveillanceIPs = (UINT32) surveillanceIPNodes->getLength();
2543 
2544  if (m_nrOfSurveillanceIPs == 0)
2545  {
2546  CAMsg::printMsg(LOG_INFO,"No surveillance IP specified.\n");
2547  return E_SUCCESS;
2548  }
2549 
2550  m_surveillanceIPs = new CAIPAddrWithNetmask[m_nrOfSurveillanceIPs];
2551  for (UINT32 i = 0; i < m_nrOfSurveillanceIPs; i++)
2552  {
2553  UINT32 ipBuffSize = TMP_BUFF_SIZE;
2554  DOMNode* pelemCurrentIP=surveillanceIPNodes->item(i);
2555  if(getDOMElementValue(pelemCurrentIP, ipBuff,&ipBuffSize) == E_SUCCESS )
2556  {
2557  m_surveillanceIPs[i].setAddr(ipBuff);
2558  ipBuffSize = TMP_BUFF_SIZE;
2559  if(getDOMElementAttribute(pelemCurrentIP,OPTIONS_NODE_CRIME_SURVEILLANCE_IP_NETMASK,ipBuff,&ipBuffSize)==E_SUCCESS)
2560  {
2561  m_surveillanceIPs[i].setNetmask(ipBuff);
2562  }
2563  ipBuffSize = TMP_BUFF_SIZE;
2564  m_surveillanceIPs[i].toString(ipBuff,&ipBuffSize);
2565  CAMsg::printMsg(LOG_INFO,"Found Surveillance IP %s\n", ipBuff);
2566  }
2567  else
2568  {
2569  CAMsg::printMsg(LOG_INFO,"Could not read surveillance IP!\n");
2570  delete[] m_surveillanceIPs;
2571  m_surveillanceIPs = NULL;
2572  m_nrOfSurveillanceIPs = 0;
2573  return E_UNKNOWN;
2574  }
2575  }
2576 
2577 
2578  return E_SUCCESS;
2579 }
2580 
2581 
2582 SINT32 CACmdLnOptions::setCrimeSurveillanceAccounts(DOMElement *elemCrimeDetection)
2583 {
2584 
2585  if(elemCrimeDetection == NULL) return E_UNKNOWN;
2586 
2588  (elemCrimeDetection->getNodeName(), OPTIONS_NODE_CRIME_SURVEILLANCE_ACCOUNT);
2589 
2590 
2591  UINT64 accountNumber;
2592 
2593  DOMNodeList *surveillanceIPNodes =getElementsByTagName(elemCrimeDetection, OPTIONS_NODE_CRIME_SURVEILLANCE_ACCOUNT);
2594  m_nrOfSurveillanceAccounts = (UINT32) surveillanceIPNodes->getLength();
2595 
2596  if (m_nrOfSurveillanceAccounts == 0)
2597  {
2598  CAMsg::printMsg(LOG_INFO,"No surveillance accounts specified.\n");
2599  return E_SUCCESS;
2600  }
2601 
2602  DOMNode* node=NULL;
2603  m_surveillanceAccounts = new UINT64[m_nrOfSurveillanceAccounts];
2604  for (UINT32 i = 0; i < m_nrOfSurveillanceAccounts; i++)
2605  {
2606  node = surveillanceIPNodes->item(i);
2607  if(getDOMElementValue(node, accountNumber) == E_SUCCESS)
2608  {
2609  m_surveillanceAccounts[i] = accountNumber;
2610  CAMsg::printMsg(LOG_INFO,"Found surveillance account %llu.\n", accountNumber);
2611  }
2612  else
2613  {
2614  CAMsg::printMsg(LOG_INFO,"Could not read surveillance account number!\n");
2615  delete[] m_surveillanceAccounts;
2616  m_surveillanceAccounts = NULL;
2617  m_nrOfSurveillanceAccounts = 0;
2618  return E_UNKNOWN;
2619  }
2620  }
2621 
2622 
2623 
2624  return E_SUCCESS;
2625 }
2626 
2627 SINT32 setRegExpressions(DOMElement *rootElement, const char* const childElementName,
2628  tre_regex_t **regExContainer, UINT32* regExNr)
2629 {
2630  if( (rootElement == NULL) || (childElementName == NULL) ||
2631  (regExNr == NULL) || (regExContainer == NULL) )
2632  {
2633  return E_UNKNOWN;
2634  }
2635 
2636  (*regExNr) = 0;
2637 
2638  DOMNodeList *nlRegExp =
2639  getElementsByTagName(rootElement, childElementName);
2640 
2641  if(nlRegExp != NULL)
2642  {
2643  (*regExContainer) = new tre_regex_t[nlRegExp->getLength()];
2644 
2645  for(UINT32 i = 0; i < nlRegExp->getLength(); i++)
2646  {
2647  DOMNode *tmpChild = nlRegExp->item(i);
2648 
2649  UINT32 lenRegExp = REGEXP_BUFF_SIZE;
2650  UINT8 buffRegExp[REGEXP_BUFF_SIZE];
2651 
2652  if(getDOMElementValue(tmpChild, buffRegExp, &lenRegExp)==E_SUCCESS)
2653  {
2654  if(tre_regcomp( &((*regExContainer)[(*regExNr)]),
2655  ((char*) buffRegExp),
2656  REG_EXTENDED | REG_ICASE | REG_NOSUB) != 0 )
2657  {
2658  CAMsg::printMsg(LOG_CRIT,"Could not compile regexp: %s\n",buffRegExp);
2659  return E_UNKNOWN;
2660  }
2661  CAMsg::printMsg(LOG_DEBUG,"Looking for RegExp: %s\n",buffRegExp);
2662  (*regExNr)++;
2663  }
2664  }
2665  }
2666  return E_SUCCESS;
2667 }
2668 #endif //LOG_CRIME
2669 
2670 
2671 
2672 
2673 #endif //ONLY_LOCAL_PROXY
2674 
2675 #ifndef ONLY_LOCAL_PROXY
2676 
2677 
2678 
2679 
2680 
2685 {
2686  XERCES_CPP_NAMESPACE::DOMDocument* doc = createDOMDocument();
2687  //Neasty but cool...
2688  bool bForLast=false;
2689  if(strFileName!=NULL&&strncmp((char*)strFileName,"last",4)==0)
2690  bForLast=true;
2691  buildDefaultConfig(doc,bForLast);
2692  saveToFile(doc, strFileName);
2693  return E_SUCCESS;
2694 }
2695 
2701 SINT32 CACmdLnOptions::buildDefaultConfig(XERCES_CPP_NAMESPACE::DOMDocument* doc,bool bForLastMix=false)
2702 {
2703  CASignature* pSignature=new CASignature();
2704  pSignature->generateSignKey(1024);
2705  DOMElement* elemRoot=createDOMElement(doc,"MixConfiguration");
2706  doc->appendChild(elemRoot);
2707  setDOMElementAttribute(elemRoot,"version",(UINT8*)"0.5");
2708  DOMElement* elemGeneral=createDOMElement(doc,"General");
2709  elemRoot->appendChild(elemGeneral);
2710 
2714  DOMElement* elemTmp=createDOMElement(doc,"MixType");
2715  if(bForLastMix)
2716  setDOMElementValue(elemTmp,(UINT8*)"LastMix");
2717  else
2718  setDOMElementValue(elemTmp,(UINT8*)"FirstMix");
2719  elemGeneral->appendChild(elemTmp);
2720 
2722  elemTmp=createDOMElement(doc,"MixID");
2723  CACertificate* pCert;
2724  pSignature->getVerifyKey(&pCert);
2725  UINT8 buf[255];
2726  UINT32 len = 255;
2727  pCert->getSubjectKeyIdentifier( buf, &len);
2728  setDOMElementValue(elemTmp,buf);
2729  elemGeneral->appendChild(elemTmp);
2730  elemTmp=createDOMElement(doc,"Dynamic");
2731  setDOMElementValue(elemTmp,(UINT8*)"True");
2732  elemGeneral->appendChild(elemTmp);
2733 
2734  elemTmp=createDOMElement(doc,"Daemon");
2735  setDOMElementValue(elemTmp,(UINT8*)"True");
2736  elemGeneral->appendChild(elemTmp);
2737 
2738  elemTmp=createDOMElement(doc,"CascadeName");
2739  setDOMElementValue(elemTmp,(UINT8*)"Dynamic Cascade");
2740  elemGeneral->appendChild(elemTmp);
2741  elemTmp=createDOMElement(doc,"MixName");
2742  setDOMElementValue(elemTmp,(UINT8*)"Dynamic Mix");
2743  elemGeneral->appendChild(elemTmp);
2744  elemTmp=createDOMElement(doc,"UserID");
2745  setDOMElementValue(elemTmp,(UINT8*)"mix");
2746  elemGeneral->appendChild(elemTmp);
2747  DOMElement* elemLogging=createDOMElement(doc,"Logging");
2748  elemGeneral->appendChild(elemLogging);
2749  elemTmp=createDOMElement(doc,"SysLog");
2750  setDOMElementValue(elemTmp,(UINT8*)"True");
2751  elemLogging->appendChild(elemTmp);
2752  DOMElement* elemNet=createDOMElement(doc,"Network");
2753  elemRoot->appendChild(elemNet);
2754 
2756  DOMElement*elemISs=createDOMElement(doc,"InfoServices");
2757  elemNet->appendChild(elemISs);
2758  elemTmp=createDOMElement(doc,"AllowAutoConfiguration");
2759  setDOMElementValue(elemTmp,(UINT8*)"True");
2760  elemISs->appendChild(elemTmp);
2761 
2762  DOMElement* elemIS=createDOMElement(doc,"InfoService");
2763  elemISs->appendChild(elemIS);
2764  DOMElement* elemISListeners=createDOMElement(doc,"ListenerInterfaces");
2765  elemIS->appendChild(elemISListeners);
2766  DOMElement* elemISLi=createDOMElement(doc,"ListenerInterface");
2767  elemISListeners->appendChild(elemISLi);
2768  elemTmp=createDOMElement(doc,"Host");
2770  elemISLi->appendChild(elemTmp);
2771  elemTmp=createDOMElement(doc,"Port");
2772  setDOMElementValue(elemTmp,6543U);
2773  elemISLi->appendChild(elemTmp);
2774  elemTmp=createDOMElement(doc,"AllowAutoConfiguration");
2775  setDOMElementValue(elemTmp,(UINT8*)"True");
2776  elemISs->appendChild(elemTmp);
2777 
2779  /* DOM_Element elemListeners=doc.createElement("ListenerInterfaces");
2780  elemNet.appendChild(elemListeners);
2781  DOM_Element elemListener=doc.createElement("ListenerInterface");
2782  elemListeners.appendChild(elemListener);
2783  elemTmp=doc.createElement("Port");
2784  setDOMElementValue(elemTmp,6544U);
2785  elemListener.appendChild(elemTmp);
2786  elemTmp=doc.createElement("NetworkProtocol");
2787  setDOMElementValue(elemTmp,(UINT8*)"RAW/TCP");
2788  elemListener.appendChild(elemTmp);
2789  */
2790  if(bForLastMix)
2791  {
2792  DOMElement* elemProxies=createDOMElement(doc,"Proxies");
2793  DOMElement* elemProxy=createDOMElement(doc,"Proxy");
2794  elemProxies->appendChild(elemProxy);
2795  elemTmp=createDOMElement(doc,"ProxyType");
2796  setDOMElementValue(elemTmp,(UINT8*)"HTTP");
2797  elemProxy->appendChild(elemTmp);
2798  elemTmp=createDOMElement(doc,"Host");
2799  setDOMElementValue(elemTmp,(UINT8*)"127.0.0.1");
2800  elemProxy->appendChild(elemTmp);
2801  elemTmp=createDOMElement(doc,"Port");
2802  setDOMElementValue(elemTmp,3128U);
2803  elemProxy->appendChild(elemTmp);
2804  elemTmp=createDOMElement(doc,"NetworkProtocol");
2805  setDOMElementValue(elemTmp,(UINT8*)"RAW/TCP");
2806  elemProxy->appendChild(elemTmp);
2807  elemNet->appendChild(elemProxies);
2808  }
2809  DOMElement* elemCerts=createDOMElement(doc,"Certificates");
2810  elemRoot->appendChild(elemCerts);
2811  DOMElement* elemOwnCert=createDOMElement(doc,"OwnCertificate");
2812  elemCerts->appendChild(elemOwnCert);
2813  DOMElement* tmpElemSigKey=NULL;
2814  pSignature->getSignKey(tmpElemSigKey,doc);
2815  elemOwnCert->appendChild(tmpElemSigKey);
2816 
2817  DOMElement* elemTmpCert=NULL;
2818  pCert->encode(elemTmpCert,doc);
2819  elemOwnCert->appendChild(elemTmpCert);
2820 
2822  delete pCert;
2823  pCert = NULL;
2824  delete pSignature;
2825  pSignature = NULL;
2826  return E_SUCCESS;
2827 }
2828 
2835 SINT32 CACmdLnOptions::saveToFile(XERCES_CPP_NAMESPACE::DOMDocument* p_doc, const UINT8* p_strFileName)
2836 {
2838  UINT32 len;
2839  UINT8* buff = DOM_Output::dumpToMem(p_doc,&len);
2840  if(p_strFileName!=NULL)
2841  {
2842  FILE *handle;
2843  handle=fopen((const char*)p_strFileName, "w");
2844  fwrite(buff,len,1,handle);
2845  fflush(handle);
2846  fclose(handle);
2847  }
2848  else
2849  {
2850  fwrite(buff,len,1,stdout);
2851  fflush(stdout);
2852  }
2853  delete[] buff;
2854  buff = NULL;
2855  return E_SUCCESS;
2856 }
2857 
2858 
2859 #ifdef DYNAMIC_MIX
2868 SINT32 CACmdLnOptions::createDefaultConfiguration()
2869 {
2870  m_docMixXml = DOM_Document::createDocument();
2873 
2874  char *configfile = (char*) malloc(sizeof(char) * (strlen(DEFAULT_CONFIG_FILE)));
2875  strcpy(configfile, DEFAULT_CONFIG_FILE);
2876 
2877  // Set default config file for possible reread attempt
2878  m_strConfigFile=new UINT8[ strlen(DEFAULT_CONFIG_FILE)+1 ];
2880  return E_SUCCESS;
2881 }
2882 
2889 SINT32 CACmdLnOptions::addListenerInterface(DOM_Element a_elem)
2890 {
2892  if(pListener == NULL)
2893  return E_UNKNOWN;
2894 
2896  {
2898  for(unsigned int i = 0; i < m_cnListenerInterfaces; i++)
2899  {
2900  tmp[i] = m_arListenerInterfaces[i];
2901  }
2902  delete[] m_arListenerInterfaces;
2904  m_arListenerInterfaces = tmp;
2906  }
2907  else
2908  {
2911  }
2912 
2914  return E_SUCCESS;
2915 
2916 }
2917 
2923 SINT32 CACmdLnOptions::resetNetworkConfiguration()
2924 {
2925  DOM_Element elemRoot = m_docMixInfo.getDocumentElement();
2926  if(elemRoot != NULL)
2927  {
2928  DOM_Element elemListeners;
2929  getDOMChildByName(elemRoot,(UINT8*)"ListenerInterfaces",elemListeners,false);
2930  if(elemListeners != NULL)
2931  {
2932  elemRoot.removeChild( elemListeners );
2933  }
2934  }
2936  return E_SUCCESS;
2937 }
2938 
2945 SINT32 CACmdLnOptions::checkListenerInterfaces()
2946 {
2947  SINT32 result = E_UNKNOWN;
2948 
2949  UINT32 interfaces = getListenerInterfaceCount();
2950  CAListenerInterface *pListener = NULL;
2951  CADynaNetworking *dyn = new CADynaNetworking();
2952 
2953  for( UINT32 i = 1; i <= interfaces; i++ )
2954  {
2955  pListener = getListenerInterface(i);
2956  if(!pListener->isVirtual())
2957  {
2958  result = E_SUCCESS;
2959  break;
2960  }
2961  delete pListener;
2962  pListener=NULL;
2963  }
2964  if( pListener == NULL )
2965  {
2967  result = dyn->updateNetworkConfiguration(DEFAULT_TARGET_PORT);
2968  if( result != E_SUCCESS )
2969  goto error;
2970  }
2971  if( dyn->verifyConnectivity() != E_SUCCESS )
2972  {
2973  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);
2974  result = E_UNKNOWN;
2975  }
2976 error:
2977  delete dyn;
2978  dyn = NULL;
2979  return result;
2980 }
2981 
2990 SINT32 CACmdLnOptions::checkInfoServices(UINT32 *r_runningInfoServices)
2991 {
2992  UINT32 i;
2993  *r_runningInfoServices = 0;
2994  if(m_addrInfoServicesSize == 0 ) // WTH?
2995  return E_UNKNOWN;
2996 
2998  for(i = 0; i < m_addrInfoServicesSize; i++)
2999  {
3000  CASocket socket;
3001  socket.setSendTimeOut(1000);
3002  if(socket.connect( *m_addrInfoServices[i]->getAddr() )== E_SUCCESS )
3003  {
3004  (*r_runningInfoServices)++;
3005  }
3006  socket.close();
3007  }
3008  if((*r_runningInfoServices) < MIN_INFOSERVICES)
3009  return E_UNKNOWN;
3010  return E_SUCCESS;
3011 }
3012 
3018 SINT32 CACmdLnOptions::checkCertificates()
3019 {
3023  return E_SUCCESS;
3024 }
3025 
3032 SINT32 CACmdLnOptions::checkMixId()
3033 {
3034  UINT8 ski[255];
3035  UINT32 len = 255;
3036  if( m_pOwnCertificate->getSubjectKeyIdentifier( ski, &len ) != E_SUCCESS )
3037  return E_UNKNOWN;
3038 
3039  CAMsg::printMsg( LOG_DEBUG, "\nID : (%s)\n SKI: (%s)\n", m_strMixID, ski);
3040  if( strcmp( (const char*)m_strMixID, (const char*)ski ) != 0 )
3041  return E_UNKNOWN;
3042  return E_SUCCESS;
3043 }
3044 
3052 SINT32 CACmdLnOptions::getRandomInfoService(CASocketAddrINet *&r_address)
3053 {
3054  UINT32 nrAddresses;
3055  CAListenerInterface** socketAddresses = pglobalOptions->getInfoServices(nrAddresses);
3056  if( socketAddresses == NULL )
3057  {
3058  CAMsg::printMsg( LOG_ERR, "Unable to get a list of InfoServices from the options, check your configuration!\n");
3059  return E_UNKNOWN;
3060  }
3061  UINT32 index = getRandom(nrAddresses);
3062  // Search for a runnung infoservice from the random index on overlapping at nrAddresses
3063  UINT32 i = (index+1) % nrAddresses;
3064  while(true)
3065  {
3066  CASocket socket;
3067  socket.setSendTimeOut(1000);
3068  r_address = (CASocketAddrINet*)m_addrInfoServices[i]->getAddr();
3069  if(socket.connect( *r_address )== E_SUCCESS )
3070  {
3071 #ifdef DEBUG
3072  UINT8 buf[2048];
3073  UINT32 len=2047;
3074  r_address->getHostName( buf, len );
3075  CAMsg::printMsg( LOG_DEBUG, "getRandomInfoService: Chose InfoService server %s:%i\n", buf, r_address->getPort());
3076 #endif
3077  socket.close();
3078  return E_SUCCESS;
3079  }
3080  else
3081  {
3082  socket.close();
3083  delete r_address;
3084  r_address = NULL;
3085  }
3086  if(i == index) break;
3087  i = (i+1) % nrAddresses;
3088  }
3089  return E_UNKNOWN;
3090 }
3091 
3098 {
3099  UINT32 result = (UINT32) (a_max * (rand() / (RAND_MAX + 1.0)));
3100  return result;
3101 }
3102 
3111 SINT32 CACmdLnOptions::changeMixType(CAMix::tMixType a_newMixType)
3112 {
3113  if( a_newMixType == CAMix::LAST_MIX )
3114  {
3115  CAMsg::printMsg( LOG_ERR,"Trying to reconfigure a dynamic mix to LastMix, that is evil!\n");
3116  return E_UNKNOWN;
3117  }
3118 
3119  if( a_newMixType == CAMix::MIDDLE_MIX && isFirstMix())
3120  {
3121  CAMsg::printMsg( LOG_DEBUG,"Reconfiguring a FirstMix to MiddleMix.\n");
3122  m_bFirstMix = false;
3123  m_bMiddleMix = true;
3124  DOM_Element elemRoot = m_docMixInfo.getDocumentElement();
3125  if(elemRoot != NULL)
3126  {
3127  DOM_Element elemMixType;
3128  getDOMChildByName(elemRoot,(UINT8*)"MixType",elemMixType,false);
3129  if(elemMixType != NULL)
3130  {
3131  setDOMElementValue(elemMixType,(UINT8*)"MiddleMix");
3132  }
3133  }
3134  }
3135  else if( a_newMixType == CAMix::FIRST_MIX && isMiddleMix())
3136  {
3137  CAMsg::printMsg( LOG_DEBUG,"Reconfiguring a MiddleMix to FirstMix.\n");
3138  m_bFirstMix = true;
3139  m_bMiddleMix = false;
3140  DOM_Element elemRoot = m_docMixInfo.getDocumentElement();
3141  if(elemRoot != NULL)
3142  {
3143  DOM_Element elemMixType;
3144  getDOMChildByName(elemRoot,(UINT8*)"MixType",elemMixType,false);
3145  if(elemMixType != NULL)
3146  {
3147  setDOMElementValue(elemMixType,(UINT8*)"FirstMix");
3148  }
3149  }
3150  }
3151  else
3152  {
3153  CAMsg::printMsg( LOG_ERR, "Error reconfiguring the mix, some strange combination of existing and new type happened\n");
3154  return E_UNKNOWN;
3155  }
3156  return E_SUCCESS;
3157 }
3158 
3159 #endif //DYNAMIC_MIX
3160 
3161 #ifdef COUNTRY_STATS
3162 SINT32 CACmdLnOptions::getCountryStatsDBConnectionLoginData(char** db_host,char**db_user,char**db_passwd)
3163  {
3164  *db_host=*db_user=*db_passwd=NULL;
3165  if(m_dbCountryStatsHost!=NULL)
3166  {
3167  *db_host=new char[strlen(m_dbCountryStatsHost)+1];
3168  strcpy(*db_host,m_dbCountryStatsHost);
3169  }
3170  if(m_dbCountryStatsUser!=NULL)
3171  {
3172  *db_user=new char[strlen(m_dbCountryStatsUser)+1];
3173  strcpy(*db_user,m_dbCountryStatsUser);
3174  }
3175  if(m_dbCountryStatsPasswd!=NULL)
3176  {
3177  *db_passwd=new char[strlen(m_dbCountryStatsPasswd)+1];
3178  strcpy(*db_passwd,m_dbCountryStatsPasswd);
3179  }
3180  return E_SUCCESS;
3181  }
3182 #endif
3183 
3184 #ifdef DATA_RETENTION_LOG
3185 SINT32 CACmdLnOptions::getDataRetentionLogDir(UINT8* strLogDir,UINT32 len)
3186  {
3187  if(strLogDir==NULL||m_strDataRetentionLogDir==NULL)
3188  return E_UNKNOWN;
3189  if(len<=(UINT32)strlen((char*)m_strDataRetentionLogDir))
3190  {
3191  return E_UNKNOWN;
3192  }
3193  strcpy((char*)strLogDir,(char*)m_strDataRetentionLogDir);
3194  return E_SUCCESS;
3195  }
3196 #endif// DATA_RETENTION_LOG
3197 
3198 #endif //ONLY_LOCAL_PROXY
3199 
3200 #if !defined ONLY_LOCAL_PROXY || defined INCLUDE_MIDDLE_MIX
3206 SINT32 CACmdLnOptions::getMixXml(XERCES_CPP_NAMESPACE::DOMDocument* & docMixInfo)
3207 {
3208  if(m_docMixInfo == NULL)
3209  {
3210  CAMsg::printMsg(LOG_CRIT,"No mixinfo document initialized!\n");
3211  return E_UNKNOWN;
3212  }
3213  docMixInfo=m_docMixInfo;
3214  //insert (or update) the Timestamp
3215  DOMElement* elemTimeStamp=NULL;
3216  DOMElement* elemRoot=docMixInfo->getDocumentElement();
3217  if(getDOMChildByName(elemRoot, UNIVERSAL_NODE_LAST_UPDATE, elemTimeStamp, false)!=E_SUCCESS)
3218  {
3219  elemTimeStamp=createDOMElement(docMixInfo, UNIVERSAL_NODE_LAST_UPDATE);
3220  elemRoot->appendChild(elemTimeStamp);
3221  }
3222  UINT64 currentMillis;
3223  getcurrentTimeMillis(currentMillis);
3224  UINT8 tmpStrCurrentMillis[50];
3225  print64(tmpStrCurrentMillis,currentMillis);
3226  setDOMElementValue(elemTimeStamp,tmpStrCurrentMillis);
3227  return E_SUCCESS;
3228 }
3229 
3231  {
3232  if(m_strCascadeName==NULL)
3233  return E_UNKNOWN;
3234  if(len<=(UINT32)strlen((char*)m_strCascadeName))
3235  {
3236  return E_UNKNOWN;
3237  }
3238  strcpy((char*)name,(char*)m_strCascadeName);
3239  return E_SUCCESS;
3240  }
3241 
3243  {
3244  r_size = m_addrInfoServicesSize;
3245  return m_addrInfoServices;
3246  }
3247 
3257 SINT32 CACmdLnOptions::readXmlConfiguration(XERCES_CPP_NAMESPACE::DOMDocument* & docConfig,const UINT8* const configFile)
3258  {
3259  int handle;
3260  handle=open((char*)configFile,O_BINARY|O_RDONLY);
3261  if(handle==-1)
3262  return E_FILE_OPEN;
3263  SINT32 len=filesize32(handle);
3264  UINT8* tmpChar=new UINT8[len];
3265  int ret=read(handle,tmpChar,len);
3266  close(handle);
3267  if(ret!=len)
3268  return E_FILE_READ;
3269  SINT32 retVal = readXmlConfiguration(docConfig, tmpChar, len);
3270  delete[] tmpChar;
3271  tmpChar = NULL;
3272  return retVal;
3273 }
3274 
3284 SINT32 CACmdLnOptions::readXmlConfiguration(XERCES_CPP_NAMESPACE::DOMDocument* & docConfig,const UINT8* const buf, UINT32 len)
3285 {
3286  docConfig=parseDOMDocument(buf,len);
3287  if(docConfig==NULL)
3288  {
3289  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");
3290  return E_UNKNOWN;
3291  }
3292  return E_SUCCESS;
3293 }
3294 
3295 // ** Processes a XML configuration document. This sets the values of the
3296 // * options to the values found in the XML document.
3297 // * Note that only the values are changed, which are given in the XML document!
3298 // * @param docConfig the configuration as XML document
3299 // * @retval E_UNKNOWN if an error occurs
3300 // * @retval E_SUCCESS otherwise
3301 //
3302 SINT32 CACmdLnOptions::processXmlConfiguration(XERCES_CPP_NAMESPACE::DOMDocument* docConfig)
3303 {
3304  SINT32 ret = E_SUCCESS;
3305  if(docConfig==NULL)
3306  {
3307  return E_UNKNOWN;
3308  }
3309  DOMElement* elemRoot=docConfig->getDocumentElement();
3310 
3311  // * Initialize Mixinfo DOM structure so that neccessary
3312  // * option can be appended to it.
3313  //
3314  DOMElement* elemMix=createDOMElement(m_docMixInfo, MIXINFO_NODE_PARENT);
3315  m_docMixInfo->appendChild(elemMix);
3316 
3317  // * invoke all main option setters
3318  // * which then invoke their own specific
3319  // * option setters
3320  //
3322  if(ret != E_SUCCESS)
3323  {
3324  return E_UNKNOWN;
3325  }
3326 
3327  //Set Software-Version...
3328  DOMElement* elemSoftware=createDOMElement(m_docMixInfo, MIXINFO_NODE_SOFTWARE);
3329  DOMElement* elemVersion=createDOMElement(m_docMixInfo, MIXINFO_NODE_VERSION);
3330  setDOMElementValue(elemVersion,(UINT8*)MIX_VERSION);
3331  elemSoftware->appendChild(elemVersion);
3332  elemMix->appendChild(elemSoftware);
3333 
3334 #ifdef PAYMENT
3335  // Add the payment reminder
3336  DOMElement* elemPaymentReminder=createDOMElement(m_docMixInfo, MIXINFO_NODE_PAYMENTREMINDER);
3337  setDOMElementValue(elemPaymentReminder, m_PaymentReminderProbability);
3338  elemMix->appendChild(elemPaymentReminder);
3339 #endif
3340 #ifdef COUNTRY_STATS
3341  DOMElement* elemCountryStats=NULL;
3342  getDOMChildByName(elemRoot,"CountryStatsDB",elemCountryStats,false);
3343  UINT8 db_tmp_buff[4096];
3344  UINT32 db_tmp_buff_len=4096;
3345  if(getDOMElementAttribute(elemCountryStats,"host",db_tmp_buff,&db_tmp_buff_len)==E_SUCCESS)
3346  {
3347  m_dbCountryStatsHost=new char[db_tmp_buff_len+1];
3348  memcpy(m_dbCountryStatsHost,db_tmp_buff,db_tmp_buff_len);
3349  m_dbCountryStatsHost[db_tmp_buff_len]=0;
3350  }
3351  db_tmp_buff_len=4096;
3352  if(getDOMElementAttribute(elemCountryStats,"user",db_tmp_buff,&db_tmp_buff_len)==E_SUCCESS)
3353  {
3354  m_dbCountryStatsUser=new char[db_tmp_buff_len+1];
3355  memcpy(m_dbCountryStatsUser,db_tmp_buff,db_tmp_buff_len);
3356  m_dbCountryStatsUser[db_tmp_buff_len]=0;
3357  }
3358  db_tmp_buff_len=4096;
3359  if(getDOMElementAttribute(elemCountryStats,"passwd",db_tmp_buff,&db_tmp_buff_len)==E_SUCCESS)
3360  {
3361  m_dbCountryStatsPasswd=new char[db_tmp_buff_len+1];
3362  memcpy(m_dbCountryStatsPasswd,db_tmp_buff,db_tmp_buff_len);
3363  m_dbCountryStatsPasswd[db_tmp_buff_len]=0;
3364  }
3365 #endif
3366 
3367  DOMElement* elemCascade;
3368  SINT32 haveCascade = getDOMChildByName(elemRoot,"MixCascade",elemCascade,false);
3369 
3370 #ifndef DYNAMIC_MIX
3371  // LERNGRUPPE: This is no error in the fully dynamic model
3372  if(isLastMix() && haveCascade != E_SUCCESS && !hasPrevMixTestCertificate() && !verifyMixCertificates())
3373  {
3374  CAMsg::printMsg(LOG_CRIT,"Error in configuration: You must either specify cascade info or the previous mix's certificate.\n");
3375  return E_UNKNOWN;
3376  }
3377 #endif
3378 #ifndef ONLY_LOCAL_PROXY
3379  if(isLastMix() && haveCascade == E_SUCCESS)
3380  {
3381  getDOMChildByName(elemRoot,"MixCascade",m_pCascadeXML,false);
3382 
3383  DOMNodeList* nl = getElementsByTagName(m_pCascadeXML,"Mix");
3384  UINT16 len = (UINT16)nl->getLength();
3385  if(len == 0)
3386  {
3387  CAMsg::printMsg(LOG_CRIT,"Error in configuration: Empty cascade specified.\n");
3388  return E_UNKNOWN;
3389  }
3390  }
3391 #endif
3392 #ifdef DATA_RETENTION_LOG
3393  DOMElement* elemDataRetention=NULL;
3394  getDOMChildByName(elemRoot,"DataRetention",elemDataRetention,false);
3395  DOMElement* elemDataRetentionLogDir=NULL;
3396  getDOMChildByName(elemDataRetention,"LogDir",elemDataRetentionLogDir,false);
3397  UINT8 log_dir[4096];
3398  UINT32 log_dir_len=4096;
3399  if(getDOMElementValue(elemDataRetentionLogDir,log_dir,&log_dir_len)==E_SUCCESS)
3400  {
3401  m_strDataRetentionLogDir=new UINT8[log_dir_len+1];
3402  memcpy(m_strDataRetentionLogDir,log_dir,log_dir_len);
3403  m_strDataRetentionLogDir[log_dir_len]=0;
3404  }
3405  CAMsg::printMsg(LOG_CRIT,"Data retention log dir in config file: %s\n",log_dir);
3406 
3407  this->m_pDataRetentionPublicEncryptionKey=new CAASymCipher();
3408  DOMElement* elemDataRetentionPublicKey=NULL;
3409  getDOMChildByName(elemDataRetention,"PublicEncryptionKey",elemDataRetentionPublicKey,false);
3410  DOMElement* elemDataRetentionPublicRSAKey=NULL;
3411  getDOMChildByName(elemDataRetentionPublicKey,"RSAKeyValue",elemDataRetentionPublicRSAKey,false);
3412  m_pDataRetentionPublicEncryptionKey->setPublicKeyAsDOMNode(elemDataRetentionPublicRSAKey);
3413 
3414  //Add info to MixInfo structure...
3415  elemDataRetention=createDOMElement(m_docMixInfo, "DataRetention");
3416  elemMix->appendChild(elemDataRetention);
3417  DOMElement* elemLoggedElements=createDOMElement(m_docMixInfo,"LoggedElements");
3418  elemDataRetention->appendChild(elemLoggedElements);
3419  DOMElement* elemTemp=createDOMElement(m_docMixInfo,"InputTime");
3420  elemLoggedElements->appendChild(elemTemp);
3421  setDOMElementValue(elemTemp,true);
3422  elemTemp=createDOMElement(m_docMixInfo,"OutputTime");
3423  elemLoggedElements->appendChild(elemTemp);
3424  setDOMElementValue(elemTemp,true);
3425  elemTemp=createDOMElement(m_docMixInfo,"InputChannelID");
3426  elemLoggedElements->appendChild(elemTemp);
3427  setDOMElementValue(elemTemp,true);
3428  elemTemp=createDOMElement(m_docMixInfo,"OutputChannelID");
3429  elemLoggedElements->appendChild(elemTemp);
3430  setDOMElementValue(elemTemp,true);
3431  elemTemp=createDOMElement(m_docMixInfo,"InputSourceIPAddress");
3432  elemLoggedElements->appendChild(elemTemp);
3433  setDOMElementValue(elemTemp,true);
3434  elemTemp=createDOMElement(m_docMixInfo,"OutputSourceIPAddress");
3435  elemLoggedElements->appendChild(elemTemp);
3436  setDOMElementValue(elemTemp,true);
3437  elemTemp=createDOMElement(m_docMixInfo,"InputSourceIPPort");
3438  elemLoggedElements->appendChild(elemTemp);
3439  setDOMElementValue(elemTemp,true);
3440  elemTemp=createDOMElement(m_docMixInfo,"OutputSourceIPPort");
3441  elemLoggedElements->appendChild(elemTemp);
3442  setDOMElementValue(elemTemp,true);
3443  elemTemp=createDOMElement(m_docMixInfo,"RetentionPeriod");
3444  elemDataRetention->appendChild(elemTemp);
3445  setDOMElementValue(elemTemp,(UINT8*)"P6M");
3446 #endif //DATA_RETENTION_LOG
3447 
3448  return E_SUCCESS;
3449 }
3450 
3456 SINT32 CACmdLnOptions::invokeOptionSetters (const optionSetter_pt *optionsSetters, DOMElement* optionsSource, SINT32 optionsSettersLength)
3457 {
3458  SINT32 i = 0;
3459  SINT32 ret = E_SUCCESS;
3460 
3461  if( optionsSetters == NULL )
3462  {
3463  CAMsg::printMsg(LOG_CRIT,"Error parsing config file: OptionSetters not initialized!\n");
3464  return E_UNKNOWN;
3465  }
3466 
3467  if( optionsSettersLength < 0)
3468  {
3469  CAMsg::printMsg(LOG_CRIT,"Error parsing config file: Negative number of option setters specified!\n");
3470  return E_UNKNOWN;
3471  }
3472 
3473  /* Only warn when we have a null DOM Element */
3474  if( optionsSource == NULL )
3475  {
3476  CAMsg::printMsg(LOG_INFO, "Found NULL DOM element. "
3477  "NULL element handling is delegated to the specified setter method!\n");
3478  }
3479 
3480  for(i=0; i < optionsSettersLength; i++ )
3481  {
3482  if(optionsSetters[i]!=NULL)
3483  {
3484  ret = (this->*(optionsSetters[i]))(optionsSource);
3485  if(ret != E_SUCCESS)
3486  {
3487  return ret;
3488  }
3489  }
3490  }
3491  return E_SUCCESS;
3492 }
3493 
3495 {
3498  int count = -1;
3499 
3500  mainOptionSetters[++count]=
3502  mainOptionSetters[++count]=
3504  mainOptionSetters[++count]=
3506 #ifdef PAYMENT
3507  mainOptionSetters[++count]=
3509 #endif
3510  mainOptionSetters[++count]=
3512  mainOptionSetters[++count]=
3514 #ifdef PAYMENT
3515  mainOptionSetters[++count]=
3517 #endif
3518 #ifdef LOG_CRIME
3519  mainOptionSetters[++count]=
3520  &CACmdLnOptions::setCrimeDetectionOptions;
3521 #endif
3522 }
3523 
3525 {
3528  int count = -1;
3529 
3530  generalOptionSetters[++count]=
3532  generalOptionSetters[++count]=
3534  generalOptionSetters[++count]=
3536  generalOptionSetters[++count]=
3538  generalOptionSetters[++count]=
3540  generalOptionSetters[++count]=
3542  generalOptionSetters[++count]=
3544  generalOptionSetters[++count]=
3546  generalOptionSetters[++count]=
3548  generalOptionSetters[++count]=
3550 
3551 #if !defined ONLY_LOCAL_PROXY || defined INCLUDE_FIRST_MIX
3552  generalOptionSetters[++count] =
3554 #endif
3555 #if !defined ONLY_LOCAL_PROXY
3556  generalOptionSetters[++count]=
3558  generalOptionSetters[++count]=
3560 
3561 #endif
3562  }
3563 
3565 {
3568 
3573 }
3574 
3575 #ifdef PAYMENT
3577 {
3579  int count = -1;
3580 
3581  accountingOptionSetters[++count]=
3583  accountingOptionSetters[++count]=
3585  accountingOptionSetters[++count]=
3587  accountingOptionSetters[++count]=
3589  accountingOptionSetters[++count]=
3591  accountingOptionSetters[++count]=
3593  accountingOptionSetters[++count]=
3595 }
3596 #endif
3598 {
3600  int count = -1;
3601 
3602  networkOptionSetters[++count]=
3604  networkOptionSetters[++count]=
3606  networkOptionSetters[++count]=
3608  networkOptionSetters[++count]=
3610  networkOptionSetters[++count]=
3612 }
3613 
3618 {
3619  UINT8 tmpBuff[TMP_BUFF_SIZE];
3620  UINT32 tmpLen = TMP_BUFF_SIZE;
3621  DOMElement* elemNextMix = NULL;
3622  DOMElement* elemProxies=NULL;
3623  CATargetInterface* targetInterfaceNextMix = NULL;
3624  //get TargetInterfaces
3625  m_cnTargets=0;
3626 
3627  if(elemNetwork == NULL) return E_UNKNOWN;
3628  ASSERT_NETWORK_OPTIONS_PARENT(elemNetwork->getNodeName(), OPTIONS_NODE_NEXT_MIX);
3629 
3630  //NextMix --> only one!!
3631  getDOMChildByName(elemNetwork, OPTIONS_NODE_NEXT_MIX, elemNextMix, false);
3632  if(elemNextMix != NULL)
3633  {
3635  CASocketAddr* addr = NULL;
3636  DOMElement* elemType = NULL;
3637  getDOMChildByName(elemNextMix, OPTIONS_NODE_NETWORK_PROTOCOL, elemType, false);
3638 
3639  bool bAddrIsSet = false;
3640 
3641  if(getDOMElementValue(elemType, tmpBuff, &tmpLen) == E_SUCCESS)
3642  {
3643  strtrim(tmpBuff);
3644  if(strcmp((char*)tmpBuff, "RAW/TCP") == 0)
3645  {
3646  type=RAW_TCP;
3647  }
3648  else if(strcmp((char*)tmpBuff, "RAW/UNIX") == 0)
3649  {
3650  type=RAW_UNIX;
3651  }
3652  else if(strcmp((char*)tmpBuff, "SSL/TCP") == 0)
3653  {
3654  type=SSL_TCP;
3655  }
3656  else if(strcmp((char*)tmpBuff, "SSL/UNIX") == 0)
3657  {
3658  type=SSL_UNIX;
3659  }
3660 
3661  if( (type == SSL_TCP) || (type == RAW_TCP) )
3662  {
3663  DOMElement* elemPort = NULL;
3664  DOMElement* elemHost = NULL;
3665  DOMElement* elemIP = NULL;
3666  UINT8 buffHost[TMP_BUFF_SIZE];
3667  UINT32 buffHostLen = TMP_BUFF_SIZE;
3668  UINT16 port;
3670  (elemNextMix, OPTIONS_NODE_PORT, elemPort, false);
3671  if(getDOMElementValue(elemPort,&port) == E_SUCCESS)
3672  {
3673  addr = new CASocketAddrINet;
3674  //bool bAddrIsSet=false;
3676  (elemNextMix, OPTIONS_NODE_HOST, elemHost, false);
3677  // The rules for <Host> and <IP> are as follows:
3678  // * 1. if <Host> is given and not empty take the <Host> value for the address of the next mix; if not go to 2
3679  // * 2. if <IP> if given and not empty take <IP> value for the address of the next mix; if not goto 3.
3680  // * 3. this entry for the next mix is invalid!
3681  if(elemHost != NULL)
3682  {
3683  if(getDOMElementValue(elemHost,buffHost,&buffHostLen)==E_SUCCESS &&
3684  ((CASocketAddrINet*)addr)->setAddr(buffHost,port)==E_SUCCESS)
3685  {
3686  bAddrIsSet = true;
3687  }
3688  }
3689  if(!bAddrIsSet)//now try <IP>
3690  {
3691  getDOMChildByName(elemNextMix, OPTIONS_NODE_IP, elemIP, false);
3692  if(elemIP == NULL || getDOMElementValue(elemIP,buffHost,&buffHostLen) == E_SUCCESS)
3693  {
3694  ((CASocketAddrINet*)addr)->setAddr(buffHost,port);
3695  bAddrIsSet = true;
3696  }
3697  }
3698  CAMsg::printMsg(LOG_INFO, "Setting target interface: %s:%d\n", buffHost, port);
3699  }
3700  }
3701 #ifdef HAVE_UNIX_DOMAIN_PROTOCOL
3702  else if( (type == SSL_UNIX) || (type == RAW_UNIX) )
3703  {
3704  DOMElement* elemFile=NULL;
3705  getDOMChildByName(elemNextMix, OPTIONS_NODE_FILE, elemFile, false);
3706  tmpLen = TMP_BUFF_SIZE;
3707  if(getDOMElementValue(elemFile, tmpBuff, &tmpLen) == E_SUCCESS)
3708  {
3709  tmpBuff[tmpLen]=0;
3710  strtrim(tmpBuff);
3711  addr=new CASocketAddrUnix;
3712  if(((CASocketAddrUnix*)addr)->setPath((char*)tmpBuff) == E_SUCCESS)
3713  {
3714  bAddrIsSet = true;
3715  }
3716  }
3717  }
3718 #endif
3719  }
3720 
3721  if(bAddrIsSet)
3722  {
3723  targetInterfaceNextMix=new CATargetInterface(TARGET_MIX,type,addr->clone());
3724  m_cnTargets=1;
3725  }
3726 
3727  delete addr;
3728  addr = NULL;
3729  }
3730 
3731  //Next Proxies and visible adresses
3732  SINT32 ret;
3733  UINT8 buff[255];
3734  UINT32 buffLen = 255;
3735  CASocket* tmpSocket;
3736 
3738  getDOMChildByName(elemNetwork, OPTIONS_NODE_PROXY_LIST, elemProxies, false);
3739  if(elemProxies != NULL)
3740  {
3741  DOMNodeList* nlTargetInterfaces=NULL;
3742  nlTargetInterfaces=getElementsByTagName(elemProxies, OPTIONS_NODE_PROXY);
3743  m_cnTargets+=nlTargetInterfaces->getLength();
3744 
3745  if(nlTargetInterfaces->getLength()>0)
3746  {
3748  UINT32 aktInterface=0;
3750  TargetType proxy_type=TARGET_UNKNOWN;
3751  CASocketAddr* addr=NULL;
3752  UINT16 port;
3753  bool bHttpProxyFound = false;
3754  for(UINT32 i=0; i < nlTargetInterfaces->getLength(); i++)
3755  {
3756  delete addr;
3757  addr=NULL;
3758  DOMNode* elemTargetInterface=NULL;
3759  elemTargetInterface=nlTargetInterfaces->item(i);
3760  DOMElement* elemType;
3761  getDOMChildByName (elemTargetInterface, OPTIONS_NODE_NETWORK_PROTOCOL, elemType,false);
3762  tmpLen = TMP_BUFF_SIZE;
3763  if(getDOMElementValue(elemType,tmpBuff,&tmpLen)!=E_SUCCESS)
3764  continue;
3765  strtrim(tmpBuff);
3766  if(strcmp((char*)tmpBuff,"RAW/TCP") == 0)
3767  {
3768  type=RAW_TCP;
3769  }
3770  else if(strcmp((char*)tmpBuff,"RAW/UNIX") == 0)
3771  {
3772  type=RAW_UNIX;
3773  }
3774  else if(strcmp((char*)tmpBuff,"SSL/TCP") == 0)
3775  {
3776  type=SSL_TCP;
3777  }
3778  else if(strcmp((char*)tmpBuff,"SSL/UNIX") == 0)
3779  {
3780  type=SSL_UNIX;
3781  }
3782  else
3783  {
3784  continue;
3785  }
3786  //ProxyType
3787  elemType=NULL;
3788  getDOMChildByName (elemTargetInterface, OPTIONS_NODE_PROXY_TYPE, elemType, false);
3789  tmpLen = TMP_BUFF_SIZE;
3790  if(getDOMElementValue(elemType,tmpBuff,&tmpLen)!=E_SUCCESS)
3791  continue;
3792  strtrim(tmpBuff);
3793  if(strcmp((char*)tmpBuff,"SOCKS")==0)
3794  {
3795  proxy_type=TARGET_SOCKS_PROXY;
3796  }
3797  else if(strcmp((char*)tmpBuff,"HTTP")==0)
3798  {
3799  proxy_type=TARGET_HTTP_PROXY;
3800  }
3801  else if (strcmp((char*)tmpBuff, "VPN") == 0)
3802  {
3803  proxy_type = TARGET_VPN_PROXY;
3804  }
3805  else
3806  {
3807  continue;
3808  }
3809 
3810  if( (type==SSL_TCP) || (type == RAW_TCP) )
3811  {
3812  DOMElement* elemPort;
3813  DOMElement* elemHost;
3815  (elemTargetInterface, OPTIONS_NODE_PORT, elemPort, false);
3816  if(getDOMElementValue(elemPort,&port)!=E_SUCCESS)
3817  {
3818  continue;
3819  }
3820  addr=new CASocketAddrINet;
3822  (elemTargetInterface, OPTIONS_NODE_HOST, elemHost, false);
3823  if(elemHost != NULL)
3824  {
3825  UINT8 buffHost[TMP_BUFF_SIZE];
3826  UINT32 buffHostLen = TMP_BUFF_SIZE;
3827  if(getDOMElementValue(elemHost, buffHost, &buffHostLen) != E_SUCCESS)
3828  {
3829  continue;
3830  }
3831  if(((CASocketAddrINet*)addr)->setAddr(buffHost, port) != E_SUCCESS)
3832  {
3833  continue;
3834  }
3835  }
3836  else
3837  {
3838  continue;
3839  }
3840  }
3841  else
3842 #ifdef HAVE_UNIX_DOMAIN_PROTOCOL
3843  {
3844  DOMElement* elemFile;
3846  (elemTargetInterface, OPTIONS_NODE_FILE, elemFile, false);
3847  tmpLen = TMP_BUFF_SIZE;
3848  if(getDOMElementValue(elemFile, tmpBuff, &tmpLen) != E_SUCCESS)
3849  {
3850  continue;
3851  }
3852  tmpBuff[tmpLen]=0;
3853  strtrim(tmpBuff);
3854  addr=new CASocketAddrUnix;
3855  if(((CASocketAddrUnix*)addr)->setPath((char*)tmpBuff) != E_SUCCESS)
3856  {
3857  continue;
3858  }
3859  }
3860 #else
3861  continue;
3862 #endif
3863 
3864 
3865 
3866  // check connection to proxy
3867  if (!m_bSkipProxyCheck)
3868  {
3869  tmpSocket = new CASocket();
3870  tmpSocket->setRecvBuff(50000);
3871  tmpSocket->setSendBuff(5000);
3872  ret = tmpSocket->connect(*addr, LAST_MIX_TO_PROXY_CONNECT_TIMEOUT);
3873  }
3874  else
3875  {//proxy check skipped --> succesful...
3876  ret = E_SUCCESS;
3877  }
3878  if (ret != E_SUCCESS)
3879  {
3880  if (addr->toString(buff, buffLen) != E_SUCCESS)
3881  {
3882  buff[0] = 0;
3883  }
3884  if (ret != E_UNKNOWN)
3885  {
3886  CAMsg::printMsg(LOG_WARNING, "Could not connect to proxy %s! Reason: %s (%i) Please check if the proxy is running.\n",
3888  }
3889  else
3890  {
3891  CAMsg::printMsg(LOG_WARNING, "Could not connect to proxy %s! Please check if the proxy is running.\n", buff);
3892  }
3893  }
3894 
3895  else //if (ret == E_SUCCESS)
3896  {
3897  if (proxy_type == TARGET_HTTP_PROXY)
3898  {
3899  // 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
3900  //if(tmpSocket->sendTimeOut(pMixPacket->payload.data,payLen,LAST_MIX_TO_PROXY_SEND_TIMEOUT)==SOCKET_ERROR) ...
3901  // else ... tmpSocket->receive(pMixPacket->payload.data,PAYLOAD_SIZE);
3902  // if we get no response or an invalid response, we set ret = E_UNKNOWN
3903 
3904  bHttpProxyFound = true;
3905  }
3906  else if (proxy_type == TARGET_SOCKS_PROXY)
3907  {
3908  // TODO maybe there is also a possibility to check the response of the SOCKS proxy?
3909  m_bSocksSupport = true;
3910  }
3911  else if (proxy_type == TARGET_VPN_PROXY)
3912  {
3913  m_bVPNSupport = true;
3914  }
3915  }
3916 
3917  if (tmpSocket != NULL)
3918  {
3919  tmpSocket->close();
3920  delete tmpSocket;
3921  tmpSocket = NULL;
3922  }
3923 
3924 
3925  if (ret == E_SUCCESS)
3926  {
3927  addVisibleAddresses(elemTargetInterface);
3928  m_arTargetInterfaces[aktInterface].set(proxy_type,type,addr->clone());
3929  aktInterface++;
3930  }
3931 
3932 
3933  delete addr;
3934  addr=NULL;
3935  }
3936 
3937  if (!bHttpProxyFound&&!m_bVPNSupport)
3938  {
3939  CAMsg::printMsg(LOG_CRIT, "No valid HTTP or VPN proxy was specified! Please install and configure an HTTP or VPN proxy like Squid or the ANONVPN proxy before starting the mix.\n");
3940  for (UINT32 i = 0; i < aktInterface; i++)
3941  {
3942  m_arTargetInterfaces[aktInterface].cleanAddr();
3943  }
3944 
3945 
3946  return E_UNKNOWN;
3947  }
3948 
3949  m_cnTargets=aktInterface;
3950  }
3951  } //end if elemProxies!=null
3952  //add NextMixInterface to the End of the List...
3953  if(targetInterfaceNextMix != NULL)
3954  {
3955  if(m_arTargetInterfaces == NULL)
3956  {
3957  m_cnTargets=0;
3959  }
3960  m_arTargetInterfaces[m_cnTargets++].set(targetInterfaceNextMix);
3961  delete targetInterfaceNextMix;
3962  targetInterfaceNextMix = NULL;
3963  }
3964  else if(m_arTargetInterfaces == NULL)
3965  {
3966  CAMsg::printMsg(LOG_CRIT, "Neither proxy nor next mix target interfaces are specified!\n");
3967  return E_UNKNOWN;
3968  }
3969 
3970  //Set Proxy Visible Addresses if Last Mix and given
3971  if(isLastMix() && (m_docMixInfo != NULL) )
3972  {
3973  DOMElement* elemMix = m_docMixInfo->getDocumentElement();
3974  if(elemMix != NULL)
3975  {
3976  DOMElement* elemProxies=createDOMElement(m_docMixInfo,"Proxies");
3977  if (m_bSocksSupport)
3978  {
3979  setDOMElementAttribute(elemProxies, "socks5Support", (UINT8*)"true");
3980  }
3981  if (m_bVPNSupport)
3982  {
3983  setDOMElementAttribute(elemProxies, "vpnSupport", (UINT8*)"true");
3984  }
3985  DOMElement* elemProxy=createDOMElement(m_docMixInfo,"Proxy");
3986  DOMElement* elemVisAddresses=createDOMElement(m_docMixInfo,"VisibleAddresses");
3987  elemMix->appendChild(elemProxies);
3988  elemProxies->appendChild(elemProxy);
3989  elemProxy->appendChild(elemVisAddresses);
3990  for(UINT32 i=1;i<=getVisibleAddressesCount();i++)
3991  {
3992  UINT8 tmp[255];
3993  UINT32 tmplen=255;
3994  if(getVisibleAddress(tmp,tmplen,i)==E_SUCCESS)
3995  {
3996  DOMElement* elemVisAddress=createDOMElement(m_docMixInfo,"VisibleAddress");
3997  DOMElement* elemHost=createDOMElement(m_docMixInfo,"Host");
3998  elemVisAddress->appendChild(elemHost);
3999  setDOMElementValue(elemHost,tmp);
4000  elemVisAddresses->appendChild(elemVisAddress);
4001  }
4002  }
4003  }
4004  }
4005 
4006  return E_SUCCESS;
4007 }
4008 
4009 // Deletes all information about the visible addresses.
4010  //
4012  {
4013  if(m_arStrVisibleAddresses!=NULL)
4014  {
4015  for(UINT32 i=0;i<m_cnVisibleAddresses;i++)
4016  {
4017  delete[] m_arStrVisibleAddresses[i];
4018  m_arStrVisibleAddresses[i] = NULL;
4019  }
4020  delete[] m_arStrVisibleAddresses;
4021  }
4024  return E_SUCCESS;
4025  }
4026 
4028 // * The structur is as follows:
4029 // *@verbatim
4030 // * <Proxy>
4031 // * <VisibleAddresses> <!-- Describes the visible addresses from the 'outside world' -->
4032 // * <VisibleAddress>
4033 // * <Host> <!-- Host or IP -->
4034 // * </Host>
4035 // * </VisibleAddress>
4036 // * </VisibleAddresses>
4037 // *
4038 // * </Proxy>
4039 // @endverbatim
4040 //
4042  {
4043  if(nodeProxy==NULL) return E_UNKNOWN;
4045  (nodeProxy->getNodeName(), OPTIONS_NODE_PROXY, OPTIONS_NODE_VISIBLE_ADDRESS_LIST);
4046  DOMNode* elemVisAdresses=NULL;
4047  getDOMChildByName(nodeProxy, OPTIONS_NODE_VISIBLE_ADDRESS_LIST, elemVisAdresses);
4048  DOMNode* elemVisAddress=NULL;
4049  getDOMChildByName(elemVisAdresses, OPTIONS_NODE_VISIBLE_ADDRESS ,elemVisAddress);
4050  while(elemVisAddress!=NULL)
4051  {
4052  if(equals(elemVisAddress->getNodeName(), OPTIONS_NODE_VISIBLE_ADDRESS))
4053  {
4054  DOMElement* elemHost=NULL;
4055  if(getDOMChildByName(elemVisAddress, OPTIONS_NODE_HOST ,elemHost)==E_SUCCESS)
4056  {
4057  UINT8 tmp[TMP_BUFF_SIZE];
4059  if(getDOMElementValue(elemHost,tmp,&len)==E_SUCCESS)
4060  {//append the new address to the list of addresses
4061  UINT8** tmpAr=new UINT8*[m_cnVisibleAddresses+1];
4062  if(m_arStrVisibleAddresses!=NULL)
4063  {
4064  memcpy(tmpAr,m_arStrVisibleAddresses,m_cnVisibleAddresses*sizeof(UINT8*));
4065  delete[] m_arStrVisibleAddresses;
4066  m_arStrVisibleAddresses = NULL;
4067  }
4068  tmpAr[m_cnVisibleAddresses]=new UINT8[len+1];
4069  memcpy(tmpAr[m_cnVisibleAddresses],tmp,len+1);
4072  }
4073  }
4074  }
4075  elemVisAddress=elemVisAddress->getNextSibling();
4076  }
4077  return E_SUCCESS;
4078  }
4079 
4081  {
4082  if(strAddressBuff==NULL||nr==0||nr>m_cnVisibleAddresses)
4083  {
4084  return E_UNKNOWN;
4085  }
4086  if(strlen((char*)m_arStrVisibleAddresses[nr-1] )>=len)
4087  {
4088  return E_SPACE;
4089  }
4090  strcpy((char*)strAddressBuff,(char*)m_arStrVisibleAddresses[nr-1]);
4091  return E_SUCCESS;
4092  }
4093 
4094 /* append the mix description to the mix info DOM structure
4095  * this is a main option (child of <MixConfiguration>)
4096  */
4098 {
4099  SINT32 ret = E_SUCCESS;
4100  DOMElement* elemMixDescription = NULL;
4101  if(elemRoot == NULL)
4102  {
4103  return E_UNKNOWN;
4104  }
4105  ret = getDOMChildByName
4106  (elemRoot, OPTIONS_NODE_DESCRIPTION, elemMixDescription, false);
4107 
4108  if(elemMixDescription != NULL )
4109  {
4110  DOMNode* tmpChild = elemMixDescription->getFirstChild();
4111  while( (tmpChild != NULL) && (ret == E_SUCCESS) )
4112  {
4113  ret = appendMixInfo_internal(tmpChild, WITH_SUBTREE);
4114  tmpChild=tmpChild->getNextSibling();
4115  }
4116  }
4117  return ret;
4118 }
4119 
4120 
4121 // ***************************************
4122 // * certificate option setter functions *
4123 // ***************************************
4125 {
4126 
4127  DOMElement* elemCertificates;
4128 
4129  if (getDOMChildByName
4130  (elemRoot, OPTIONS_NODE_CERTIFICATE_LIST, elemCertificates, false) != E_SUCCESS)
4131  {
4133  return E_UNKNOWN;
4134  }
4135 
4137 }
4138 
4139 // ***********************************
4140 // network option setter functions *
4141 // ***********************************
4143 {
4144  DOMElement* elemNetwork = NULL;
4145  if (getDOMChildByName
4146  (elemRoot, OPTIONS_NODE_NETWORK, elemNetwork, false) != E_SUCCESS)
4147  {
4149  return E_UNKNOWN;
4150  }
4151 
4152  return invokeOptionSetters
4153  (networkOptionSetters, elemNetwork, NETWORK_OPTIONS_NR);
4154 }
4155 
4156 SINT32 CACmdLnOptions::setOwnCertificate(DOMElement *elemCertificates)
4157 {
4158  DOMElement* elemOwnCert=NULL;
4159  UINT8 tmpBuff[TMP_BUFF_SIZE];
4160  UINT32 tmpLen = TMP_BUFF_SIZE;
4161 
4162  UINT8 passwd[500];
4163  passwd[0] = 0;
4164 
4165  if(elemCertificates == NULL) return E_UNKNOWN;
4167  (elemCertificates->getNodeName(), OPTIONS_NODE_OWN_CERTIFICATE);
4168 
4169  //Own Certiticate first
4170  getDOMChildByName(elemCertificates, OPTIONS_NODE_OWN_CERTIFICATE, elemOwnCert, false);
4171  if (elemOwnCert == NULL)
4172  {
4174  return E_UNKNOWN;
4175  }
4176 
4178 
4179  //if(m_pSignKey->setSignKey
4180  // (elemOwnCert->getFirstChild(), SIGKEY_PKCS12) != E_SUCCESS)
4181  //{
4182  // //Maybe not an empty passwd
4183  // printf("I need a passwd for the SignKey: ");
4184  // fflush(stdout);
4185  // readPasswd(passwd, 500);
4186  // if(m_pSignKey->setSignKey
4187  // (elemOwnCert->getFirstChild(),
4188  // SIGKEY_PKCS12,(char*)passwd) != E_SUCCESS)
4189  // {
4190  // CAMsg::printMsg(LOG_CRIT,"Could not read own signature key!\n");
4191  // delete m_pSignKey;
4192  // m_pSignKey=NULL;
4193  // }
4194  //}
4195 
4197  // CACertificate::decode(elemOwnCert->getFirstChild(), CERT_PKCS12, (char*)passwd);
4198  //if (m_pOwnCertificate == NULL)
4199  //{
4200  // CAMsg::printMsg(LOG_CRIT, "Could not decode mix certificate!\n");
4201  // return E_UNKNOWN;
4202  //}
4203 
4204  // new
4205  //m_ownCertsLength = 0;
4206  //m_opCertsLength = 0;
4207 
4208  //decode OpCerts
4209  UINT32 opCertsLen = m_opCertList->getLength();
4210  CACertificate** opCerts=new CACertificate*[opCertsLen];
4211  for(UINT32 j=0; j<opCertsLen; j++)
4212  {
4213  DOMNode* a_opCert = m_opCertList->item(j);
4214  opCerts[j] = CACertificate::decode(a_opCert,CERT_X509CERTIFICATE);
4215  if(opCerts[j] == NULL)
4216  {
4217  CAMsg::printMsg(LOG_CRIT, "Error while decoding operator certificates!");
4218  delete[] opCerts;
4219  return E_UNKNOWN;
4220  }
4221  }
4222 
4223  DOMNodeList* ownCertList = getElementsByTagName(elemOwnCert, OPTIONS_NODE_X509_PKCS12);
4224 
4226  for (UINT32 i=0; i<ownCertList->getLength(); i++)
4227  {
4228  DOMNode* a_cert = ownCertList->item(i);
4229  CASignature* signature = new CASignature();
4230  CACertStore* certs = new CACertStore();
4231 
4232  //try to get signature key from ownCert
4233  if(signature->setSignKey(a_cert, SIGKEY_PKCS12, (char*)passwd) != E_SUCCESS)
4234  {
4235  //Read password if necessary
4236  printf("I need a password for the private Mix certificate nr. %d: ", i+1);
4237  fflush(stdout);
4238  readPasswd(passwd,500);
4239  printf("\n");
4240  if(signature->setSignKey(a_cert, SIGKEY_PKCS12, (char*)passwd) != E_SUCCESS)
4241  {
4242  CAMsg::printMsg(LOG_CRIT,"Unable to load private Mix certificate nr. %d! Please check your password.\n", i+1);
4243  delete signature;
4244  delete certs;
4245  delete[] opCerts;
4246  signature = NULL;
4247  return E_UNKNOWN;
4248  }
4249  }
4250  //decode own certifciate
4251  CACertificate* tmpCert = CACertificate::decode(a_cert, CERT_PKCS12, (char*)passwd);
4252  if(tmpCert== NULL)
4253  {
4254  CAMsg::printMsg(LOG_CRIT, "Error while getting own certificate %d!\n", i+1);
4255  delete signature;
4256  delete certs;
4257  delete[] opCerts;
4258  return E_UNKNOWN;
4259  }
4260 
4261  //get SKI
4262  UINT32 tmpSKIlen = 255;
4263  UINT8 tmpSKI[255];
4264  if(tmpCert->getSubjectKeyIdentifier(tmpSKI, &tmpSKIlen) != E_SUCCESS)
4265  {
4266  CAMsg::printMsg(LOG_CRIT, "Error while getting SKI of own certificate %d!\n", i+1);
4267  delete signature;
4268  delete certs;
4269  delete tmpCert;
4270  delete[] opCerts;
4271  return E_UNKNOWN;
4272  }
4273  //CAMsg::printMsg(LOG_DEBUG, "SKI of own cert %d is: %s\n", i+1, tmpSKI);
4274  //get AKI
4275  UINT32 tmpAKIlen = 255;
4276  UINT8 tmpAKI[255];
4277  if(tmpCert->getAuthorityKeyIdentifier(tmpAKI, &tmpAKIlen) != E_SUCCESS)
4278  {
4279  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");
4280  }
4281  else
4282  {
4283  //CAMsg::printMsg(LOG_DEBUG, "AKI of own cert %d is: %s\n", i+1, tmpAKI);
4284  }
4285  //try to find right opCert
4286  for(UINT32 j=0; j<opCertsLen; j++)
4287  {
4288  if(tmpCert->verify(opCerts[j]) == E_SUCCESS)
4289  {
4290  //found right operator cert -> add it to store
4291  // CAMsg::printMsg(LOG_DEBUG, "Found operator cert for sign key %d!\n", i+1);
4292  certs->add(opCerts[j]);
4293  break;
4294  }
4295  }
4296  for(UINT32 j=0; j<opCertsLen; j++)
4297  {
4298  delete opCerts[j];
4299  }
4300  delete[]opCerts;
4301  opCerts=NULL;
4302 
4303  if(certs->getNumber() == 0)
4304  {
4305  CAMsg::printMsg(LOG_CRIT, "Could not find operator cert for sign key %d! Please check your configuration. Exiting...\n", i+1);
4306  exit(EXIT_FAILURE);
4307  }
4308  //add own cert to store
4309  certs->add(tmpCert);
4310  //get Raw SKI
4311  UINT32 tmpRawSKIlen = 255;
4312  UINT8 tmpRawSKI[255];
4313  if(tmpCert->getRawSubjectKeyIdentifier(tmpRawSKI, &tmpRawSKIlen) != E_SUCCESS)
4314  {
4315  delete signature;
4316  delete certs;
4317  delete tmpCert;
4318  return E_UNKNOWN;
4319  }
4320  if (certs->getNumber() < 2)
4321  {
4322  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());
4323  exit(EXIT_FAILURE);
4324  }
4325  delete tmpCert;
4326  tmpCert=NULL;
4327  CAMsg::printMsg(LOG_DEBUG, "Adding Sign-Key %d with %d certificate(s).\n", i+1, certs->getNumber());
4328  m_pMultiSignature->addSignature(signature, certs, tmpRawSKI, tmpRawSKIlen);
4329  }
4331  {
4332  CAMsg::printMsg(LOG_CRIT, "Could not set a signature key for MultiCert!\n");
4333  delete m_pMultiSignature;
4334  m_pMultiSignature = NULL;
4335  return E_UNKNOWN;
4336  }
4337  //end new
4339  // (m_strMixID == NULL))
4340  //{
4341  // LOG_NODE_NOT_FOUND(OPTIONS_NODE_MIX_ID);
4342  // return E_UNKNOWN;
4343  //}
4344  //check Mix-ID
4345  if(m_pMultiSignature->getXORofSKIs(tmpBuff, tmpLen) != E_SUCCESS)
4346  {
4347  return E_UNKNOWN;
4348  }
4349 
4350  if(m_strMixID != NULL )
4351  {
4352  if(strncmp(m_strMixID, (char*)tmpBuff, strlen((char*)tmpBuff) ) != 0)
4353  {
4354  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);
4355  return E_UNKNOWN;
4356  }
4357  }
4358  else
4359  {
4360  m_strMixID=new char[strlen((char*)tmpBuff)+1];
4361  m_strMixID[strlen((char*)tmpBuff)]= (char) 0;
4362  strcpy(m_strMixID,(char*) tmpBuff);
4363  return addMixIdToMixInfo();
4364  }
4365 
4366 #ifdef PAYMENT
4368  {
4369  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");
4370  }
4371 #endif
4372 
4373 #ifdef DYNAMIC_MIX
4374  // LERNGRUPPE: Dynamic Mixes must have a cascade name, as MiddleMixes may be reconfigured to be FirstMixes
4375  if(bNeedCascadeNameFromMixID)
4376  {
4377  m_strCascadeName = new char[strlen(m_strMixID) + 1];
4378  memset(m_strCascadeName, 0, strlen(m_strMixID) + 1);
4379  strncpy(m_strCascadeName, m_strMixID, strlen(m_strMixID)+1);
4380  }
4381 #endif
4382  return E_SUCCESS;
4383 }
4384 
4389 SINT32 CACmdLnOptions::setMixType(DOMElement* elemGeneral)
4390 {
4391  DOMElement* elemMixType=NULL;
4392  UINT8 tmpBuff[TMP_BUFF_SIZE];
4393  UINT32 tmpLen = TMP_BUFF_SIZE;
4394 
4395  if(elemGeneral == NULL) return E_UNKNOWN;
4397  (elemGeneral->getNodeName(), OPTIONS_NODE_MIX_TYPE);
4398 
4399  //getMixType
4400  if (getDOMChildByName(elemGeneral, OPTIONS_NODE_MIX_TYPE,
4401  elemMixType,false) != E_SUCCESS)
4402  {
4404  return E_UNKNOWN;
4405  }
4406 
4407  if( getDOMElementValue(elemMixType,tmpBuff,&tmpLen) == E_SUCCESS )
4408  {
4409  if(memcmp(tmpBuff,"FirstMix",8) == 0)
4410  {
4411  m_bFirstMix = true;
4412  }
4413  else if (memcmp(tmpBuff,"MiddleMix",9) == 0)
4414  {
4415  m_bMiddleMix = true;
4416  }
4417  else if (memcmp(tmpBuff,"LastMix",7) == 0)
4418  {
4419  m_bLastMix = true;
4420  }
4421  if ( appendMixInfo_internal(elemMixType, WITH_SUBTREE) != E_SUCCESS )
4422  {
4423  return E_UNKNOWN;
4424  }
4425  }
4426  else
4427  {
4429  return E_UNKNOWN;
4430  }
4431  return E_SUCCESS;
4432 }
4433 
4434 SINT32 CACmdLnOptions::setMixName(DOMElement* elemGeneral)
4435 {
4436  DOMElement *elemMixName = NULL, *elemMixInfoName = NULL;
4437  UINT8 tmpBuff[TMP_BUFF_SIZE];
4438  UINT32 tmpLen = TMP_BUFF_SIZE;
4439  UINT8 *typeValue = NULL; //(UINT8 *) OPTIONS_VALUE_NAMETYPE_DEFAULT;
4440  //uncomment the above line to enable a default name type
4441 
4442  if(elemGeneral == NULL) return E_UNKNOWN;
4444  (elemGeneral->getNodeName(), OPTIONS_NODE_MIX_NAME);
4445 
4446  //Inserting the Name if given...
4447  getDOMChildByName(elemGeneral, OPTIONS_NODE_MIX_NAME, elemMixName, false);
4448  if(elemMixName != NULL)
4449  {
4450  if(getDOMElementValue(elemMixName, tmpBuff, &tmpLen) == E_SUCCESS)
4451  {
4452  m_strMixName = new char[tmpLen+1];
4453  memset(m_strMixName, 0, tmpLen+1);
4454  memcpy(m_strMixName, tmpBuff, tmpLen);
4455  }
4456  tmpLen = TMP_BUFF_SIZE;
4457  getDOMElementAttribute(elemMixName, OPTIONS_ATTRIBUTE_NAME_FOR_CASCADE, tmpBuff, &tmpLen);
4458  }
4459  else
4460  {
4461  tmpLen = 0;
4462  m_strMixName = NULL;
4463  }
4464 
4465  /* now append the values to the mix info
4466  * conditions:
4467  * - if name is set, m_strMixname points to it.
4468  * - if name type is set then it is in tmpBuff.
4469  */
4471 
4472  /* if name is set */
4473  if(m_strMixName != NULL)
4474  {
4475  setDOMElementValue(elemMixInfoName, (UINT8*) m_strMixName);
4476  }
4477 
4478  if( tmpLen != 0 ) /* if name type is set */
4479  {
4480  if( strncasecmp( ((char *)tmpBuff),
4482  strlen(OPTIONS_VALUE_OPERATOR_NAME)) == 0 ) /* type is operator name*/
4483  {
4484  typeValue = (UINT8 *) OPTIONS_VALUE_OPERATOR_NAME;
4485  }
4486  else if( strncasecmp( ((char *)tmpBuff),
4488  strlen(OPTIONS_VALUE_MIX_NAME)) == 0 ) /* type is mix name*/
4489  {
4490  typeValue = (UINT8 *) OPTIONS_VALUE_MIX_NAME;
4491  }
4492  }
4493  if(typeValue != NULL)
4494  {
4495  setDOMElementAttribute(elemMixInfoName,
4497  }
4498 
4499  if(m_docMixInfo->getDocumentElement() != NULL)
4500  {
4501  m_docMixInfo->getDocumentElement()->appendChild(elemMixInfoName);
4502  }
4503  else
4504  {
4505  //Should never happen
4506  return E_UNKNOWN;
4507  }
4508  return E_SUCCESS;
4509 }
4510 
4511 SINT32 CACmdLnOptions::setMixID(DOMElement* elemGeneral)
4512 {
4513  DOMElement* elemMixID=NULL;
4514  UINT8 tmpBuff[TMP_BUFF_SIZE];
4515  UINT32 tmpLen = TMP_BUFF_SIZE;
4516  size_t mixID_strlen = 0;
4517 
4518  if(elemGeneral == NULL) return E_UNKNOWN;
4520  (elemGeneral->getNodeName(), OPTIONS_NODE_MIX_NAME);
4521 
4522  getDOMChildByName(elemGeneral, OPTIONS_NODE_MIX_ID, elemMixID, false);
4523  if(elemMixID != NULL)
4524  {
4525  if(getDOMElementValue(elemMixID,tmpBuff,&tmpLen) == E_SUCCESS)
4526  {
4527  strtrim(tmpBuff);
4528  mixID_strlen = strlen((char*)tmpBuff)+1;
4529  m_strMixID = new char[strlen((char*)tmpBuff)+1];
4530  memset(m_strMixID, 0, mixID_strlen);
4531  memcpy(m_strMixID, tmpBuff, mixID_strlen);
4532 
4533  return addMixIdToMixInfo();
4534  }
4535  }
4536  return E_SUCCESS;
4537 
4538 }
4540 {
4541  DOMElement* elemCascadeName=NULL;
4542  UINT8 tmpBuff[TMP_BUFF_SIZE];
4543  UINT32 tmpLen = TMP_BUFF_SIZE;
4544 
4545  if(elemGeneral == NULL) return E_UNKNOWN;
4547  (elemGeneral->getNodeName(), OPTIONS_NODE_CASCADE_NAME);
4548 
4549  //getCascadeName
4550  getDOMChildByName(elemGeneral, OPTIONS_NODE_CASCADE_NAME, elemCascadeName, false);
4551 
4552 #ifdef DYNAMIC_MIX
4553  bool bNeedCascadeNameFromMixID=false;
4554 #endif
4555  if(getDOMElementValue(elemCascadeName,tmpBuff,&tmpLen)==E_SUCCESS)
4556  {
4557  setCascadeName(tmpBuff);
4558  }
4559 #ifdef DYNAMIC_MIX
4560  /* LERNGRUPPE: Dynamic Mixes must have a cascade name, as MiddleMixes may be reconfigured to be FirstMixes */
4561  else
4562  {
4563  bNeedCascadeNameFromMixID=true;
4565  }
4566 #endif
4567  return E_SUCCESS;
4568 }
4569 
4570 SINT32 CACmdLnOptions::setUserID(DOMElement* elemGeneral)
4571 {
4572  DOMElement* elemUID=NULL;
4573  UINT8 tmpBuff[TMP_BUFF_SIZE];
4574  UINT32 tmpLen = TMP_BUFF_SIZE;
4575 
4576  if(elemGeneral == NULL) return E_UNKNOWN;
4578  (elemGeneral->getNodeName(), OPTIONS_NODE_USER_ID);
4579 
4580  //get Username to run as...
4581  getDOMChildByName(elemGeneral, OPTIONS_NODE_USER_ID, elemUID,false);
4582 
4583  if(getDOMElementValue(elemUID,tmpBuff,&tmpLen)==E_SUCCESS)
4584  {
4585  m_strUser=new char[tmpLen+1];
4586  memcpy(m_strUser,tmpBuff,tmpLen);
4587  m_strUser[tmpLen]=0;
4588  }
4589 
4590 #ifndef WIN32
4591  UINT8 buff[255];
4592  if(getUser(buff,255)==E_SUCCESS) //switching user
4593  {
4594  struct passwd* pwd=getpwnam((char*)buff);
4595  if(pwd==NULL || (setegid(pwd->pw_gid)==-1) || (seteuid(pwd->pw_uid)==-1) )
4596  {
4597  if (pwd==NULL)
4598  {
4599  CAMsg::printMsg(LOG_ERR,
4600  "Could not switch to effective user '%s'! Reason: User '%s' does not exist on this system. Create this user first.\n",
4601  buff, buff);
4602  }
4603  else
4604  {
4605  CAMsg::printMsg(LOG_ERR,"Could not switch to effective user '%s'! Reason: %s (%i)\n",
4607  }
4608  }
4609  else
4610  CAMsg::printMsg(LOG_INFO,"Switched to effective user '%s'!\n",buff);
4611  }
4612 
4613  if(geteuid()==0)
4614  CAMsg::printMsg(LOG_WARNING,"Mix is running as root/superuser!\n");
4615 #endif
4616  return E_SUCCESS;
4617 }
4618 
4620 {
4621  DOMElement* elemNrFd=NULL;
4622  UINT32 tmp = 0;
4623 
4624  if(elemGeneral == NULL) return E_UNKNOWN;
4626  (elemGeneral->getNodeName(), OPTIONS_NODE_FD_NR);
4627 
4628  //get Number of File Descriptors to use
4629  getDOMChildByName(elemGeneral, OPTIONS_NODE_FD_NR, elemNrFd, false);
4630 
4631  if(getDOMElementValue(elemNrFd,&tmp) == E_SUCCESS)
4632  {
4633  m_nrOfOpenFiles=tmp;
4634  }
4635 
4636 #ifndef WIN32
4637 
4638  struct rlimit coreLimit;
4639  coreLimit.rlim_cur = coreLimit.rlim_max = RLIM_INFINITY;
4640  if (setrlimit(RLIMIT_CORE, &coreLimit) != 0)
4641  {
4642  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);
4643  }
4644 
4645  if(m_nrOfOpenFiles>0)
4646  {
4647  struct rlimit lim;
4648  // Set the new MAX open files limit
4649  lim.rlim_cur = lim.rlim_max = m_nrOfOpenFiles;
4650  if (setrlimit(RLIMIT_NOFILE, &lim) != 0)
4651  {
4652  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",
4654  exit(EXIT_FAILURE);
4655  }
4656  }
4657 #endif
4658 
4659  return E_SUCCESS;
4660 }
4661 
4662 SINT32 CACmdLnOptions::setDaemonMode(DOMElement* elemGeneral)
4663 {
4664  DOMElement* elemDaemonMode = NULL;
4665  UINT8 tmpBuff[TMP_BUFF_SIZE];
4666  UINT32 tmpLen = TMP_BUFF_SIZE;
4667 
4668  if(elemGeneral == NULL) return E_UNKNOWN;
4670  (elemGeneral->getNodeName(), OPTIONS_NODE_DAEMON);
4671 
4672  //get Run as Daemon
4673  getDOMChildByName(elemGeneral, OPTIONS_NODE_DAEMON, elemDaemonMode,false);
4674 
4675  if(getDOMElementValue(elemDaemonMode, tmpBuff, &tmpLen) == E_SUCCESS &&
4676  memcmp(tmpBuff,"True",4)==0)
4677  {
4678  m_bDaemon=true;
4679  }
4680  return E_SUCCESS;
4681 }
4682 
4683 SINT32 CACmdLnOptions::setNextMixCertificate(DOMElement *elemCertificates)
4684 {
4685  DOMElement* elemNextCert = NULL;
4686 
4687  if(!m_bVerifyMixCerts)
4688  {
4689  if(elemCertificates == NULL) return E_UNKNOWN;
4691  (elemCertificates->getNodeName(), OPTIONS_NODE_NEXT_MIX_CERTIFICATE);
4692 
4693  //nextMixCertificate if given
4694  getDOMChildByName(elemCertificates, OPTIONS_NODE_NEXT_MIX_CERTIFICATE, elemNextCert,false);
4695  if(elemNextCert!=NULL)
4696  {
4698  CACertificate::decode(elemNextCert->getFirstChild(),CERT_X509CERTIFICATE);
4699  if(m_pNextMixCertificate == NULL)
4700  {
4701  CAMsg::printMsg(LOG_CRIT,"Could not decode the certificate of the next mix!\n");
4702  return E_UNKNOWN;
4703  }
4704  }
4705  }
4706  return E_SUCCESS;
4707 
4708 }
4709 
4710 SINT32 CACmdLnOptions::setPrevMixCertificate(DOMElement *elemCertificates)
4711 {
4712  //prevMixCertificate if given
4713  DOMElement* elemPrevCert=NULL;
4714 
4715  if(!m_bVerifyMixCerts)
4716  {
4717  if(elemCertificates == NULL) return E_UNKNOWN;
4719  (elemCertificates->getNodeName(), OPTIONS_NODE_PREV_MIX_CERTIFICATE);
4720 
4721  getDOMChildByName(elemCertificates, OPTIONS_NODE_PREV_MIX_CERTIFICATE, elemPrevCert, false);
4722  if(elemPrevCert!=NULL)
4723  {
4725  CACertificate::decode(elemPrevCert->getFirstChild(),CERT_X509CERTIFICATE);
4726  }
4727  }
4728  return E_SUCCESS;
4729 
4730 }
4731 
4733 {
4734  DOMElement* elemTrustedCerts=NULL;
4735  DOMNodeList* trustedCerts=NULL;
4736  CACertificate* cert;
4737 
4738  if(m_bVerifyMixCerts)
4739  {
4740  if(elemCertificates == NULL) return E_UNKNOWN;
4742  (elemCertificates->getNodeName(), OPTIONS_NODE_TRUSTED_ROOT_CERTIFICATES);
4743 
4744  getDOMChildByName(elemCertificates, OPTIONS_NODE_TRUSTED_ROOT_CERTIFICATES, elemTrustedCerts, false);
4745  if(elemTrustedCerts!=NULL)
4746  {
4747  trustedCerts = getElementsByTagName(elemTrustedCerts, OPTIONS_NODE_X509_CERTIFICATE);
4748 
4749  for(UINT32 i=0; i<trustedCerts->getLength(); i++)
4750  {
4751  cert = CACertificate::decode(trustedCerts->item(i), CERT_X509CERTIFICATE);
4752  if(cert != NULL)
4753  {
4755  }
4756  else
4757  {
4758  CAMsg::printMsg(LOG_WARNING, "Root certificate could not be decoded\n");
4759  }
4760  }
4761  }
4762  else
4763  {
4765  return E_UNKNOWN;
4766  }
4768  {
4769  CAMsg::printMsg(LOG_CRIT, "No trusted root certificates found.\n");
4770  return E_UNKNOWN;
4771  }
4772  CAMsg::printMsg(LOG_INFO, "Loaded %d trusted root certificates.\n", m_pTrustedRootCertificates->getNumber());
4773  }
4774  return E_SUCCESS;
4775 }
4776 
4777 // Read Configuration of KeepAliveTraffic
4779 {
4780  DOMElement* elemKeepAlive = NULL;
4781  DOMElement* elemKeepAliveSendInterval = NULL;
4782  DOMElement* elemKeepAliveRecvInterval = NULL;
4783 
4784  if(elemNetwork == NULL) return E_UNKNOWN;
4786  (elemNetwork->getNodeName(), OPTIONS_NODE_SERVER_MONITORING);
4787 
4788  getDOMChildByName(elemNetwork, OPTIONS_NODE_KEEP_ALIVE, elemKeepAlive, false);
4789  getDOMChildByName(elemKeepAlive, OPTIONS_NODE_KEEP_ALIVE_SEND_IVAL, elemKeepAliveSendInterval, false);
4790  getDOMChildByName(elemKeepAlive, OPTIONS_NODE_KEEP_ALIVE_RECV_IVAL, elemKeepAliveRecvInterval, false);
4793  return E_SUCCESS;
4794 }
4795 
4796 /* this method is only for internal use in order to intialize the
4797  * mixinfo structure when the options are parsed. Don't get confused
4798  * with the method addMixInfo of class CAMix which appends an
4799  * additional timestamp.
4800  * if NULL is specified as name the name of a_node is used
4801  */
4802 SINT32 CACmdLnOptions::appendMixInfo_internal(DOMNode* a_node, bool with_subtree)
4803 {
4804  DOMNode *importedNode = NULL;
4805  DOMNode *appendedNode = NULL;
4806 
4807 if(a_node == NULL)
4808  {
4809  CAMsg::printMsg(LOG_CRIT,"No node specified!\n");
4810  return E_UNKNOWN;
4811  }
4812  if(m_docMixInfo == NULL)
4813  {
4814  CAMsg::printMsg(LOG_CRIT,"No mixinfo document initialized!\n");
4815  return E_UNKNOWN;
4816  }
4817  if(m_docMixInfo->getDocumentElement() == NULL)
4818  {
4819  CAMsg::printMsg(LOG_CRIT,"No mixinfo dom structure initialized!\n");
4820  return E_UNKNOWN;
4821  }
4822 
4823  importedNode = m_docMixInfo->importNode(a_node, with_subtree);
4824 
4825  if(importedNode != NULL)
4826  {
4828  if (importedNode->getNodeType() == DOMNode::ELEMENT_NODE)
4829  {
4830  DOMNodeList* nodesMail = getElementsByTagName((DOMElement*)importedNode, "EMail");
4831  for (UINT32 i = 0; i < nodesMail->getLength (); i++)
4832  {
4833  nodesMail->item(i)->getParentNode()->removeChild(nodesMail->item(i));
4834  }
4835  }
4836 
4837  appendedNode = m_docMixInfo->getDocumentElement()->appendChild(importedNode);
4838  if( appendedNode != NULL )
4839  {
4840  return E_SUCCESS;
4841  }
4842  }
4843  CAMsg::printMsg(LOG_CRIT,"Could not append Node \"%s\" to Mixinfo!\n", a_node->getNodeName());
4844  return E_UNKNOWN;
4845 }
4846 
4851 {
4852  if( (m_docMixInfo != NULL) && (m_strMixID != NULL) )
4853  {
4854  return setDOMElementAttribute
4855  (m_docMixInfo->getDocumentElement(), MIXINFO_ATTRIBUTE_MIX_ID, (UINT8*) m_strMixID);
4856  }
4857  CAMsg::printMsg(LOG_CRIT,"No mixinfo document initialized!\n");
4858  return E_UNKNOWN;
4859 }
4861 {
4862  DOMElement* elemListenerInterfaces=NULL;
4863 
4864  if(elemNetwork == NULL) return E_UNKNOWN;
4866  (elemNetwork->getNodeName(), OPTIONS_NODE_LISTENER_INTERFACES);
4867 
4869  (elemNetwork, OPTIONS_NODE_LISTENER_INTERFACES, elemListenerInterfaces, false);
4871  elemListenerInterfaces, m_cnListenerInterfaces);
4872 
4873 #ifndef DYNAMIC_MIX
4874  // LERNGRUPPE: ListenerInterfaces may be configured dynamically
4875  if (m_cnListenerInterfaces == 0)
4876  {
4877  CAMsg::printMsg(LOG_CRIT, "No listener interfaces found!\n");
4878  return E_UNKNOWN;
4879  }
4880 #endif
4881  if(elemListenerInterfaces != NULL)
4882  {
4883  // import listener interfaces element; this is needed for cascade auto configuration
4884  // -- inserted by ronin <ronin2@web.de> 2004-08-16
4885  appendMixInfo_internal(elemListenerInterfaces, WITH_SUBTREE);
4886  }
4887 
4888  UINT32 i;
4889  SINT32 ret;
4890  CASocket** arrSocketsIn=new CASocket*[getListenerInterfaceCount()];
4891  for (i = 0; i < getListenerInterfaceCount(); i++)
4892  {
4893  arrSocketsIn[i] = NULL;
4894  }
4895 
4896  ret = createSockets(false, arrSocketsIn, getListenerInterfaceCount());
4897 
4898  for(i=0;i<getListenerInterfaceCount();i++)
4899  {
4900  if (arrSocketsIn[i] != NULL)
4901  {
4902  arrSocketsIn[i]->close();
4903  delete arrSocketsIn[i];
4904  arrSocketsIn[i] = NULL;
4905  }
4906  }
4907  delete[] arrSocketsIn;
4908  arrSocketsIn=NULL;
4909 
4910 
4911  if (ret != E_SUCCESS && ret != E_UNSPECIFIED && ret != E_SPACE)
4912  {
4913  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");
4914  }
4915 
4916  return ret;
4917 }
4918 
4920 {
4921  DOMElement* elemOpCert = NULL;
4922  DOMElement *opCertX509 = NULL;
4923 
4924  if(elemCertificates == NULL) return E_UNKNOWN;
4926  (elemCertificates->getNodeName(), OPTIONS_NODE_OWN_OPERATOR_CERTIFICATE);
4927 
4928  //then Operator Certificate
4929  if (getDOMChildByName
4930  (elemCertificates, OPTIONS_NODE_OWN_OPERATOR_CERTIFICATE,
4931  elemOpCert, false) != E_SUCCESS)
4932  {
4934  return E_UNKNOWN;
4935  }
4936 
4937  if (elemOpCert != NULL)
4938  {
4939  m_opCertList = getElementsByTagName(elemOpCert, "X509Certificate");
4940 
4941  getDOMChildByName(elemOpCert, OPTIONS_NODE_X509_CERTIFICATE, opCertX509, true);
4942  if( opCertX509 != NULL)
4943  {
4945  }
4946  else
4947  {
4949  return E_UNKNOWN;
4950  }
4951  }
4952  return E_SUCCESS;
4953 }
4954 
4956 {
4957  DOMElement *elemMixVerify;
4958  UINT8 tmpBuff[TMP_BUFF_SIZE];
4959  UINT32 tmpLen = TMP_BUFF_SIZE;
4960 
4961  if(elemCertificates == NULL) return E_UNKNOWN;
4963  (elemCertificates->getNodeName(), OPTIONS_NODE_MIX_CERTIFICATE_VERIFICATION);
4964 
4965  getDOMChildByName(elemCertificates, OPTIONS_NODE_MIX_CERTIFICATE_VERIFICATION, elemMixVerify, false);
4966  if(elemMixVerify != NULL)
4967  {
4968  if(getDOMElementValue(elemMixVerify, tmpBuff, &tmpLen) == E_SUCCESS &&
4969  memcmp(tmpBuff,"True",4)==0)
4970  {
4971  m_bVerifyMixCerts = true;
4973  CAMsg::printMsg(LOG_INFO, "Mix certificate verification is enabled.\n");
4974  }
4975  }
4976  return E_SUCCESS;
4977 }
4978 
4980  {
4981  //get Logging
4982  DOMElement* elemLogging=NULL;
4983  DOMElement* elemEncLog=NULL;
4984  DOMElement* elem=NULL;
4985 
4986  UINT8 tmpBuff[TMP_BUFF_SIZE];
4987  UINT32 tmpLen = TMP_BUFF_SIZE;
4988 
4989  SINT32 maxLogFilesTemp = 0;
4990  if(elemGeneral == NULL) return E_UNKNOWN;
4992  (elemGeneral->getNodeName(), OPTIONS_NODE_LOGGING);
4993 
4994  getDOMChildByName(elemGeneral, OPTIONS_NODE_LOGGING, elemLogging, false);
4995  if(elemLogging != NULL)
4996  {
4997  if (getDOMElementAttribute(elemLogging, "level", tmpBuff, &tmpLen) == E_SUCCESS)
4998  {
4999  strtrim(tmpBuff);
5000  toLower(tmpBuff);
5001  m_strLogLevel = new char[strlen((char*)tmpBuff)+1];
5002  strcpy(m_strLogLevel, (char*)tmpBuff);
5003  }
5004  else
5005  {
5006  m_strLogLevel = new char[strlen("debug")+1];
5007  strcpy(m_strLogLevel, "debug");
5008  }
5009 
5010 
5011 
5012  getDOMChildByName(elemLogging, OPTIONS_NODE_LOGGING_FILE, elem, false);
5013  tmpLen = TMP_BUFF_SIZE;
5014  if(getDOMElementValue(elem, tmpBuff, &tmpLen) == E_SUCCESS)
5015  {
5016  strtrim(tmpBuff);
5017  m_strLogDir = new char[strlen((char*)tmpBuff)+1];
5018  strcpy(m_strLogDir, (char*)tmpBuff);
5021  //Set maximum number of logging files
5022  //CAMsg::printMsg(LOG_ERR,"!!!!!!!!\n");
5024  (elem, OPTIONS_ATTRIBUTE_LOGGING_MAXFILES, &maxLogFilesTemp) != E_SUCCESS) ||
5025  (maxLogFilesTemp == 0) )
5026  {
5028  }
5029  else
5030  {
5031  if(maxLogFilesTemp < 0)
5032  {
5033  //CAMsg::printMsg(LOG_ERR,"Negative number of log files specified.\n");
5034  return E_UNKNOWN;
5035  }
5036  m_maxLogFiles = (UINT32) maxLogFilesTemp;
5037  //CAMsg::printMsg(LOG_ERR,"Max log files are %u\n", m_maxLogFiles);
5038  }
5039  }
5040  getDOMChildByName(elemLogging, OPTIONS_NODE_SYSLOG, elem, false);
5041  tmpLen = TMP_BUFF_SIZE;
5042  memset(tmpBuff, 0, tmpLen);
5043  if( (getDOMElementValue(elem, tmpBuff, &tmpLen) == E_SUCCESS) &&
5044  (memcmp(tmpBuff,"True",4) == 0) )
5045  {
5046  m_bSyslog = true;
5047  }
5048 
5049  getDOMChildByName(elemLogging, OPTIONS_NODE_LOGGING_CONSOLE, elem, false);
5050  tmpLen = TMP_BUFF_SIZE;
5051  memset(tmpBuff, 0, tmpLen);
5052  if( (getDOMElementValue(elem, tmpBuff, &tmpLen) == E_SUCCESS) &&
5053  (memcmp(tmpBuff,"True",4) == 0) )
5054  {
5055  m_bLogConsole = true;
5056  }
5057 
5058  //get Encrypted Log Info
5059  if( getDOMChildByName
5060  (elemLogging, OPTIONS_NODE_ENCRYPTED_LOG, elemEncLog,false) == E_SUCCESS )
5061  {
5062  m_bIsEncryptedLogEnabled = true;
5063  getDOMChildByName(elemEncLog, OPTIONS_NODE_LOGGING_FILE, elem, false);
5064 
5065  tmpLen = TMP_BUFF_SIZE;
5066  memset(tmpBuff, 0, tmpLen);
5067  if( getDOMElementValue(elem, tmpBuff, &tmpLen) == E_SUCCESS )
5068  {
5069  strtrim(tmpBuff);
5070  m_strEncryptedLogDir = new char[strlen((char*)tmpBuff)+1];
5071  strcpy(m_strEncryptedLogDir, (char*)tmpBuff);
5072  }
5073  DOMElement* elemKeyInfo;
5074  DOMElement* elemX509Data;
5076  (elemEncLog, OPTIONS_NODE_LOGGING_KEYINFO, elemKeyInfo, false) == E_SUCCESS &&
5078  (elemKeyInfo, OPTIONS_NODE_X509DATA, elemX509Data, false) == E_SUCCESS )
5079  {
5081  CACertificate::decode(elemX509Data->getFirstChild(), CERT_X509CERTIFICATE);
5082  }
5083  }
5084  else
5085  {
5087  }
5088 
5089  }
5090 
5091  SINT32 ret = initLogging();
5092  if (ret == E_SUCCESS)
5093  {
5095 #ifdef MIX_VERSION_TESTING
5097 #endif
5098  }
5099 
5100  return ret;
5101  }
5102 
5103 /***********************************
5104  * general option setter functions *
5105  ***********************************/
5107 {
5108  DOMElement* elemGeneral=NULL;
5109 
5111  elemGeneral,false) != E_SUCCESS)
5112  {
5114  return E_UNKNOWN;
5115  }
5116 
5118 
5120 #ifdef NO_ENCRYPTION
5122 #else
5123  #ifdef SYM_CHANNEL_CIPHER_CTR
5125  #else
5127  #endif
5129 #endif
5130  return ret;
5131 }
5132 
5133 SINT32 CACmdLnOptions::createSockets(bool a_bMessages, CASocket** a_sockets, UINT32 a_socketsLen)
5134 {
5135  if (a_socketsLen <= 0)
5136  {
5137  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.");
5138  return E_SPACE;
5139  }
5140 
5141 
5142  UINT32 aktSocket;
5143  UINT8 buff[255];
5144  SINT32 ret = E_UNKNOWN;
5145  UINT32 currentInterface;
5146  CASocketAddr* pAddr;
5147  UINT32* arrayVirtualPorts = new UINT32[a_socketsLen];
5148  UINT32 iVirtualPortsLen = 0;
5149  UINT32 iHiddenPortsLen = 0;
5150  UINT32* arrayHiddenPorts = new UINT32[a_socketsLen];
5151 
5152 
5153  aktSocket = 0;
5154  for (currentInterface = 0; currentInterface < getListenerInterfaceCount(); currentInterface++)
5155  {
5156  CAListenerInterface* pListener = NULL;
5157  pListener = getListenerInterface(currentInterface + 1);
5158  if (pListener == NULL)
5159  {
5160  CAMsg::printMsg(LOG_CRIT, "Error: Listener interface %d is invalid.\n", currentInterface + 1);
5161 
5162  delete[] arrayVirtualPorts;
5163  delete[] arrayHiddenPorts;
5164 
5165  return E_UNKNOWN;
5166  }
5167 
5168  pAddr = pListener->getAddr();
5169  pAddr->toString(buff, 255);
5170 
5171  if (pAddr->getType() == AF_INET)
5172  {
5173  if (pListener->isVirtual())
5174  {
5175  arrayVirtualPorts[iVirtualPortsLen] = ((CASocketAddrINet*)pAddr)->getPort();
5176  iVirtualPortsLen++;
5177  }
5178  else if (pListener->isHidden())
5179  {
5180  arrayHiddenPorts[iHiddenPortsLen] = ((CASocketAddrINet*)pAddr)->getPort();
5181  iHiddenPortsLen++;
5182  }
5183  }
5184 
5185  if (pListener->isVirtual())
5186  {
5187  delete pListener;
5188  pListener = NULL;
5189  delete pAddr;
5190  pAddr = NULL;
5191  continue;
5192  }
5193 
5194  if (a_socketsLen < aktSocket)
5195  {
5196  CAMsg::printMsg(LOG_CRIT,
5197  "Found %d listener sockets, but we have only reserved memory for %d sockets. This seems to be an implementation error in the code.\n",
5198  (aktSocket + 1), a_socketsLen);
5199 
5200  delete[] arrayVirtualPorts;
5201  delete[] arrayHiddenPorts;
5202  delete pAddr;
5203 
5204  return E_SPACE;
5205  }
5206 
5207  ret = E_SUCCESS;
5208  a_sockets[aktSocket] = new CASocket();
5209  a_sockets[aktSocket]->create(pAddr->getType());
5210  a_sockets[aktSocket]->setReuseAddr(true);
5211 
5212  delete pListener;
5213  pListener = NULL;
5214 #ifndef _WIN32
5215  //we have to be a temporary superuser if port <1024...
5216  int old_uid = -1;
5217 
5218  if (pAddr->getType() == AF_INET && ((CASocketAddrINet*)pAddr)->getPort() < 1024)
5219  {
5220  old_uid = geteuid();
5221  if (seteuid(0) == -1) //changing to root
5222  {
5223  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",
5224  currentInterface + 1, buff);
5225  }
5226  }
5227 #endif
5228  ret = a_sockets[aktSocket]->listen(*pAddr);
5229  delete pAddr;
5230  pAddr = NULL;
5231 
5232  if (ret != E_SUCCESS)
5233  {
5234  CAMsg::printMsg(LOG_CRIT, "Socket error while listening on interface %d (%s). Reason: %s (%i)\n", currentInterface + 1, buff,
5236  }
5237 
5238 #ifndef _WIN32
5239  if (old_uid != -1)
5240  {
5241  seteuid(old_uid);
5242  }
5243 #endif
5244  if(ret!=E_SUCCESS)
5245  {
5246  delete[] arrayVirtualPorts;
5247  delete[] arrayHiddenPorts;
5248  return E_UNKNOWN;
5249  }
5250 
5251  if (a_bMessages)
5252  {
5253  CAMsg::printMsg(LOG_DEBUG,"Listening on Interface: %s\n",buff);
5254  }
5255  aktSocket++;
5256  } //END FOR
5257 
5258  if (ret == E_UNKNOWN)
5259  {
5260  CAMsg::printMsg(LOG_CRIT,"Could not find any valid (non-virtual) listener interface!\n");
5261  }
5262  else if (ret == E_SUCCESS)
5263  { // This check is rather stupi as it does not reflect more complicated networking settings.
5264  //Only re-enable if you are really know what you are doing!
5265  /* for (UINT32 iHiddenPort = 0; iHiddenPort < iHiddenPortsLen; iHiddenPort++)
5266  {
5267  bool bVirtualFound = false;
5268  for (UINT32 iVirtualPort = 0; iVirtualPort < iVirtualPortsLen; iVirtualPort++)
5269  {
5270  if (arrayHiddenPorts[iHiddenPort] == arrayVirtualPorts[iVirtualPort])
5271  {
5272  bVirtualFound = true;
5273  arrayVirtualPorts[iVirtualPort] = 0;
5274  }
5275  }
5276  if (!bVirtualFound)
5277  {
5278  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]);
5279  ret = E_UNSPECIFIED;
5280  break;
5281  }
5282  }
5283 
5284  if (ret == E_SUCCESS)
5285  {
5286  for (UINT32 iVirtualPort = 0; iVirtualPort < iVirtualPortsLen; iVirtualPort++)
5287  {
5288  if (arrayVirtualPorts[iVirtualPort] != 0)
5289  {
5290  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]);
5291  ret = E_UNSPECIFIED;
5292  break;
5293  }
5294  }
5295 
5296  }
5297 */ }
5298 
5299  if (ret == E_SUCCESS && a_bMessages)
5300  {
5301  CAMsg::printMsg(LOG_DEBUG,"Listening on all interfaces.\n");
5302  }
5303 
5304  delete[] arrayVirtualPorts;
5305  delete[] arrayHiddenPorts;
5306  arrayVirtualPorts = NULL;
5307 
5308  return ret;
5309 }
5310 
5311 
5316 SINT32 CACmdLnOptions::setDynamicMix(DOMElement* elemGeneral)
5317 {
5318  // LERNGRUPPE
5319  // get Dynamic flag
5320  DOMElement* elemDynamic=NULL;
5321  UINT8 tmpBuff[TMP_BUFF_SIZE];
5322  UINT32 tmpLen = TMP_BUFF_SIZE;
5323  m_bDynamic = false;
5324 
5325  if(elemGeneral == NULL) return E_UNKNOWN;
5327  (elemGeneral->getNodeName(), OPTIONS_NODE_DYNAMIC_MIX);
5328 
5329  getDOMChildByName(elemGeneral, OPTIONS_NODE_DYNAMIC_MIX, elemDynamic, false);
5330  if(elemDynamic != NULL)
5331  {
5332  if(getDOMElementValue(elemDynamic, tmpBuff, &tmpLen)==E_SUCCESS)
5333  {
5334  m_bDynamic = (strcmp("True",(char*)tmpBuff) == 0);
5335  }
5336  }
5337  if(m_bDynamic)
5338  {
5339  CAMsg::printMsg( LOG_DEBUG, "I am a dynamic mix\n");
5340  }
5341  return E_SUCCESS;
5342 }
5343 
5344 
5345 SINT32 CACmdLnOptions::setInfoServices(DOMElement *elemNetwork)
5346 {
5347  UINT8 tmpBuff[TMP_BUFF_SIZE];
5348  UINT32 tmpLen = TMP_BUFF_SIZE;
5349  DOMElement* elemInfoServiceContainer=NULL;
5350 
5351  if(elemNetwork == NULL) return E_UNKNOWN;
5353  (elemNetwork->getNodeName(), OPTIONS_NODE_INFOSERVICE_LIST);
5354 
5356  (elemNetwork, OPTIONS_NODE_INFOSERVICE_LIST, elemInfoServiceContainer,false);
5357  if (elemInfoServiceContainer == NULL)
5358  {
5359  // old configuration version <= 0.61
5360  DOMElement* elemInfoService=NULL;
5361  DOMElement* elemAllowReconfig=NULL;
5362  if (getDOMChildByName
5363  (elemNetwork, OPTIONS_NODE_INFOSERVICE, elemInfoService, false) != E_SUCCESS)
5364  {
5366  }
5367  // LERNGRUPPE: There might not be any InfoService configuration in the file, but in infoservices.xml, so check this
5368  if(elemInfoService != NULL)
5369  {
5371  (elemInfoService, OPTIONS_NODE_ALLOW_AUTO_CONF, elemAllowReconfig, false);
5372  CAListenerInterface* isListenerInterface = CAListenerInterface::getInstance(elemInfoService);
5373  if (!isListenerInterface)
5374  {
5376  }
5377  else
5378  {
5381  m_addrInfoServices[0] = isListenerInterface;
5382  if(getDOMElementValue(elemAllowReconfig,tmpBuff,&tmpLen)==E_SUCCESS)
5383  {
5384  m_bAcceptReconfiguration = (strcmp("True",(char*)tmpBuff) == 0);
5385  }
5386  }
5387  }
5388  }
5389  else
5390  {
5391  // Refactored
5392  parseInfoServices(elemInfoServiceContainer);
5393  }
5394 
5395  return E_SUCCESS;
5396 }
5397 
5399 {
5400 #ifdef SERVER_MONITORING
5401 
5402  UINT8 tmpBuff[TMP_BUFF_SIZE];
5403  UINT32 tmpLen = TMP_BUFF_SIZE;
5404 
5405  DOMElement* elemServerMonitoringRoot = NULL;
5406  DOMElement* elemServerMonitoringHost = NULL;
5407  DOMElement* elemServerMonitoringPort = NULL;
5408 
5409  if(elemNetwork == NULL) return E_UNKNOWN;
5411  (elemNetwork->getNodeName(), OPTIONS_NODE_SERVER_MONITORING);
5412 
5413  m_strMonitoringListenerHost = NULL;
5414  m_iMonitoringListenerPort = 0xFFFF;
5415 
5416  if (getDOMChildByName
5417  (elemNetwork, OPTIONS_NODE_SERVER_MONITORING, elemServerMonitoringRoot,false) == E_SUCCESS)
5418  {
5420  (elemServerMonitoringRoot, OPTIONS_NODE_HOST, elemServerMonitoringHost, false) == E_SUCCESS)
5421  {
5422  if(getDOMElementValue(elemServerMonitoringHost,
5423  (UINT8 *)tmpBuff,&tmpLen)==E_SUCCESS)
5424  {
5425  m_strMonitoringListenerHost = new char[tmpLen+1];
5426  strncpy(m_strMonitoringListenerHost, (const char*) tmpBuff, tmpLen);
5427  m_strMonitoringListenerHost[tmpLen] = 0;
5428  }
5429  }
5431  (elemServerMonitoringRoot, OPTIONS_NODE_PORT,
5432  elemServerMonitoringPort, false) == E_SUCCESS)
5433  {
5434  UINT16 port = 0xFFFF;
5435  if(getDOMElementValue(elemServerMonitoringPort, &port)==E_SUCCESS)
5436  {
5437  m_iMonitoringListenerPort = port;
5438  }
5439  }
5440 
5441  // only non-local ListnerInterfaces are showed in Mix status info
5442  if( (elemServerMonitoringRoot != NULL) &&
5443  (m_strMonitoringListenerHost != NULL))
5444  {
5445  if( (strncmp("localhost", m_strMonitoringListenerHost, 9) != 0) &&
5446  (strncmp("127.0.0.1", m_strMonitoringListenerHost, 9) != 0) )
5447  {
5448  appendMixInfo_internal(elemServerMonitoringRoot, WITH_SUBTREE);
5449  }
5450  }
5451  }
5452  else
5453  {
5454  CAMsg::printMsg(LOG_DEBUG, "Server Monitoring Config not found\n");
5455  }
5456 #endif // SERVER_MONITORING
5457  return E_SUCCESS;
5458 }
5459 
5461 // * LERNGRUPPE
5462 // * Parses the \c InfoServices Node in a) a mix configuration or b) out of \c infoservices.xml
5463 // * (Code refactored from CACmdLnOptions::processXmlConfiguration
5464 // * @param a_infoServiceNode The \c InfoServices Element
5465 // * @retval E_SUCCESS
5466 //
5467 SINT32 CACmdLnOptions::parseInfoServices(DOMElement* a_infoServiceNode)
5468 {
5469  DOMElement* elemAllowReconfig;
5470  getDOMChildByName(a_infoServiceNode, OPTIONS_NODE_ALLOW_AUTO_CONF, elemAllowReconfig, false);
5471  DOMNodeList* isList = getElementsByTagName(a_infoServiceNode, OPTIONS_NODE_INFOSERVICE);
5472  // If there are no InfoServices in the file, keep the (hopefully) previously configured InfoServices
5473  if(isList->getLength() == 0)
5474  {
5475  return E_SUCCESS;
5476  }
5477  // If there are already InfoServices, delete them
5478  // ** @todo merge could be better...
5479  if(m_addrInfoServices!=NULL)
5480  {
5481  for(UINT32 i=0;i<m_addrInfoServicesSize;i++)
5482  {
5483  delete m_addrInfoServices[i];
5484  m_addrInfoServices[i] = NULL;
5485  }
5486  delete[] m_addrInfoServices;
5487  }
5489  m_addrInfoServices=NULL;
5490 
5491  UINT32 nrListenerInterfaces;
5492  m_addrInfoServices = new CAListenerInterface*[isList->getLength()];
5493  CAListenerInterface** isListenerInterfaces;
5494  for (UINT32 i = 0; i < isList->getLength(); i++)
5495  {
5496  //get ListenerInterfaces
5497  DOMElement* elemListenerInterfaces;
5498  getDOMChildByName(isList->item(i),CAListenerInterface::XML_ELEMENT_CONTAINER_NAME,elemListenerInterfaces,false);
5499  isListenerInterfaces = CAListenerInterface::getInstance(elemListenerInterfaces, nrListenerInterfaces);
5500  if (nrListenerInterfaces > 0)
5501  {
5502  // @todo Take more than one listener interface for a given IS...
5503  m_addrInfoServices[m_addrInfoServicesSize] = isListenerInterfaces[0];
5505  for (UINT32 j = 1; j < nrListenerInterfaces; j++)
5506  {
5507  // the other interfaces are not needed...
5508  delete isListenerInterfaces[j];
5509  isListenerInterfaces[j] = NULL;
5510  }
5511  }
5512  delete isListenerInterfaces;
5513  }
5514  UINT8 tmpBuff[255];
5515  UINT32 tmpLen=255;
5516  if(getDOMElementValue(elemAllowReconfig,tmpBuff,&tmpLen)==E_SUCCESS)
5517  {
5518  m_bAcceptReconfiguration = (strcmp("True",(char*)tmpBuff) == 0);
5519  }
5520 
5521  return E_SUCCESS;
5522 }
5523 
5525 {
5526  DOMElement* elemMinCascadeLength = NULL;
5527  if(elemGeneral == NULL) return E_UNKNOWN;
5529  (elemGeneral->getNodeName(), OPTIONS_NODE_MIN_CASCADE_LENGTH);
5530  //Inserting the min. cascade length if given...
5532  (elemGeneral, OPTIONS_NODE_MIN_CASCADE_LENGTH, elemMinCascadeLength, false);
5533  if(elemMinCascadeLength != NULL)
5534  {
5535  appendMixInfo_internal(elemMinCascadeLength, WITH_SUBTREE);
5536  }
5537  return E_SUCCESS;
5538 }
5539 
5540 // ***************************************
5541 // * ressource option setter function(s) *
5542 // * (delay options) *
5543 // ***************************************
5544 
5546 {
5547 #if defined (DELAY_CHANNELS) ||defined(DELAY_USERS)||defined(DELAY_CHANNELS_LATENCY)
5549  //this is at the moment:
5550  //<Ressources>
5551  //<UnlimitTraffic></UnlimitTraffic> #Number of bytes/packets without resource limitation
5552  //<BytesPerIntervall></BytesPerIntervall> #upper limit of number of bytes/packets which are processed per channel/per user per time intervall
5553  //<Intervall></Intervall> #duration of one intervall in ms
5554  //<Latency></Latency> #minimum Latency per channel in ms
5555  //</Ressources>
5556  CAMsg::printMsg(LOG_INFO,"Loading Parameters for traffic shaping / resource limitation....\n");
5557  UINT32 u32 = 0;
5558  DOMElement *elemRessources=NULL;
5559  DOMElement *elem = NULL;
5560 
5561  if(elemRoot == NULL)
5562  {
5563  return E_UNKNOWN;
5564  }
5565 
5566  getDOMChildByName(elemRoot, OPTIONS_NODE_RESSOURCES, elemRessources,false);
5567  if(elemRessources!=NULL)
5568  {
5569 #if defined (DELAY_CHANNELS) || defined(DELAY_USERS)
5570  if( getDOMChildByName
5571  (elemRessources, OPTIONS_NODE_UNLIMIT_TRAFFIC, elem, false) == E_SUCCESS &&
5572  getDOMElementValue(elem, &u32) == E_SUCCESS )
5573  {
5575  }
5576  if( getDOMChildByName
5577  (elemRessources, OPTIONS_NODE_BYTES_PER_IVAL, elem, false) == E_SUCCESS &&
5578  getDOMElementValue(elem, &u32) == E_SUCCESS)
5579  {
5581  }
5582  if( getDOMChildByName
5583  (elemRessources, OPTIONS_NODE_DELAY_IVAL, elem, false) == E_SUCCESS &&
5584  getDOMElementValue(elem, &u32) == E_SUCCESS)
5585  {
5587  }
5588 #endif
5589 #if defined (DELAY_CHANNELS_LATENCY)
5590  if( getDOMChildByName
5591  (elemRessources, OPTIONS_NODE_LATENCY, elem, false) == E_SUCCESS &&
5592  getDOMElementValue(elem, &u32) == E_SUCCESS)
5593  {
5594  m_u32DelayChannelLatency = u32;
5595  }
5596 #endif
5597  }
5598 #endif
5599  return E_SUCCESS;
5600 }
5601 
5602 
5603 #endif
5604 
5605 
#define CERT_PKCS12
#define CERT_X509CERTIFICATE
THREAD_RETURN threadReConfigure(void *param)
Thread that does the actual reconfigure work.
#define OPTIONS_VALUE_OPERATOR_NAME
#define OPTIONS_NODE_PROXY
#define OPTIONS_NODE_DELAY_IVAL
#define OPTIONS_NODE_CRIME_SURVEILLANCE_IP_NETMASK
#define OPTIONS_NODE_VISIBLE_ADDRESS
#define OPTIONS_ATTRIBUTE_LOGGING_MAXFILES
#define OPTIONS_NODE_TNCS_OPTS
#define OPTIONS_NODE_CRIME_DETECTION
#define OPTIONS_NODE_ALLOW_AUTO_CONF
#define OPTIONS_NODE_DESCRIPTION
#define OPTIONS_NODE_KEEP_ALIVE_SEND_IVAL
#define OPTIONS_NODE_PREV_OPERATOR_CERTIFICATE
#define OPTIONS_NODE_MIX_ID
#define OPTIONS_NODE_CERTIFICATE_LIST
#define OPTIONS_NODE_PROXY_LIST
#define DEFAULT_TARGET_PORT
#define OPTIONS_NODE_PRICE_CERTIFICATE
#define OPTIONS_NODE_DAEMON
#define OPTIONS_NODE_TNCS_OPERATOR
#define ASSERT_GENERAL_OPTIONS_PARENT(Parentname, Childname)
#define OPTIONS_NODE_IP
#define OPTIONS_NODE_PROXY_TYPE
#define OPTIONS_NODE_LOGGING_FILE
#define OPTIONS_NODE_ENCRYPTED_LOG
#define MIXINFO_NODE_MIX_NAME
#define MIXINFO_NODE_SOFTWARE
#define OPTIONS_NODE_AI_DB_PORT
#define OPTIONS_NODE_AI_DB_PASSW
#define TERMS_AND_CONDITIONS_OPTIONS_NR
#define OPTIONS_NODE_CREDENTIAL
#define OPTIONS_NODE_GENERAL
#define DEFAULT_CONFIG_FILE
#define OPTIONS_NODE_USER_ID
#define OPTIONS_NODE_SETTLE_IVAL
SINT32(CACmdLnOptions::* optionSetter_pt)(DOMElement *)
#define OPTIONS_NODE_NETWORK
#define LOG_NODE_EMPTY_OR_INVALID(Nodename)
#define OPTIONS_NODE_KEEP_ALIVE
#define OPTIONS_NODE_PORT
#define ASSERT_PARENT_NODE_NAME(Parentname, NameToMatch, Childname)
#define OPTIONS_NODE_FILE
#define OPTIONS_NODE_CRIME_REGEXP_URL
#define MIXINFO_NODE_PARENT
#define OPTIONS_ATTRIBUTE_TNC_ID
#define ASSERT_CRIME_DETECTION_OPTIONS_PARENT(Parentname, Childname)
#define OPTIONS_NODE_SYSLOG
#define OPTIONS_NODE_NEXT_MIX
#define MIXINFO_NODE_VERSION
#define OPTIONS_ATTRIBUTE_NAME_FOR_CASCADE
#define GENERAL_OPTIONS_NR
#define OPTIONS_NODE_AI_SOFT_LIMIT
#define OPTIONS_NODE_AI_DB_USER
#define OPTIONS_VALUE_MIX_NAME
#define OPTIONS_NODE_TNCS_TEMPLATES
#define OPTIONS_NODE_VISIBLE_ADDRESS_LIST
#define OPTIONS_NODE_PREV_MIX_CERTIFICATE
#define OPTIONS_NODE_CRIME_SURVEILLANCE_ACCOUNT
#define OPTIONS_NODE_OWN_CERTIFICATE
#define OPTIONS_NODE_CRIME_SURVEILLANCE_IP
#define OPTIONS_NODE_PAYMENT_INSTANCE
#define OPTIONS_NODE_AI_HARD_LIMIT
#define OPTIONS_NODE_LOGGING_KEYINFO
#define NETWORK_OPTIONS_NR
#define OPTIONS_NODE_TNCS
#define MAX_CERTIFICATE_OPTIONS_NR
#define OPTIONS_NODE_MAX_USERS
#define OPTIONS_NODE_HOST
#define OPTIONS_NODE_BYTES_PER_IVAL
#define OPTIONS_NODE_MIX_TYPE
#define OPTIONS_NODE_FD_NR
#define ACCOUNTING_OPTIONS_NR
#define OPTIONS_NODE_KEEP_ALIVE_RECV_IVAL
#define OPTIONS_NODE_RESSOURCES
#define OPTIONS_NODE_TRUSTED_ROOT_CERTIFICATES
#define MAIN_OPTION_SETTERS_NR
#define ASSERT_ACCOUNTING_OPTIONS_PARENT(Parentname, Childname)
#define MIN_INFOSERVICES
#define OPTIONS_NODE_AI_DB_HOST
#define ASSERT_NETWORK_OPTIONS_PARENT(Parentname, Childname)
#define OPTIONS_NODE_CRIME_REGEXP_PAYLOAD
#define OPTIONS_NODE_NEXT_MIX_CERTIFICATE
#define OPTIONS_NODE_PREPAID_IVAL
#define OPTIONS_NODE_ACCOUNTING
#define LOG_NODE_NOT_FOUND(Nodename)
#define OPTIONS_NODE_X509_PKCS12
#define OPTIONS_NODE_LOGGING_CONSOLE
#define OPTIONS_NODE_LOGGING
#define LOGGING_MAXFILES_DEFAULT
#define OPTIONS_NODE_PREPAID_IVAL_KB
#define OPTIONS_NODE_TNCS_TRANSLATION_IMPORTS
#define OPTIONS_NODE_INFOSERVICE
#define OPTIONS_NODE_LATENCY
#define OPTIONS_ATTRIBUTE_TNC_DATE
#define OPTIONS_NODE_CASCADE_NAME
#define MIXINFO_NODE_PAYMENTREMINDER
#define OPTIONS_NODE_UNLIMIT_TRAFFIC
#define OPTIONS_NODE_INFOSERVICE_LIST
#define OPTIONS_NODE_OWN_OPERATOR_CERTIFICATE
#define OPTIONS_NODE_NETWORK_PROTOCOL
#define OPTIONS_NODE_LISTENER_INTERFACE_LIST
#define OPTIONS_NODE_SERVER_MONITORING
#define OPTIONS_NODE_TNCS_TEMPLATE
#define WITH_SUBTREE
#define OPTIONS_NODE_X509_CERTIFICATE
#define OPTIONS_NODE_NEXT_OPERATOR_CERTIFICATE
#define OPTIONS_NODE_MIX_CERTIFICATE_VERIFICATION
#define OPTIONS_NODE_MIX_NAME
#define OPTIONS_ATTRIBUTE_LOGGING_MAXFILESIZE
#define OPTIONS_NODE_AI_DB_NAME
#define OPTIONS_NODE_AI_DB
#define REGEXP_BUFF_SIZE
#define OPTIONS_NODE_DYNAMIC_MIX
#define OPTIONS_NODE_PAYMENT_REMINDER
#define OPTIONS_NODE_MIN_CASCADE_LENGTH
#define OPTIONS_NODE_LISTENER_INTERFACE
SINT32 setRegExpressions(DOMElement *rootElement, const char *const childElementName, tre_regex_t **regExContainer, UINT32 *regExNr)
#define OPTIONS_ATTRIBUTE_TNC_LOCALE
#define MIXINFO_ATTRIBUTE_MIX_ID
#define OPTIONS_ATTRIBUTE_TNC_DEFAULT_LANG_DEFINED
#define OPTIONS_ATTRIBUTE_TNC_TEMPLATE_REFID
#define ASSERT_CERTIFICATES_OPTIONS_PARENT(Parentname, Childname)
#define OPTIONS_NODE_TNCS_TRANSLATION
#define OPTIONS_NODE_X509DATA
#define OPTIONS_NODE_LISTENER_INTERFACES
#define OPTIONS_DEFAULT_PREPAID_IVAL
#define OPTIONS_NODE_SIGNATURE
#define OPTIONS_ATTRIBUTE_LOG_PAYLOAD
#define MSG_FILE
Definition: CAMsg.hpp:36
#define MSG_NOLOG
Definition: CAMsg.hpp:33
#define MSG_LOG
Definition: CAMsg.hpp:35
#define MSG_STDOUT
Definition: CAMsg.hpp:34
#define MSG_COMPRESSED_FILE
Definition: CAMsg.hpp:37
#define SIGKEY_PKCS12
Definition: CASignature.hpp:32
SYMCHANNELCIPHER_ALGORITHM
@ NULL_CIPHER
SINT32 setDOMElementAttribute(DOMNode *pElem, const char *attrName, const char *value)
Definition: CAUtil.cpp:831
SINT32 getcurrentTimeMillis(UINT64 &u64Time)
Gets the current Systemtime in milli seconds.
Definition: CAUtil.cpp:252
SINT32 getDOMElementValue(const DOMNode *const pElem, UINT8 *value, UINT32 *valuelen)
Returns the content of the text node(s) under elem as null-terminated C String.
Definition: CAUtil.cpp:746
SINT32 setDOMElementValue(DOMElement *pElem, SINT32 value)
Definition: CAUtil.cpp:939
SINT32 readPasswd(UINT8 *buff, UINT32 len)
Read a passwd (i.e.
Definition: CAUtil.cpp:1473
UINT32 strtrim(UINT8 *s)
Removes leading and ending whitespaces (chars<=32) from a zero terminated string.
Definition: CAUtil.cpp:49
bool equals(const XMLCh *const e1, const char *const e2)
Definition: CAUtil.cpp:645
UINT8 * getTermsAndConditionsTemplateRefId(DOMNode *tcTemplateRoot)
Definition: CAUtil.cpp:865
XERCES_CPP_NAMESPACE::DOMDocument * parseDOMDocument(const UINT8 *const buff, UINT32 len)
Parses a buffer containing an XML document and returns this document.
Definition: CAUtil.cpp:663
DOMNodeList * getElementsByTagName(DOMElement *pElem, const char *const name)
Definition: CAUtil.cpp:1711
SINT32 getRandom(UINT32 *val)
Gets 32 random bits.
Definition: CAUtil.cpp:346
XERCES_CPP_NAMESPACE::DOMDocument * createDOMDocument()
Parses a timestamp in JDBC timestamp escape format (as it comes from the BI) and outputs the value in...
Definition: CAUtil.cpp:1568
DOMElement * createDOMElement(XERCES_CPP_NAMESPACE::DOMDocument *pOwnerDoc, const char *const name)
Creates a new DOMElement with the given name which belongs to the DOMDocument owernDoc.
Definition: CAUtil.cpp:814
SINT32 getDOMChildByName(const DOMNode *pNode, const char *const name, DOMElement *&child, bool deep)
Definition: CAUtil.cpp:458
UINT32 toLower(UINT8 *a_string)
Definition: CAUtil.cpp:74
SINT32 getDOMElementAttribute(const DOMNode *const elem, const char *attrName, UINT8 *value, UINT32 *len)
Definition: CAUtil.cpp:780
SINT32 integrateDOMNode(const DOMNode *srcNode, DOMNode *dstNode, bool recursive, bool replace)
integrates the source node in the destination Node.
Definition: CAUtil.cpp:533
void setZero64(UINT64 &op1)
Definition: CAUtil.hpp:355
#define TMP_LOCALE_SIZE
Definition: CAUtil.hpp:39
SINT32 filesize32(int handle)
Definition: CAUtil.hpp:102
void print64(UINT8 *buff, UINT64 num)
Definition: CAUtil.hpp:482
#define TEMPLATE_REFID_MAXLEN
Definition: CAUtil.hpp:42
#define UNIVERSAL_NODE_LAST_UPDATE
Definition: CAUtil.hpp:33
#define TMP_BUFF_SIZE
Definition: CAUtil.hpp:38
#define TMP_DATE_SIZE
Definition: CAUtil.hpp:40
#define KEEP_ALIVE_TRAFFIC_RECV_WAIT_TIME
Definition: StdAfx.h:178
#define GET_NET_ERROR
Definition: StdAfx.h:469
#define DELAY_USERS_BUCKET_GROW
Definition: StdAfx.h:160
#define MIX_VERSION
Definition: StdAfx.h:36
#define KEEP_ALIVE_TRAFFIC_SEND_WAIT_TIME
Definition: StdAfx.h:180
#define GET_NET_ERROR_STR(x)
Definition: StdAfx.h:471
#define THREAD_RETURN
Definition: StdAfx.h:540
#define LAST_MIX_TO_PROXY_CONNECT_TIMEOUT
Definition: StdAfx.h:198
#define DELAY_CHANNEL_LATENCY
Definition: StdAfx.h:169
#define THREAD_RETURN_SUCCESS
Definition: StdAfx.h:542
#define MIX_VERSION_INFO
Definition: StdAfx.h:761
#define DEFAULT_INFOSERVICE
Definition: StdAfx.h:240
#define MIX_VERSION_TESTING_TEXT
Definition: StdAfx.h:41
#define DELAY_USERS_BUCKET_GROW_INTERVALL
Definition: StdAfx.h:159
#define DELAY_USERS_TRAFFIC
Definition: StdAfx.h:154
unsigned short UINT16
Definition: basetypedefs.h:133
signed int SINT32
Definition: basetypedefs.h:132
unsigned char UINT8
Definition: basetypedefs.h:135
unsigned int UINT32
Definition: basetypedefs.h:131
UINT32 getNumber()
Definition: CACertStore.hpp:49
SINT32 add(CACertificate *cert)
Adds a COPY of a given certifcate to this CertStore.
Definition: CACertStore.cpp:60
SINT32 encode(UINT8 *buff, UINT32 *bufflen, UINT32 type) const
SINT32 getAuthorityKeyIdentifier(UINT8 *r_aki, UINT32 *r_akiLen) const
SINT32 verify(const CACertificate *a_cert) const
SINT32 getSubjectKeyIdentifier(UINT8 *r_ski, UINT32 *r_skiLen)
LERNGRUPPE Accessor method for the subjectKeyIdentifier (SKI) extension stored in this certificate.
SINT32 getRawSubjectKeyIdentifier(UINT8 *r_ski, UINT32 *r_skiLen)
static CACertificate * decode(const UINT8 *const buff, UINT32 bufflen, UINT32 type, const char *const passwd=NULL)
Extracts a certificate from an encoded (DER,XML) form.
UINT8 * m_strAccessControlCredential
SINT32 getAiID(UINT8 *id, UINT32 len)
SINT32 setPrevMixCertificate(DOMElement *elemCertificates)
SINT32 setMixName(DOMElement *elemGeneral)
SINT32 getDatabaseName(UINT8 *name, UINT32 len)
UINT32 getListenerInterfaceCount()
UINT8 * m_strDatabaseName
friend THREAD_RETURN threadReConfigure(void *param)
Thread that does the actual reconfigure work.
SINT32 getCredential(UINT8 *name, UINT32 len)
SINT32 processXmlConfiguration(XERCES_CPP_NAMESPACE::DOMDocument *docConfig)
XERCES_CPP_NAMESPACE::DOMDocument * m_docMixXml
CACertificate * m_pLogEncryptionCertificate
UINT32 m_nCertificateOptionsSetters
UINT32 m_addrInfoServicesSize
SINT32 createSockets(bool a_bPrintMessages, CASocket **a_sockets, UINT32 a_socketsLen)
SINT32 setNextMix(XERCES_CPP_NAMESPACE::DOMDocument *pDoc)
Modifies the next mix settings (target interface and certificate) according to the specified options ...
UINT32 getDelayChannelBucketGrow()
SINT32 getDatabasePassword(UINT8 *pass, UINT32 len)
SINT32 setGeneralOptions(DOMElement *elemRoot)
SINT32 setAccountingOptions(DOMElement *elemRoot)
optionSetter_pt * mainOptionSetters
SINT32 setMaxUsers(DOMElement *elemGeneral)
UINT8 * m_strDatabasePassword
SINT32 parse(int argc, const char **arg)
SINT32 setKeepAliveTraffic(DOMElement *elemNetwork)
SINT32 getMixHost(UINT8 *host, UINT32 len)
SINT32 getMixId(UINT8 *id, UINT32 len)
SINT32 setAccessControlCredential(DOMElement *elemGeneral)
DOMElement * getTermsAndConditions()
SINT32 setMixDescription(DOMElement *elemRoot)
XERCES_CPP_NAMESPACE::DOMDocument ** m_termsAndConditionsTemplates
void clean()
Deletes all resssource allocated by objects of this class EXPECT the locks necessary to controll acce...
DOMNodeList * m_opCertList
SYMCHANNELCIPHER_ALGORITHM m_algSymChannelCipher
SINT32 setMixType(DOMElement *elemGeneral)
determines whether this mix is a first a middle or a last mix appears in <General></General> and must...
SINT32 reread(CAMix *pMix)
Rereads the configuration file (if one was given on startup) and reconfigures the mix according to th...
CACertificate * m_pPrevMixCertificate
optionSetter_pt * generalOptionSetters
void initAccountingOptionSetters()
XERCES_CPP_NAMESPACE::DOMDocument * m_docOpTnCs
CACertificate * m_OpCert
bool hasPrevMixTestCertificate()
optionSetter_pt * certificateOptionSetters
UINT32 getDelayChannelBucketGrowIntervall()
SINT32 setTrustedRootCertificates(DOMElement *elemCertificates)
SINT32 setCertificateOptions(DOMElement *elemRoot)
UINT8 * m_strDatabaseUser
SINT32 getCascadeName(UINT8 *name, UINT32 len) const
CAThread m_threadReConfigure
SINT32 parseInfoServices(DOMElement *a_infoServiceNode)
**
bool isEncryptedLogEnabled()
Returns if the encrpyted Log could/should be used.
void initNetworkOptionSetters()
SINT32 setTermsAndConditionsList(DOMElement *elemTnCs)
char * m_strEncryptedLogDir
SINT32 setTermsAndConditionsTemplates(DOMElement *elemTnCs)
static SINT32 buildDefaultConfig(XERCES_CPP_NAMESPACE::DOMDocument *a_doc, bool bForLastMix)
Creates a default mix configuration.
SINT32 setLogDir(const UINT8 *name, UINT32 len)
char * m_dbCountryStatsHost
SINT32 setDaemonMode(DOMElement *elemGeneral)
void initTermsAndConditionsOptionSetters()
SINT32 setDynamicMix(DOMElement *elemGeneral)
determines whether this mix is a dynamic mix or not appears in <General></General> and is optional.
UINT32 getNumberOfTermsAndConditionsTemplates()
Get the XML describing the Mix.
CAListenerInterface ** m_arListenerInterfaces
SINT32 setPrevMix(XERCES_CPP_NAMESPACE::DOMDocument *pDoc)
Modifies the next mix settings (target interface and certificate) according to the specified options ...
SINT32 clearVisibleAddresses()
CAXMLPriceCert * m_pPriceCertificate
SINT32 setNetworkOptions(DOMElement *elemRoot)
SINT32 setSettleInterval(DOMElement *elemAccounting)
SINT32 setNewValues(CACmdLnOptions &newOptions)
Copies options from newOptions.
SINT32 setTermsAndConditions(DOMElement *elemRoot)
static SINT32 createMixOnCDConfiguration(const UINT8 *strFileName)
Writes a default configuration file into the file named by filename.
SINT32 getPidFile(UINT8 *pidfile, UINT32 len)
SINT32 readXmlConfiguration(XERCES_CPP_NAMESPACE::DOMDocument *&docConfig, const UINT8 *const configFileName)
Tries to read the XML configuration file configFile and parses (but not process) it.
UINT32 m_cnListenerInterfaces
SINT32 setServerMonitoring(DOMElement *elemNetwork)
SINT32 getSOCKSHost(UINT8 *host, UINT32 len)
SINT32 setNrOfFileDescriptors(DOMElement *elemGeneral)
UINT8 * m_strDatabaseHost
char * m_dbCountryStatsPasswd
SINT32 getUser(UINT8 *user, UINT32 len)
UINT32 getMaxNrOfUsers()
CACertStore * m_pTrustedRootCertificates
void initGeneralOptionSetters()
SINT32 setAccountingSoftLimit(DOMElement *elemAccounting)
optionSetter_pt * m_arpTermsAndConditionsOptionSetters
SINT32 setOwnCertificate(DOMElement *elemCertificates)
UINT32 getDelayChannelUnlimitTraffic()
void initCertificateOptionSetters()
UINT32 m_iPaymentSettleInterval
UINT8 * m_strCascadeName
UINT32 m_u32KeepAliveRecvInterval
UINT16 getDatabasePort()
UINT32 getPaymentSettleInterval()
UINT32 m_u32DelayChannelBucketGrow
SINT32 setMixCertificateVerification(DOMElement *elemCertificates)
UINT32 m_iPaymentSoftLimit
UINT32 m_u32DelayChannelBucketGrowIntervall
SINT32 setAccountingDatabase(DOMElement *elemAccounting)
SINT32 getCountryStatsDBConnectionLoginData(char **db_host, char **db_user, char **db_passwd)
SINT32 getDatabaseHost(UINT8 *host, UINT32 len)
void initMainOptionSetters()
UINT32 getPrepaidInterval()
SINT32 setCascadeNameFromOptions(DOMElement *elemGeneral)
SINT32 getEncryptedLogDir(UINT8 *name, UINT32 len)
SINT32 addVisibleAddresses(DOMNode *nodeProxy)
** Add all the visible addresses to the list of visible addresses found in the XML description of the...
SINT32 getOperatorSubjectKeyIdentifier(UINT8 *buffer, UINT32 *length)
Returns a COPY of the public test certifcate for that mix.
SINT32 getLogDir(UINT8 *name, UINT32 len)
CAListenerInterface * getListenerInterface(UINT32 nr)
UINT32 m_iPaymentHardLimit
SINT32 m_PaymentReminderProbability
SINT32 setInfoServices(DOMElement *elemNetwork)
CAMutex * m_pcsReConfigure
SINT32 setMixID(DOMElement *elemGeneral)
SINT32 clearListenerInterfaces()
SINT32 appendMixInfo_internal(DOMNode *a_node, bool with_subtree)
SINT32 setLoggingOptions(DOMElement *elemGeneral)
CATargetInterface * m_arTargetInterfaces
SINT32 setAccountingHardLimit(DOMElement *elemAccounting)
CAListenerInterface ** m_addrInfoServices
XERCES_CPP_NAMESPACE::DOMDocument ** getAllTermsAndConditionsTemplates()
SINT32 setTargetInterfaces(DOMElement *elemNetwork)
This method sets the proxy or next mix settings.
SINT32 getDatabaseUsername(UINT8 *user, UINT32 len)
UINT8 ** m_arStrVisibleAddresses
SINT32 setPriceCertificate(DOMElement *elemAccounting)
SINT32 setPaymentReminder(DOMElement *elemGeneral)
SINT32 setNextMixCertificate(DOMElement *elemCertificates)
UINT32 getPaymentHardLimit()
UINT32 m_nrOfTermsAndConditionsTemplates
UINT16 getSOCKSServerPort()
SYMCHANNELCIPHER_ALGORITHM getSymChannelCipherAlgorithm() const
SINT32 setRessourceOptions(DOMElement *elemRoot)
UINT32 getPaymentSoftLimit()
CAMultiSignature * m_pMultiSignature
DOMElement * m_pCascadeXML
optionSetter_pt * accountingOptionSetters
UINT32 m_u32KeepAliveSendInterval
SINT32 setSymChannelCipherAlgorithm(SYMCHANNELCIPHER_ALGORITHM cipherAlgorithm)
XERCES_CPP_NAMESPACE::DOMDocument * m_docMixInfo
optionSetter_pt * networkOptionSetters
SINT32 addMixIdToMixInfo()
Just add the id of the Mix to the MixInfo Document.
SINT32 setCascadeName(const UINT8 *name)
static SINT32 saveToFile(XERCES_CPP_NAMESPACE::DOMDocument *a_doc, const UINT8 *a_strFileName)
Saves the given XML Document to a file.
UINT32 m_u32DelayChannelUnlimitTraffic
bool getCompressLogs()
ONLY_LOCAL_PROXY or first mix.
SINT32 invokeOptionSetters(const optionSetter_pt *optionsSetters, DOMElement *target, SINT32 optionsSettersLength)
framework-function for calling predefined option setter functions.
CAXMLBI * getBI()
Returns an CAXMLBI object, which describes the BI this AI uses.
UINT32 getTargetInterfaceCount()
SINT32 setPrepaidInterval(DOMElement *elemAccounting)
SINT32 getAccessControlCredential(UINT8 *outbuff, UINT32 *outbuffsize)
SINT32 setPaymentInstance(DOMElement *elemAccounting)
bool verifyMixCertificates()
UINT32 m_cnVisibleAddresses
SINT32 setUserID(DOMElement *elemGeneral)
SINT32 setListenerInterfaces(DOMElement *elemNetwork)
SINT32 getMixXml(XERCES_CPP_NAMESPACE::DOMDocument *&docMixInfo)
Returns the XML tree describing the Mix .
SINT32 setMinCascadeLength(DOMElement *elemGeneral)
SINT32 getVisibleAddress(UINT8 *strAddressBuff, UINT32 len, UINT32 nr)
Fills strAddressBuff with a outside visible adress.
SINT32 setOwnOperatorCertificate(DOMElement *elemCertificates)
SINT32 clearTargetInterfaces()
UINT32 getVisibleAddressesCount()
bool m_bLocalProxy
ONLY_LOCAL_PROXY or first.
CAListenerInterface ** getInfoServices(UINT32 &r_size)
SINT32 getTargetInterface(CATargetInterface &oTargetInterface, UINT32 nr)
Fills a TargetInterface struct with the values which belongs to the target interface nr.
char * m_dbCountryStatsUser
CACertificate * m_pNextMixCertificate
static const char * XML_ELEMENT_CONTAINER_NAME
CASocketAddr * getAddr() const
static const char * XML_ELEMENT_NAME
static CAListenerInterface * getInstance(const DOMNode *node)
Definition: CAMix.hpp:49
virtual SINT32 reconfigure()
Definition: CAMix.hpp:65
tMixType
Definition: CAMix.hpp:52
@ LAST_MIX
Definition: CAMix.hpp:55
@ FIRST_MIX
Definition: CAMix.hpp:53
@ MIDDLE_MIX
Definition: CAMix.hpp:54
static SINT32 init()
Definition: CAMsg.hpp:69
static SINT32 openEncryptedLog()
Open a log, where the logged messages are store encrypted.
Definition: CAMsg.cpp:520
static SINT32 setLogOptions(UINT32 options)
Definition: CAMsg.cpp:161
static SINT32 setLogLevel(UINT32 a_logLevel)
Definition: CAMsg.cpp:127
static SINT32 printMsg(UINT32 typ, const char *format,...)
Writes a given message to the log.
Definition: CAMsg.cpp:251
SINT32 addSignature(CASignature *a_signature, CACertStore *a_certs, UINT8 *a_ski, UINT32 a_skiLen)
SINT32 getXORofSKIs(UINT8 *out, UINT32 outlen)
static SINT32 verifyXML(const UINT8 *const in, UINT32 inlen, CACertificate *a_cert)
SINT32 findSKI(const UINT8 *a_strSKI)
SINT32 getVerifyKey(CACertificate **)
Get the public key as XML encoded X509 certificate.
SINT32 generateSignKey(UINT32 size)
Definition: CASignature.cpp:90
SINT32 setSignKey(const UINT8 *buff, UINT32 len, UINT32 type, const char *passwd=NULL)
SINT32 getSignKey(DOMElement *&node, XERCES_CPP_NAMESPACE::DOMDocument *doc)
Gets the secret sign key as XML encode PKCS#12 struct.
This is an abstract class for representing a socket address used in CASocket, CADatagramSocket and CA...
virtual SINT32 getType() const =0
The type (family) of socket for which this address is useful.
virtual CASocketAddr * clone() const =0
Creates a copy of the Address.
virtual SINT32 toString(UINT8 *buff, UINT32 bufflen) const =0
Returns a string which describes this address in a human readable form.
This class represents a socket address for Internet (IP) connections.
SINT32 getHostName(UINT8 *buff, UINT32 len) const
Returns the hostname for this address.
UINT16 getPort() const
Returns the port value of the address.
This is a class for Unix Domain Protocol Sockat Addresses.
CASocketAddr * clone() const
Creates a new copy of this address.
virtual SINT32 listen(const CASocketAddr &psa)
Starts listening on address psa.
Definition: CASocket.cpp:142
virtual SINT32 setSendTimeOut(UINT32 msTimeOut)
Definition: CASocket.cpp:883
virtual SINT32 setRecvBuff(UINT32 r)
Definition: CASocket.cpp:846
virtual SINT32 setReuseAddr(bool b)
Definition: CASocket.cpp:839
virtual SINT32 setSendBuff(SINT32 r)
Returns < 0 on error, otherwise the new sendbuffersize (which may be less than r)
Definition: CASocket.cpp:862
virtual SINT32 create()
Definition: CASocket.cpp:73
virtual SINT32 close()
Definition: CASocket.cpp:351
virtual SINT32 connect(const CASocketAddr &psa)
Definition: CASocket.hpp:64
static const UINT8 *const getAlgorithmName(SYMCHANNELCIPHER_ALGORITHM alg)
SINT32 set(TargetType target_t, NetworkType net_t, CASocketAddr *p_addr)
SINT32 start(void *param, bool bDaemon=false, bool bSilent=false)
Starts the execution of the main function of this thread.
Definition: CAThread.cpp:115
SINT32 setMainLoop(THREAD_MAIN_TYP fnc)
Sets the main function which will be executed within this thread.
Definition: CAThread.hpp:148
static SINT32 dumpToMem(const DOMNode *node, UINT8 *buff, UINT32 *size)
Dumps the node and all childs into buff.
Definition: DOM_Output.hpp:161
#define O_BINARY
Definition: config.h:179
const SINT32 E_SUCCESS
Definition: errorcodes.hpp:2
#define E_SPACE
Definition: errorcodes.hpp:7
#define E_FILE_OPEN
Definition: errorcodes.hpp:19
#define E_FILE_READ
Definition: errorcodes.hpp:20
#define E_XML_PARSE
Definition: errorcodes.hpp:21
#define E_UNKNOWN
Definition: errorcodes.hpp:3
#define E_UNSPECIFIED
Definition: errorcodes.hpp:6
#define POPT_ERROR_BADOPT
Definition: popt.cpp:718
int poptGetNextOpt(poptContext con)
Definition: popt.cpp:407
void poptFreeContext(poptContext con)
Definition: popt.cpp:654
poptContext poptGetContext(const char *name, int argc, const char **argv, const struct poptOption *options, int flags)
Definition: popt.cpp:51
#define POPT_ARG_INT
Definition: popt.h:18
#define POPT_ARG_NONE
Definition: popt.h:16
#define POPT_ARG_STRING
Definition: popt.h:17
#define POPT_AUTOHELP
Definition: popt.h:66
CAMix * pMix
Definition: proxytest.cpp:75
CACmdLnOptions * pCmdLnOptions
TargetType
Definition: typedefs.hpp:32
@ TARGET_VPN_PROXY
Definition: typedefs.hpp:32
@ TARGET_UNKNOWN
Definition: typedefs.hpp:32
@ TARGET_SOCKS_PROXY
Definition: typedefs.hpp:32
@ TARGET_HTTP_PROXY
Definition: typedefs.hpp:32
@ TARGET_MIX
Definition: typedefs.hpp:32
NetworkType
Definition: typedefs.hpp:30
@ RAW_TCP
Definition: typedefs.hpp:30
@ SSL_TCP
Definition: typedefs.hpp:30
@ RAW_UNIX
Definition: typedefs.hpp:30
@ SSL_UNIX
Definition: typedefs.hpp:30
@ UNKNOWN_NETWORKTYPE
Definition: typedefs.hpp:30
UINT8 type
Definition: typedefs.hpp:1
UINT16 len
Definition: typedefs.hpp:0