diff options
author | Natanael Copa <ncopa@alpinelinux.org> | 2013-03-08 16:42:03 +0100 |
---|---|---|
committer | Natanael Copa <ncopa@alpinelinux.org> | 2013-03-08 16:51:15 +0100 |
commit | 3e2d86693f6e8920c97fe296491e7741e31f922c (patch) | |
tree | 1c755422fd27c7f192243e8eb7f7811193efa1f6 /client/lua-client.c | |
parent | e0cabd6295204fe8a6b54edfc9141302943fdbfb (diff) | |
download | privsep-master.tar.bz2 privsep-master.tar.xz |
This allows you load various modules into a server lua state and give
a performance boost when calling the privileged functions
Diffstat (limited to 'client/lua-client.c')
-rw-r--r-- | client/lua-client.c | 112 |
1 files changed, 112 insertions, 0 deletions
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; +} |