summaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
Diffstat (limited to 'client')
-rw-r--r--client/Makefile23
-rwxr-xr-xclient/client.sobin0 -> 13897 bytes
-rw-r--r--client/list.h112
-rw-r--r--client/lua-client.c112
l---------client/modules1
-rw-r--r--client/privsep.lua57
-rw-r--r--client/test.lua20
7 files changed, 325 insertions, 0 deletions
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/client/list.h b/client/list.h
new file mode 100644
index 0000000..1fca5e7
--- /dev/null
+++ b/client/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/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()
+