summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--anytun.cpp53
-rw-r--r--options.cpp66
-rw-r--r--options.h12
3 files changed, 130 insertions, 1 deletions
diff --git a/anytun.cpp b/anytun.cpp
index a115ff6..cb25349 100644
--- a/anytun.cpp
+++ b/anytun.cpp
@@ -29,8 +29,11 @@
*/
#include <iostream>
+#include <fstream>
#include <poll.h>
#include <fcntl.h>
+#include <pwd.h>
+#include <grp.h>
#include <gcrypt.h>
#include <cerrno> // for ENOMEM
@@ -302,7 +305,7 @@ void* receiver(void* p)
pthread_exit(NULL);
}
-#define MIN_GCRYPT_VERSION "1.2.3"
+#define MIN_GCRYPT_VERSION "1.2.0"
// make libgcrypt thread safe
extern "C" {
GCRY_THREAD_OPTION_PTHREAD_IMPL;
@@ -338,6 +341,37 @@ bool initLibGCrypt()
return true;
}
+void chrootAndDrop(string const& chrootdir, string const& username)
+{
+ if (getuid() != 0)
+ {
+ std::cerr << "this programm has to be run as root in order to run in a chroot" << std::endl;
+ exit(-1);
+ }
+
+ struct passwd *pw = getpwnam(username.c_str());
+ if(pw) {
+ if(chroot(chrootdir.c_str()))
+ {
+ std::cerr << "can't chroot to " << chrootdir << std::endl;
+ exit(-1);
+ }
+ std::cout << "we are in chroot jail (" << chrootdir << ") now" << std::endl;
+ chdir("/");
+ if (initgroups(pw->pw_name, pw->pw_gid) || setgid(pw->pw_gid) || setuid(pw->pw_uid))
+ {
+ std::cerr << "can't drop to user " << username << " " << pw->pw_uid << ":" << pw->pw_gid << std::endl;
+ exit(-1);
+ }
+ std::cout << "dropped user to " << username << " " << pw->pw_uid << ":" << pw->pw_gid << std::endl;
+ }
+ else
+ {
+ std::cerr << "unknown user " << username << std::endl;
+ exit(-1);
+ }
+}
+
void daemonize()
{
pid_t pid;
@@ -358,6 +392,18 @@ void daemonize()
dup(fd); // stderr
umask(027);
}
+
+void writePid(string const& pidFilename)
+{
+ std::ofstream pidFile(pidFilename.c_str());
+ if(!pidFile.is_open()) {
+ std::cout << "can't open pid file" << std::endl;
+ return;
+ }
+ pid_t pid = getpid();
+ pidFile << pid;
+ pidFile.close();
+}
int main(int argc, char* argv[])
{
@@ -367,8 +413,13 @@ int main(int argc, char* argv[])
gOpt.printUsage();
exit(-1);
}
+
+ if(gOpt.getChroot())
+ chrootAndDrop(gOpt.getChrootDir(), gOpt.getUsername());
if(gOpt.getDaemonize())
daemonize();
+ if(gOpt.getPidFile() != "")
+ writePid(gOpt.getPidFile());
cLog.msg(Log::PRIO_NOTICE) << "anytun started...";
diff --git a/options.cpp b/options.cpp
index 53589cb..86fd50a 100644
--- a/options.cpp
+++ b/options.cpp
@@ -54,6 +54,10 @@ Options::Options() : key_(u_int32_t(0)), salt_(u_int32_t(0))
{
progname_ = "anytun";
daemonize_ = true;
+ chroot_ = false;
+ username_ = "nobody";
+ chroot_dir_ = "/var/run/anytun";
+ pid_file_ = "";
sender_id_ = 0;
local_addr_ = "";
local_port_ = 4444;
@@ -152,6 +156,10 @@ bool Options::parse(int argc, char* argv[])
if(str == "-h" || str == "--help")
return false;
PARSE_INVERSE_BOOL_PARAM("-D","--nodaemonize", daemonize_)
+ PARSE_BOOL_PARAM("-C","--chroot", chroot_)
+ PARSE_SCALAR_PARAM("-u","--username", username_)
+ PARSE_SCALAR_PARAM("-H","--chroot-dir", chroot_dir_)
+ PARSE_SCALAR_PARAM("-P","--write-pid", pid_file_)
PARSE_SCALAR_PARAM("-s","--sender-id", sender_id_)
PARSE_SCALAR_PARAM("-i","--interface", local_addr_)
PARSE_SCALAR_PARAM("-p","--port", local_port_)
@@ -201,6 +209,10 @@ void Options::printUsage()
std::cout << "anytun [-h|--help] prints this..." << std::endl;
// std::cout << " [-f|--config] <file> the config file" << std::endl;
std::cout << " [-D|--nodaemonize] don't run in background" << std::endl;
+ std::cout << " [-C|--chroot] chroot and drop privileges" << std::endl;
+ std::cout << " [-u|--username] if chroot change to this user" << std::endl;
+ std::cout << " [-H|--chroot-dir] chroot to this directory" << std::endl;
+ std::cout << " [-P|--write-pid] write pid to this file" << std::endl;
std::cout << " [-s|--sender-id ] <sender id> the sender id to use" << std::endl;
std::cout << " [-i|--interface] <ip-address> local anycast ip address to bind to" << std::endl;
std::cout << " [-p|--port] <port> local anycast(data) port to bind to" << std::endl;
@@ -228,6 +240,10 @@ void Options::printOptions()
Lock lock(mutex);
std::cout << "Options:" << std::endl;
std::cout << "daemonize=" << daemonize_ << std::endl;
+ std::cout << "chroot=" << chroot_ << std::endl;
+ std::cout << "username='" << username_ << "'" << std::endl;
+ std::cout << "chroot_dir='" << chroot_dir_ << "'" << std::endl;
+ std::cout << "pid_file='" << pid_file_ << "'" << std::endl;
std::cout << "sender_id='" << sender_id_ << "'" << std::endl;
std::cout << "local_addr='" << local_addr_ << "'" << std::endl;
std::cout << "local_port='" << local_port_ << "'" << std::endl;
@@ -273,6 +289,56 @@ Options& Options::setDaemonize(bool d)
return *this;
}
+bool Options::getChroot()
+{
+ return chroot_;
+}
+
+Options& Options::setChroot(bool c)
+{
+ chroot_ = c;
+ return *this;
+}
+
+std::string Options::getUsername()
+{
+ Lock lock(mutex);
+ return username_;
+}
+
+Options& Options::setUsername(std::string u)
+{
+ Lock lock(mutex);
+ username_ = u;
+ return *this;
+}
+
+std::string Options::getChrootDir()
+{
+ Lock lock(mutex);
+ return chroot_dir_;
+}
+
+Options& Options::setChrootDir(std::string c)
+{
+ Lock lock(mutex);
+ chroot_dir_ = c;
+ return *this;
+}
+
+std::string Options::getPidFile()
+{
+ Lock lock(mutex);
+ return pid_file_;
+}
+
+Options& Options::setPidFile(std::string p)
+{
+ Lock lock(mutex);
+ pid_file_ = p;
+ return *this;
+}
+
ConnectToList Options::getConnectTo()
{
Lock lock(mutex);
diff --git a/options.h b/options.h
index 598250e..3b68780 100644
--- a/options.h
+++ b/options.h
@@ -57,6 +57,14 @@ public:
Options& setProgname(std::string p);
bool getDaemonize();
Options& setDaemonize(bool d);
+ bool getChroot();
+ Options& setChroot(bool b);
+ std::string getUsername();
+ Options& setUsername(std::string u);
+ std::string getChrootDir();
+ Options& setChrootDir(std::string c);
+ std::string getPidFile();
+ Options& setPidFile(std::string p);
sender_id_t getSenderId();
Options& setSenderId(sender_id_t s);
std::string getLocalAddr();
@@ -121,6 +129,10 @@ private:
ConnectToList connect_to_;
std::string progname_;
bool daemonize_;
+ bool chroot_;
+ std::string username_;
+ std::string chroot_dir_;
+ std::string pid_file_;
sender_id_t sender_id_;
std::string local_addr_;
std::string local_sync_addr_;