aboutsummaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorsmill <smill@cuckoo.sh>2016-09-04 01:30:27 +0000
committersmill <smill@cuckoo.sh>2016-09-04 01:30:27 +0000
commitfbfedbdc8f02bc36191d3fbf0f5cb7756331c89d (patch)
treeb064696ab20a9f831c02e342b8ed02a2d8c93b15 /examples
parent377921fa99e5c602ff04ed412be76072abc1d1c0 (diff)
downloadmitmproxy-fbfedbdc8f02bc36191d3fbf0f5cb7756331c89d.tar.gz
mitmproxy-fbfedbdc8f02bc36191d3fbf0f5cb7756331c89d.tar.bz2
mitmproxy-fbfedbdc8f02bc36191d3fbf0f5cb7756331c89d.zip
Improved error-handling / supplemented documention.
Diffstat (limited to 'examples')
-rw-r--r--examples/mitmproxy_shim.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/examples/mitmproxy_shim.c b/examples/mitmproxy_shim.c
new file mode 100644
index 00000000..9688bb41
--- /dev/null
+++ b/examples/mitmproxy_shim.c
@@ -0,0 +1,79 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <string.h>
+#include <sys/prctl.h>
+#include <sys/types.h>
+#include <sys/capability.h>
+#include <unistd.h>
+#include <errno.h>
+
+int set_caps(cap_t cap_struct, cap_value_t *cap_list, size_t bufsize) {
+ int cap_count = bufsize / sizeof(cap_list[0]);
+
+ if (cap_set_flag(cap_struct, CAP_PERMITTED, cap_count, cap_list, CAP_SET) ||
+ cap_set_flag(cap_struct, CAP_EFFECTIVE, cap_count, cap_list, CAP_SET) ||
+ cap_set_flag(cap_struct, CAP_INHERITABLE, cap_count, cap_list, CAP_SET)) {
+ if (cap_count < 2) {
+ fprintf(stderr, "Cannot manipulate capability data structure as user: %s.\n", strerror(errno));
+ } else {
+ fprintf(stderr, "Cannot manipulate capability data structure as root: %s.\n", strerror(errno));
+ }
+ return -1;
+ }
+
+ if (cap_count < 2) {
+ if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, CAP_NET_RAW, 0, 0)) {
+ fprintf(stderr, "Failed to add CAP_NET_RAW to the ambient set: %s.\n", strerror(errno));
+ return -2;
+ }
+ }
+
+ if (cap_set_proc(cap_struct)) {
+ if (cap_count < 2) {
+ fprintf(stderr, "Cannot set capabilities as user: %s.\n", strerror(errno));
+ } else {
+ fprintf(stderr, "Cannot set capabilities as root: %s.\n", strerror(errno));
+ }
+ return -3;
+ }
+
+ if (cap_count > 1) {
+ if (prctl(PR_SET_KEEPCAPS, 1L)) {
+ fprintf(stderr, "Cannot keep capabilities after dropping privileges: %s.\n", strerror(errno));
+ return -4;
+ }
+ if (cap_clear(cap_struct)) {
+ fprintf(stderr, "Cannot clear capability data structure: %s.\n", strerror(errno));
+ return -5;
+ }
+ }
+}
+
+int main(int argc, char **argv, char **envp) {
+ cap_t cap_struct = cap_init();
+ cap_value_t root_caps[2] = { CAP_NET_RAW, CAP_SETUID };
+ cap_value_t user_caps[1] = { CAP_NET_RAW };
+ uid_t user = getuid();
+ int res;
+
+ if (setresuid(0, 0, 0)) {
+ fprintf(stderr, "Cannot switch to root: %s.\n", strerror(errno));
+ return 1;
+ }
+
+ if (res = set_caps(cap_struct, root_caps, sizeof(root_caps)))
+ return res;
+
+ if (setresuid(user, user, user)) {
+ fprintf(stderr, "Cannot drop root privileges: %s.\n", strerror(errno));
+ return 2;
+ }
+
+ if (res = set_caps(cap_struct, user_caps, sizeof(user_caps)))
+ return res;
+
+ if (execve(argv[1], argv + 1, envp)) {
+ fprintf(stderr, "Failed to execute %s: %s\n", argv[1], strerror(errno));
+ return 3;
+ }
+}