summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile7
-rw-r--r--bin/conn.h8
-rw-r--r--bin/lua-privsep.h6
-rw-r--r--client/Makefile23
-rwxr-xr-xclient/client.sobin0 -> 13897 bytes
-rw-r--r--client/list.h (renamed from bin/list.h)0
-rw-r--r--client/lua-client.c112
l---------client/modules1
-rw-r--r--client/privsep.lua57
-rw-r--r--client/test.lua20
-rw-r--r--example.lua12
-rw-r--r--privileged-main.lua59
-rw-r--r--privsep.lua40
-rw-r--r--server/Makefile (renamed from bin/Makefile)1
-rw-r--r--server/conn.c (renamed from bin/conn.c)20
-rw-r--r--server/conn.h21
-rw-r--r--server/handler.lua64
-rw-r--r--server/list.h112
-rw-r--r--server/lua-privsep.c (renamed from bin/lua-privsep.c)64
-rw-r--r--server/lua-privsep.h11
-rwxr-xr-xserver/privsep-serverbin0 -> 27672 bytes
-rw-r--r--server/privsep-server.c (renamed from bin/privsep-server.c)0
22 files changed, 483 insertions, 155 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..61f6f65
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,7 @@
+SUBDIRS=server client
+
+
+all:
+ for dir in $(SUBDIRS); do \
+ $(MAKE) -C $$dir || exit 1; \
+ done
diff --git a/bin/conn.h b/bin/conn.h
deleted file mode 100644
index f5b33a9..0000000
--- a/bin/conn.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef CONN_H
-#define CONN_H
-
-#include <ev.h>
-
-int conn_init(struct ev_loop *loop, const char *socket_path);
-
-#endif
diff --git a/bin/lua-privsep.h b/bin/lua-privsep.h
deleted file mode 100644
index 9b7e219..0000000
--- a/bin/lua-privsep.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef LUA_PRIVSEP_H
-#define LUA_PRIVSEP_H
-
-int call_lua(int fd, const char *msg, size_t msglen);
-
-#endif
diff --git a/client/Makefile b/client/Makefile
new file mode 100644
index 0000000..b318964
--- /dev/null
+++ b/client/Makefile
@@ -0,0 +1,23 @@
+
+COMPILE_PROG = $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $($@-objs) $($@-libs)
+COMPILE_LUALIB = $(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $($@-objs) $($@-libs)
+
+CFLAGS ?= -g
+
+PKGCONF ?= pkg-config
+
+LUA_PKG ?= lua
+LUA_CFLAGS := $(shell $(PKGCONF) --cflags $(LUA_PKG))
+LUA_LIBS := $(shell $(PKGCONF) --libs $(LUA_PKG))
+
+client.so-objs = lua-client.o
+client.so-libs = $(LUA_LIBS)
+
+all: client.so
+
+client.so: $(client.so-objs)
+ $(COMPILE_LUALIB)
+
+clean:
+ rm -f client.so
+
diff --git a/client/client.so b/client/client.so
new file mode 100755
index 0000000..a6567bd
--- /dev/null
+++ b/client/client.so
Binary files differ
diff --git a/bin/list.h b/client/list.h
index 1fca5e7..1fca5e7 100644
--- a/bin/list.h
+++ b/client/list.h
diff --git a/client/lua-client.c b/client/lua-client.c
new file mode 100644
index 0000000..ca4365a
--- /dev/null
+++ b/client/lua-client.c
@@ -0,0 +1,112 @@
+
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+
+#define LIBNAME "client"
+
+#ifndef VERSION
+#define VERSION "(unknown)"
+#endif
+
+#ifndef DEFAULT_SOCKET_PATH
+#define DEFAULT_SOCKET_PATH "/var/run/privsep/root.sock"
+#endif
+
+#define BUFSIZE 32768
+
+static int pusherror(lua_State *L, const char *info)
+{
+ lua_pushnil(L);
+ if (info == NULL)
+ lua_pushstring(L, strerror(errno));
+ else
+ lua_pushfstring(L, "%s: %s", info, strerror(errno));
+ lua_pushinteger(L, errno);
+ return 3;
+}
+
+static int Pconnect(lua_State *L)
+{
+ const char *socket_path = luaL_optstring(L, 1, DEFAULT_SOCKET_PATH);
+ struct sockaddr_un sun;
+ int fd, ret;
+
+ memset(&sun, 0, sizeof(sun));
+ sun.sun_family = AF_UNIX;
+ strncpy(sun.sun_path, socket_path, sizeof(sun.sun_path));
+
+ fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (fd < 0)
+ return pusherror(L, "socket");
+
+ if (connect(fd, (struct sockaddr *) &sun, sizeof(sun)) < 0) {
+ ret = pusherror(L, socket_path);
+ goto close_err;
+ }
+
+ lua_pushinteger(L, fd);
+ return 1;
+
+close_err:
+ close(fd);
+ return ret;
+}
+
+static int push_err_or_int(lua_State *L, ssize_t n)
+{
+ if (n < 0)
+ return pusherror(L, NULL);
+ lua_pushinteger(L, n);
+ return 1;
+}
+
+static int Pwrite(lua_State *L)
+{
+ int fd = luaL_checkinteger(L, 1);
+ size_t len = 0;
+ const char *msg = luaL_checklstring(L, 2, &len);
+ return push_err_or_int(L, write(fd, msg, len));
+}
+
+static int Precv(lua_State *L)
+{
+ int fd = luaL_checkinteger(L, 1);
+ static char buf[BUFSIZE];
+ ssize_t n = recv(fd, buf, sizeof(buf), 0);
+ if (n < 0)
+ return pusherror(L, NULL);
+ lua_pushlstring(L, buf, n);
+ return 1;
+}
+
+static int Pclose(lua_State *L)
+{
+ int fd = luaL_checkinteger(L, 1);
+ return push_err_or_int(L, close(fd));
+}
+
+static const luaL_reg reg_client_methods[] = {
+ {"connect", Pconnect},
+ {"write", Pwrite},
+ {"recv", Precv},
+ {"close", Pclose},
+ {NULL, NULL},
+};
+
+
+LUALIB_API int luaopen_client(lua_State *L)
+{
+ luaL_register(L, LIBNAME, reg_client_methods);
+ lua_pushliteral(L, "version");
+ lua_pushliteral(L, VERSION);
+ lua_settable(L, -3);
+ return 1;
+}
diff --git a/client/modules b/client/modules
new file mode 120000
index 0000000..464b823
--- /dev/null
+++ b/client/modules
@@ -0,0 +1 @@
+../modules \ No newline at end of file
diff --git a/client/privsep.lua b/client/privsep.lua
new file mode 100644
index 0000000..432f472
--- /dev/null
+++ b/client/privsep.lua
@@ -0,0 +1,57 @@
+
+ipcmsg = require("cmsgpack")
+ipcmsg.encode = ipcmsg.pack
+ipcmsg.decode = ipcmsg.unpack
+
+client = require("client")
+
+local ml = require("ml")
+
+local modules_path = "./modules"
+
+local privsep = {}
+
+local function call(conn, req)
+ local n = client.write(conn.fd, ipcmsg.encode(req))
+ retmsg, errmsg = client.recv(conn.fd)
+ if retmsg then
+ local data = ipcmsg.decode(retmsg)
+ return unpack(data.result or {})
+ end
+ return nil, errmsg
+end
+
+local function wrap(conn, modname)
+ local mod = dofile(modules_path.."/"..modname..".lua")
+ local f = {}
+ local i = #conn.mods + 1
+ local ret = conn:call{ type = "load", modidx = i,
+ modname = modname }
+ if ret == nil then
+ return nil
+ end
+ for k,v in pairs(mod) do
+ f[k] = function(...)
+ return conn:call{ type = "call", modidx = i,
+ func = k, args = {...}}
+ end
+ end
+ conn[i] = f
+ return f
+end
+
+function privsep.connect(token)
+ return {
+ ["fd"] = client.connect(),
+ ["call"] = call,
+ ["wrap"] = wrap,
+ ["close"] = function(self)
+ return client.close(self.fd)
+ end,
+ ["mods"] = {},
+ }
+end
+
+
+return privsep
+
diff --git a/client/test.lua b/client/test.lua
new file mode 100644
index 0000000..38e7429
--- /dev/null
+++ b/client/test.lua
@@ -0,0 +1,20 @@
+
+ps = require("privsep")
+
+c = ps.connect()
+
+mymod = c:wrap("mymod")
+
+if mymod == nil then
+ print("mymod is nil")
+end
+
+pos = require("posix")
+
+print(mymod.myfunc("arg1", true))
+for i = 1, 1000 do
+ mymod.myfunc("foo", false)
+end
+
+c:close()
+
diff --git a/example.lua b/example.lua
deleted file mode 100644
index db9973a..0000000
--- a/example.lua
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-mymod = require("privsep").wrap("mymod", "dummy session token")
-posix = require("posix")
-
-print(mymod.myfunc("foo", false))
-
-print("posix.getpid:", posix.getpid().pid)
-print("mymod.getpid:", mymod.getpid().pid)
-
-
-
diff --git a/privileged-main.lua b/privileged-main.lua
deleted file mode 100644
index 6aa9681..0000000
--- a/privileged-main.lua
+++ /dev/null
@@ -1,59 +0,0 @@
-msg = ...
-
---print("DEBUG: got message:", msg)
-
-ipcmsg = require("cmsgpack")
-ipcmsg.encode = ipcmsg.pack
-ipcmsg.decode = ipcmsg.unpack
-
-
-function ret_error(errmsg)
- io.stderr:write("ERROR: "..tostring(errmsg).."\n")
- return ipcmsg.encode{ status = false, errmsg = errmsg}
-end
-
-function ret_success(result)
- return ipcmsg.encode{ status = true, errmsg = "success", result = result}
-end
-
-req = ipcmsg.decode(msg)
-
---print("DEBUG: msg decoded")
-
--- path must be absolute for production so users cannot load scripts from
--- non secured dirs
-modules_path = "./modules/"
-
-if type(req.mod) ~= "string" then
- return ret_error("mod is missing in message or is bad format")
-end
-
-if type(req.func) ~= "string" then
- return ret_error("func is missing in message or is wrong format")
-end
-
--- make sure we dont have any path elements in modname so we cannot pass
--- modnames like '../myevilmod'
-mfile = modules_path..string.gsub(req.mod, ".*/", "")..".lua"
-
--- load the module
-m = dofile(mfile)
---print("DEBUG: mfile:", mfile)
---print("DEBUG: '"..req.func.."' type:", type(m[req.func]))
-
--- check that the func we want exists
-if type(m[req.func]) ~= "function" then
- ret_error(func..": not a function in '".. mfile .."'")
-end
-
--- TODO: check permissions here
-print("Calling '"..req.mod.."."..req.func.."'")
-
---print("DEBUG: args:", req.args)
--- execute the func and pack the return values into a table
-result = { m[req.func](unpack(req.args)) }
---result = { m[func](unpack(req.args or {})) }
-
---print("DEBUG: result:", result)
-
-return ret_success(result)
diff --git a/privsep.lua b/privsep.lua
deleted file mode 100644
index b6e8f95..0000000
--- a/privsep.lua
+++ /dev/null
@@ -1,40 +0,0 @@
-
-ipcmsg = require("cmsgpack")
-ipcmsg.encode = ipcmsg.pack
-ipcmsg.decode = ipcmsg.unpack
-
-socket = require("socket")
-socket.unix = require("socket.unix")
-
-
-local modules_path = "./modules"
-
-local privsep = {}
-
-function privsep.call_privileged(mod, func, sectoken, args)
- local c = assert(socket.unix())
- assert(c:connect("/var/run/privsep/root.sock"))
-
- local req = { mod = mod, func = func, args = args, sectoken = sectoken }
- c:send(ipcmsg.encode(req))
- local retmsg, errmsg = c:receive("*a")
- if retmsg then
- local data = ipcmsg.decode(retmsg)
- return unpack(data.result or {})
- end
- return nil
-end
-
-function privsep.wrap(modname, sessionid)
- local mod = dofile(modules_path.."/"..modname..".lua")
- local f = {}
- for k,v in pairs(mod) do
- f[k] = function(...)
- return privsep.call_privileged(modname, k, sessionid, {...})
- end
- end
- return f
-end
-
-return privsep
-
diff --git a/bin/Makefile b/server/Makefile
index 07a522a..0f14b48 100644
--- a/bin/Makefile
+++ b/server/Makefile
@@ -1,5 +1,6 @@
COMPILE_PROG = $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $($@-objs) $($@-libs)
+COMPILE_LUALIB = $(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $($@-objs) $($@-libs)
CFLAGS ?= -g
diff --git a/bin/conn.c b/server/conn.c
index f953d09..f167cdd 100644
--- a/bin/conn.c
+++ b/server/conn.c
@@ -22,19 +22,8 @@
#define log_perror(x) perror(x)
#endif
-#ifndef MSG_MAX_SIZE
-#define MSG_MAX_SIZE 16386
-#endif
-
static struct ev_io accept_io;
-struct conn {
- struct ev_io io;
- struct ev_timer timeout;
- size_t num_read;
- char msg[MSG_MAX_SIZE];
-};
-
static void conn_free(struct ev_loop *loop, struct conn *rm)
{
int fd = rm->io.fd;
@@ -42,6 +31,7 @@ static void conn_free(struct ev_loop *loop, struct conn *rm)
ev_io_stop(loop, &rm->io);
ev_timer_stop(loop, &rm->timeout);
close(fd);
+ close_lua(rm);
free(rm);
log_debug("Connection closed");
}
@@ -63,8 +53,10 @@ static void conn_recv_cb (struct ev_loop *loop, struct ev_io *w,
conn->num_read += len;
if (conn->num_read >= sizeof(conn->msg))
goto err;
-
- call_lua(conn->io.fd, conn->msg, conn->num_read);
+
+ call_lua(conn, conn->msg, conn->num_read);
+ conn->num_read = 0;
+ return;
err:
conn_free(loop, conn);
@@ -98,6 +90,8 @@ static void conn_accept_cb(struct ev_loop *loop, struct ev_io *w,
ev_io_start(loop, &conn->io);
ev_timer_init(&conn->timeout, conn_timeout_cb, 10.0, 0.);
ev_timer_start(loop, &conn->timeout);
+
+ init_lua(conn);
}
diff --git a/server/conn.h b/server/conn.h
new file mode 100644
index 0000000..f698054
--- /dev/null
+++ b/server/conn.h
@@ -0,0 +1,21 @@
+#ifndef CONN_H
+#define CONN_H
+
+#include <ev.h>
+#include <lua.h>
+
+#ifndef MSG_MAX_SIZE
+#define MSG_MAX_SIZE 16386
+#endif
+
+struct conn {
+ struct ev_io io;
+ struct ev_timer timeout;
+ size_t num_read;
+ lua_State *L;
+ char msg[MSG_MAX_SIZE];
+};
+
+int conn_init(struct ev_loop *loop, const char *socket_path);
+
+#endif
diff --git a/server/handler.lua b/server/handler.lua
new file mode 100644
index 0000000..41a02fb
--- /dev/null
+++ b/server/handler.lua
@@ -0,0 +1,64 @@
+
+--print("DEBUG: got message:", msg)
+
+--ipcmsg = require("json")
+ipcmsg = require("cmsgpack")
+ipcmsg.encode = ipcmsg.pack
+ipcmsg.decode = ipcmsg.unpack
+
+ml = require("ml")
+
+modules_path = "../modules/"
+
+mods = {}
+
+local function ret_error(errmsg)
+ io.stderr:write("ERROR: "..tostring(errmsg).."\n")
+ return ipcmsg.encode{ status = false, errmsg = errmsg}
+end
+
+local function ret_success(...)
+ return ipcmsg.encode{ status = true, errmsg = "success",
+ result = {...} }
+end
+
+reqhandler = {}
+function reqhandler.load(req)
+ -- make sure we dont have any path elements in modname so we cannot pass
+ -- modnames like '../myevilmod'
+ local file = modules_path..string.gsub(req.modname, ".*/", "")..".lua"
+ mods[req.modidx] = dofile(file)
+ if mods[req.modidx] == nil then
+ return ret_error(file)
+ end
+ return true
+end
+
+function reqhandler.call(req)
+ if req.modidx == nil or req.func == nil then
+ return ret_error("failed to call function "..tostring(req.func))
+ end
+ local m = mods[req.modidx]
+ -- check that the func we want exists
+ if type(m[req.func]) ~= "function" then
+ ret_error(func..": not a function in '".. mfile .."'")
+ end
+
+ -- TODO: check permissions here
+-- print("DEBUG: Calling mods["..req.modidx.."]."..req.func)
+
+ -- execute the func and pack the return values into a table
+ return m[req.func](unpack(req.args))
+end
+
+function handler(msg)
+ local req = ipcmsg.decode(msg)
+-- print("DEBUG: req="..ml.tstring(req))
+ if type(req.type) ~= "string" then
+ return ret_error("request type missing")
+ end
+ if type(reqhandler[req.type]) == "function" then
+ return ret_success(reqhandler[req.type](req))
+ end
+ return ret_error("no handler for request type "..req.type)
+end
diff --git a/server/list.h b/server/list.h
new file mode 100644
index 0000000..1fca5e7
--- /dev/null
+++ b/server/list.h
@@ -0,0 +1,112 @@
+/* list.h - Single and double linked list macros
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 or later as
+ * published by the Free Software Foundation.
+ *
+ * See http://www.gnu.org/ for details.
+ *
+ * This is more or less based on the code in the linux kernel. There are
+ * minor differences and this is only a subset of the kernel version.
+ */
+
+#ifndef LIST_H
+#define LIST_H
+
+#ifndef NULL
+#define NULL 0L
+#endif
+
+#ifndef offsetof
+#ifdef __compiler_offsetof
+#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
+#else
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+#endif
+
+#ifndef container_of
+#define container_of(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
+#endif
+
+struct list_head {
+ struct list_head *next, *prev;
+};
+
+#define LIST_INITIALIZER(l) { .next = &l, .prev = &l }
+
+static inline void list_init(struct list_head *list)
+{
+ list->next = list;
+ list->prev = list;
+}
+
+static inline void __list_add(struct list_head *new,
+ struct list_head *prev,
+ struct list_head *next)
+{
+ next->prev = new;
+ new->next = next;
+ new->prev = prev;
+ prev->next = new;
+}
+
+static inline void list_add(struct list_head *new, struct list_head *head)
+{
+ __list_add(new, head, head->next);
+}
+
+static inline void list_add_tail(struct list_head *new, struct list_head *head)
+{
+ __list_add(new, head->prev, head);
+}
+
+static inline void __list_del(struct list_head * prev, struct list_head * next)
+{
+ next->prev = prev;
+ prev->next = next;
+}
+
+static inline void list_del(struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+ entry->next = NULL;
+ entry->prev = NULL;
+}
+
+static inline int list_hashed(const struct list_head *n)
+{
+ return n->next != n && n->next != NULL;
+}
+
+static inline int list_empty(const struct list_head *n)
+{
+ return !list_hashed(n);
+}
+
+#define list_next(ptr, type, member) \
+ (list_hashed(ptr) ? container_of((ptr)->next,type,member) : NULL)
+
+#define list_entry(ptr, type, member) container_of(ptr,type,member)
+
+#define list_for_each(pos, head) \
+ for (pos = (head)->next; pos != (head); pos = pos->next)
+
+#define list_for_each_safe(pos, n, head) \
+ for (pos = (head)->next, n = pos->next; pos != (head); \
+ pos = n, n = pos->next)
+
+#define list_for_each_entry(pos, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.next, typeof(*pos), member))
+
+#define list_for_each_entry_safe(pos, n, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member), \
+ n = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+#endif
diff --git a/bin/lua-privsep.c b/server/lua-privsep.c
index d6d750c..65dc39e 100644
--- a/bin/lua-privsep.c
+++ b/server/lua-privsep.c
@@ -1,4 +1,7 @@
+#include <stdarg.h>
#include <stdio.h>
+#include <stdlib.h>
+
#include <lua.h>
#include <lauxlib.h>
@@ -35,32 +38,59 @@ static int traceback (lua_State *L) {
return 1;
}
-int call_lua(int fd, const char *msg, size_t msglen)
+static void lerror(lua_State *L, const char *fmt, ...)
+{
+ va_list argp;
+ va_start(argp, fmt);
+ vfprintf(stderr, fmt, argp);
+ va_end(argp);
+ lua_close(L);
+ exit(EXIT_FAILURE);
+}
+
+int call_lua(struct conn *c, const char *msg, size_t msglen)
{
- const char *luamain = PRIVSEP_PATH "privileged-main.lua";
- int traceback_index;
const char *retbuf;
size_t retsize;
+ lua_State *L = c->L;
- lua_State *L = luaL_newstate();
- luaL_openlibs(L);
-
- lua_pushcfunction(L, traceback);
- traceback_index = lua_gettop(L);
-
- if (luaL_loadfile(L, luamain))
- return luaL_error(L, "%s", luamain);
-
+ lua_getglobal(L, "handler");
lua_pushlstring(L, msg, msglen);
- if (lua_pcall(L, 1, 1, traceback_index))
- return luaL_error(L, "error");
+ if (lua_pcall(L, 1, 1, 0))
+ return luaL_error(L, lua_tostring(L, -1));
if (!lua_isstring(L, -1))
- error(L, "function must return string");
-
+ lerror(L, "handler function must return string\n");
+
retbuf = lua_tolstring(L, -1, &retsize);
- return write(fd, retbuf, retsize);
+ return write(c->io.fd, retbuf, retsize);
+}
+
+int init_lua(struct conn *c)
+{
+ const char *luamain = PRIVSEP_PATH "handler.lua";
+ int traceback_index;
+ const char *retbuf;
+ size_t retsize;
+
+ c->L = luaL_newstate();
+ if (c == NULL)
+ return -1;
+ luaL_openlibs(c->L);
+
+ if (luaL_loadfile(c->L, luamain) || lua_pcall(c->L, 0, 0, 0)) {
+ lerror(c->L, "%s: %s", luamain, lua_tostring(c->L, -1));
+ lua_close(c->L);
+ c->L = NULL;
+ return -1;
+ }
+ return 0;
}
+void close_lua(struct conn *c)
+{
+ lua_close(c->L);
+ c->L = NULL;
+}
diff --git a/server/lua-privsep.h b/server/lua-privsep.h
new file mode 100644
index 0000000..2d27a11
--- /dev/null
+++ b/server/lua-privsep.h
@@ -0,0 +1,11 @@
+#ifndef LUA_PRIVSEP_H
+#define LUA_PRIVSEP_H
+
+#include "conn.h"
+#include <lua.h>
+
+int call_lua(struct conn *c, const char *msg, size_t msglen);
+int init_lua(struct conn *c);
+void close_lua(struct conn *c);
+
+#endif
diff --git a/server/privsep-server b/server/privsep-server
new file mode 100755
index 0000000..5be1ad1
--- /dev/null
+++ b/server/privsep-server
Binary files differ
diff --git a/bin/privsep-server.c b/server/privsep-server.c
index 76d3f4c..76d3f4c 100644
--- a/bin/privsep-server.c
+++ b/server/privsep-server.c