aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xconfigure20
-rw-r--r--util-src/Makefile9
-rw-r--r--util-src/crand.c156
-rw-r--r--util/debug.lua3
-rw-r--r--util/import.lua1
-rw-r--r--util/iterators.lua5
-rw-r--r--util/multitable.lua3
-rw-r--r--util/random.lua3
-rw-r--r--util/session.lua6
-rw-r--r--util/sql.lua2
10 files changed, 200 insertions, 8 deletions
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 <string.h>
+#include <errno.h>
+
+/*
+ * TODO: Decide on fixed size or dynamically allocated buffer
+ */
+#if 1
+#include <malloc.h>
+#else
+#define BUFLEN 256
+#endif
+
+#if defined(WITH_GETRANDOM)
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <linux/random.h>
+
+#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 <stdlib.h>
+#elif defined(WITH_OPENSSL)
+#include <openssl/rand.h>
+#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/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;
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);
diff --git a/util/iterators.lua b/util/iterators.lua
index aa9c3ec0..868ba786 100644
--- a/util/iterators.lua
+++ b/util/iterators.lua
@@ -11,8 +11,9 @@
local it = {};
local t_insert = table.insert;
-local select, unpack, next = select, unpack, next;
-local function pack(...) return { n = select("#", ...), ... }; end
+local select, next = select, next;
+local unpack = table.unpack or unpack; --luacheck: ignore 113
+local pack = table.pack or function (...) return { n = select("#", ...), ... }; end
-- Reverse an iterator
function it.reverse(f, s, var)
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;
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()
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;
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;