From 58a6a4b140a317a9e77c803dfda08c5e4770e3fa Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 22 Feb 2016 17:30:12 +0100 Subject: util.sql: Localize unpack() in Lua 5.2 compatible way --- util/sql.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/sql.lua b/util/sql.lua index b4d14537..9981ac3c 100644 --- a/util/sql.lua +++ b/util/sql.lua @@ -1,6 +1,6 @@ local setmetatable, getmetatable = setmetatable, getmetatable; -local ipairs, unpack, select = ipairs, unpack, select; +local ipairs, unpack, select = ipairs, table.unpack or unpack, select; --luacheck: ignore 113 local tonumber, tostring = tonumber, tostring; local assert, xpcall, debug_traceback = assert, xpcall, debug.traceback; local t_concat = table.concat; -- cgit v1.2.3 From 5a4948a7447c459b604465d412759c44afc4362e Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 22 Feb 2016 17:32:11 +0100 Subject: util.session: Fix luacheck warnings --- util/session.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/util/session.lua b/util/session.lua index fda7fccd..b2a726ce 100644 --- a/util/session.lua +++ b/util/session.lua @@ -9,13 +9,13 @@ local function new_session(typ) end local function set_id(session) - local id = typ .. tostring(session):match("%x+$"):lower(); + local id = session.type .. tostring(session):match("%x+$"):lower(); session.id = id; return session; end local function set_logger(session) - local log = logger.init(id); + local log = logger.init(session.id); session.log = log; return session; end @@ -30,7 +30,7 @@ local function set_send(session) local conn = session.conn; if not conn then function session.send(data) - log("debug", "Discarding data sent to unconnected session: %s", tostring(data)); + session.log("debug", "Discarding data sent to unconnected session: %s", tostring(data)); return false; end return session; -- cgit v1.2.3 From 847ba75e55404bc8d386e1edf80699c921520aca Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 22 Feb 2016 17:34:42 +0100 Subject: util.debug: Silence luacheck warning about modifying 'debug' lib --- util/debug.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/util/debug.lua b/util/debug.lua index a78524a9..00f476d0 100644 --- a/util/debug.lua +++ b/util/debug.lua @@ -1,6 +1,9 @@ -- Variables ending with these names will not -- have their values printed ('password' includes -- 'new_password', etc.) +-- +-- luacheck: ignore 122/debug + local censored_names = { password = true; passwd = true; -- cgit v1.2.3 From 792b0e8d798c02f811d2dc0428a3babcd80f558f Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 22 Feb 2016 17:37:55 +0100 Subject: util.import: Localize unpack() in Lua 5.2 compatible way --- util/import.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/util/import.lua b/util/import.lua index 174da0ca..c2b9dce1 100644 --- a/util/import.lua +++ b/util/import.lua @@ -8,6 +8,7 @@ +local unpack = table.unpack or unpack; --luacheck: ignore 113 local t_insert = table.insert; function import(module, ...) local m = package.loaded[module] or require(module); -- cgit v1.2.3 From a2c0f6d6458193baa67e1df44a9c94fec357011b Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 22 Feb 2016 17:38:46 +0100 Subject: util.iterators: Localize unpack() in Lua 5.2 compatible way --- util/iterators.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/util/iterators.lua b/util/iterators.lua index aa9c3ec0..e688980b 100644 --- a/util/iterators.lua +++ b/util/iterators.lua @@ -11,7 +11,8 @@ local it = {}; local t_insert = table.insert; -local select, unpack, next = select, unpack, next; +local select, next = select, next; +local unpack = table.unpack or unpack; --luacheck: ignore 113 local function pack(...) return { n = select("#", ...), ... }; end -- Reverse an iterator -- cgit v1.2.3 From 29c6aed489216d03ecc070ee262d0943465441a7 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 22 Feb 2016 17:40:42 +0100 Subject: util.multitable: Localize unpack() in Lua 5.2 compatible way --- util/multitable.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/util/multitable.lua b/util/multitable.lua index 7a2d2b2a..e4321d3d 100644 --- a/util/multitable.lua +++ b/util/multitable.lua @@ -8,7 +8,8 @@ local select = select; local t_insert = table.insert; -local unpack, pairs, next, type = unpack, pairs, next, type; +local pairs, next, type = pairs, next, type; +local unpack = table.unpack or unpack; --luacheck: ignore 113 local _ENV = nil; -- cgit v1.2.3 From 11ebf4f1dc56644712e12e451e9b37c472c69238 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 22 Feb 2016 17:43:40 +0100 Subject: util.iterators: Use table.pack() on Lua 5.2 --- util/iterators.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/iterators.lua b/util/iterators.lua index e688980b..868ba786 100644 --- a/util/iterators.lua +++ b/util/iterators.lua @@ -13,7 +13,7 @@ local it = {}; local t_insert = table.insert; local select, next = select, next; local unpack = table.unpack or unpack; --luacheck: ignore 113 -local function pack(...) return { n = select("#", ...), ... }; end +local pack = table.pack or function (...) return { n = select("#", ...), ... }; end -- Reverse an iterator function it.reverse(f, s, var) -- cgit v1.2.3 From ed8199402ff2a84e57f256818ebc2c505c2ac41d Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 22 Feb 2016 18:44:43 +0100 Subject: util.crand: C binding to one of OpenSSL, Linux getrandom() or OpenBSD arc4random() CSPRNG --- configure | 20 +++++++ util-src/Makefile | 9 +++- util-src/crand.c | 156 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ util/random.lua | 3 ++ 4 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 util-src/crand.c diff --git a/configure b/configure index b64c2654..77aa1329 100755 --- a/configure +++ b/configure @@ -19,6 +19,8 @@ CXX=g++ LD=gcc RUNWITH=lua EXCERTS=yes +PRNG= +PRNGLIBS= CFLAGS="-fPIC -Wall" LDFLAGS="-shared" @@ -58,6 +60,11 @@ Configure Prosody prior to building. icu: use ICU from IBM --with-ssl=LIB The name of the SSL to link with. Default is $OPENSSL_LIB +--with-random=METHOD CSPRNG backend to use. One of + getrandom: Linux kernel + arc4random: OpenBSD kernel + openssl: OpenSSL RAND method + Default is to use /dev/urandom --cflags=FLAGS Flags to pass to the compiler Default is $CFLAGS --ldflags=FLAGS Flags to pass to the linker @@ -174,6 +181,16 @@ do --with-ssl=*) OPENSSL_LIB="$value" ;; + --with-random=getrandom) + PRNG=GETRANDOM + ;; + --with-random=openssl) + PRNG=OPENSSL + PRNGLIBS=-lcrypto + ;; + --with-random=arc4random) + PRNG=ARC4RANDOM + ;; --cflags=*) CFLAGS="$value" ;; @@ -372,6 +389,9 @@ CXX=$CXX LD=$LD RUNWITH=$RUNWITH EXCERTS=$EXCERTS +RANDOM=$PRNG +RANDOM_LIBS=$PRNGLIBS + EOF diff --git a/util-src/Makefile b/util-src/Makefile index 85b190b9..9c6c377c 100644 --- a/util-src/Makefile +++ b/util-src/Makefile @@ -8,6 +8,10 @@ TARGET?=../util/ ALL=encodings.so hashes.so net.so pposix.so signal.so table.so ringbuffer.so +ifdef RANDOM +ALL+=crand.so +endif + .PHONY: all install clean .SUFFIXES: .c .o .so @@ -17,11 +21,14 @@ install: $(ALL) $(INSTALL_DATA) $^ $(TARGET) clean: - rm -f $(ALL) + rm -f $(ALL) $(patsubst %.so,%.o,$(ALL)) encodings.so: LDLIBS+=$(IDNA_LIBS) hashes.so: LDLIBS+=$(OPENSSL_LIBS) +crand.o: CFLAGS+=-DWITH_$(RANDOM) +crand.so: LDLIBS+=$(RANDOM_LIBS) + %.so: %.o $(LD) $(LDFLAGS) -o $@ $^ $(LDLIBS) diff --git a/util-src/crand.c b/util-src/crand.c new file mode 100644 index 00000000..9a45f10f --- /dev/null +++ b/util-src/crand.c @@ -0,0 +1,156 @@ +/* Prosody IM +-- Copyright (C) 2008-2016 Matthew Wild +-- Copyright (C) 2008-2016 Waqas Hussain +-- Copyright (C) 2016 Kim Alvefur +-- +-- This project is MIT/X11 licensed. Please see the +-- COPYING file in the source package for more information. +-- +*/ + +/* +* crand.c +* C PRNG interface +*/ + +#include "lualib.h" +#include "lauxlib.h" + +#include +#include + +/* + * TODO: Decide on fixed size or dynamically allocated buffer + */ +#if 1 +#include +#else +#define BUFLEN 256 +#endif + +#if defined(WITH_GETRANDOM) +#include +#include +#include + +#ifndef SYS_getrandom +#error getrandom() requires Linux 3.17 or later +#endif + +/* Was this not supposed to be a function? */ +int getrandom(char *buf, size_t len, int flags) { + return syscall(SYS_getrandom, buf, len, flags); +} + +#elif defined(WITH_ARC4RANDOM) +#include +#elif defined(WITH_OPENSSL) +#include +#else +#error util.crand compiled without a random source +#endif + +int Lrandom(lua_State *L) { +#ifdef BUFLEN + unsigned char buf[BUFLEN]; +#else + unsigned char *buf; +#endif + int ret = 0; + size_t len = (size_t)luaL_checkint(L, 1); +#ifdef BUFLEN + len = len > BUFLEN ? BUFLEN : len; +#else + buf = malloc(len); + + if(buf == NULL) { + lua_pushnil(L); + lua_pushstring(L, "out of memory"); + /* or it migth be better to + * return lua_error(L); + */ + return 2; + } +#endif + +#if defined(WITH_GETRANDOM) + ret = getrandom(buf, len, 0); + + if(ret < 0) { +#ifndef BUFLEN + free(buf); +#endif + lua_pushnil(L); + lua_pushstring(L, strerror(errno)); + lua_pushinteger(L, errno); + return 3; + } + +#elif defined(WITH_ARC4RANDOM) + arc4random_buf(buf, len); + ret = len; +#elif defined(WITH_OPENSSL) + ret = RAND_bytes(buf, len); + + if(ret == 1) { + ret = len; + } else { +#ifndef BUFLEN + free(buf); +#endif + lua_pushnil(L); + lua_pushstring(L, "failed"); + /* lua_pushinteger(L, ERR_get_error()); */ + return 2; + } + +#endif + + lua_pushlstring(L, buf, ret); +#ifndef BUFLEN + free(buf); +#endif + return 1; +} + +#ifdef ENABLE_SEEDING +int Lseed(lua_State *L) { + size_t len; + const char *seed = lua_tolstring(L, 1, &len); + +#if defined(WITH_OPENSSL) + RAND_add(seed, len, len); + return 0; +#else + lua_pushnil(L); + lua_pushliteral(L, "not-supported"); + return 2; +#endif +} +#endif + +int luaopen_util_crand(lua_State *L) { + lua_newtable(L); + lua_pushcfunction(L, Lrandom); + lua_setfield(L, -2, "bytes"); +#ifdef ENABLE_SEEDING + lua_pushcfunction(L, Lseed); + lua_setfield(L, -2, "seed"); +#endif + +#if defined(WITH_GETRANDOM) + lua_pushstring(L, "Linux"); +#elif defined(WITH_ARC4RANDOM) + lua_pushstring(L, "arc4random()"); +#elif defined(WITH_OPENSSL) + lua_pushstring(L, "OpenSSL"); +#endif + lua_setfield(L, -2, "_source"); + +#if defined(WITH_OPENSSL) && defined(_WIN32) + /* Do we need to seed this on Windows? */ +#endif + + return 1; +} + diff --git a/util/random.lua b/util/random.lua index e4b4a700..574e2e1c 100644 --- a/util/random.lua +++ b/util/random.lua @@ -6,6 +6,9 @@ -- COPYING file in the source package for more information. -- +local ok, crand = pcall(require, "util.crand"); +if ok then return crand; end + local urandom, urandom_err = io.open("/dev/urandom", "r"); local function seed() -- cgit v1.2.3