aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--core/portmanager.lua4
-rw-r--r--net/server_event.lua1
-rw-r--r--net/server_select.lua1
-rw-r--r--plugins/mod_compression.lua6
-rw-r--r--plugins/muc/muc.lib.lua2
-rw-r--r--util/dependencies.lua10
-rw-r--r--util/xmppstream.lua90
8 files changed, 101 insertions, 15 deletions
diff --git a/Makefile b/Makefile
index c5390599..a1de1b6d 100644
--- a/Makefile
+++ b/Makefile
@@ -55,7 +55,7 @@ util/%.so:
$(MAKE) install -C util-src
%.install: %
- sed "1s/\blua\b/$(RUNWITH)/; \
+ sed "1s| lua$$| $(RUNWITH)|; \
s|^CFG_SOURCEDIR=.*;$$|CFG_SOURCEDIR='$(INSTALLEDSOURCE)';|; \
s|^CFG_CONFIGDIR=.*;$$|CFG_CONFIGDIR='$(INSTALLEDCONFIG)';|; \
s|^CFG_DATADIR=.*;$$|CFG_DATADIR='$(INSTALLEDDATA)';|; \
diff --git a/core/portmanager.lua b/core/portmanager.lua
index 95900c08..4cbf3eb3 100644
--- a/core/portmanager.lua
+++ b/core/portmanager.lua
@@ -29,6 +29,8 @@ if socket.tcp6 and config.get("*", "use_ipv6") ~= false then
table.insert(default_local_interfaces, "::1");
end
+local default_mode = config.get("*", "network_default_read_size") or 4096;
+
--- Private state
-- service_name -> { service_info, ... }
@@ -111,7 +113,7 @@ function activate(service_name)
}
bind_ports = set.new(type(bind_ports) ~= "table" and { bind_ports } or bind_ports );
- local mode, ssl = listener.default_mode or "*a";
+ local mode, ssl = listener.default_mode or default_mode;
local hooked_ports = {};
for interface in bind_interfaces do
diff --git a/net/server_event.lua b/net/server_event.lua
index 59217a0c..53330997 100644
--- a/net/server_event.lua
+++ b/net/server_event.lua
@@ -367,6 +367,7 @@ do
function interface_mt:ssl()
return self._usingssl
end
+ interface_mt.clientport = interface_mt.port -- COMPAT server_select
function interface_mt:type()
return self._type or "client"
diff --git a/net/server_select.lua b/net/server_select.lua
index c5e0772f..daad0f50 100644
--- a/net/server_select.lua
+++ b/net/server_select.lua
@@ -401,6 +401,7 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport
handler.clientport = function( )
return clientport
end
+ handler.port = handler.clientport -- COMPAT server_event
local write = function( self, data )
bufferlen = bufferlen + #data
if bufferlen > maxsendlen then
diff --git a/plugins/mod_compression.lua b/plugins/mod_compression.lua
index f44e8a6d..9da5254e 100644
--- a/plugins/mod_compression.lua
+++ b/plugins/mod_compression.lua
@@ -125,8 +125,8 @@ end
module:hook("stanza/http://jabber.org/protocol/compress:compressed", function(event)
local session = event.origin;
-
- if session.type == "s2sout_unauthed" or session.type == "s2sout" then
+
+ if session.type == "s2sout" then
session.log("debug", "Activating compression...")
-- create deflate and inflate streams
local deflate_stream = get_deflate_stream(session);
@@ -150,7 +150,7 @@ end);
module:hook("stanza/http://jabber.org/protocol/compress:compress", function(event)
local session, stanza = event.origin, event.stanza;
- if session.type == "c2s" or session.type == "s2sin" or session.type == "c2s_unauthed" or session.type == "s2sin_unauthed" then
+ if session.type == "c2s" or session.type == "s2sin" then
-- fail if we are already compressed
if session.compressed then
local error_st = st.stanza("failure", {xmlns=xmlns_compression_protocol}):tag("setup-failed");
diff --git a/plugins/muc/muc.lib.lua b/plugins/muc/muc.lib.lua
index d09c768e..8cf8d882 100644
--- a/plugins/muc/muc.lib.lua
+++ b/plugins/muc/muc.lib.lua
@@ -1032,7 +1032,7 @@ function room_mt:can_set_role(actor_jid, occupant_jid, role)
if actor_jid == true then return true; end
local actor = self._occupants[self._jid_nick[actor_jid]];
- if actor.role == "moderator" then
+ if actor and actor.role == "moderator" then
if occupant.affiliation ~= "owner" and occupant.affiliation ~= "admin" then
if actor.affiliation == "owner" or actor.affiliation == "admin" then
return true;
diff --git a/util/dependencies.lua b/util/dependencies.lua
index 109a3332..9d80d241 100644
--- a/util/dependencies.lua
+++ b/util/dependencies.lua
@@ -140,7 +140,15 @@ function log_warnings()
if not pcall(lxp.new, { StartDoctypeDecl = false }) then
log("error", "The version of LuaExpat on your system leaves Prosody "
.."vulnerable to denial-of-service attacks. You should upgrade to "
- .."LuaExpat 1.1.1 or higher as soon as possible. See "
+ .."LuaExpat 1.3.0 or higher as soon as possible. See "
+ .."http://prosody.im/doc/depends#luaexpat for more information.");
+ end
+ if not lxp.new({}).getcurrentbytecount then
+ log("error", "The version of LuaExpat on your system does not support "
+ .."stanza size limits, which may leave servers on untrusted "
+ .."networks (e.g. the internet) vulnerable to denial-of-service "
+ .."attacks. You should upgrade to LuaExpat 1.3.0 or higher as "
+ .."soon as possible. See "
.."http://prosody.im/doc/depends#luaexpat for more information.");
end
end
diff --git a/util/xmppstream.lua b/util/xmppstream.lua
index 550170c9..586ad5f9 100644
--- a/util/xmppstream.lua
+++ b/util/xmppstream.lua
@@ -6,7 +6,6 @@
-- COPYING file in the source package for more information.
--
-
local lxp = require "lxp";
local st = require "util.stanza";
local stanza_mt = st.stanza_mt;
@@ -20,6 +19,10 @@ local setmetatable = setmetatable;
-- COMPAT: w/LuaExpat 1.1.0
local lxp_supports_doctype = pcall(lxp.new, { StartDoctypeDecl = false });
+local lxp_supports_xmldecl = pcall(lxp.new, { XmlDecl = false });
+local lxp_supports_bytecount = not not lxp.new({}).getcurrentbytecount;
+
+local default_stanza_size_limit = 1024*1024*10; -- 10MB
module "xmppstream"
@@ -40,13 +43,16 @@ local ns_pattern = "^([^"..ns_separator.."]*)"..ns_separator.."?(.*)$";
_M.ns_separator = ns_separator;
_M.ns_pattern = ns_pattern;
-function new_sax_handlers(session, stream_callbacks)
+local function dummy_cb() end
+
+function new_sax_handlers(session, stream_callbacks, cb_handleprogress)
local xml_handlers = {};
local cb_streamopened = stream_callbacks.streamopened;
local cb_streamclosed = stream_callbacks.streamclosed;
local cb_error = stream_callbacks.error or function(session, e, stanza) error("XML stream error: "..tostring(e)..(stanza and ": "..tostring(stanza) or ""),2); end;
local cb_handlestanza = stream_callbacks.handlestanza;
+ cb_handleprogress = cb_handleprogress or dummy_cb;
local stream_ns = stream_callbacks.stream_ns or xmlns_streams;
local stream_tag = stream_callbacks.stream_tag or "stream";
@@ -59,6 +65,7 @@ function new_sax_handlers(session, stream_callbacks)
local stack = {};
local chardata, stanza = {};
+ local stanza_size = 0;
local non_streamns_depth = 0;
function xml_handlers:StartElement(tagname, attr)
if stanza and #chardata > 0 then
@@ -87,10 +94,17 @@ function new_sax_handlers(session, stream_callbacks)
end
if not stanza then --if we are not currently inside a stanza
+ if lxp_supports_bytecount then
+ stanza_size = self:getcurrentbytecount();
+ end
if session.notopen then
if tagname == stream_tag then
non_streamns_depth = 0;
if cb_streamopened then
+ if lxp_supports_bytecount then
+ cb_handleprogress(stanza_size);
+ stanza_size = 0;
+ end
cb_streamopened(session, attr);
end
else
@@ -105,6 +119,9 @@ function new_sax_handlers(session, stream_callbacks)
stanza = setmetatable({ name = name, attr = attr, tags = {} }, stanza_mt);
else -- we are inside a stanza, so add a tag
+ if lxp_supports_bytecount then
+ stanza_size = stanza_size + self:getcurrentbytecount();
+ end
t_insert(stack, stanza);
local oldstanza = stanza;
stanza = setmetatable({ name = name, attr = attr, tags = {} }, stanza_mt);
@@ -112,12 +129,45 @@ function new_sax_handlers(session, stream_callbacks)
t_insert(oldstanza.tags, stanza);
end
end
+ if lxp_supports_xmldecl then
+ function xml_handlers:XmlDecl(version, encoding, standalone)
+ if lxp_supports_bytecount then
+ cb_handleprogress(self:getcurrentbytecount());
+ end
+ end
+ end
+ function xml_handlers:StartCdataSection()
+ if lxp_supports_bytecount then
+ if stanza then
+ stanza_size = stanza_size + self:getcurrentbytecount();
+ else
+ cb_handleprogress(self:getcurrentbytecount());
+ end
+ end
+ end
+ function xml_handlers:EndCdataSection()
+ if lxp_supports_bytecount then
+ if stanza then
+ stanza_size = stanza_size + self:getcurrentbytecount();
+ else
+ cb_handleprogress(self:getcurrentbytecount());
+ end
+ end
+ end
function xml_handlers:CharacterData(data)
if stanza then
+ if lxp_supports_bytecount then
+ stanza_size = stanza_size + self:getcurrentbytecount();
+ end
t_insert(chardata, data);
+ elseif lxp_supports_bytecount then
+ cb_handleprogress(self:getcurrentbytecount());
end
end
function xml_handlers:EndElement(tagname)
+ if lxp_supports_bytecount then
+ stanza_size = stanza_size + self:getcurrentbytecount()
+ end
if non_streamns_depth > 0 then
non_streamns_depth = non_streamns_depth - 1;
end
@@ -129,6 +179,10 @@ function new_sax_handlers(session, stream_callbacks)
end
-- Complete stanza
if #stack == 0 then
+ if lxp_supports_bytecount then
+ cb_handleprogress(stanza_size);
+ end
+ stanza_size = 0;
if tagname ~= stream_error_tag then
cb_handlestanza(session, stanza);
else
@@ -159,7 +213,7 @@ function new_sax_handlers(session, stream_callbacks)
xml_handlers.ProcessingInstruction = restricted_handler;
local function reset()
- stanza, chardata = nil, {};
+ stanza, chardata, stanza_size = nil, {}, 0;
stack = {};
end
@@ -170,19 +224,39 @@ function new_sax_handlers(session, stream_callbacks)
return xml_handlers, { reset = reset, set_session = set_session };
end
-function new(session, stream_callbacks)
- local handlers, meta = new_sax_handlers(session, stream_callbacks);
- local parser = new_parser(handlers, ns_separator);
+function new(session, stream_callbacks, stanza_size_limit)
+ -- Used to track parser progress (e.g. to enforce size limits)
+ local n_outstanding_bytes = 0;
+ local handle_progress;
+ if lxp_supports_bytecount then
+ function handle_progress(n_parsed_bytes)
+ n_outstanding_bytes = n_outstanding_bytes - n_parsed_bytes;
+ end
+ stanza_size_limit = stanza_size_limit or default_stanza_size_limit;
+ elseif stanza_size_limit then
+ error("Stanza size limits are not supported on this version of LuaExpat")
+ end
+
+ local handlers, meta = new_sax_handlers(session, stream_callbacks, handle_progress);
+ local parser = new_parser(handlers, ns_separator, false);
local parse = parser.parse;
return {
reset = function ()
- parser = new_parser(handlers, ns_separator);
+ parser = new_parser(handlers, ns_separator, false);
parse = parser.parse;
+ n_outstanding_bytes = 0;
meta.reset();
end,
feed = function (self, data)
- return parse(parser, data);
+ if lxp_supports_bytecount then
+ n_outstanding_bytes = n_outstanding_bytes + #data;
+ end
+ local ok, err = parse(parser, data);
+ if lxp_supports_bytecount and n_outstanding_bytes > stanza_size_limit then
+ return nil, "stanza-too-large";
+ end
+ return ok, err;
end,
set_session = meta.set_session;
};