diff options
Diffstat (limited to 'client')
-rw-r--r-- | client/Makefile | 23 | ||||
-rwxr-xr-x | client/client.so | bin | 0 -> 13897 bytes | |||
-rw-r--r-- | client/list.h | 112 | ||||
-rw-r--r-- | client/lua-client.c | 112 | ||||
l--------- | client/modules | 1 | ||||
-rw-r--r-- | client/privsep.lua | 57 | ||||
-rw-r--r-- | client/test.lua | 20 |
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 Binary files differnew file mode 100755 index 0000000..a6567bd --- /dev/null +++ b/client/client.so 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() + |