From 346ef768b1b911a89e3d9bc1b03b442fd85d3739 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Sat, 6 Feb 2010 18:12:12 +0000 Subject: introduced posixDaemon as DaemonService for posix targets some dependency cleanups --- src/Makefile | 26 +++++--- src/anytun-controld.cpp | 21 +++--- src/anytun.cpp | 28 ++++---- src/anytun.vcproj | 36 +++++----- src/configure | 6 ++ src/daemon.hpp | 167 ---------------------------------------------- src/nullDaemon.cpp | 58 ++++++++++++++++ src/nullDaemon.h | 48 +++++++++++++ src/options.cpp | 4 +- src/posix/posixDaemon.cpp | 160 ++++++++++++++++++++++++++++++++++++++++++++ src/posix/posixDaemon.h | 55 +++++++++++++++ src/signalController.h | 8 ++- src/win32/winService.cpp | 25 +++++++ src/win32/winService.h | 8 +++ 14 files changed, 422 insertions(+), 228 deletions(-) delete mode 100644 src/daemon.hpp create mode 100644 src/nullDaemon.cpp create mode 100644 src/nullDaemon.h create mode 100644 src/posix/posixDaemon.cpp create mode 100644 src/posix/posixDaemon.h (limited to 'src') diff --git a/src/Makefile b/src/Makefile index 6a3683d..ec4e34f 100644 --- a/src/Makefile +++ b/src/Makefile @@ -34,9 +34,7 @@ ifneq ($(MAKECMDGOALS),distclean) include include.mk endif -OBJS := tunDevice.o \ - packetSource.o \ - buffer.o \ +OBJS := buffer.o \ syncBuffer.o \ plainPacket.o \ encryptedPacket.o \ @@ -51,7 +49,6 @@ OBJS := tunDevice.o \ networkAddress.o \ networkPrefix.o \ routingTable.o \ - signalController.o \ log.o \ logTargets.o \ sysExec.o \ @@ -61,6 +58,11 @@ OBJS := tunDevice.o \ routingTreeNode.o \ resolver.o +ANYTUNOBJS := tunDevice.o \ + packetSource.o \ + signalController.o \ + daemonService.o + SYNCOBJS := syncServer.o \ syncClient.o \ syncQueue.o \ @@ -70,6 +72,7 @@ SYNCOBJS := syncServer.o \ syncTcpConnection.o ANYCTROBJS := signalController.o \ + daemonService.o \ anyCtrOptions.o \ buffer.o \ log.o \ @@ -107,6 +110,7 @@ EXEOBJS := anytun.o anytun-config.o anytun-controld.o anytun-showtables.o SRCS := $(OBJS:%.o=%.cpp) SYNCSRCS := $(SYNCOBJS:%.o=%.cpp) +ANYTUNSRCS := $(ANYTUNOBJS:%.o=%.cpp) ANYCTRSRCS := $(ANYCTROBJS:%.o=%.cpp) ANYCONFSRCS := $(ANYCONFOBJS:%.o=%.cpp) EXESRCS := $(EXEOBJS:%.o=%.cpp) @@ -122,21 +126,21 @@ all: $(EXECUTABLES) #libAnysync.a rm -f $@.$$$$; echo '(re)building $@' ifneq ($(MAKECMDGOALS),distclean) --include $(SRCS:%.cpp=%.d) $(SYNCSRCS:%.cpp=%.d) $(ANYCTRSRCS:%.cpp=%.d) $(ANYCONFSRCS:%.cpp=%.d) $(EXESRCS:%.cpp=%.d) +-include $(SRCS:%.cpp=%.d) $(SYNCSRCS:%.cpp=%.d) $(ANYTUNSRCS:%.cpp=%.d) $(ANYCTRSRCS:%.cpp=%.d) $(ANYCONFSRCS:%.cpp=%.d) $(EXESRCS:%.cpp=%.d) endif strip: $(EXECUTABLES) $(STRIP) -s $(EXECUTABLES) -anytun: $(OBJS) $(SYNCOBJS) anytun.o - $(LD) $(OBJS) $(SYNCOBJS) anytun.o -o $@ $(LDFLAGS) +anytun: $(OBJS) $(ANYTUNOBJS) $(SYNCOBJS) anytun.o + $(LD) $(OBJS) $(ANYTUNOBJS) $(SYNCOBJS) anytun.o -o $@ $(LDFLAGS) -anytun-static: $(OBJS) $(SYNCOBJS) anytun-noprivdrop.o - $(LD) $(OBJS) $(SYNCOBJS) anytun-noprivdrop.o -o $@ -Bstatic -lstdc++ -static $(LDFLAGS) -lpthread +anytun-static: $(OBJS) $(ANYTUNOBJS) $(SYNCOBJS) anytun-noprivdrop.o + $(LD) $(OBJS) $(ANYTUNOBJS) $(SYNCOBJS) anytun-noprivdrop.o -o $@ -Bstatic -lstdc++ -static $(LDFLAGS) -lpthread $(STRIP) -s anytun-static -anytun-nosync: $(OBJS) anytun-nosync.o - $(LD) $(OBJS) anytun-nosync.o -o $@ $(LDFLAGS) +anytun-nosync: $(OBJS) $(ANYTUNOBJS) anytun-nosync.o + $(LD) $(OBJS) $(ANYTUNOBJS) anytun-nosync.o -o $@ $(LDFLAGS) anytun-nosync.o: anytun.cpp $(CXX) $(CXXFLAGS) -DANYTUN_NOSYNC $< -c -o anytun-nosync.o diff --git a/src/anytun-controld.cpp b/src/anytun-controld.cpp index 724296d..43196dc 100644 --- a/src/anytun-controld.cpp +++ b/src/anytun-controld.cpp @@ -46,7 +46,7 @@ #include "resolver.h" #include "syncServer.h" -#include "daemon.hpp" +#include "daemonService.h" #include std::list config_; @@ -77,7 +77,7 @@ void syncListener() int main(int argc, char* argv[]) { - bool daemonized=false; + DaemonService daemon; try { try @@ -114,15 +114,14 @@ int main(int argc, char* argv[]) exit(-1); } - PrivInfo privs(gOpt.getUsername(), gOpt.getGroupname()); - if(gOpt.getDaemonize()) { - daemonize(); - daemonized = true; - } + daemon.initPrivs(gOpt.getUsername(), gOpt.getGroupname()); + if(gOpt.getDaemonize()) + daemon.daemonize(); if(gOpt.getChrootDir() != "") - do_chroot(gOpt.getChrootDir()); - privs.drop(); + daemon.chroot(gOpt.getChrootDir()); + daemon.dropPrivs(); + gSignalController.init(); gResolver.init(); @@ -135,14 +134,14 @@ int main(int argc, char* argv[]) } catch(std::runtime_error& e) { - if(daemonized) + if(daemon.isDaemonized()) cLog.msg(Log::PRIO_ERROR) << "uncaught runtime error, exiting: " << e.what(); else std::cout << "uncaught runtime error, exiting: " << e.what() << std::endl; } catch(std::exception& e) { - if(daemonized) + if(daemon.isDaemonized()) cLog.msg(Log::PRIO_ERROR) << "uncaught exception, exiting: " << e.what(); else std::cout << "uncaught exception, exiting: " << e.what() << std::endl; diff --git a/src/anytun.cpp b/src/anytun.cpp index 384b7c3..ddec0c0 100644 --- a/src/anytun.cpp +++ b/src/anytun.cpp @@ -50,8 +50,14 @@ #include "authAlgoFactory.h" #include "keyDerivationFactory.h" #include "signalController.h" +#ifndef _MSC_VER +#include "daemonService.h" +#else #ifdef WIN_SERVICE #include "win32/winService.h" +#else +#include "nullDaemon.h" +#endif #endif #include "packetSource.h" #include "tunDevice.h" @@ -73,7 +79,6 @@ #endif #include "cryptinit.hpp" -#include "daemon.hpp" #include "sysExec.h" bool disableRouting = false; @@ -359,7 +364,8 @@ int real_main(int argc, char* argv[], WinService* service) #else int main(int argc, char* argv[]) { - DaemonService* service = NULL; + DaemonService daemon; + DaemonService* service = &daemon; bool daemonized=false; #endif try @@ -384,16 +390,11 @@ int main(int argc, char* argv[]) gOpt.parse_post(); // print warnings // daemonizing has to done before any thread gets started -#ifndef NO_DAEMON -#ifndef NO_PRIVDROP - PrivInfo privs(gOpt.getUsername(), gOpt.getGroupname()); -#endif + service->initPrivs(gOpt.getUsername(), gOpt.getGroupname()); if(gOpt.getDaemonize()) { - daemonize(); + service->daemonize(); daemonized = true; } -#endif - OptionNetwork net = gOpt.getIfconfigParam(); TunDevice dev(gOpt.getDevName(), gOpt.getDevType(), net.net_addr, net.prefix_length); @@ -407,19 +408,16 @@ int main(int argc, char* argv[]) postup_script = new SysExec(gOpt.getPostUpScript(), args); } -#ifndef NO_DAEMON if(gOpt.getChrootDir() != "") { try { - do_chroot(gOpt.getChrootDir()); + service->chroot(gOpt.getChrootDir()); } catch(const std::runtime_error& e) { cLog.msg(Log::PRIO_WARNING) << "ignoring chroot error: " << e.what(); } } -#ifndef NO_PRIVDROP - privs.drop(); -#endif -#endif + service->dropPrivs(); + // this has to be called before the first thread is started gSignalController.init(service); gResolver.init(); diff --git a/src/anytun.vcproj b/src/anytun.vcproj index fea7ffa..721daee 100644 --- a/src/anytun.vcproj +++ b/src/anytun.vcproj @@ -46,7 +46,7 @@ Name="VCCLCompilerTool" AdditionalOptions="/I "C:\Program Files\boost\boost_1_35_0\"" Optimization="0" - PreprocessorDefinitions="LOG_FILE;LOG_STDOUT;LOG_WINEVENTLOG;USE_SSL_CRYPTO;NO_DAEMON;WIN32_LEAN_AND_MEAN;NOMINMAX;BOOST_ALL_DYN_LINK" + PreprocessorDefinitions="LOG_FILE;LOG_STDOUT;LOG_WINEVENTLOG;USE_SSL_CRYPTO;WIN32_LEAN_AND_MEAN;NOMINMAX;BOOST_ALL_DYN_LINK" MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="3" @@ -120,7 +120,7 @@ /> - - diff --git a/src/configure b/src/configure index 1524577..bcadb99 100755 --- a/src/configure +++ b/src/configure @@ -150,6 +150,9 @@ case $TARGET in ln -sf posix/signalHandler.hpp rm -f sysExec.hpp ln -sf posix/sysExec.hpp + rm -f daemonService.h daemonService.cpp + ln -sf posix/posixDaemon.h daemonService.h + ln -sf posix/posixDaemon.cpp daemonService.cpp echo "loading Linux specific TUN Device" ;; OpenBSD|FreeBSD|NetBSD|GNU/kFreeBSD) @@ -159,6 +162,9 @@ case $TARGET in ln -sf posix/signalHandler.hpp rm -f sysExec.hpp ln -sf posix/sysExec.hpp + rm -f daemonService.h daemonService.cpp + ln -sf posix/posixDaemon.h daemonService.h + ln -sf posix/posixDaemon.cpp daemonService.cpp echo "loading BSD specific TUN Device" CXXFLAGS=$CXXFLAGS' -I/usr/local/include' LDFLAGS=$LDFLAGS' -L/usr/local/lib' diff --git a/src/daemon.hpp b/src/daemon.hpp deleted file mode 100644 index 850f57a..0000000 --- a/src/daemon.hpp +++ /dev/null @@ -1,167 +0,0 @@ -/* - * 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-2009 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 as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * 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 ANYTUN_daemon_hpp_INCLUDED -#define ANYTUN_daemon_hpp_INCLUDED -#ifndef NO_DAEMON - -#include -#include -#include -#include -#include -#include -#include - -#include "log.h" -#include "anytunError.h" - -#ifndef NO_PRIVDROP -class PrivInfo -{ -public: - PrivInfo(std::string const& username, std::string const& groupname) - { - pw_ = NULL; - gr_ = NULL; - - if(username == "") - return; - - pw_ = getpwnam(username.c_str()); - if(!pw_) - AnytunError::throwErr() << "unknown user " << username; - - if(groupname != "") - gr_ = getgrnam(groupname.c_str()); - else - gr_ = getgrgid(pw_->pw_gid); - - if(!gr_) - AnytunError::throwErr() << "unknown group " << groupname; - } - - void drop() - { - if(!pw_ || !gr_) - return; - - if(setgid(gr_->gr_gid)) - AnytunError::throwErr() << "setgid('" << gr_->gr_name << "') failed: " << AnytunErrno(errno); - - gid_t gr_list[1]; - gr_list[0] = gr_->gr_gid; - if(setgroups (1, gr_list)) - AnytunError::throwErr() << "setgroups(['" << gr_->gr_name << "']) failed: " << AnytunErrno(errno); - - if(setuid(pw_->pw_uid)) - AnytunError::throwErr() << "setuid('" << pw_->pw_name << "') failed: " << AnytunErrno(errno); - - cLog.msg(Log::PRIO_NOTICE) << "dropped privileges to " << pw_->pw_name << ":" << gr_->gr_name; - } - -private: - struct passwd* pw_; - struct group* gr_; -}; -#endif - -void do_chroot(std::string const& chrootdir) -{ - if (getuid() != 0) - AnytunError::throwErr() << "this program has to be run as root in order to run in a chroot"; - - if(chroot(chrootdir.c_str())) - AnytunError::throwErr() << "can't chroot to " << chrootdir; - - cLog.msg(Log::PRIO_NOTICE) << "we are in chroot jail (" << chrootdir << ") now" << std::endl; - if(chdir("/")) - AnytunError::throwErr() << "can't change to /"; -} - -void daemonize() -{ - std::ofstream pidFile; - if(gOpt.getPidFile() != "") { - pidFile.open(gOpt.getPidFile().c_str()); - if(!pidFile.is_open()) - AnytunError::throwErr() << "can't open pid file (" << gOpt.getPidFile() << "): " << AnytunErrno(errno); - } - - pid_t pid; - - pid = fork(); - if(pid < 0) - AnytunError::throwErr() << "daemonizing failed at fork(): " << AnytunErrno(errno) << ", exitting"; - - if(pid) exit(0); - - umask(0); - - if(setsid() < 0) - AnytunError::throwErr() << "daemonizing failed at setsid(): " << AnytunErrno(errno) << ", exitting"; - - pid = fork(); - if(pid < 0) - AnytunError::throwErr() << "daemonizing failed at fork(): " << AnytunErrno(errno) << ", exitting"; - - if(pid) exit(0); - - if ((chdir("/")) < 0) - AnytunError::throwErr() << "daemonizing failed at chdir(): " << AnytunErrno(errno) << ", exitting"; - -// std::cout << "running in background now..." << std::endl; - - int fd; -// for (fd=getdtablesize();fd>=0;--fd) // close all file descriptors - for (fd=0;fd<=2;fd++) // close all file descriptors - close(fd); - fd = open("/dev/null",O_RDWR); // stdin - if(fd == -1) - cLog.msg(Log::PRIO_WARNING) << "can't open /dev/null as stdin"; - else { - if(dup(fd) == -1) // stdout - cLog.msg(Log::PRIO_WARNING) << "can't open /dev/null as stdout"; - if(dup(fd) == -1) // stderr - cLog.msg(Log::PRIO_WARNING) << "can't open /dev/null as stderr"; - } - - if(pidFile.is_open()) { - pid_t pid = getpid(); - pidFile << pid; - pidFile.close(); - } - - setpgid(0, 0); -} -#endif -#endif diff --git a/src/nullDaemon.cpp b/src/nullDaemon.cpp new file mode 100644 index 0000000..5c1235c --- /dev/null +++ b/src/nullDaemon.cpp @@ -0,0 +1,58 @@ +/* + * 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-2009 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 as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * 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 "nullDaemon.h" + +void DaemonService::initPrivs(std::string const& username, std::string const& groupname) +{ +// nothing here +} + +void DaemonService::dropPrivs() +{ +// nothing here +} + +void DaemonService::chroot(std::string const& chrootdir) +{ +// nothing here +} + +void DaemonService::daemonize() +{ +// nothing here +} + +bool DaemonService::isDaemonized() +{ + return false; +} diff --git a/src/nullDaemon.h b/src/nullDaemon.h new file mode 100644 index 0000000..379b300 --- /dev/null +++ b/src/nullDaemon.h @@ -0,0 +1,48 @@ +/* + * 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-2009 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 as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * 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 ANYTUN_nullDaemon_h_INCLUDED +#define ANYTUN_nullDaemon_h_INCLUDED + +#include + +class DaemonService +{ +public: + void initPrivs(std::string const& username, std::string const& groupname); + void dropPrivs(); + void chroot(std::string const& dir); + void daemonize(); + bool isDaemonized(); +}; + +#endif diff --git a/src/options.cpp b/src/options.cpp index 6458621..5d70751 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -384,7 +384,7 @@ bool Options::parse(int argc, char* argv[]) #if defined(ANYTUN_OPTIONS) || defined(ANYCTR_OPTIONS) - #ifndef NO_DAEMON + #ifndef _MSC_VER PARSE_INVERSE_BOOL_PARAM("-D","--nodaemonize", daemonize_, NOTHING) PARSE_SCALAR_PARAM("-u","--username", username_, NOTHING) PARSE_SCALAR_PARAM("-g","--groupname", groupname_, NOTHING) @@ -556,7 +556,7 @@ void Options::printUsage() #if defined(ANYTUN_OPTIONS) || defined(ANYCTR_OPTIONS) - #ifndef NO_DAEMON + #ifndef _MSC_VER std::cout << " [-D|--nodaemonize] don't run in background" << std::endl; std::cout << " [-u|--username] change to this user" << std::endl; std::cout << " [-g|--groupname] change to this group" << std::endl; diff --git a/src/posix/posixDaemon.cpp b/src/posix/posixDaemon.cpp new file mode 100644 index 0000000..4b4f63b --- /dev/null +++ b/src/posix/posixDaemon.cpp @@ -0,0 +1,160 @@ +/* + * 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-2009 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 as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * 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 +#include +#include +#include +#include +#include + +#include "daemonService.h" +#include "log.h" +#include "options.h" +#include "anytunError.h" + +DaemonService::DaemonService() : pw_(NULL), gr_(NULL), daemonized_(false) +{ +} + +void DaemonService::initPrivs(std::string const& username, std::string const& groupname) +{ + if(username == "") + return; + + pw_ = getpwnam(username.c_str()); + if(!pw_) + AnytunError::throwErr() << "unknown user " << username; + + if(groupname != "") + gr_ = getgrnam(groupname.c_str()); + else + gr_ = getgrgid(pw_->pw_gid); + + if(!gr_) + AnytunError::throwErr() << "unknown group " << groupname; +} + +void DaemonService::dropPrivs() +{ + if(!pw_ || !gr_) + return; + + if(setgid(gr_->gr_gid)) + AnytunError::throwErr() << "setgid('" << gr_->gr_name << "') failed: " << AnytunErrno(errno); + + gid_t gr_list[1]; + gr_list[0] = gr_->gr_gid; + if(setgroups (1, gr_list)) + AnytunError::throwErr() << "setgroups(['" << gr_->gr_name << "']) failed: " << AnytunErrno(errno); + + if(setuid(pw_->pw_uid)) + AnytunError::throwErr() << "setuid('" << pw_->pw_name << "') failed: " << AnytunErrno(errno); + + cLog.msg(Log::PRIO_NOTICE) << "dropped privileges to " << pw_->pw_name << ":" << gr_->gr_name; +} + +void DaemonService::chroot(std::string const& chrootdir) +{ + if (getuid() != 0) + AnytunError::throwErr() << "this program has to be run as root in order to run in a chroot"; + + if(::chroot(chrootdir.c_str())) + AnytunError::throwErr() << "can't chroot to " << chrootdir; + + cLog.msg(Log::PRIO_NOTICE) << "we are in chroot jail (" << chrootdir << ") now" << std::endl; + if(chdir("/")) + AnytunError::throwErr() << "can't change to /"; +} + +void DaemonService::daemonize() +{ + std::ofstream pidFile; + if(gOpt.getPidFile() != "") { + pidFile.open(gOpt.getPidFile().c_str()); + if(!pidFile.is_open()) + AnytunError::throwErr() << "can't open pid file (" << gOpt.getPidFile() << "): " << AnytunErrno(errno); + } + + pid_t pid; + + pid = fork(); + if(pid < 0) + AnytunError::throwErr() << "daemonizing failed at fork(): " << AnytunErrno(errno) << ", exitting"; + + if(pid) exit(0); + + umask(0); + + if(setsid() < 0) + AnytunError::throwErr() << "daemonizing failed at setsid(): " << AnytunErrno(errno) << ", exitting"; + + pid = fork(); + if(pid < 0) + AnytunError::throwErr() << "daemonizing failed at fork(): " << AnytunErrno(errno) << ", exitting"; + + if(pid) exit(0); + + if ((chdir("/")) < 0) + AnytunError::throwErr() << "daemonizing failed at chdir(): " << AnytunErrno(errno) << ", exitting"; + +// std::cout << "running in background now..." << std::endl; + + int fd; +// for (fd=getdtablesize();fd>=0;--fd) // close all file descriptors + for (fd=0;fd<=2;fd++) // close all file descriptors + close(fd); + fd = open("/dev/null",O_RDWR); // stdin + if(fd == -1) + cLog.msg(Log::PRIO_WARNING) << "can't open /dev/null as stdin"; + else { + if(dup(fd) == -1) // stdout + cLog.msg(Log::PRIO_WARNING) << "can't open /dev/null as stdout"; + if(dup(fd) == -1) // stderr + cLog.msg(Log::PRIO_WARNING) << "can't open /dev/null as stderr"; + } + + if(pidFile.is_open()) { + pid_t pid = getpid(); + pidFile << pid; + pidFile.close(); + } + + setpgid(0, 0); + daemonized_ = true; +} + +bool DaemonService::isDaemonized() +{ + return daemonized_; +} diff --git a/src/posix/posixDaemon.h b/src/posix/posixDaemon.h new file mode 100644 index 0000000..e6d56d5 --- /dev/null +++ b/src/posix/posixDaemon.h @@ -0,0 +1,55 @@ +/* + * 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-2009 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 as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * 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 ANYTUN_posixDaemon_h_INCLUDED +#define ANYTUN_posixDaemon_h_INCLUDED + +#include + +class DaemonService +{ +public: + DaemonService(); + + void initPrivs(std::string const& username, std::string const& groupname); + void dropPrivs(); + void chroot(std::string const& dir); + void daemonize(); + bool isDaemonized(); + +private: + struct passwd* pw_; + struct group* gr_; + bool daemonized_; +}; + +#endif diff --git a/src/signalController.h b/src/signalController.h index fdc778a..8a82c9e 100644 --- a/src/signalController.h +++ b/src/signalController.h @@ -38,11 +38,15 @@ #include #include "threadUtils.hpp" + +#ifndef _MSC_VER +#include "daemonService.h" +#else #ifdef WIN_SERVICE #include "win32/winService.h" -typedef class WinService DaemonService; #else -typedef void DaemonService; +#include "nullDaemon.h" +#endif #endif #define SIGERROR -1 diff --git a/src/win32/winService.cpp b/src/win32/winService.cpp index f796fcf..e39fe56 100644 --- a/src/win32/winService.cpp +++ b/src/win32/winService.cpp @@ -169,4 +169,29 @@ void WinService::reportStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode) SetServiceStatus(status_handle_, &status_); } +void WinService::initPrivs(std::string const& username, std::string const& groupname) +{ +// nothing here +} + +void WinService::dropPrivs() +{ +// nothing here +} + +void WinService::chroot(std::string const& dir) +{ +// nothing here +} + +void WinService::daemonize() +{ +// nothing here +} + +bool WinService::isDaemonized() +{ + return true; +} + #endif diff --git a/src/win32/winService.h b/src/win32/winService.h index ed05367..ecba55d 100644 --- a/src/win32/winService.h +++ b/src/win32/winService.h @@ -52,6 +52,12 @@ public: void reportStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode); int handleCtrlSignal(int sig, const std::string& msg); + void initPrivs(std::string const& username, std::string const& groupname); + void dropPrivs(); + void chroot(std::string const& dir); + void daemonize(); + bool isDaemonized(); + private: WinService() {}; ~WinService() {}; @@ -62,6 +68,8 @@ private: SERVICE_STATUS_HANDLE status_handle_; }; +typedef class WinService DaemonService; + #endif #endif -- cgit v1.2.3