Mixe for Privacy and Anonymity in the Internet
CAMsg.cpp
Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2000, The JAP-Team
00003 All rights reserved.
00004 Redistribution and use in source and binary forms, with or without modification,
00005 are permitted provided that the following conditions are met:
00006 
00007   - Redistributions of source code must retain the above copyright notice,
00008     this list of conditions and the following disclaimer.
00009 
00010   - Redistributions in binary form must reproduce the above copyright notice,
00011     this list of conditions and the following disclaimer in the documentation and/or
00012     other materials provided with the distribution.
00013 
00014   - Neither the name of the University of Technology Dresden, Germany nor the names of its contributors
00015     may be used to endorse or promote products derived from this software without specific
00016     prior written permission.
00017 
00018 
00019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
00020 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
00021 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS
00022 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00023 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00024 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
00025 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00026 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00027 */
00028 #include "StdAfx.h"
00029 #include "CAMsg.hpp"
00030 #include "CACmdLnOptions.hpp"
00031 #include "CAASymCipher.hpp"
00032 #include "CASymCipher.hpp"
00033 #include "CAUtil.hpp"
00034 #include "CABase64.hpp"
00035 #include "CALibProxytest.hpp"
00036 
00037 #define FILENAME_ENCRYPTEDLOG "/encrypted_messages"
00038 #define FILENAME_INFOLOG "/messages"
00039 #define FILENAME_INFOLOG_GZ "/messages.gz"
00040 
00041 #define MAX_MSG_SIZE 8192
00042 
00043 CAMsg* CAMsg::pMsg=NULL;
00044 
00045 const char* const CAMsg::m_strMsgTypes[6]={", error   ] ",", critical] ",", info    ] ",", debug   ] ",", special ] ",", warning ] "}; //all same size!
00046 #define STRMSGTYPES_SIZE 12
00047 
00048 
00049 CAMsg::CAMsg()
00050     {
00051       m_pcsPrint=new CAMutex();
00052       m_logLevel = LOG_DEBUG;
00053       setZero64(m_maxLogFileSize);
00054       m_strMsgBuff=new char[MAX_MSG_SIZE+1+20+STRMSGTYPES_SIZE];
00055       m_uLogType=MSG_STDOUT;
00056       m_hFileInfo=-1;
00057       m_hFileEncrypted=-1;
00058       m_strLogFile=new char[1024];
00059       m_strMsgBuff[0]='[';
00060 #ifdef COMPRESSED_LOGS
00061       m_gzFileInfo=NULL;
00062 #endif
00063       m_pCipher=NULL;
00064       m_lastLogFileNumber = 0;
00065       m_alreadyOpened = false;
00066     }
00067 
00068 CAMsg::~CAMsg()
00069     {
00070       closeLog();
00071 #ifndef ONLY_LOCAL_PROXY
00072       closeEncryptedLog();
00073 #endif
00074       delete[] m_strMsgBuff;
00075       m_strMsgBuff = NULL;
00076       delete[] m_strLogFile;
00077       m_strLogFile = NULL;
00078       delete m_pcsPrint;
00079       m_pcsPrint = NULL;
00080     }
00081 
00082 char* CAMsg::createLogFileMessage(UINT32 opt)
00083 {
00084   const char* strLogAtPath = " at path '%s'";
00085   char* strLogFile = NULL;
00086   
00087   
00088   if ((opt & MSG_FILE) == MSG_FILE || (opt & MSG_COMPRESSED_FILE) == MSG_COMPRESSED_FILE)
00089   {
00090     if (pMsg->m_strLogFile != NULL)
00091     {
00092       strLogFile = new char[strlen(strLogAtPath) + strlen(pMsg->m_strLogFile) + 1];
00093       sprintf(strLogFile, strLogAtPath, pMsg->m_strLogFile);
00094     }
00095   }
00096   if (strLogFile == NULL)
00097   {
00098     strLogFile = new char[1];
00099     strLogFile[0] = '\0';
00100   }
00101   return strLogFile;
00102 }
00103 
00104 char* CAMsg::createLogDirMessage(UINT32 opt)
00105 {
00106   const char* strLogAtPath = " Please also check if the directory '%s' exists and create or change it if it does not.";
00107   char* strLogFile = NULL;
00108 
00109 
00110   if ((opt & MSG_FILE) == MSG_FILE || (opt & MSG_COMPRESSED_FILE) == MSG_COMPRESSED_FILE)
00111   {
00112     if (pMsg->m_strLogDir != NULL)
00113     {
00114       strLogFile = new char[strlen(strLogAtPath) + strlen(pMsg->m_strLogDir) + 1];
00115       sprintf(strLogFile, strLogAtPath, pMsg->m_strLogDir);
00116     }
00117   }
00118   if (strLogFile == NULL)
00119   {
00120     strLogFile = new char[1];
00121     strLogFile[0] = '\0';
00122   }
00123   return strLogFile;
00124 }
00125 
00126 
00127 SINT32 CAMsg::setLogLevel(UINT32 a_logLevel)
00128 {
00129   if (a_logLevel == LOG_DEBUG ||
00130     a_logLevel == LOG_INFO ||
00131     a_logLevel == LOG_WARNING ||
00132     a_logLevel == LOG_ERR ||
00133     a_logLevel == LOG_CRIT)
00134   {
00135     pMsg->m_logLevel = a_logLevel;
00136     return E_SUCCESS;
00137   }
00138   return E_UNKNOWN;
00139 }
00140 
00141 SINT32 CAMsg::setLogOptions(UINT32 opt)
00142     {
00143       SINT32 ret; 
00144       const char* strLogOpened = "Message log opened%s%s.\n";
00145       const char* strLogErrorMsg = "Could not open message log%s%s!%s Do you have write permissions?%s\n";
00146       const char* strReasonMsg = " Reason: %s (%u)";
00147       char* strLogFile = NULL;
00148       char* strLogDir = NULL;
00149       char* strReason = NULL;
00150       char* strBuff;
00151       const char* strLogType = "";
00152   
00153 
00154       if(pMsg->m_uLogType==opt)
00155       {
00156           return E_SUCCESS;
00157       }
00158 
00159 
00160       if (opt == MSG_LOG)
00161       {
00162         strLogType = " as Syslog";
00163       }
00164       else if ((opt & MSG_LOG) == MSG_LOG)
00165       {
00166         strLogType = " as Syslog and";
00167       }
00168 
00169       if ((opt & MSG_FILE) == MSG_FILE)
00170       {
00171         strLogType = " as file";
00172       }
00173       else if ((opt & MSG_COMPRESSED_FILE) == MSG_COMPRESSED_FILE)
00174       {
00175         strLogType = " as compressed file";
00176       }
00177       
00178       
00179 
00180       if((ret = pMsg->openLog(opt))==E_SUCCESS)
00181       {
00182         strLogFile = pMsg->createLogFileMessage(opt);
00183         strBuff = new char[strlen(strLogOpened) + strlen(strLogType) + strlen(strLogFile) + 1];
00184         sprintf(strBuff, strLogOpened, strLogType, strLogFile);
00185         delete[] strLogFile;
00186         printMsg(LOG_DEBUG, strBuff);
00187         delete[] strBuff;
00188 
00189         pMsg->closeLog(); //closes the OLD Log!
00190         pMsg->m_uLogType=opt;
00191 
00192         
00193         return E_SUCCESS;
00194       }
00195       
00196 
00197       strLogFile = pMsg->createLogFileMessage(opt);
00198       
00199       strLogDir = pMsg->createLogDirMessage(opt);
00200 
00201       if (ret == E_FILE_OPEN)
00202       {
00203         strReason = new char[strlen(strReasonMsg) + strlen(GET_NET_ERROR_STR(GET_NET_ERROR)) + 5 + 1];
00204         sprintf(strReason, strReasonMsg, GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR);
00205       }
00206       else
00207       {
00208         strReason = new char[1];
00209         strReason[0] = '\0';
00210       }
00211 
00212       strBuff = new char[strlen(strLogErrorMsg) + strlen(strLogType) + strlen(strLogFile) + strlen(strReason) + strlen(strLogDir) + 1];
00213     
00214       sprintf(strBuff, strLogErrorMsg, strLogType, strLogFile, strReason, strLogDir);
00215       //snprintf(strBuff, strlen(strLogErrorMsg) + strlen(strLogFile) + strlen(strReason) + 1,  strLogErrorMsg, strLogFile, strReason);
00216       delete[] strLogFile;
00217       delete[] strReason;
00218 
00219       printMsg(LOG_CRIT, strBuff);
00220 
00221       delete[] strBuff;
00222       return ret;
00223     }
00224 
00225 SINT32 CAMsg::printMsg(UINT32 type,const char* format,...)
00226   {
00227     if(pMsg != NULL)
00228     {
00229       pMsg->m_pcsPrint->lock();
00230       va_list ap;
00231       va_start(ap,format);
00232       SINT32 ret=E_SUCCESS;
00233       
00234       //Date is: yyyy/mm/dd-hh:mm:ss   -- the size is: 19
00235       time_t currtime=time(NULL);
00236       strftime(pMsg->m_strMsgBuff+1,255,"%Y/%m/%d-%H:%M:%S",localtime(&currtime));
00237       switch(type)
00238         {
00239           case LOG_DEBUG:
00240             if (pMsg->m_logLevel != LOG_DEBUG)
00241             {
00242               ret = E_UNKNOWN;
00243             }
00244             strcat(pMsg->m_strMsgBuff,pMsg->m_strMsgTypes[3]);
00245           break;
00246           case LOG_INFO:
00247             if (pMsg->m_logLevel == LOG_WARNING || pMsg->m_logLevel == LOG_ERR || pMsg->m_logLevel == LOG_CRIT)
00248             {
00249               ret = E_UNKNOWN;
00250             }
00251             strcat(pMsg->m_strMsgBuff,pMsg->m_strMsgTypes[2]);
00252           break;
00253           case LOG_CRIT:
00254             strcat(pMsg->m_strMsgBuff,pMsg->m_strMsgTypes[1]);
00255           break;
00256           case LOG_ERR:
00257             if (pMsg->m_logLevel == LOG_CRIT)
00258             {
00259               ret = E_UNKNOWN;
00260             }
00261             strcat(pMsg->m_strMsgBuff,pMsg->m_strMsgTypes[0]);
00262           break;
00263           case LOG_ENCRYPTED:
00264             strcat(pMsg->m_strMsgBuff,pMsg->m_strMsgTypes[4]);
00265           break;
00266           case LOG_WARNING:
00267             if (pMsg->m_logLevel == LOG_ERR || pMsg->m_logLevel == LOG_CRIT)
00268             {
00269               ret = E_UNKNOWN;
00270             }
00271             strcat(pMsg->m_strMsgBuff,pMsg->m_strMsgTypes[5]);
00272           break;
00273           default:
00274             va_end(ap);
00275             pMsg->m_pcsPrint->unlock();
00276             return E_UNKNOWN;
00277         }
00278   #ifdef HAVE_VSNPRINTF
00279       vsnprintf(pMsg->m_strMsgBuff+20+STRMSGTYPES_SIZE,MAX_MSG_SIZE,format,ap);
00280   #else
00281       trio_vsnprintf(pMsg->m_strMsgBuff+20+STRMSGTYPES_SIZE,MAX_MSG_SIZE,format,ap);
00282   #endif
00283       va_end(ap);
00284       if (ret != E_SUCCESS)
00285       {
00286         pMsg->m_pcsPrint->unlock();
00287         return ret;
00288       }
00289       if(type==LOG_ENCRYPTED)
00290       {
00291         ret=strlen(pMsg->m_strMsgBuff);
00292         if( pMsg->m_pCipher==NULL)
00293         {
00294           ret=E_UNKNOWN;
00295         }
00296         else
00297         {
00298           UINT8 bp[MAX_MSG_SIZE];
00299           AES_ofb128_encrypt((UINT8*)pMsg->m_strMsgBuff,
00300                               bp,ret,
00301                               &(pMsg->m_pCipher->oKey),
00302                               pMsg->m_pCipher->iv,
00303                               &(pMsg->m_pCipher->iv_off));
00304           if(write(pMsg->m_hFileEncrypted,bp,ret)!=ret)
00305             ret=E_UNKNOWN;
00306         }
00307       }
00308       else
00309         {
00310               if ((pMsg->m_uLogType & MSG_LOG) == MSG_LOG)
00311               {
00312   #ifndef _WIN32
00313             syslog(type,pMsg->m_strMsgBuff);
00314   #endif
00315               }
00316   #ifdef COMPRESSED_LOGS
00317               if ((pMsg->m_uLogType & MSG_COMPRESSED_FILE) == MSG_COMPRESSED_FILE)
00318               {
00319                 if(pMsg->m_gzFileInfo!=NULL)
00320                 {
00321                   if(gzwrite(pMsg->m_gzFileInfo,pMsg->m_strMsgBuff,strlen(pMsg->m_strMsgBuff))==-1)
00322                     ret=E_UNKNOWN;
00323                 }
00324               }
00325   #endif
00326               else if ((pMsg->m_uLogType & MSG_FILE) == MSG_FILE)
00327               {
00328 /*                if(pMsg->m_hFileInfo==-1)
00329                   {
00330                     pMsg->m_hFileInfo=open(pMsg->m_strLogFile,O_APPEND|O_CREAT|O_WRONLY|O_NONBLOCK|O_LARGEFILE|O_SYNC,S_IREAD|S_IWRITE);
00331                   }
00332 *///                if(pMsg->m_hFileInfo!=-1)
00333 //                  {
00334       #ifdef PSEUDO_LOG
00335                     char buff[255];
00336                     sprintf(buff,"%.15s mix AnonMix: ",ctime(&currtime)+4);
00337                     write(pMsg->m_hFileInfo,buff,strlen(buff));
00338       #endif
00339                     if(write(pMsg->m_hFileInfo,pMsg->m_strMsgBuff,strlen(pMsg->m_strMsgBuff))==-1)
00340                       ret=E_UNKNOWN;
00341                     pMsg->m_NrOfWrites++;
00342                     if( //(pMsg->m_NrOfWrites > 10000) &&
00343                       !isZero64(pMsg->m_maxLogFileSize) &&
00344                       isGreater64(filesize64(pMsg->m_hFileInfo), pMsg->m_maxLogFileSize))
00345                       {
00346                         pMsg->closeLog();
00347                         pMsg->openLog(pMsg->m_uLogType);
00348                       }
00349 //                  }
00350               }
00351               if ((pMsg->m_uLogType & MSG_STDOUT) == MSG_STDOUT)
00352               {
00353                 printf("%s",pMsg->m_strMsgBuff);
00354               }
00355         }
00356       pMsg->m_pcsPrint->unlock();
00357       return ret;
00358     }
00359     else
00360     {
00361       printf("Warning logger is not active!\n");
00362       return E_UNKNOWN;
00363     }
00364   }
00365 
00366 SINT32 CAMsg::closeLog()
00367   {
00368         if ((pMsg->m_uLogType & MSG_LOG) == MSG_LOG)
00369         {
00370 #ifndef _WIN32
00371           ::closelog();
00372 #endif
00373         }
00374 #ifdef COMPRESSED_LOGS
00375         if ((pMsg->m_uLogType & MSG_COMPRESSED_FILE) == MSG_COMPRESSED_FILE)
00376         {
00377           if(m_gzFileInfo!=NULL)
00378             gzclose(m_gzFileInfo);
00379           m_gzFileInfo=NULL;
00380         }
00381 #endif
00382         else if ((pMsg->m_uLogType & MSG_FILE) == MSG_FILE)
00383         {
00384           if(m_hFileInfo!=-1)
00385             close(m_hFileInfo);
00386           m_hFileInfo=-1;
00387         }
00388     return E_SUCCESS;
00389   }
00390 
00391 SINT32 CAMsg::rotateLog()
00392 {
00393     if ((pMsg->m_uLogType & MSG_COMPRESSED_FILE) == MSG_COMPRESSED_FILE)
00394     {
00395       // TODO
00396     }
00397     else if ((pMsg->m_uLogType & MSG_FILE) == MSG_FILE)
00398     {
00399 
00400       char logFileSaveName[1026];
00401       memset(logFileSaveName, 0, 1026);
00402       //memcpy(logFileSave, m_strMsgBuff, 1024);
00403       snprintf(logFileSaveName, 1025, "%s%u", m_strLogFile, m_lastLogFileNumber);
00404       m_lastLogFileNumber = (m_lastLogFileNumber+1) % CALibProxytest::getOptions()->getMaxLogFiles();
00405       rename(m_strLogFile, logFileSaveName);
00406       /*if(m_hFileInfo!=-1)
00407         close(m_hFileInfo);
00408       m_hFileInfo=-1;*/
00409     }
00410 
00411   return E_SUCCESS;
00412 }
00413 
00414 SINT32 CAMsg::openLog(UINT32 type)
00415   {
00416         if ((type & MSG_LOG) == MSG_LOG)
00417         {
00418 #ifndef _WIN32
00419       openlog("AnonMix",0,LOG_USER);
00420 #endif
00421         }
00422 #ifdef COMPRESSED_LOGS
00423         if ((type & MSG_COMPRESSED_FILE) == MSG_COMPRESSED_FILE)
00424         {
00425       char logdir[255];
00426       char buff[1024];
00427       if(CALibProxytest::getOptions()->getLogDir((UINT8*)logdir,255)!=E_SUCCESS)
00428         return E_UNKNOWN;
00429       strcpy(buff,logdir);
00430       strcat(buff,FILENAME_INFOLOG_GZ);
00431       tmpHandle=open(buff,O_APPEND|O_CREAT|O_WRONLY,S_IREAD|S_IWRITE);
00432       if (tmpHandle == -1)
00433       {
00434         return E_FILE_OPEN;
00435       }
00436       m_gzFileInfo=gzdopen(tmpHandle,"wb9");
00437       if(m_gzFileInfo==NULL)
00438       {
00439         SINT32 iError = GET_NET_ERROR;
00440         close(tmpHandle);
00441         SET_NET_ERROR(iError);
00442         return E_FILE_OPEN;
00443       }
00444       }
00445 #endif
00446     else if ((type & MSG_FILE) == MSG_FILE)
00447         {
00448           if(CALibProxytest::getOptions()->getLogDir((UINT8*)m_strLogFile,1024)!=E_SUCCESS)
00449           {
00450             return E_UNKNOWN;
00451           }
00452           m_strLogDir = new char[strlen(m_strLogFile) + 1];
00453           strcpy(m_strLogDir, m_strLogFile);
00454           strcat(m_strLogFile,FILENAME_INFOLOG);
00455           if(CALibProxytest::getOptions()->getMaxLogFileSize()>0)
00456           {
00457             if(m_alreadyOpened)
00458             {
00459               rotateLog();
00460             }
00461 
00462             setMaxLogFileSize(CALibProxytest::getOptions()->getMaxLogFileSize());
00463             m_alreadyOpened = true;
00464           }
00465           m_NrOfWrites=0;
00466           m_hFileInfo=open(m_strLogFile,O_APPEND|O_CREAT|O_WRONLY|O_NONBLOCK|O_LARGEFILE,S_IREAD|S_IWRITE);
00467           if (m_hFileInfo == -1)
00468           {
00469             return E_FILE_OPEN;
00470           }
00471         }
00472     return E_SUCCESS;
00473   }
00474 
00475 #ifndef ONLY_LOCAL_PROXY
00476 
00489   SINT32 CAMsg::openEncryptedLog()
00490   {
00491     CACertificate* pCert=CALibProxytest::getOptions()->getLogEncryptionKey();
00492     if(pCert==NULL)
00493       return E_UNKNOWN;
00494     CAASymCipher oRSA;
00495     SINT32 ret=oRSA.setPublicKey(pCert);
00496     delete pCert;
00497     pCert = NULL;
00498     if(ret!=E_SUCCESS)
00499       return E_UNKNOWN;
00500     UINT8 buff[1024];
00501     if(CALibProxytest::getOptions()->getEncryptedLogDir(buff,1024)!=E_SUCCESS)
00502       if(CALibProxytest::getOptions()->getLogDir(buff,1024)!=E_SUCCESS)
00503         return E_UNKNOWN;
00504     strcat((char*)buff,FILENAME_ENCRYPTEDLOG);
00505     pMsg->m_hFileEncrypted=open((char*)buff,O_APPEND|O_CREAT|O_WRONLY|O_LARGEFILE|O_BINARY,S_IREAD|S_IWRITE);
00506     if(pMsg->m_hFileEncrypted<=0)
00507       {
00508         pMsg->m_hFileEncrypted=-1;
00509         return E_UNKNOWN;
00510       }
00511     //create sym enc key and write it to the file (enc with pub enc key)
00512     write(pMsg->m_hFileEncrypted,"\n----Start of EncryptionKey----\n",32);
00513     UINT8 keyandiv[128];
00514     getRandom(keyandiv,128);
00515     keyandiv[0]&=0x7F;
00516     pMsg->m_pCipher=new t_LogEncCipher;
00517     AES_set_encrypt_key(keyandiv+50,128,&pMsg->m_pCipher->oKey);
00518     memcpy(pMsg->m_pCipher->iv,keyandiv+66,16);
00519     pMsg->m_pCipher->iv_off=0;
00520     UINT8 out[255];
00521     UINT32 outlen=255;
00522     oRSA.encrypt(keyandiv,keyandiv);
00523     CABase64::encode(keyandiv,128,out,&outlen);
00524     write(pMsg->m_hFileEncrypted,out,outlen);
00525     write(pMsg->m_hFileEncrypted,"-----End of EncryptionKey-----\n",31);
00526     return E_SUCCESS;
00527   }
00528 
00529 SINT32 CAMsg::closeEncryptedLog()
00530   {
00531     if(pMsg->m_hFileEncrypted>=0)
00532       {
00533         close(pMsg->m_hFileEncrypted);
00534       }
00535     delete pMsg->m_pCipher;
00536     pMsg->m_pCipher=NULL;
00537     pMsg->m_hFileEncrypted=-1;
00538     return E_SUCCESS;
00539   }
00540 #endif //ONLY_LOCAL_PROXY