From c9bc8e82a25fd160872fac488bfe920f95f5fe5f Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Sun, 22 Feb 2009 02:35:13 +0000 Subject: added extended logging capability --- src/Makefile | 9 +- src/anytun-config.cpp | 5 +- src/anytun-controld.cpp | 2 +- src/anytun.cpp | 17 +- src/configure | 2 +- src/log.cpp | 96 ++--------- src/log.h | 85 ++-------- src/logTargets.cpp | 433 ++++++++++++++++++++++++++++++++++++++++++++++++ src/logTargets.h | 200 ++++++++++++++++++++++ 9 files changed, 677 insertions(+), 172 deletions(-) create mode 100644 src/logTargets.cpp create mode 100644 src/logTargets.h (limited to 'src') diff --git a/src/Makefile b/src/Makefile index 87c3f47..fa4c519 100644 --- a/src/Makefile +++ b/src/Makefile @@ -50,6 +50,7 @@ OBJS := tunDevice.o \ routingTable.o \ signalController.o \ log.o \ + logTargets.o \ options.o \ seqWindow.o \ routingTreeNode.o \ @@ -66,10 +67,12 @@ ANYCTROBJS := signalController.o \ anyCtrOptions.o \ buffer.o \ log.o \ + logTargets.o \ syncTcpConnection.o \ syncServer.o ANYCONFOBJS := log.o \ + logTargets.o \ buffer.o \ keyDerivation.o \ keyDerivationFactory.o \ @@ -141,13 +144,13 @@ anytun-controld: $(ANYCTROBJS) anytun-controld.o options.o: options.cpp - $(CXX) -DANYTUN_OPTIONS $(CXXFLAGS) $< -c -o $@ + $(CXX) $(CXXFLAGS) -DANYTUN_OPTIONS $< -c -o $@ anyCtrOptions.o: options.cpp - $(CXX) -DANYCTR_OPTIONS $(CXXFLAGS) $< -c -o $@ + $(CXX) $(CXXFLAGS) -DANYCTR_OPTIONS $< -c -o $@ anyConfOptions.o: options.cpp - $(CXX) -DANYCONF_OPTIONS $(CXXFLAGS) $< -c -o $@ + $(CXX) $(CXXFLAGS) -DANYCONF_OPTIONS $< -c -o $@ %.o: %.cpp $(CXX) $(CXXFLAGS) $< -c diff --git a/src/anytun-config.cpp b/src/anytun-config.cpp index 650c75b..07344c1 100644 --- a/src/anytun-config.cpp +++ b/src/anytun-config.cpp @@ -55,7 +55,7 @@ void createConnection(const PacketSourceEndpoint & remote_end, ConnectionList & seq_nr_t seq_nr_ = 0; KeyDerivation * kd = KeyDerivationFactory::create( gOpt.getKdPrf() , gOpt.getAnytun02Compat() ); kd->init( gOpt.getKey(), gOpt.getSalt() ); -// cLog.msg(Log::PRIO_NOTICE) << "added connection remote host " << remote_end; + cLog.msg(Log::PRIO_NOTICE) << "added connection remote host " << remote_end; ConnectionParam connparam ( (*kd), (*seq), seq_nr_, remote_end ); cl.addConnection( connparam, mux ); @@ -89,6 +89,7 @@ int main(int argc, char* argv[]) int ret=0; try { + cLog.addTarget("stderr:4"); bool result = gOpt.parse(argc, argv); if(!result) { gOpt.printUsage(); @@ -98,7 +99,7 @@ int main(int argc, char* argv[]) catch(syntax_error& e) { std::cerr << e << std::endl; -// cLog.msg(Log::PRIO_NOTICE) << "exitting after syntax error"; + cLog.msg(Log::PRIO_ERR) << "exitting after syntax error"; gOpt.printUsage(); exit(-1); } diff --git a/src/anytun-controld.cpp b/src/anytun-controld.cpp index cff0932..680d143 100644 --- a/src/anytun-controld.cpp +++ b/src/anytun-controld.cpp @@ -97,7 +97,7 @@ int main(int argc, char* argv[]) bool daemonized=false; try { - cLog.setLogName("anytun-controld"); + cLog.addTarget("syslog:7,anytun-controld,daemon"); cLog.msg(Log::PRIO_NOTICE) << "anytun-controld started..."; try diff --git a/src/anytun.cpp b/src/anytun.cpp index 292d924..d954eae 100644 --- a/src/anytun.cpp +++ b/src/anytun.cpp @@ -360,11 +360,12 @@ int main(int argc, char* argv[]) #endif try { - cLog.msg(Log::PRIO_NOTICE) << "anytun started..."; -/// std::cout << "anytun - secure anycast tunneling protocol" << std::endl; - try { + cLog.addTarget("syslog:7,anytun,daemon"); + cLog.msg(Log::PRIO_DEBUG) << "anytun started..."; +/// std::cout << "anytun - secure anycast tunneling protocol" << std::endl; + bool result = gOpt.parse(argc, argv); if(!result) { cLog.msg(Log::PRIO_NOTICE) << "printing help text and exitting"; @@ -375,7 +376,7 @@ int main(int argc, char* argv[]) catch(syntax_error& e) { std::cerr << e << std::endl; - cLog.msg(Log::PRIO_NOTICE) << "exitting after syntax error"; + cLog.msg(Log::PRIO_ERR) << "exitting after syntax error"; gOpt.printUsage(); exit(-1); } @@ -532,18 +533,14 @@ int main(int argc, char* argv[]) catch(std::runtime_error& e) { cLog.msg(Log::PRIO_ERR) << "uncaught runtime error, exiting: " << e.what(); -#ifndef LOG_STDOUT - if(!daemonized) + if(!daemonized) std::cout << "uncaught runtime error, exiting: " << e.what() << std::endl; -#endif } catch(std::exception& e) { cLog.msg(Log::PRIO_ERR) << "uncaught exception, exiting: " << e.what(); -#ifndef LOG_STDOUT - if(!daemonized) + if(!daemonized) std::cout << "uncaught exception, exiting: " << e.what() << std::endl; -#endif } #if defined(WIN_SERVICE) gWinService.stop(); diff --git a/src/configure b/src/configure index 764f83e..b664850 100755 --- a/src/configure +++ b/src/configure @@ -32,7 +32,7 @@ TARGET=`uname -s` -CXXFLAGS='-g -Wall -O2 -DLOG_SYSLOG' +CXXFLAGS='-g -Wall -O2 -DLOG_SYSLOG -DLOG_FILE -DLOG_STDOUT' LDFLAGS='-g -Wall -O2 -lboost_thread -lboost_serialization -lboost_system' CRYPTO_LIB='gcrypt' diff --git a/src/log.cpp b/src/log.cpp index 026a851..f99ee78 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -36,11 +36,6 @@ #include "threadUtils.hpp" -#ifdef LOG_WINEVENTLOG -#include -#include -#endif - Log* Log::inst = NULL; Mutex Log::instMutex; Log& cLog = Log::instance(); @@ -59,7 +54,6 @@ std::ostream& operator<<(std::ostream& stream, LogGpgError const& value) std::ostream& operator<<(std::ostream& stream, LogErrno const& value) { boost::system::system_error err(boost::system::error_code(value.err_,boost::system::get_system_category())); -// boost::system::system_error err(boost::system::error_code(value.err_,boost::system::get_posix_category())); return stream << err.what(); } @@ -88,65 +82,28 @@ Log& Log::instance() return *inst; } -Log::Log() -{ - facility = FAC_DAEMON; - logName = "anytun"; - open(); -} - -Log::~Log() +void Log::addTarget(std::string conf) { -#ifdef LOG_SYSLOG - closelog(); -#endif -#ifdef LOG_FILE - if(log_file.is_open()) - log_file.close(); -#endif -#ifdef LOG_WINEVENTLOG - if(h_event_source_) - DeregisterEventSource(h_event_source_); -#endif + Lock lock(mutex); + LogTarget* target = targets.add(conf); + target->open(); + target->enable(); } -void Log::open() +void Log::addTarget(LogTargetList::target_type_t type, int prio, std::string conf) { -#ifdef LOG_SYSLOG - openlog(logName.c_str(), LOG_PID, facility); -#endif -#ifdef LOG_FILE - log_file.open("anytun.log", std::fstream::out | std::fstream::app); -#endif -#ifdef LOG_WINEVENTLOG - h_event_source_ = RegisterEventSourceA(NULL, logName.c_str()); -#endif + Lock lock(mutex); + LogTarget* target = targets.add(type, prio, conf); + target->open(); + target->enable(); } void Log::log(std::string msg, int prio) { Lock lock(mutex); -#ifdef LOG_SYSLOG - syslog(prio | facility, "%s", msg.c_str()); -#endif -#ifdef LOG_STDOUT - std::cout << "LOG-" << Log::prioToString(prio) << ": " << msg << std::endl; -#endif -#ifdef LOG_FILE - if(log_file.is_open()) - log_file << Log::prioToString(prio) << ": " << msg << std::endl; -#endif -#ifdef LOG_WINEVENTLOG - LPCTSTR lpszStrings[1]; - CHAR buffer[STERROR_TEXT_MAX]; - StringCchPrintfA(buffer, STERROR_TEXT_MAX, "%s", msg.c_str()); - lpszStrings[0] = buffer; - if(log.h_event_source_) - ReportEventA(log.h_event_source_, Log::prioToEventLogType(prio), 0, prio, NULL, 1, 0, lpszStrings, NULL); -#endif + targets.log(msg, prio); } -#if defined(LOG_STDOUT) || defined(LOG_FILE) std::string Log::prioToString(int prio) { switch(prio) { @@ -161,34 +118,3 @@ std::string Log::prioToString(int prio) default: return "UNKNOWN"; } } -#endif -#ifdef LOG_WINEVENTLOG -WORD Log::prioToEventLogType(int prio) -{ - switch(prio) { - case PRIO_EMERG: return EVENTLOG_ERROR_TYPE; - case PRIO_ALERT: return EVENTLOG_ERROR_TYPE; - case PRIO_CRIT: return EVENTLOG_ERROR_TYPE; - case PRIO_ERR: return EVENTLOG_ERROR_TYPE; - case PRIO_WARNING: return EVENTLOG_WARNING_TYPE; - case PRIO_NOTICE: return EVENTLOG_INFORMATION_TYPE; - case PRIO_INFO: return EVENTLOG_SUCCESS; - case PRIO_DEBUG: return EVENTLOG_INFORMATION_TYPE; - default: return EVENTLOG_ERROR_TYPE; - } -} -#endif - -Log& Log::setLogName(std::string newLogName) -{ - logName = newLogName; - open(); - return *this; -} - -Log& Log::setFacility(int newFacility) -{ - facility = newFacility; - open(); - return *this; -} diff --git a/src/log.h b/src/log.h index 861ad2c..6550b10 100644 --- a/src/log.h +++ b/src/log.h @@ -34,7 +34,8 @@ #include #include -#include + +#include "logTargets.h" #ifdef LOG_SYSLOG #include @@ -88,26 +89,6 @@ class Log : public std::ostringstream { public: #ifdef LOG_SYSLOG - static const int FAC_USER = LOG_USER; - static const int FAC_MAIL = LOG_MAIL; - static const int FAC_DAEMON = LOG_DAEMON; - static const int FAC_AUTH = LOG_AUTH; - static const int FAC_SYSLOG = LOG_SYSLOG; - static const int FAC_LPR = LOG_LPR; - static const int FAC_NEWS = LOG_NEWS; - static const int FAC_UUCP = LOG_UUCP; - static const int FAC_CRON = LOG_CRON; - static const int FAC_AUTHPRIV = LOG_AUTHPRIV; - static const int FAC_FTP = LOG_FTP; - static const int FAC_LOCAL0 = LOG_LOCAL0; - static const int FAC_LOCAL1 = LOG_LOCAL1; - static const int FAC_LOCAL2 = LOG_LOCAL2; - static const int FAC_LOCAL3 = LOG_LOCAL3; - static const int FAC_LOCAL4 = LOG_LOCAL4; - static const int FAC_LOCAL5 = LOG_LOCAL5; - static const int FAC_LOCAL6 = LOG_LOCAL6; - static const int FAC_LOCAL7 = LOG_LOCAL7; - static const int PRIO_EMERG = LOG_EMERG; static const int PRIO_ALERT = LOG_ALERT; static const int PRIO_CRIT = LOG_CRIT; @@ -117,54 +98,26 @@ public: static const int PRIO_INFO = LOG_INFO; static const int PRIO_DEBUG = LOG_DEBUG; #else - static const int FAC_USER = 0; - static const int FAC_MAIL = 0; - static const int FAC_DAEMON = 0; - static const int FAC_AUTH = 0; - static const int FAC_SYSLOG = 0; - static const int FAC_LPR = 0; - static const int FAC_NEWS = 0; - static const int FAC_UUCP = 0; - static const int FAC_CRON = 0; - static const int FAC_AUTHPRIV = 0; - static const int FAC_FTP = 0; - static const int FAC_LOCAL0 = 0; - static const int FAC_LOCAL1 = 0; - static const int FAC_LOCAL2 = 0; - static const int FAC_LOCAL3 = 0; - static const int FAC_LOCAL4 = 0; - static const int FAC_LOCAL5 = 0; - static const int FAC_LOCAL6 = 0; - static const int FAC_LOCAL7 = 0; - - static const int PRIO_EMERG = 1; - static const int PRIO_ALERT = 2; - static const int PRIO_CRIT = 3; - static const int PRIO_ERR = 4; - static const int PRIO_WARNING = 5; - static const int PRIO_NOTICE = 6; - static const int PRIO_INFO = 7; - static const int PRIO_DEBUG = 8; + static const int PRIO_EMERG = 0; + static const int PRIO_ALERT = 1; + static const int PRIO_CRIT = 2; + static const int PRIO_ERR = 3; + static const int PRIO_WARNING = 4; + static const int PRIO_NOTICE = 5; + static const int PRIO_INFO = 6; + static const int PRIO_DEBUG = 7; #endif -#if defined(LOG_STDOUT) || defined(LOG_FILE) static std::string prioToString(int prio); -#endif -#ifdef LOG_WINEVENTLOG - static WORD prioToEventLogType(int prio); -#endif static Log& instance(); - Log& setLogName(std::string newLogName); - std::string getLogName() const { return logName; } - Log& setFacility(int newFacility); - int getFacility() const { return facility; } - + void addTarget(std::string conf); + void addTarget(LogTargetList::target_type_t type, int prio, std::string conf); LogStringBuilder msg(int prio=PRIO_INFO) { return LogStringBuilder(*this, prio); } private: - Log(); - ~Log(); + Log() {}; + ~Log() {}; Log(const Log &l); void operator=(const Log &l); @@ -178,20 +131,12 @@ private: }; friend class instanceCleaner; - void open(); void log(std::string msg, int prio); Mutex mutex; friend class LogStringBuilder; - std::string logName; - int facility; -#ifdef LOG_FILE - std::ofstream log_file; -#endif -#ifdef LOG_WINEVENTLOG - HANDLE h_event_source_; -#endif + LogTargetList targets; }; extern Log& cLog; diff --git a/src/logTargets.cpp b/src/logTargets.cpp new file mode 100644 index 0000000..82bb6fd --- /dev/null +++ b/src/logTargets.cpp @@ -0,0 +1,433 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with anytun. If not, see . + */ + +#include + +#include "datatypes.h" + +#include "logTargets.h" +#include "log.h" + +#include "options.h" + +#ifdef LOG_WINEVENTLOG +#include +#include +#endif + +LogTarget::LogTarget() : opened(false), enabled(false), max_prio(Log::PRIO_NOTICE) +{ +} + +LogTarget::LogTarget(int prio) : opened(false), enabled(false), max_prio(prio) +{ +} + +LogTargetList::~LogTargetList() +{ + clear(); +} + +LogTargetList::target_type_t LogTargetList::targetTypeFromString(std::string type) +{ + if(type == "syslog") return TARGET_SYSLOG; + if(type == "file") return TARGET_FILE; + if(type == "stdout") return TARGET_STDOUT; + if(type == "stderr") return TARGET_STDERR; + if(type == "eventlog") return TARGET_WINEVENTLOG; + return TARGET_UNKNOWN; +} + +std::string LogTargetList::targetTypeToString(target_type_t type) +{ + switch(type) { + case TARGET_SYSLOG: return "syslog"; + case TARGET_FILE: return "file"; + case TARGET_STDOUT: return "stdout"; + case TARGET_STDERR: return "stderr"; + case TARGET_WINEVENTLOG: return "eventlog"; + default: return "unknown"; + } +} + +LogTarget* LogTargetList::add(std::string conf) +{ + std::stringstream s(conf); + std::string type; + getline(s, type, ':'); + if(!s.good()) + throw syntax_error(conf, 0); + + int prio = 0; + s >> prio; + if(s.fail()) + throw syntax_error(conf, conf.find_first_of(':')+1); + + char buff[100]; + if(s.good()) { + s.ignore(1); + s.get(buff, 100); + } + else + buff[0] = 0; + + return add(targetTypeFromString(type), prio, buff); +} + +LogTarget* LogTargetList::add(target_type_t type, int prio, std::string conf) +{ + switch(type) { + case TARGET_SYSLOG: { + #ifdef LOG_SYSLOG + if(!LogTargetSyslog::duplicateAllowed() && targets.count(TARGET_SYSLOG)) + throw std::runtime_error(targetTypeToString(TARGET_SYSLOG) + " logtarget is supported only once"); + + return targets.insert(TargetsMap::value_type(TARGET_SYSLOG, new LogTargetSyslog(prio, conf)))->second; + #else + throw std::runtime_error(targetTypeToString(TARGET_SYSLOG) + " logtarget is not supported"); + #endif + } + case TARGET_FILE: { + #ifdef LOG_FILE + if(!LogTargetFile::duplicateAllowed() && targets.count(TARGET_FILE)) + throw std::runtime_error(targetTypeToString(TARGET_FILE) + " logtarget is supported only once"); + + return targets.insert(TargetsMap::value_type(TARGET_FILE, new LogTargetFile(prio, conf)))->second; + #else + throw std::runtime_error(targetTypeToString(TARGET_FILE) + " logtarget is not supported"); + #endif + } + case TARGET_STDOUT: + case TARGET_STDERR: { + #ifdef LOG_STDOUT + if(!LogTargetStdout::duplicateAllowed() && targets.count(type)) + throw std::runtime_error(targetTypeToString(type) + " logtarget is supported only once"); + + if(type == TARGET_STDERR) + return targets.insert(TargetsMap::value_type(type, new LogTargetStdout(prio, std::cerr)))->second; + else + return targets.insert(TargetsMap::value_type(type, new LogTargetStdout(prio, std::cout)))->second; + #else + throw std::runtime_error(targetTypeToString(type) + " logtarget is not supported"); + #endif + } + case TARGET_WINEVENTLOG: { + #ifdef LOG_WINEVENTLOG + if(!LogTargetSyslog::duplicateAllowed() && targets.count(TARGET_WINEVENTLOG)) + throw std::runtime_error(targetTypeToString(TARGET_WINEVENTLOG) + " logtarget is supported only once"); + + return targets.insert(TargetsMap::value_type(TARGET_WINEVENTLOG, new LogTargetWinEventlog(prio, conf)))->second; + #else + throw std::runtime_error(targetTypeToString(TARGET_WINEVENTLOG) + " logtarget is not supported"); + #endif + } + default: + throw std::runtime_error("unknown log target"); + } +} + +void LogTargetList::clear() +{ + TargetsMap::iterator it; + for(it = targets.begin(); it != targets.end(); ++it) + delete it->second; + targets.clear(); +} + +void LogTargetList::log(std::string msg, int prio) +{ + TargetsMap::const_iterator it; + for(it = targets.begin(); it != targets.end(); ++it) { + if(it->second->isEnabled() && it->second->getMaxPrio() >= prio) + it->second->log(msg, prio); + } +} + + +#ifdef LOG_SYSLOG +int LogTargetSyslog::facilityFromString(std::string fac) +{ + if(fac == "user") return FAC_USER; + if(fac == "mail") return FAC_MAIL; + if(fac == "daemon") return FAC_DAEMON; + if(fac == "auth") return FAC_AUTH; + if(fac == "syslog") return FAC_SYSLOG; + if(fac == "lpr") return FAC_LPR; + if(fac == "news") return FAC_NEWS; + if(fac == "uucp") return FAC_UUCP; + if(fac == "cron") return FAC_CRON; + if(fac == "authpriv") return FAC_AUTHPRIV; + if(fac == "ftp") return FAC_FTP; + if(fac == "local0") return FAC_LOCAL0; + if(fac == "local1") return FAC_LOCAL1; + if(fac == "local2") return FAC_LOCAL2; + if(fac == "local3") return FAC_LOCAL3; + if(fac == "local4") return FAC_LOCAL4; + if(fac == "local5") return FAC_LOCAL5; + if(fac == "local6") return FAC_LOCAL6; + if(fac == "local7") return FAC_LOCAL7; + + throw std::runtime_error("unknown syslog facility"); +} + +std::string LogTargetSyslog::facilityToString(int fac) +{ + switch(fac) { + case FAC_USER: return "user"; + case FAC_MAIL: return "mail"; + case FAC_DAEMON: return "daemon"; + case FAC_AUTH: return "auth"; + case FAC_SYSLOG: return "syslog"; + case FAC_LPR: return "lpr"; + case FAC_NEWS: return "news"; + case FAC_UUCP: return "uucp"; + case FAC_CRON: return "cron"; + case FAC_AUTHPRIV: return "authpriv"; + case FAC_FTP: return "ftp"; + case FAC_LOCAL0: return "local0"; + case FAC_LOCAL1: return "local1"; + case FAC_LOCAL2: return "local2"; + case FAC_LOCAL3: return "local3"; + case FAC_LOCAL4: return "local4"; + case FAC_LOCAL5: return "local5"; + case FAC_LOCAL6: return "local6"; + case FAC_LOCAL7: return "local7"; + default: throw std::runtime_error("unknown syslog facility"); + } +} + +LogTargetSyslog::LogTargetSyslog(int prio, std::string conf) : LogTarget(prio) +{ + std::stringstream s(conf); + facility = FAC_DAEMON; + getline(s, logname, ','); + if(s.fail()) { + logname = "anytun"; + return; + } + std::string fac; + getline(s, fac, ','); + if(s.fail()) + return; + + facility = LogTargetSyslog::facilityFromString(fac); +} + +LogTargetSyslog::~LogTargetSyslog() +{ + if(opened) + close(); +} + +void LogTargetSyslog::open() +{ + openlog(logname.c_str(), LOG_PID, facility); + opened = true; +} + +void LogTargetSyslog::close() +{ + closelog(); + opened = false; +} + +void LogTargetSyslog::log(std::string msg, int prio) +{ + if(!opened) + return; + + syslog(prio | facility, "%s", msg.c_str()); +} + +LogTargetSyslog& LogTargetSyslog::setLogName(std::string l) +{ + logname = l; + if(opened) + close(); + open(); + return *this; +} + +LogTargetSyslog& LogTargetSyslog::setFacility(int f) +{ + facility = f; + if(opened) + close(); + open(); + return *this; +} +#endif + + +#ifdef LOG_FILE +LogTargetFile::LogTargetFile(int prio, std::string conf) : LogTarget(prio) +{ + std::stringstream s(conf); + getline(s, logfilename, ','); + if(s.fail()) + logfilename = "anytun.log"; +} + +LogTargetFile::~LogTargetFile() +{ + if(opened) + close(); +} + +void LogTargetFile::open() +{ + logfile.open(logfilename.c_str(), std::fstream::out | std::fstream::app); + opened = logfile.is_open(); +} + +void LogTargetFile::close() +{ + if(logfile.is_open()) + logfile.close(); + opened = false; +} + +void LogTargetFile::log(std::string msg, int prio) +{ + if(!opened) + return; + + logfile << Log::prioToString(prio) << ": " << msg << std::endl; +} + +LogTargetFile& LogTargetFile::setLogFilename(std::string l) +{ + logfilename = l; + if(opened) + close(); + open(); + return *this; +} +#endif + + +#ifdef LOG_STDOUT +LogTargetStdout::LogTargetStdout(int prio, std::ostream& s) : LogTarget(prio), stream(s) +{ +} + +LogTargetStdout::~LogTargetStdout() +{ + if(opened) + close(); +} + +void LogTargetStdout::open() +{ + opened = true; +} + +void LogTargetStdout::close() +{ + opened = false; +} + +void LogTargetStdout::log(std::string msg, int prio) +{ + if(!opened) + return; + + stream << "LOG-" << Log::prioToString(prio) << ": " << msg << std::endl; +} +#endif + + +#ifdef LOG_WINEVENTLOG +LogTargetWinEventlog::LogTargetWinEventlog(int prio, std::string conf) : LogTarget(prio) +{ + std::stringstream s(conf); + getline(s, logname, ','); + if(s.fail()) + logname = "anytun"; +} + +LogTargetWinEventlog::~LogTargetWinEventlog() +{ + if(opened) + close(); +} + +void LogTargetWinEventlog::open() +{ + h_event_source = RegisterEventSourceA(NULL, logname.c_str()); + if(h_event_source) + opened = true; +} + +void LogTargetWinEventlog::close() +{ + if(h_event_source) + DeregisterEventSource(h_event_source); + opened = false; +} + +void LogTargetWinEventlog::log(std::string msg, int prio) +{ + if(!opened) + return; + + LPCTSTR lpszStrings[1]; + CHAR buffer[STERROR_TEXT_MAX]; + StringCchPrintfA(buffer, STERROR_TEXT_MAX, "%s", msg.c_str()); + lpszStrings[0] = buffer; + if(log.h_event_source) + ReportEventA(log.h_event_source_, Log::prioToEventLogType(prio), 0, prio, NULL, 1, 0, lpszStrings, NULL); +} + +LogTargetEventlog& LogTargetWinEventlog::setLogName(std::string l) +{ + logname = l; + if(opened) + close(); + open(); + return *this; +} + +WORD LogTargetWinEventlog::prioToEventLogType(int prio) +{ + switch(prio) { + case PRIO_EMERG: return EVENTLOG_ERROR_TYPE; + case PRIO_ALERT: return EVENTLOG_ERROR_TYPE; + case PRIO_CRIT: return EVENTLOG_ERROR_TYPE; + case PRIO_ERR: return EVENTLOG_ERROR_TYPE; + case PRIO_WARNING: return EVENTLOG_WARNING_TYPE; + case PRIO_NOTICE: return EVENTLOG_INFORMATION_TYPE; + case PRIO_INFO: return EVENTLOG_SUCCESS; + case PRIO_DEBUG: return EVENTLOG_INFORMATION_TYPE; + default: return EVENTLOG_ERROR_TYPE; + } +} +#endif diff --git a/src/logTargets.h b/src/logTargets.h new file mode 100644 index 0000000..4f249d4 --- /dev/null +++ b/src/logTargets.h @@ -0,0 +1,200 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with anytun. If not, see . + */ + +#ifndef _LOG_TARGETS_H_ +#define _LOG_TARGETS_H_ + +#include +#include + +#ifdef LOG_SYSLOG +#include +#endif + +#ifdef LOG_FILE +#include +#endif + +class LogTarget +{ +public: + LogTarget();; + LogTarget(int prio); + + virtual void open() = 0; + virtual void close() = 0; + bool isOpen() { return opened; }; + + void enable() { enabled = true; }; + void disable() { enabled = false; }; + bool isEnabled() { return enabled; }; + + int getMaxPrio() { return max_prio; }; + void setMaxPrio(int p) { max_prio = p; }; + + virtual void log(std::string msg, int prio) = 0; + +protected: + bool opened; + bool enabled; + int max_prio; +}; + +class LogTargetList +{ +public: + typedef enum { TARGET_UNKNOWN, TARGET_SYSLOG, TARGET_FILE, + TARGET_STDOUT, TARGET_STDERR, TARGET_WINEVENTLOG } target_type_t; + + static target_type_t targetTypeFromString(std::string type); + static std::string targetTypeToString(target_type_t type); + + ~LogTargetList(); + LogTarget* add(std::string conf); + LogTarget* add(target_type_t type, int prio, std::string conf); + void clear(); + + void log(std::string msg, int prio); + +private: + typedef std::multimap TargetsMap; + TargetsMap targets; +}; + + +#ifdef LOG_SYSLOG +class LogTargetSyslog : public LogTarget +{ +public: + static const int FAC_USER = LOG_USER; + static const int FAC_MAIL = LOG_MAIL; + static const int FAC_DAEMON = LOG_DAEMON; + static const int FAC_AUTH = LOG_AUTH; + static const int FAC_SYSLOG = LOG_SYSLOG; + static const int FAC_LPR = LOG_LPR; + static const int FAC_NEWS = LOG_NEWS; + static const int FAC_UUCP = LOG_UUCP; + static const int FAC_CRON = LOG_CRON; + static const int FAC_AUTHPRIV = LOG_AUTHPRIV; + static const int FAC_FTP = LOG_FTP; + static const int FAC_LOCAL0 = LOG_LOCAL0; + static const int FAC_LOCAL1 = LOG_LOCAL1; + static const int FAC_LOCAL2 = LOG_LOCAL2; + static const int FAC_LOCAL3 = LOG_LOCAL3; + static const int FAC_LOCAL4 = LOG_LOCAL4; + static const int FAC_LOCAL5 = LOG_LOCAL5; + static const int FAC_LOCAL6 = LOG_LOCAL6; + static const int FAC_LOCAL7 = LOG_LOCAL7; + + static int facilityFromString(std::string fac); + static std::string facilityToString(int fac); + + LogTargetSyslog(int prio, std::string conf); + ~LogTargetSyslog(); + + void open(); + void close(); + void log(std::string msg, int prio); + static bool duplicateAllowed() { return false; }; + + LogTargetSyslog& setLogName(std::string l); + std::string getLogName() const { return logname; } + LogTargetSyslog& setFacility(int f); + int getFacility() const { return facility; } + +private: + std::string logname; + int facility; +}; +#endif + +#ifdef LOG_FILE +class LogTargetFile : public LogTarget +{ +public: + LogTargetFile(int prio, std::string conf); + ~LogTargetFile(); + + void open(); + void close(); + void log(std::string msg, int prio); + static bool duplicateAllowed() { return true; }; + + LogTargetFile& setLogFilename(std::string l); + std::string getLogFilename() const { return logfilename; } + +private: + std::string logfilename; + std::ofstream logfile; +}; +#endif + +#ifdef LOG_STDOUT +class LogTargetStdout : public LogTarget +{ +public: + LogTargetStdout(int prio, std::ostream& s); + ~LogTargetStdout(); + + void open(); + void close(); + void log(std::string msg, int prio); + static bool duplicateAllowed() { return false; }; + +private: + std::ostream& stream; +}; +#endif + +#ifdef LOG_WINEVENTLOG +class LogTargetWinEventlog : public LogTarget +{ +public: + LogTargetWinEventlog(int prio, std::string conf); + ~LogTargetWinEventlog(); + + void open(); + void close(); + void log(std::string msg, int prio); + static bool duplicateAllowed() { return false; }; + + LogTargetWinEventlog& setLogName(std::string l); + std::string getLogName() const { return logname; } + +private: + static WORD prioToEventLogType(int prio); + + std::string logname; + HANDLE h_event_source; +}; +#endif + +#endif -- cgit v1.2.3