summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRoland Reichwein <mail@reichwein.it>2020-04-05 15:11:44 +0200
committerRoland Reichwein <mail@reichwein.it>2020-04-05 15:11:44 +0200
commitddc02ba7a6cc92d07cf073395b2d41347a8d35fb (patch)
tree167664302cbc7b67e4fe2f7bb02740f9139fc623
parente234229ae80da0fa9967b797f7b5f4f381cba4b4 (diff)
Drop privileges
-rw-r--r--Makefile1
-rw-r--r--TODO1
-rw-r--r--privileges.cpp49
-rw-r--r--privileges.h5
-rw-r--r--server.cpp4
5 files changed, 59 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index 1021231..bc7d147 100644
--- a/Makefile
+++ b/Makefile
@@ -63,6 +63,7 @@ PROGSRC=\
https.cpp \
http_debian10.cpp \
plugin.cpp \
+ privileges.cpp \
server.cpp \
stringutil.cpp
diff --git a/TODO b/TODO
index 26cd06d..42ac228 100644
--- a/TODO
+++ b/TODO
@@ -2,6 +2,5 @@ Certbot: https://certbot.eff.org/lets-encrypt/debianbuster-other
Webbox
Debian 10
-drop privileges: www-data,www-data, ...?
Speed up DocRoot, use string_view
read: The socket was closed due to a timeout
diff --git a/privileges.cpp b/privileges.cpp
new file mode 100644
index 0000000..94f1fed
--- /dev/null
+++ b/privileges.cpp
@@ -0,0 +1,49 @@
+#include "privileges.h"
+
+#include <cstdlib>
+#include <iostream>
+#include <string>
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "config.h"
+
+using namespace std::string_literals;
+
+namespace {
+
+ int get_number_from_process(std::string command) {
+ char value[100];
+
+ FILE* p = popen(command.data(), "r");
+ if (p == NULL)
+ throw std::runtime_error("Error executing: "s + command);
+
+ if (fgets(value, sizeof(value), p) == NULL)
+ throw std::runtime_error("Error reading from command: "s + command);
+
+ pclose(p);
+
+ return atoi(value);
+ }
+
+}
+
+void drop_privileges(const Config& config)
+{
+ // skip when run as user
+ if (geteuid() != 0) {
+ std::cout << "Note: not running as root -> not dropping privileges" << std::endl;
+ return;
+ }
+
+ int gid = get_number_from_process("id -g "s + config.Group());
+ if (setgid(gid) == -1)
+ throw std::runtime_error("setgid()");
+
+ int uid = get_number_from_process("id -u "s + config.User());
+ if (setuid(uid) == -1)
+ throw std::runtime_error("setuid()");
+}
+
diff --git a/privileges.h b/privileges.h
new file mode 100644
index 0000000..c436dda
--- /dev/null
+++ b/privileges.h
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "config.h"
+
+void drop_privileges(const Config& config);
diff --git a/server.cpp b/server.cpp
index bbe7223..91ee9e8 100644
--- a/server.cpp
+++ b/server.cpp
@@ -13,6 +13,7 @@
#include "http.h"
#include "https.h"
+#include "privileges.h"
namespace beast = boost::beast; // from <boost/beast.hpp>
namespace http = beast::http; // from <boost/beast/http.hpp>
@@ -46,6 +47,9 @@ int server(Config& config)
servers.back()->start();
}
+ // set UID, GID
+ drop_privileges(config);
+
// Run the I/O service on the requested number of threads
std::vector<std::thread> v;
v.reserve(threads - 1);