aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AUTHORS2
-rwxr-xr-xconfigure20
-rw-r--r--core/configmanager.lua27
-rw-r--r--plugins/mod_saslauth.lua1
-rw-r--r--plugins/mod_version.lua19
-rwxr-xr-xprosody18
-rw-r--r--tests/test_util_multitable.lua62
-rw-r--r--util-src/Makefile15
-rw-r--r--util-src/pposix.c92
-rw-r--r--util/sasl.lua14
10 files changed, 240 insertions, 30 deletions
diff --git a/AUTHORS b/AUTHORS
index 8fe161bb..0875361d 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,4 +1,4 @@
== Core development team ==
-Matthew Wild (matthew AT heavy-horse.co.uk)
+Matthew Wild (matthew.wild AT heavy-horse.co.uk)
Waqas Hussain (waqas20 AT gmail.com)
diff --git a/configure b/configure
index 8eb7b367..e310b7a7 100755
--- a/configure
+++ b/configure
@@ -12,8 +12,10 @@ LUA_INCDIR="/usr/include"
LUA_LIBDIR="/usr/lib"
IDN_LIB=idn
OPENSSL_LIB=crypto
+CC=gcc
+LD=gcc
-CFLAGS="-fPIC"
+CFLAGS="-fPIC -Wall"
LFLAGS="-shared"
# Help
@@ -45,6 +47,12 @@ Configure Prosody prior to building.
Default is $OPENSSL_LIB
--cflags=FLAGS Flags to pass to the compiler
Default is $CFLAGS
+--lflags=FLAGS Flags to pass to the linker
+ Default is $LFLAGS
+--c-compiler=CC The C compiler to use when building modules.
+ Default is $CC
+--linker=CC The linker to use when building modules.
+ Default is $LD
--require-config Will cause Prosody to refuse to run when
it fails to find a configuration file
EOF
@@ -105,6 +113,12 @@ do
--cflags=*)
CFLAGS="$value"
;;
+ --c-compiler=*)
+ CC="$value"
+ ;;
+ --linker=*)
+ LD="$value"
+ ;;
*)
echo "Error: Unknown flag: $1"
exit 1
@@ -126,7 +140,7 @@ then
LUA_INCDIR_SET=yes
LUA_LIBDIR=/usr/local/lib
LUA_LIBDIR_SET=yes
- CFLAGS=""
+ CFLAGS="-Wall"
LFLAGS="-bundle -undefined dynamic_lookup"
fi
fi
@@ -279,6 +293,8 @@ IDN_LIB=$IDN_LIB
OPENSSL_LIB=$OPENSSL_LIB
CFLAGS=$CFLAGS
LFLAGS=$LFLAGS
+CC=$CC
+LD=$LD
EOF
diff --git a/core/configmanager.lua b/core/configmanager.lua
index 075fcd3e..049862c2 100644
--- a/core/configmanager.lua
+++ b/core/configmanager.lua
@@ -9,8 +9,8 @@
local _G = _G;
-local setmetatable, loadfile, pcall, rawget, rawset, io =
- setmetatable, loadfile, pcall, rawget, rawset, io;
+local setmetatable, loadfile, pcall, rawget, rawset, io, error, dofile =
+ setmetatable, loadfile, pcall, rawget, rawset, io, error, dofile;
module "configmanager"
@@ -68,15 +68,15 @@ function load(filename, format)
if f then
local ok, err = parsers[format].load(f:read("*a"));
f:close();
- return ok, err;
+ return ok, "parser", err;
end
- return f, err;
+ return f, "file", err;
end
if not format then
- return nil, "no parser specified";
+ return nil, "file", "no parser specified";
else
- return nil, "no parser for "..(format);
+ return nil, "file", "no parser for "..(format);
end
end
@@ -97,7 +97,8 @@ do
function parsers.lua.load(data)
local env;
-- The ' = true' are needed so as not to set off __newindex when we assign the functions below
- env = setmetatable({ Host = true; host = true; Component = true, component = true }, { __index = function (t, k)
+ env = setmetatable({ Host = true; host = true; Component = true, component = true,
+ Include = true, include = true, RunScript = dofile }, { __index = function (t, k)
return rawget(_G, k) or
function (settings_table)
config[__currenthost or "*"][k] = settings_table;
@@ -124,6 +125,18 @@ do
end
env.component = env.Component;
+ function env.Include(file)
+ local f, err = io.open(file);
+ if f then
+ local data = f:read("*a");
+ local ok, err = parsers.lua.load(data);
+ if not ok then error(err:gsub("%[string.-%]", file), 0); end
+ end
+ if not f then error("Error loading included "..file..": "..err, 0); end
+ return f, err;
+ end
+ env.include = env.Include;
+
local chunk, err = loadstring(data);
if not chunk then
diff --git a/plugins/mod_saslauth.lua b/plugins/mod_saslauth.lua
index 7fec1f3f..ed19a150 100644
--- a/plugins/mod_saslauth.lua
+++ b/plugins/mod_saslauth.lua
@@ -106,6 +106,7 @@ module:add_event_hook("stream-features",
-- TODO: Provide PLAIN only if TLS is active, this is a SHOULD from the introduction of RFC 4616. This behavior could be overridden via configuration but will issuing a warning or so.
features:tag("mechanism"):text("PLAIN"):up();
features:tag("mechanism"):text("DIGEST-MD5"):up();
+ features:tag("mechanism"):text("ANONYMOUS"):up();
features:up();
else
features:tag("bind", bind_attr):tag("required"):up():up();
diff --git a/plugins/mod_version.lua b/plugins/mod_version.lua
index d96da41e..e577c6f8 100644
--- a/plugins/mod_version.lua
+++ b/plugins/mod_version.lua
@@ -14,11 +14,28 @@ local xmlns_version = "jabber:iq:version"
module:add_feature(xmlns_version);
+local version = "the best operating system ever!";
+
+if not require "core.configmanager".get("*", "core", "hide_os_type") then
+ if os.getenv("WINDIR") then
+ version = "Windows";
+ else
+ local uname = io.popen("uname");
+ if uname then
+ version = uname:read("*a");
+ else
+ version = "an OS";
+ end
+ end
+end
+
+version = version:match("^%s*(.-)%s*$") or version;
+
module:add_iq_handler({"c2s", "s2sin"}, xmlns_version, function(session, stanza)
if stanza.attr.type == "get" then
session.send(st.reply(stanza):query(xmlns_version)
:tag("name"):text("Prosody"):up()
:tag("version"):text("0.3"):up()
- :tag("os"):text("the best operating system ever!"));
+ :tag("os"):text(version));
end
end);
diff --git a/prosody b/prosody
index f63fc50d..197446e6 100755
--- a/prosody
+++ b/prosody
@@ -40,17 +40,25 @@ log = require "util.logger".init("general");
do
-- TODO: Check for other formats when we add support for them
-- Use lfs? Make a new conf/ dir?
- local ok, err = config.load((CFG_CONFIGDIR or ".").."/prosody.cfg.lua");
+ local ok, level, err = config.load((CFG_CONFIGDIR or ".").."/prosody.cfg.lua");
if not ok then
print("");
print("**************************");
- print("Prosody was unable to find the configuration file.");
- print("We looked for: "..(CFG_CONFIGDIR or ".").."/prosody.cfg.lua");
- print("A sample config file is included in the Prosody download called prosody.cfg.lua.dist");
- print("Copy or rename it to prosody.cfg.lua and edit as necessary.");
+ if level == "parser" then
+ print("A problem occured while reading the config file "..(CFG_CONFIGDIR or ".").."/prosody.cfg.lua");
+ local err_line, err_message = tostring(err):match("%[string .-%]:(%d*): (.*)");
+ print("Error"..(err_line and (" on line "..err_line) or "")..": "..(err_message or tostring(err)));
+ print("");
+ elseif level == "file" then
+ print("Prosody was unable to find the configuration file.");
+ print("We looked for: "..(CFG_CONFIGDIR or ".").."/prosody.cfg.lua");
+ print("A sample config file is included in the Prosody download called prosody.cfg.lua.dist");
+ print("Copy or rename it to prosody.cfg.lua and edit as necessary.");
+ end
print("More help on configuring Prosody can be found at http://prosody.im/doc/configure");
print("Good luck!");
print("**************************");
+ print("");
os.exit(1);
end
end
diff --git a/tests/test_util_multitable.lua b/tests/test_util_multitable.lua
new file mode 100644
index 00000000..aa93fc8d
--- /dev/null
+++ b/tests/test_util_multitable.lua
@@ -0,0 +1,62 @@
+-- Prosody IM v0.3
+-- Copyright (C) 2008-2009 Matthew Wild
+-- Copyright (C) 2008-2009 Waqas Hussain
+--
+-- This project is MIT/X11 licensed. Please see the
+-- COPYING file in the source package for more information.
+--
+
+
+function new(new, multitable)
+ mt = new();
+ assert_table(mt, "Multitable is a table");
+ assert_function(mt.add, "Multitable has method add");
+ assert_function(mt.get, "Multitable has method get");
+ assert_function(mt.remove, "Multitable has method remove");
+
+ get(mt.get, multitable);
+end
+
+function get(get, multitable)
+ local function has_items(list, ...)
+ local should_have = {};
+ if select('#', ...) > 0 then
+ assert_table(list, "has_items: list is table", 3);
+ else
+ assert_is_not(list and #list > 0, "No items, and no list");
+ return true, "has-all";
+ end
+ for n=1,select('#', ...) do should_have[select(n, ...)] = true; end
+ for n, item in ipairs(list) do
+ if not should_have[item] then return false, "too-many"; end
+ should_have[item] = nil;
+ end
+ if next(should_have) then
+ return false, "not-enough";
+ end
+ return true, "has-all";
+ end
+ local function assert_has_all(message, list, ...)
+ return assert_equal(select(2, has_items(list, ...)), "has-all", message or "List has all expected items, and no more", 2);
+ end
+
+ mt = multitable.new();
+
+ local trigger1, trigger2, trigger3 = {}, {}, {};
+ local item1, item2, item3 = {}, {}, {};
+
+ assert_has_all("Has no items with trigger1", mt:get(trigger1));
+
+
+ mt:add(1, 2, 3, item1);
+
+ assert_has_all("Has item1 for 1, 2, 3", mt:get(1, 2, 3), item1);
+
+-- Doesn't support nil
+--[[ mt:add(nil, item1);
+ mt:add(nil, item2);
+ mt:add(nil, item3);
+
+ assert_has_all("Has all items with (nil)", mt:get(nil), item1, item2, item3);
+]]
+end
diff --git a/util-src/Makefile b/util-src/Makefile
index 06e72577..4058b59d 100644
--- a/util-src/Makefile
+++ b/util-src/Makefile
@@ -6,7 +6,8 @@ LUA_INCDIR?=/usr/include/lua$(LUA_SUFFIX)
LUA_LIB?=lua$(LUA_SUFFIX)
IDN_LIB?=idn
OPENSSL_LIB?=crypto
-
+CC?=gcc
+LD?=gcc
all: encodings.so hashes.so pposix.so
@@ -21,18 +22,18 @@ clean:
rm -f ../util/*.so
encodings.o: encodings.c
- gcc $(CFLAGS) -I$(LUA_INCDIR) -c -o encodings.o encodings.c
+ $(CC) $(CFLAGS) -I$(LUA_INCDIR) -c -o encodings.o encodings.c
encodings.so: encodings.o
- export MACOSX_DEPLOYMENT_TARGET="10.3"; gcc $(LFLAGS) -o encodings.so encodings.o -L/usr/local/lib -llua$(LUA_SUFFIX) -lidn
+ export MACOSX_DEPLOYMENT_TARGET="10.3"; $(LD) $(LFLAGS) -o encodings.so encodings.o -L$(LUA_LIBDIR) -llua$(LUA_SUFFIX) -lidn
hashes.o: hashes.c
- gcc $(CFLAGS) -I$(LUA_INCDIR) -c -o hashes.o hashes.c
+ $(CC) $(CFLAGS) -I$(LUA_INCDIR) -c -o hashes.o hashes.c
hashes.so: hashes.o
- export MACOSX_DEPLOYMENT_TARGET="10.3"; gcc $(LFLAGS) -o hashes.so hashes.o -L/usr/local/lib -llua$(LUA_SUFFIX) -lcrypto
+ export MACOSX_DEPLOYMENT_TARGET="10.3"; $(LD) $(LFLAGS) -o hashes.so hashes.o -L$(LUA_LIBDIR) -llua$(LUA_SUFFIX) -lcrypto
pposix.o: pposix.c
- gcc $(CFLAGS) -I$(LUA_INCDIR) -c -o pposix.o pposix.c
+ $(CC) $(CFLAGS) -I$(LUA_INCDIR) -c -o pposix.o pposix.c
pposix.so: pposix.o
- export MACOSX_DEPLOYMENT_TARGET="10.3"; gcc $(LFLAGS) -o pposix.so pposix.o -L/usr/local/lib -llua$(LUA_SUFFIX)
+ export MACOSX_DEPLOYMENT_TARGET="10.3"; $(LD) $(LFLAGS) -o pposix.so pposix.o -L$(LUA_LIBDIR) -llua$(LUA_SUFFIX)
diff --git a/util-src/pposix.c b/util-src/pposix.c
index 1257fa8c..075c9c8e 100644
--- a/util-src/pposix.c
+++ b/util-src/pposix.c
@@ -22,9 +22,10 @@
#include <fcntl.h>
#include <syslog.h>
+#include <pwd.h>
#include <string.h>
-
+#include <errno.h>
#include "lua.h"
#include "lauxlib.h"
@@ -85,7 +86,8 @@ static int lc_daemonize(lua_State *L)
/* Syslog support */
-char *facility_strings[] = { "auth",
+const char * const facility_strings[] = {
+ "auth",
"authpriv",
"cron",
"daemon",
@@ -142,7 +144,7 @@ char* syslog_ident = NULL;
int lc_syslog_open(lua_State* L)
{
- int facility = luaL_checkoption(L, 2, "daemon", &facility_strings);
+ int facility = luaL_checkoption(L, 2, "daemon", facility_strings);
facility = facility_constants[facility];
luaL_checkstring(L, 1);
@@ -156,7 +158,7 @@ int lc_syslog_open(lua_State* L)
return 0;
}
-char *level_strings[] = {
+const char * const level_strings[] = {
"debug",
"info",
"notice",
@@ -174,7 +176,7 @@ int level_constants[] = {
};
int lc_syslog_log(lua_State* L)
{
- int level = luaL_checkoption(L, 1, "notice", &level_strings);
+ int level = luaL_checkoption(L, 1, "notice", level_strings);
level = level_constants[level];
luaL_checkstring(L, 2);
@@ -196,7 +198,7 @@ int lc_syslog_close(lua_State* L)
int lc_syslog_setmask(lua_State* L)
{
- int level_idx = luaL_checkoption(L, 1, "notice", &level_strings);
+ int level_idx = luaL_checkoption(L, 1, "notice", level_strings);
int mask = 0;
do
{
@@ -215,6 +217,78 @@ int lc_getpid(lua_State* L)
return 1;
}
+/* UID/GID functions */
+
+int lc_getuid(lua_State* L)
+{
+ lua_pushinteger(L, getuid());
+ return 1;
+}
+
+int lc_getgid(lua_State* L)
+{
+ lua_pushinteger(L, getgid());
+ return 1;
+}
+
+int lc_setuid(lua_State* L)
+{
+ int uid = -1;
+ if(lua_gettop(L) < 1)
+ return 0;
+ if(!lua_isnumber(L, 1) && lua_tostring(L, 1))
+ {
+ /* Passed UID is actually a string, so look up the UID */
+ struct passwd *p;
+ p = getpwnam(lua_tostring(L, 1));
+ if(!p)
+ {
+ lua_pushboolean(L, 0);
+ lua_pushstring(L, "no-such-user");
+ return 2;
+ }
+ uid = p->pw_uid;
+ }
+ else
+ {
+ uid = lua_tonumber(L, 1);
+ }
+
+ if(uid>-1)
+ {
+ /* Ok, attempt setuid */
+ errno = 0;
+ if(setuid(uid))
+ {
+ /* Fail */
+ lua_pushboolean(L, 0);
+ switch(errno)
+ {
+ case EINVAL:
+ lua_pushstring(L, "invalid-uid");
+ break;
+ case EPERM:
+ lua_pushstring(L, "permission-denied");
+ break;
+ default:
+ lua_pushstring(L, "unknown-error");
+ }
+ return 2;
+ }
+ else
+ {
+ /* Success! */
+ lua_pushboolean(L, 1);
+ return 1;
+ }
+ }
+
+ /* Seems we couldn't find a valid UID to switch to */
+ lua_pushboolean(L, 0);
+ lua_pushstring(L, "invalid-uid");
+ return 2;
+}
+
/* Register functions */
int luaopen_util_pposix(lua_State *L)
@@ -239,6 +313,12 @@ int luaopen_util_pposix(lua_State *L)
lua_pushcfunction(L, lc_getpid);
lua_setfield(L, -2, "getpid");
+ lua_pushcfunction(L, lc_getuid);
+ lua_setfield(L, -2, "getuid");
+
+ lua_pushcfunction(L, lc_setuid);
+ lua_setfield(L, -2, "setuid");
+
lua_pushliteral(L, "pposix");
lua_setfield(L, -2, "_NAME");
diff --git a/util/sasl.lua b/util/sasl.lua
index 43455909..03115fb6 100644
--- a/util/sasl.lua
+++ b/util/sasl.lua
@@ -1,4 +1,4 @@
--- sasl.lua v0.2
+-- sasl.lua v0.3
-- Copyright (C) 2008-2009 Tobias Markmann
--
-- All rights reserved.
@@ -235,10 +235,22 @@ local function new_digest_md5(realm, password_handler)
return object
end
+local function new_anonymous(realm, password_handler)
+ local object = { mechanism = "ANONYMOUS", realm = realm, password_handler = password_handler}
+ function object.feed(self, message)
+ return "success"
+ end
+ --TODO: From XEP-0175 "It is RECOMMENDED for the node identifier to be a UUID as specified in RFC 4122 [5]." So util.uuid() should (or have an option to) behave as specified in RFC 4122.
+ object["username"] = generate_uuid()
+ return object
+end
+
+
function new(mechanism, realm, password_handler)
local object
if mechanism == "PLAIN" then object = new_plain(realm, password_handler)
elseif mechanism == "DIGEST-MD5" then object = new_digest_md5(realm, password_handler)
+ elseif mechanism == "ANONYMOUS" then object = new_anonymous(realm, password_handler)
else
log("debug", "Unsupported SASL mechanism: "..tostring(mechanism));
return nil