Skip to content

SO_PEERCRED/SO_PASSCRED porting + allow NULL bytes in the UDS name #277

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ SOCKET_macosx=usocket.o
SO_linux=so
O_linux=o
CC_linux=gcc
DEF_linux=-DLUASOCKET_$(DEBUG)
DEF_linux=-DLUASOCKET_$(DEBUG) -D_GNU_SOURCE
CFLAGS_linux=$(LUAINC:%=-I%) $(DEF) -Wall -Wshadow -Wextra \
-Wimplicit -O2 -ggdb3 -fpic
LDFLAGS_linux=-O -shared -fpic -o
Expand Down
29 changes: 29 additions & 0 deletions src/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,35 @@ int opt_get_ip6_multicast_loop(lua_State *L, p_socket ps)
return opt_getboolean(L, ps, IPPROTO_IPV6, IPV6_MULTICAST_LOOP);
}

// -------------------------------------------------------
#ifndef _WIN32
int opt_set_passcred(lua_State *L, p_socket ps)
{
return opt_setboolean(L, ps, SOL_SOCKET, SO_PASSCRED);
}

int opt_get_passcred(lua_State *L, p_socket ps)
{
return opt_getboolean(L, ps, SOL_SOCKET, SO_PASSCRED);
}

int opt_get_peercred(lua_State *L, p_socket ps)
{
struct ucred cred;
int len = sizeof(cred);
int err = opt_get(L, ps, SOL_SOCKET, SO_PEERCRED, (char *) &cred, &len);
if (err < 0)
return err;
lua_newtable(L);
lua_pushinteger(L, (long) cred.pid);
lua_setfield(L, -2, "pid");
lua_pushinteger(L, (long) cred.uid);
lua_setfield(L, -2, "uid");
lua_pushinteger(L, (long) cred.gid);
lua_setfield(L, -2, "gid");
return 1;
}
#endif
// -------------------------------------------------------
int opt_set_linger(lua_State *L, p_socket ps)
{
Expand Down
6 changes: 6 additions & 0 deletions src/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ int opt_set_ip6_drop_membersip(lua_State *L, p_socket ps);
int opt_set_ip6_v6only(lua_State *L, p_socket ps);
int opt_get_ip6_v6only(lua_State *L, p_socket ps);

#ifndef _WIN32
int opt_set_passcred(lua_State *L, p_socket ps);
int opt_get_passcred(lua_State *L, p_socket ps);
int opt_get_peercred(lua_State *L, p_socket ps);
#endif

int opt_get_error(lua_State *L, p_socket ps);

#ifndef _WIN32
Expand Down
55 changes: 38 additions & 17 deletions src/unixstream.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ static int meth_receive(lua_State *L);
static int meth_accept(lua_State *L);
static int meth_close(lua_State *L);
static int meth_setoption(lua_State *L);
static int meth_getoption(lua_State *L);
static int meth_settimeout(lua_State *L);
static int meth_getfd(lua_State *L);
static int meth_setfd(lua_State *L);
Expand All @@ -33,8 +34,8 @@ static int meth_getstats(lua_State *L);
static int meth_setstats(lua_State *L);
static int meth_getsockname(lua_State *L);

static const char *unixstream_tryconnect(p_unix un, const char *path);
static const char *unixstream_trybind(p_unix un, const char *path);
static const char *unixstream_tryconnect(p_unix un, const char *path, size_t pathlen);
static const char *unixstream_trybind(p_unix un, const char *path, size_t pathlen);

/* unixstream object methods */
static luaL_Reg unixstream_methods[] = {
Expand All @@ -58,6 +59,9 @@ static luaL_Reg unixstream_methods[] = {
{"getsockname", meth_getsockname},
{"settimeout", meth_settimeout},
{"shutdown", meth_shutdown},
#ifndef _WIN32
{"getoption", meth_getoption},
#endif
{NULL, NULL}
};

Expand All @@ -66,6 +70,9 @@ static t_opt optset[] = {
{"keepalive", opt_set_keepalive},
{"reuseaddr", opt_set_reuseaddr},
{"linger", opt_set_linger},
#ifndef _WIN32
{"passcred", opt_set_passcred},
#endif
{NULL, NULL}
};

Expand All @@ -75,6 +82,14 @@ static luaL_Reg func[] = {
{NULL, NULL}
};

#ifndef _WIN32

static t_opt optget[] = {
{"passcred", opt_get_passcred},
{"peercred", opt_get_peercred},
{NULL, NULL}
};
#endif
/*-------------------------------------------------------------------------*\
* Initializes module
\*-------------------------------------------------------------------------*/
Expand Down Expand Up @@ -128,6 +143,11 @@ static int meth_setoption(lua_State *L) {
return opt_meth_setoption(L, optset, &un->sock);
}

static int meth_getoption(lua_State *L) {
p_unix un = (p_unix) auxiliar_checkgroup(L, "unixstream{any}", 1);
return opt_meth_getoption(L, optget, &un->sock);
}

/*-------------------------------------------------------------------------*\
* Select support methods
\*-------------------------------------------------------------------------*/
Expand Down Expand Up @@ -181,13 +201,12 @@ static int meth_accept(lua_State *L) {
/*-------------------------------------------------------------------------*\
* Binds an object to an address
\*-------------------------------------------------------------------------*/
static const char *unixstream_trybind(p_unix un, const char *path) {
static const char *unixstream_trybind(p_unix un, const char *path, size_t pathlen) {
struct sockaddr_un local;
size_t len = strlen(path);
int err;
if (len >= sizeof(local.sun_path)) return "path too long";
if (pathlen >= sizeof(local.sun_path)) return "path too long";
memset(&local, 0, sizeof(local));
strcpy(local.sun_path, path);
memcpy(local.sun_path, path, pathlen);
local.sun_family = AF_UNIX;
#ifdef UNIX_HAS_SUN_LEN
local.sun_len = sizeof(local.sun_family) + sizeof(local.sun_len)
Expand All @@ -196,16 +215,17 @@ static const char *unixstream_trybind(p_unix un, const char *path) {

#else
err = socket_bind(&un->sock, (SA *) &local,
sizeof(local.sun_family) + len);
sizeof(local.sun_family) + pathlen);
#endif
if (err != IO_DONE) socket_destroy(&un->sock);
return socket_strerror(err);
}

static int meth_bind(lua_State *L) {
p_unix un = (p_unix) auxiliar_checkclass(L, "unixstream{master}", 1);
const char *path = luaL_checkstring(L, 2);
const char *err = unixstream_trybind(un, path);
size_t len = 0;
const char *path = luaL_checklstring(L, 2, &len);
const char *err = unixstream_trybind(un, path, len);
if (err) {
lua_pushnil(L);
lua_pushstring(L, err);
Expand Down Expand Up @@ -234,23 +254,22 @@ static int meth_getsockname(lua_State *L)
/*-------------------------------------------------------------------------*\
* Turns a master unixstream object into a client object.
\*-------------------------------------------------------------------------*/
static const char *unixstream_tryconnect(p_unix un, const char *path)
static const char *unixstream_tryconnect(p_unix un, const char *path, size_t pathlen)
{
struct sockaddr_un remote;
int err;
size_t len = strlen(path);
if (len >= sizeof(remote.sun_path)) return "path too long";
if (pathlen >= sizeof(remote.sun_path)) return "path too long";
memset(&remote, 0, sizeof(remote));
strcpy(remote.sun_path, path);
memcpy(remote.sun_path, path, pathlen);
remote.sun_family = AF_UNIX;
timeout_markstart(&un->tm);
#ifdef UNIX_HAS_SUN_LEN
remote.sun_len = sizeof(remote.sun_family) + sizeof(remote.sun_len)
+ len + 1;
+ pathlen + 1;
err = socket_connect(&un->sock, (SA *) &remote, remote.sun_len, &un->tm);
#else
err = socket_connect(&un->sock, (SA *) &remote,
sizeof(remote.sun_family) + len, &un->tm);
sizeof(remote.sun_family) + pathlen, &un->tm);
#endif
if (err != IO_DONE) socket_destroy(&un->sock);
return socket_strerror(err);
Expand All @@ -259,8 +278,10 @@ static const char *unixstream_tryconnect(p_unix un, const char *path)
static int meth_connect(lua_State *L)
{
p_unix un = (p_unix) auxiliar_checkclass(L, "unixstream{master}", 1);
const char *path = luaL_checkstring(L, 2);
const char *err = unixstream_tryconnect(un, path);
size_t len = 0;

const char *path = luaL_checklstring(L, 2, &len);
const char *err = unixstream_tryconnect(un, path, len);
if (err) {
lua_pushnil(L);
lua_pushstring(L, err);
Expand Down