summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@anytun.org>2008-04-11 19:07:41 +0000
committerChristian Pointner <equinox@anytun.org>2008-04-11 19:07:41 +0000
commitecd7d470831c61bc78e33cdbc786937eed0fa2d1 (patch)
tree41824072ed2504711757f302acf1f5c475917bd8
parentadded control host option (diff)
anytun-controld: bind to option
ctr: daemonize, chroot drop privs
-rw-r--r--anymuxOptions.cpp126
-rw-r--r--anymuxOptions.h27
-rw-r--r--anytun-controld.cpp84
-rw-r--r--anytun.cpp2
4 files changed, 218 insertions, 21 deletions
diff --git a/anymuxOptions.cpp b/anymuxOptions.cpp
index 92726e7..418eebd 100644
--- a/anymuxOptions.cpp
+++ b/anymuxOptions.cpp
@@ -52,9 +52,15 @@ Options& Options::instance()
Options::Options()
{
- progname_ = "anymux";
- local_port_ = 1234;
+ progname_ = "anytun-controld";
file_name_ = "";
+ daemonize_ = true;
+ chroot_ = false;
+ username_ = "nobody";
+ chroot_dir_ = "/var/run/anytun-controld";
+ pid_file_ = "";
+ bind_to_addr_ = "127.0.0.1";
+ bind_to_port_ = 4445;
}
Options::~Options()
@@ -128,6 +134,7 @@ bool Options::parse(int argc, char* argv[])
progname_ = argv[0];
argc--;
+ std::string control_host("");
for(int i=1; argc > 0; ++i)
{
std::string str(argv[i]);
@@ -135,28 +142,50 @@ bool Options::parse(int argc, char* argv[])
if(str == "-h" || str == "--help")
return false;
- PARSE_SCALAR_PARAM("-p","--port", local_port_)
PARSE_SCALAR_PARAM("-f","--file", file_name_)
+ 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("-X","--control-host", control_host)
else
return false;
}
+ if(control_host != "") {
+ std::stringstream tmp_stream(control_host);
+ getline(tmp_stream,bind_to_addr_,':');
+ if(!tmp_stream.good())
+ return false;
+ tmp_stream >> bind_to_port_;
+ }
+
return true;
}
void Options::printUsage()
{
std::cout << "USAGE:" << std::endl;
- std::cout << "anymux [-h|--help] prints this..." << std::endl;
- std::cout << " [-p|--port] <port> local port to bind to" << std::endl;
- std::cout << " [-f|--file] <path> path to file" << std::endl;
+ std::cout << "anytun-controld [-h|--help] prints this..." << 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 << " [-f|--file] <path> path to file" << std::endl;
+
}
void Options::printOptions()
{
Lock lock(mutex);
std::cout << "Options:" << std::endl;
- std::cout << "local_port='" << local_port_ << "'" << 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::string Options::getProgname()
@@ -173,13 +202,73 @@ Options& Options::setProgname(std::string p)
return *this;
}
+bool Options::getDaemonize()
+{
+ return daemonize_;
+}
+
+Options& Options::setDaemonize(bool d)
+{
+ daemonize_ = 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;
+}
+
std::string Options::getFileName()
{
Lock lock(mutex);
return file_name_;
}
-
Options& Options::setFileName(std::string f)
{
Lock lock(mutex);
@@ -187,13 +276,26 @@ Options& Options::setFileName(std::string f)
return *this;
}
-u_int16_t Options::getLocalPort()
+std::string Options::getBindToAddr()
+{
+ Lock lock(mutex);
+ return bind_to_addr_;
+}
+
+Options& Options::setBindToAddr(std::string b)
+{
+ Lock lock(mutex);
+ bind_to_addr_ = b;
+ return *this;
+}
+
+uint16_t Options::getBindToPort()
{
- return local_port_;
+ return bind_to_port_;
}
-Options& Options::setLocalPort(u_int16_t l)
+Options& Options::setBindToPort(uint16_t b)
{
- local_port_ = l;
+ bind_to_port_ = b;
return *this;
}
diff --git a/anymuxOptions.h b/anymuxOptions.h
index 45e6a93..dfbc213 100644
--- a/anymuxOptions.h
+++ b/anymuxOptions.h
@@ -36,8 +36,6 @@
#include "threadUtils.hpp"
#include <list>
-
-
class Options
{
public:
@@ -47,12 +45,25 @@ public:
void printUsage();
void printOptions();
- u_int16_t getLocalPort();
- Options& setLocalPort(u_int16_t l);
std::string getProgname();
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);
std::string getFileName();
Options& setFileName(std::string f);
+ std::string getBindToAddr();
+ Options& setBindToAddr(std::string b);
+ uint16_t getBindToPort();
+ Options& setBindToPort(uint16_t b);
+
private:
Options();
@@ -72,8 +83,14 @@ private:
Mutex mutex;
+ std::string bind_to_addr_;
+ uint16_t bind_to_port_;
std::string progname_;
- u_int16_t local_port_;
+ bool daemonize_;
+ bool chroot_;
+ std::string username_;
+ std::string chroot_dir_;
+ std::string pid_file_;
std::string file_name_;
};
diff --git a/anytun-controld.cpp b/anytun-controld.cpp
index ff5db52..204694e 100644
--- a/anytun-controld.cpp
+++ b/anytun-controld.cpp
@@ -31,6 +31,9 @@
#include <iostream>
#include <fstream>
#include <poll.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <grp.h>
#include "datatypes.h"
@@ -46,7 +49,8 @@
class ThreadParam
{
public:
- ThreadParam() : port(0) {};
+ ThreadParam() : addr(""), port(0) {};
+ std::string addr;
u_int16_t port;
};
@@ -57,7 +61,7 @@ void* syncListener(void* p )
SOCKETS_NAMESPACE::SocketHandler h;
SOCKETS_NAMESPACE::ListenSocket<MuxSocket> l(h,true);
- if( l.Bind(param->port) )
+ if( l.Bind(param->addr, param->port) )
pthread_exit(NULL);
Utility::ResolveLocal(); // resolve local hostname
@@ -67,6 +71,60 @@ void* syncListener(void* p )
h.Select(1,0);
}
}
+
+void chrootAndDrop(std::string const& chrootdir, std::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);
+ }
+ cLog.msg(Log::PRIO_NOTICE) << "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);
+ }
+ cLog.msg(Log::PRIO_NOTICE) << "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;
+
+ pid = fork();
+ if(pid) exit(0);
+ setsid();
+ pid = fork();
+ if(pid) exit(0);
+
+// 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
+ dup(fd); // stdout
+ dup(fd); // stderr
+ umask(027);
+}
+
int main(int argc, char* argv[])
{
if(!gOpt.parse(argc, argv))
@@ -84,11 +142,31 @@ int main(int argc, char* argv[])
exit(-1);
}
+ std::ofstream pidFile;
+ if(gOpt.getPidFile() != "") {
+ pidFile.open(gOpt.getPidFile().c_str());
+ if(!pidFile.is_open()) {
+ std::cout << "can't open pid file" << std::endl;
+ }
+ }
+
+ if(gOpt.getChroot())
+ chrootAndDrop(gOpt.getChrootDir(), gOpt.getUsername());
+ if(gOpt.getDaemonize())
+ daemonize();
+
+ if(pidFile.is_open()) {
+ pid_t pid = getpid();
+ pidFile << pid;
+ pidFile.close();
+ }
+
SignalController sig;
sig.init();
ThreadParam p;
- p.port = gOpt.getLocalPort();
+ p.addr = gOpt.getBindToAddr();
+ p.port = gOpt.getBindToPort();
pthread_t syncListenerThread;
pthread_create(&syncListenerThread, NULL, syncListener, &p);
diff --git a/anytun.cpp b/anytun.cpp
index a309f67..5100ab8 100644
--- a/anytun.cpp
+++ b/anytun.cpp
@@ -342,7 +342,7 @@ bool initLibGCrypt()
return true;
}
-void chrootAndDrop(string const& chrootdir, string const& username)
+void chrootAndDrop(std::string const& chrootdir, std::string const& username)
{
if (getuid() != 0)
{