From 2dcab0372d9b7604aee8e0034599a5a2cbb66613 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Fri, 11 Apr 2008 15:26:41 +0000 Subject: added chroot and drop privileges added write-pid option --- anytun.cpp | 53 ++++++++++++++++++++++++++++++++++++++++++++++++- options.cpp | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ options.h | 12 +++++++++++ 3 files changed, 130 insertions(+), 1 deletion(-) diff --git a/anytun.cpp b/anytun.cpp index a115ff6..cb25349 100644 --- a/anytun.cpp +++ b/anytun.cpp @@ -29,8 +29,11 @@ */ #include +#include #include #include +#include +#include #include #include // 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] 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 ] the sender id to use" << std::endl; std::cout << " [-i|--interface] local anycast ip address to bind to" << std::endl; std::cout << " [-p|--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_; -- cgit v1.2.3