summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bin/Makefile1
-rw-r--r--bin/conn.c5
-rw-r--r--bin/lua-privsep.c19
-rw-r--r--bin/lua-privsep.h2
-rw-r--r--privileged-main.lua48
-rw-r--r--privsep.lua37
6 files changed, 65 insertions, 47 deletions
diff --git a/bin/Makefile b/bin/Makefile
index de61268..07a522a 100644
--- a/bin/Makefile
+++ b/bin/Makefile
@@ -1,6 +1,7 @@
COMPILE_PROG = $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $($@-objs) $($@-libs)
+CFLAGS ?= -g
PKGCONF ?= pkg-config
diff --git a/bin/conn.c b/bin/conn.c
index 90777ba..f953d09 100644
--- a/bin/conn.c
+++ b/bin/conn.c
@@ -14,6 +14,8 @@
#include "list.h"
#include "conn.h"
+#include "lua-privsep.h"
+
#ifndef DEBUG
#define log_debug(x) printf("%s\n", x)
@@ -62,8 +64,7 @@ static void conn_recv_cb (struct ev_loop *loop, struct ev_io *w,
if (conn->num_read >= sizeof(conn->msg))
goto err;
- call_lua(conn->num_read, conn->msg);
- return;
+ call_lua(conn->io.fd, conn->msg, conn->num_read);
err:
conn_free(loop, conn);
diff --git a/bin/lua-privsep.c b/bin/lua-privsep.c
index 0307d7c..d6d750c 100644
--- a/bin/lua-privsep.c
+++ b/bin/lua-privsep.c
@@ -4,6 +4,9 @@
#include <lauxlib.h>
#include <lualib.h>
+#include "conn.h"
+#include "lua-privsep.h"
+
#ifndef PRIVSEP_PATH
#define PRIVSEP_PATH "./"
#endif
@@ -32,10 +35,12 @@ static int traceback (lua_State *L) {
return 1;
}
-int call_lua(const char *msg, size_t msglen)
+int call_lua(int fd, const char *msg, size_t msglen)
{
const char *luamain = PRIVSEP_PATH "privileged-main.lua";
- int i, traceback_index;
+ int traceback_index;
+ const char *retbuf;
+ size_t retsize;
lua_State *L = luaL_newstate();
luaL_openlibs(L);
@@ -48,10 +53,14 @@ int call_lua(const char *msg, size_t msglen)
lua_pushlstring(L, msg, msglen);
- if (lua_pcall(L, 1, 0, traceback_index))
- return luaL_error(L, "error");
+ if (lua_pcall(L, 1, 1, traceback_index))
+ return luaL_error(L, "error");
- return 0;
+ if (!lua_isstring(L, -1))
+ error(L, "function must return string");
+
+ retbuf = lua_tolstring(L, -1, &retsize);
+ return write(fd, retbuf, retsize);
}
diff --git a/bin/lua-privsep.h b/bin/lua-privsep.h
index fae8fcc..9b7e219 100644
--- a/bin/lua-privsep.h
+++ b/bin/lua-privsep.h
@@ -1,6 +1,6 @@
#ifndef LUA_PRIVSEP_H
#define LUA_PRIVSEP_H
-int call_lua(const char *msg size_t msglen);
+int call_lua(int fd, const char *msg, size_t msglen);
#endif
diff --git a/privileged-main.lua b/privileged-main.lua
index 8fe447c..8b8793a 100644
--- a/privileged-main.lua
+++ b/privileged-main.lua
@@ -1,50 +1,58 @@
-modname = ...
+msg = ...
-if not modname then
- modname = "session"
-end
+--print("DEBUG: got message:", msg)
-json = require("json")
+ipcmsg = require("cmsgpack")
+ipcmsg.encode = ipcmsg.pack
+ipcmsg.decode = ipcmsg.unpack
function ret_error(errmsg)
- io.write(json.encode({false, errmsg, nil}).."\n")
- os.exit(0)
+ io.stderr:write("ERROR: "..tostring(errmsg).."\n")
+ return ipcmsg.encode{ status = false, errmsg = errmsg}
end
function ret_success(result)
- io.write(json.encode({true, "success", result}).."\n")
+ 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 not modname then
- return 1
+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(modname, ".*/", "")..".lua"
+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]))
--- read args from stdin
-request = json.decode(io.read("*a"))
-funcname, sessionid, args = unpack(request)
-
---ret_error(funcname)
-- check that the func we want exists
-if type(m[funcname]) ~= "function" then
- ret_error(funcname..": not a function")
+if type(m[req.func]) ~= "function" then
+ ret_error(func..": not a function in '".. mfile .."'")
end
-- TODO: check permissions here
+--print("DEBUG: args:", req.args)
-- execute the func and pack the return values into a table
-result = { m[funcname](unpack(args)) }
+result = { m[req.func](unpack(req.args)) }
+--result = { m[func](unpack(req.args or {})) }
-ret_success(result)
+--print("DEBUG: result:", result)
+return ret_success(result)
diff --git a/privsep.lua b/privsep.lua
index 5e0b915..a07b8ed 100644
--- a/privsep.lua
+++ b/privsep.lua
@@ -1,31 +1,29 @@
lpc = require("lpc")
-ipcmsg = require("json")
+ipcmsg = require("cmsgpack")
+ipcmsg.encode = ipcmsg.pack
+ipcmsg.decode = ipcmsg.unpack
+
+socket = require("socket")
+socket.unix = require("socket.unix")
+
-local privsep_exec = "./lua-privsep"
local modules_path = "./modules"
local privsep = {}
-function privsep.call_privileged(modname, funcname, sessionid, args)
- local pid, w, r = lpc.run(privsep_exec, modname)
- w:write(ipcmsg.encode{ funcname, sessionid, args }.."\n")
- w:close()
- local resp = r:read("*all")
- local retcode = lpc.wait(pid)
+function privsep.call_privileged(mod, func, sectoken, args)
+ local c = assert(socket.unix())
+ assert(c:connect("/var/run/privsep/root.sock"))
- if resp == nil or resp == "" then
- io.stderr:write("remote '"..modname.."' failed: "..tostring(retcode).."\n")
- return nil
+ 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
-
- local data = ipcmsg.decode(resp)
- local status, errmsg, result = unpack(data)
- if not status then
- io.stderr:write("modname: "..tostring(errmsg).."\n")
- return nil
- end
- return unpack(result)
+ return nil
end
function privsep.wrap(modname, sessionid)
@@ -40,3 +38,4 @@ function privsep.wrap(modname, sessionid)
end
return privsep
+