summaryrefslogtreecommitdiff
path: root/src/posix/posixDaemon.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/posix/posixDaemon.cpp')
-rw-r--r--src/posix/posixDaemon.cpp160
1 files changed, 160 insertions, 0 deletions
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 <satp@wirdorange.org>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <poll.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <grp.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#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_;
+}