View | Details | Raw Unified
Collapse All | Expand All

(-) bfilter-0.9.4/main/main_unix.cpp (-2 / +52 lines)
 Lines 26-38    Link Here 
#include <popt.h>
#include <popt.h>
#include "network.h"
#include "network.h"
#include <ipcportal.h>
#include <ipcportal.h>
#include <sys/stat.h>
#include <pwd.h>
#include <grp.h>
// some older versions of popt don't define POPT_TABLEEND
// some older versions of popt don't define POPT_TABLEEND
#ifndef POPT_TABLEEND
#ifndef POPT_TABLEEND
#define POPT_TABLEEND { NULL, '\0', 0, 0, 0, NULL, NULL }
#define POPT_TABLEEND { NULL, '\0', 0, 0, 0, NULL, NULL }
#endif
#endif
int main_unix_standalone(const std::string& confdir, bool nodaemon);
int main_unix_standalone(const std::string& confdir, bool nodaemon, char *chroot, uid_t user, gid_t group);
int main_unix_backend(Network::Socket csock, IPCPortal* portal);
int main_unix_backend(Network::Socket csock, IPCPortal* portal);
int main(int argc, char *argv[])
int main(int argc, char *argv[])
 Lines 40-55    Link Here 
	enum {
	enum {
		ARG_VERSION = 1,
		ARG_VERSION = 1,
		ARG_CONFDIR,
		ARG_CONFDIR,
		ARG_CHROOT,
		ARG_USER,
		ARG_GROUP,
		ARG_NODAEMON,
		ARG_NODAEMON,
		ARG_BACKEND
		ARG_BACKEND
	};
	};
	bool backend = false;
	bool backend = false;
	bool nodaemon = false;
	bool nodaemon = false;
	char *cdir = 0;
	char *cdir = 0;
	char *chroot = 0;
	char *user = 0;
	char *group = 0;
	uid_t uid = 0;
	uid_t gid = 0;
	std::string confdir = CONFDIR;
	std::string confdir = CONFDIR;
	struct poptOption options[] = {
	struct poptOption options[] = {
		{ "version", 'v', POPT_ARG_NONE, NULL, ARG_VERSION, "Print version and exit" },
		{ "version", 'v', POPT_ARG_NONE, NULL, ARG_VERSION, "Print version and exit" },
		{ "confdir", 'c', POPT_ARG_STRING, &cdir, ARG_CONFDIR, "Set custom config directory", "dir" },
		{ "confdir", 'c', POPT_ARG_STRING, &cdir, ARG_CONFDIR, "Set custom config directory", "dir" },
		{ "chroot", 'r', POPT_ARG_STRING, &chroot, ARG_CHROOT, "Set chroot directory", "dir" },
		{ "user", 'u', POPT_ARG_STRING, &user, ARG_USER, "Set unprivileged user", "name" },
		{ "group", 'g', POPT_ARG_STRING, &group, ARG_GROUP, "Set unprivileged group", "name" },
		{ "nodaemon", 'n', POPT_ARG_NONE, NULL, ARG_NODAEMON, "Disable background daemon mode" },
		{ "nodaemon", 'n', POPT_ARG_NONE, NULL, ARG_NODAEMON, "Disable background daemon mode" },
		{ "backend", '\0', POPT_ARG_NONE|POPT_ARGFLAG_DOC_HIDDEN, NULL, ARG_BACKEND },
		{ "backend", '\0', POPT_ARG_NONE|POPT_ARGFLAG_DOC_HIDDEN, NULL, ARG_BACKEND },
		POPT_AUTOHELP
		POPT_AUTOHELP
 Lines 78-90    Link Here 
			<< ": " << poptStrerror(arg) << std::endl;
			<< ": " << poptStrerror(arg) << std::endl;
		return 1;
		return 1;
	}
	}
	if (!backend && (chroot || user || group)) {
		struct stat stat_r;
		struct passwd *user_r;
		struct group *group_r;
		if (getuid()) {
			std::cerr << "Cannot lower privileges, not running as root" << std::endl;
			return 1;
		}
		if (chroot && stat(chroot, &stat_r)) {
			if (!S_ISDIR(stat_r.st_mode)){
				std::cerr << "Cannot lower privileges, chroot directory does not exist" << std::endl;
				return 1;
			}
		}
		if (user) {
			user_r = getpwnam(user);
			if (user_r)
				uid = user_r->pw_uid;
			else {
				std::cerr << "Cannot lower privileges, unknown user" << std::endl;
				return 1;
			}
		}
		if (group) {
			group_r = getgrnam(group);
			if (group_r)
				gid = group_r->gr_gid;
			else {
				std::cerr << "Cannot lower privileges, unknown group" << std::endl;
				return 1;
			}
		}
	}
	poptFreeContext(context);
	poptFreeContext(context);
	
	
	if (backend) {
	if (backend) {
		IPCPortal portal(0, 1);
		IPCPortal portal(0, 1);
		return main_unix_backend(3, &portal);
		return main_unix_backend(3, &portal);
	} else {
	} else {
		return main_unix_standalone(confdir, nodaemon);
		return main_unix_standalone(confdir, nodaemon, chroot, uid, gid);
	}
	}
}
}
(-) bfilter-0.9.4/main/main_unix_standalone.cpp (-1 / +35 lines)
 Lines 26-31    Link Here 
#include "state.h"
#include "state.h"
#include <ipcportal.h>
#include <ipcportal.h>
#include "syscall.h"
#include "syscall.h"
#include <pwd.h>
#include <grp.h>
#include <resolv.h>
class StandaloneState : public State
class StandaloneState : public State
{
{
 Lines 175-181    Link Here 
	return strm.str();
	return strm.str();
}
}
int main_unix_standalone(const std::string& confdir, bool nodaemon)
static int drop_privileges(char *dir, uid_t uid, gid_t gid)
{
	if (dir) {
		// Using gethostbyname before chrooting means that the chroot
		// directory can be empty (no etc/resolv.conf or dynamically
		// loaded lib/libnss* libraries). Unfortunately simply using
		// gethostbyname once in the parent process does translate
		// for forked children. Using localhost here to prevent remote
		// name resolution also does not work.
		gethostbyname("slashdot.org");
		if (chroot(dir)) {
			std::cerr << "Cannot lower privileges, chroot directory no longer exists" << std::endl;
			return 1;
		}
		chdir("/");
	}
	if (gid) {
		setgroups(0, NULL);
		setgid(gid);
	}
	if (uid) {
		setuid(uid);
	}
	return 0;
}
int main_unix_standalone(const std::string& confdir, bool nodaemon, char *chroot, uid_t uid, gid_t gid)
{
{
	Network::Socket serv_sock = Network::INVALID_SOCK;
	Network::Socket serv_sock = Network::INVALID_SOCK;
	Network::Socket clnt_sock = Network::INVALID_SOCK;
	Network::Socket clnt_sock = Network::INVALID_SOCK;
 Lines 261-266    Link Here 
			setup_child_signals();
			setup_child_signals();
			Network::closeSocket(serv_sock);
			Network::closeSocket(serv_sock);
			Network::sockSetNodelay(clnt_sock, true);
			Network::sockSetNodelay(clnt_sock, true);
			if (drop_privileges(chroot, uid, gid)) {
				Network::disconnectAndCloseSocket(clnt_sock, 10);
				return 1;
			}
			BFilter filter(clnt_sock, &state);
			BFilter filter(clnt_sock, &state);
			filter.run();
			filter.run();
			Network::disconnectAndCloseSocket(clnt_sock, 10);
			Network::disconnectAndCloseSocket(clnt_sock, 10);