From 02018380e85a42d07adea922f3155da1f49079c4 Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Fri, 3 Jan 2014 15:52:52 -0500 Subject: =?UTF-8?q?tools/migration/migrator/prosody=5Ffiles:=20Fix=20undef?= =?UTF-8?q?ined=20global=20access=20of=20=E2=80=98error=E2=80=99,=20print?= =?UTF-8?q?=20the=20actual=20error=20message=20and=20correct=20file=20path?= =?UTF-8?q?=20in=20the=20error=20message=20when=20we=20fail=20to=20load=20?= =?UTF-8?q?a=20file,=20skip=20broken=20files=20instead=20of=20failing=20mi?= =?UTF-8?q?gration.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tools/migration/migrator/prosody_files.lua | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tools/migration/migrator/prosody_files.lua b/tools/migration/migrator/prosody_files.lua index 4462fb3e..c9367d9c 100644 --- a/tools/migration/migrator/prosody_files.lua +++ b/tools/migration/migrator/prosody_files.lua @@ -13,6 +13,7 @@ local next = next; local pairs = pairs; local json = require "util.json"; local os_getenv = os.getenv; +local error = error; prosody = {}; local dm = require "util.datamanager" @@ -95,15 +96,18 @@ function reader(input) local iter = mtools.sorted { reader = function() local x = iter(); - if x then + while x do dm.set_data_path(path); local err; x.data, err = dm.load(x.user, x.host, x.store); if x.data == nil and err then - error(("Error loading data at path %s for %s@%s (%s store)") - :format(path, x.user or "", x.host or "", x.store or ""), 0); + local p = dm.getpath(x.user, x.host, x.store); + print(("Error loading data at path %s for %s@%s (%s store): %s") + :format(p, x.user or "", x.host or "", x.store or "", err or "")); + else + return x; end - return x; + x = iter(); end end; sorter = function(a, b) -- cgit v1.2.3 From 4923ba82551161cc0cb46af8ff248c378645ec55 Mon Sep 17 00:00:00 2001 From: Florian Zeitz Date: Sun, 5 Jan 2014 22:21:50 +0100 Subject: mod_s2s: Include IP in log messages, if host is unavailable --- plugins/mod_s2s/mod_s2s.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua index bb46cd2f..aa517bbd 100644 --- a/plugins/mod_s2s/mod_s2s.lua +++ b/plugins/mod_s2s/mod_s2s.lua @@ -356,7 +356,7 @@ function stream_callbacks.streamopened(session, attr) if to then hosts[to].events.fire_event("s2s-stream-features", { origin = session, features = features }); else - (session.log or log)("warn", "No 'to' on stream header from %s means we can't offer any features", from or "unknown host"); + (session.log or log)("warn", "No 'to' on stream header from %s means we can't offer any features", from or session.ip or "unknown host"); end log("debug", "Sending stream features: %s", tostring(features)); @@ -457,7 +457,7 @@ local function session_close(session, reason, remote_reason) end if reason then -- nil == no err, initiated by us, false == initiated by remote if type(reason) == "string" then -- assume stream error - log("debug", "Disconnecting %s[%s], is: %s", session.host or "(unknown host)", session.type, reason); + log("debug", "Disconnecting %s[%s], is: %s", session.host or session.ip or "(unknown host)", session.type, reason); session.sends2s(st.stanza("stream:error"):tag(reason, {xmlns = 'urn:ietf:params:xml:ns:xmpp-streams' })); elseif type(reason) == "table" then if reason.condition then @@ -468,7 +468,7 @@ local function session_close(session, reason, remote_reason) if reason.extra then stanza:add_child(reason.extra); end - log("debug", "Disconnecting %s[%s], is: %s", session.host or "(unknown host)", session.type, tostring(stanza)); + log("debug", "Disconnecting %s[%s], is: %s", session.host or session.ip or "(unknown host)", session.type, tostring(stanza)); session.sends2s(stanza); elseif reason.name then -- a stanza log("debug", "Disconnecting %s->%s[%s], is: %s", session.from_host or "(unknown host)", session.to_host or "(unknown host)", session.type, tostring(reason)); @@ -643,7 +643,7 @@ function check_auth_policy(event) end if must_secure and (session.cert_chain_status ~= "valid" or session.cert_identity_status ~= "valid") then - module:log("warn", "Forbidding insecure connection to/from %s", host); + module:log("warn", "Forbidding insecure connection to/from %s", host or session.ip or "(unknown host)"); if session.direction == "incoming" then session:close({ condition = "not-authorized", text = "Your server's certificate is invalid, expired, or not trusted by "..session.to_host }); else -- Close outgoing connections without warning -- cgit v1.2.3 From 01f7ef6c9159fae3b9f0f8a1cd9eeb39e05d206e Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sun, 12 Jan 2014 06:16:49 -0500 Subject: mod_tls: Log error when TLS initialization fails --- plugins/mod_tls.lua | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/plugins/mod_tls.lua b/plugins/mod_tls.lua index 80b56abb..54c69873 100644 --- a/plugins/mod_tls.lua +++ b/plugins/mod_tls.lua @@ -91,14 +91,21 @@ module:hook_stanza(xmlns_starttls, "proceed", function (session, stanza) return true; end); +local function assert_log(ret, err) + if not ret then + module:log("error", "Unable to initialize TLS: %s", err); + end + return ret; +end + function module.load() local ssl_config = config.rawget(module.host, "ssl"); if not ssl_config then local base_host = module.host:match("%.(.*)"); ssl_config = config.get(base_host, "ssl"); end - host.ssl_ctx = create_context(host.host, "client", ssl_config); -- for outgoing connections - host.ssl_ctx_in = create_context(host.host, "server", ssl_config); -- for incoming connections + host.ssl_ctx = assert_log(create_context(host.host, "client", ssl_config)); -- for outgoing connections + host.ssl_ctx_in = assert_log(create_context(host.host, "server", ssl_config)); -- for incoming connections end function module.unload() -- cgit v1.2.3 -- cgit v1.2.3 From adc050b555c7a8910344617fcedfc504b6dab0c8 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 15 Jan 2014 21:57:15 +0100 Subject: mod_tls: Rename variables to be less confusing --- plugins/mod_tls.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/mod_tls.lua b/plugins/mod_tls.lua index 54c69873..6db02c2c 100644 --- a/plugins/mod_tls.lua +++ b/plugins/mod_tls.lua @@ -10,8 +10,8 @@ local config = require "core.configmanager"; local create_context = require "core.certmanager".create_context; local st = require "util.stanza"; -local secure_auth_only = module:get_option("c2s_require_encryption") or module:get_option("require_encryption"); -local secure_s2s_only = module:get_option("s2s_require_encryption"); +local c2s_require_encryption = module:get_option("c2s_require_encryption") or module:get_option("require_encryption"); +local s2s_require_encryption = module:get_option("s2s_require_encryption"); local allow_s2s_tls = module:get_option("s2s_allow_encryption") ~= false; local xmlns_starttls = 'urn:ietf:params:xml:ns:xmpp-tls'; @@ -20,8 +20,8 @@ local starttls_proceed = st.stanza("proceed", starttls_attr); local starttls_failure = st.stanza("failure", starttls_attr); local c2s_feature = st.stanza("starttls", starttls_attr); local s2s_feature = st.stanza("starttls", starttls_attr); -if secure_auth_only then c2s_feature:tag("required"):up(); end -if secure_s2s_only then s2s_feature:tag("required"):up(); end +if c2s_require_encryption then c2s_feature:tag("required"):up(); end +if s2s_require_encryption then s2s_feature:tag("required"):up(); end local global_ssl_ctx = prosody.global_ssl_ctx; -- cgit v1.2.3 From ad7e898be12b8592c20b0ee92f614c23f97de2b9 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 15 Jan 2014 22:47:50 +0100 Subject: mod_tls: Let s2s_secure_auth override s2s_require_encryption and warn if they differ --- plugins/mod_tls.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/mod_tls.lua b/plugins/mod_tls.lua index 6db02c2c..2741b8d4 100644 --- a/plugins/mod_tls.lua +++ b/plugins/mod_tls.lua @@ -13,6 +13,12 @@ local st = require "util.stanza"; local c2s_require_encryption = module:get_option("c2s_require_encryption") or module:get_option("require_encryption"); local s2s_require_encryption = module:get_option("s2s_require_encryption"); local allow_s2s_tls = module:get_option("s2s_allow_encryption") ~= false; +local s2s_secure_auth = module:get_option("s2s_secure_auth"); + +if s2s_secure_auth and s2s_require_encryption == false then + module:log("warn", "s2s_secure_auth implies s2s_require_encryption, but s2s_require_encryption is set to false"); + s2s_require_encryption = true; +end local xmlns_starttls = 'urn:ietf:params:xml:ns:xmpp-tls'; local starttls_attr = { xmlns = xmlns_starttls }; -- cgit v1.2.3 From 876969b5458ddfadf2e4702b2e999fbfddfc065f Mon Sep 17 00:00:00 2001 From: Vadim Misbakh-Soloviov Date: Fri, 14 Jun 2013 15:15:05 +0700 Subject: package{,c}path fixes for migration tools --- tools/ejabberd2prosody.lua | 10 ++++++---- tools/ejabberdsql2prosody.lua | 8 ++++++++ tools/jabberd14sql2prosody.lua | 9 ++++++++- tools/openfire2prosody.lua | 6 ++++++ tools/xep227toprosody.lua | 6 ++++++ 5 files changed, 34 insertions(+), 5 deletions(-) diff --git a/tools/ejabberd2prosody.lua b/tools/ejabberd2prosody.lua index c11e41d9..941bd4d5 100755 --- a/tools/ejabberd2prosody.lua +++ b/tools/ejabberd2prosody.lua @@ -11,8 +11,10 @@ package.path = package.path ..";../?.lua"; -if arg[0]:match("[/\\]") then - package.path = package.path .. ";"..arg[0]:gsub("[^/\\]*$", "?.lua"); +local my_name = arg[0]; +if my_name:match("[/\\]") then + package.path = package.path..";"..my_name:gsub("[^/\\]+$", "../?.lua"); + package.cpath = package.cpath..";"..my_name:gsub("[^/\\]+$", "../?.so"); end local erlparse = require "erlparse"; @@ -229,10 +231,10 @@ local help = "/? -? ? /h -h /help -help --help"; if not arg or help:find(arg, 1, true) then print([[ejabberd db dump importer for Prosody - Usage: ejabberd2prosody.lua filename.txt + Usage: ]]..my_name..[[ filename.txt The file can be generated from ejabberd using: - sudo ./bin/ejabberdctl dump filename.txt + sudo ejabberdctl dump filename.txt Note: The path of ejabberdctl depends on your ejabberd installation, and ejabberd needs to be running for ejabberdctl to work.]]); os.exit(1); diff --git a/tools/ejabberdsql2prosody.lua b/tools/ejabberdsql2prosody.lua index 43720643..d80b9e46 100644 --- a/tools/ejabberdsql2prosody.lua +++ b/tools/ejabberdsql2prosody.lua @@ -10,6 +10,14 @@ prosody = {}; package.path = package.path ..";../?.lua"; + +local my_name = arg[0]; +if my_name:match("[/\\]") then + package.path = package.path..";"..my_name:gsub("[^/\\]+$", "../?.lua"); + package.cpath = package.cpath..";"..my_name:gsub("[^/\\]+$", "../?.so"); +end + + local serialize = require "util.serialization".serialize; local st = require "util.stanza"; local parse_xml = require "util.xml".parse; diff --git a/tools/jabberd14sql2prosody.lua b/tools/jabberd14sql2prosody.lua index b85d2c20..d6a6753f 100644 --- a/tools/jabberd14sql2prosody.lua +++ b/tools/jabberd14sql2prosody.lua @@ -428,7 +428,14 @@ end end -- import modules -package.path = [[C:\Documents and Settings\Waqas\Desktop\mercurial\prosody-hg\?.lua;]]..package.path; +package.path = package.path.."..\?.lua;"; + +local my_name = arg[0]; +if my_name:match("[/\\]") then + package.path = package.path..";"..my_name:gsub("[^/\\]+$", "../?.lua"); + package.cpath = package.cpath..";"..my_name:gsub("[^/\\]+$", "../?.so"); +end + -- ugly workaround for getting datamanager to work outside of prosody :( prosody = { }; diff --git a/tools/openfire2prosody.lua b/tools/openfire2prosody.lua index bdea9a63..5ef47602 100644 --- a/tools/openfire2prosody.lua +++ b/tools/openfire2prosody.lua @@ -9,6 +9,12 @@ package.path = package.path..";../?.lua"; package.cpath = package.cpath..";../?.so"; -- needed for util.pposix used in datamanager +local my_name = arg[0]; +if my_name:match("[/\\]") then + package.path = package.path..";"..my_name:gsub("[^/\\]+$", "../?.lua"); + package.cpath = package.cpath..";"..my_name:gsub("[^/\\]+$", "../?.so"); +end + -- ugly workaround for getting datamanager to work outside of prosody :( prosody = { }; prosody.platform = "unknown"; diff --git a/tools/xep227toprosody.lua b/tools/xep227toprosody.lua index b5156f45..0862b0c1 100755 --- a/tools/xep227toprosody.lua +++ b/tools/xep227toprosody.lua @@ -25,6 +25,12 @@ package.path = package.path..";../?.lua"; package.cpath = package.cpath..";../?.so"; -- needed for util.pposix used in datamanager +local my_name = arg[0]; +if my_name:match("[/\\]") then + package.path = package.path..";"..my_name:gsub("[^/\\]+$", "../?.lua"); + package.cpath = package.cpath..";"..my_name:gsub("[^/\\]+$", "../?.so"); +end + -- ugly workaround for getting datamanager to work outside of prosody :( prosody = { }; prosody.platform = "unknown"; -- cgit v1.2.3 From bb7f2ddd244db5ac02c6e174f3221df9adcbd9f6 Mon Sep 17 00:00:00 2001 From: Vadim Misbakh-Soloviov Date: Fri, 14 Jun 2013 15:43:35 +0700 Subject: additional fix for erlparse loading in ejabberd2prosody.lua --- tools/ejabberd2prosody.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/ejabberd2prosody.lua b/tools/ejabberd2prosody.lua index 941bd4d5..ff3004c2 100755 --- a/tools/ejabberd2prosody.lua +++ b/tools/ejabberd2prosody.lua @@ -14,6 +14,7 @@ package.path = package.path ..";../?.lua"; local my_name = arg[0]; if my_name:match("[/\\]") then package.path = package.path..";"..my_name:gsub("[^/\\]+$", "../?.lua"); + package.path = package.path..";"..my_name:gsub("[^/\\]+$", "?.lua"); package.cpath = package.cpath..";"..my_name:gsub("[^/\\]+$", "../?.so"); end -- cgit v1.2.3 From 7fdba300aac9bb0c228950c787976973c96b6858 Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Thu, 16 Jan 2014 14:03:27 -0500 Subject: tools/ejabberdsql2prosody: Skip invalid XML in data, and print out errors. --- tools/ejabberdsql2prosody.lua | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/tools/ejabberdsql2prosody.lua b/tools/ejabberdsql2prosody.lua index d80b9e46..40be8190 100644 --- a/tools/ejabberdsql2prosody.lua +++ b/tools/ejabberdsql2prosody.lua @@ -291,11 +291,21 @@ for i, row in ipairs(t["rostergroups"] or NULL) do roster_group(row.username, host, row.jid, row.grp); end for i, row in ipairs(t["vcard"] or NULL) do - local ret, err = dm.store(row.username, host, "vcard", st.preserialize(parse_xml(row.vcard))); - print("["..(err or "success").."] vCard: "..row.username.."@"..host); + local stanza, err = parse_xml(row.vcard); + if stanza then + local ret, err = dm.store(row.username, host, "vcard", st.preserialize(stanza)); + print("["..(err or "success").."] vCard: "..row.username.."@"..host); + else + print("[error] vCard XML parse failed: "..row.username.."@"..host); + end end for i, row in ipairs(t["private_storage"] or NULL) do - private_storage(row.username, host, row.namespace, parse_xml(row.data)); + local stanza, err = parse_xml(row.data); + if stanza then + private_storage(row.username, host, row.namespace, stanza); + else + print("[error] Private XML parse failed: "..row.username.."@"..host); + end end table.sort(t["spool"] or NULL, function(a,b) return a.seq < b.seq; end); -- sort by sequence number, just in case local time_offset = os.difftime(os.time(os.date("!*t")), os.time(os.date("*t"))) -- to deal with timezones @@ -304,11 +314,15 @@ local date_parse = function(s) return os.time({year=year, month=month, day=day, hour=hour, min=min, sec=sec-time_offset}); end for i, row in ipairs(t["spool"] or NULL) do - local stanza = parse_xml(row.xml); - local last_child = stanza.tags[#stanza.tags]; - if not last_child or last_child ~= stanza[#stanza] then error("Last child of offline message is not a tag"); end - if last_child.name ~= "x" and last_child.attr.xmlns ~= "jabber:x:delay" then error("Last child of offline message is not a timestamp"); end - stanza[#stanza], stanza.tags[#stanza.tags] = nil, nil; - local t = date_parse(last_child.attr.stamp); - offline_msg(row.username, host, t, stanza); + local stanza, err = parse_xml(row.xml); + if stanza then + local last_child = stanza.tags[#stanza.tags]; + if not last_child or last_child ~= stanza[#stanza] then error("Last child of offline message is not a tag"); end + if last_child.name ~= "x" and last_child.attr.xmlns ~= "jabber:x:delay" then error("Last child of offline message is not a timestamp"); end + stanza[#stanza], stanza.tags[#stanza.tags] = nil, nil; + local t = date_parse(last_child.attr.stamp); + offline_msg(row.username, host, t, stanza); + else + print("[error] Offline message XML parsing failed: "..row.username.."@"..host); + end end -- cgit v1.2.3 From 4b8e2cba01dd06b3c57b40d1a7f3a76bf6a0494e Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Sat, 18 Jan 2014 10:37:12 -0500 Subject: tools/ejabberd2prosody: Add support for importing MUC rooms. --- tools/ejabberd2prosody.lua | 51 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/tools/ejabberd2prosody.lua b/tools/ejabberd2prosody.lua index ff3004c2..a8bfad0e 100755 --- a/tools/ejabberd2prosody.lua +++ b/tools/ejabberd2prosody.lua @@ -152,6 +152,48 @@ function privacy(node, host, default, lists) local ret, err = dm.store(node, host, "privacy", privacy); print("["..(err or "success").."] privacy: " ..node.."@"..host.." - "..count.." list(s)"); end +local function _table_to_jid(t) + if type(t[2]) == "string" then + local jid = t[2]; + if type(t[1]) == "string" then jid = t[1].."@"..jid; end + if type(t[3]) == "string" then jid = jid.."/"..t[3]; end + return jid; + end +end +function muc_room(node, host, properties) + local store = { jid = node.."@"..host, _data = {}, _affiliations = {} }; + for _,aff in ipairs(properties.affiliations) do + store._affiliations[_table_to_jid(aff[1])] = aff[2]; + end + store._data.subject = properties.subject; + if properties.subject_author then + store._data.subject_from = store.jid .. "/" .. properties.subject_author; + end + store._data.name = properties.title; + store._data.description = properties.description; + store._data.password = properties.password; + store._data.moderated = (properties.moderated == "true") or nil; + store._data.members_only = (properties.members_only == "true") or nil; + store._data.persistent = (properties.persistent == "true") or nil; + store._data.changesubject = (properties.allow_change_subj == "true") or nil; + store._data.whois = properties.anonymous == "true" and "moderators" or "anyone"; + store._data.hidden = (properties.public_list == "false") or nil; + + if not store._data.persistent then + return print("[error] muc_room: skipping non-persistent room: "..node.."@"..host); + end + + local ret, err = dm.store(node, host, "config", store); + if ret then + ret, err = dm.load(nil, host, "persistent"); + if ret or not err then + ret = ret or {}; + ret[store.jid] = true; + ret, err = dm.store(nil, host, "persistent", ret); + end + end + print("["..(err or "success").."] muc_room: " ..node.."@"..host); +end local filters = { @@ -196,6 +238,15 @@ local filters = { privacy = function(tuple) privacy(tuple[2][1], tuple[2][2], tuple[3], tuple[4]); end; + muc_room = function(tuple) + local properties = {}; + for _,pair in ipairs(tuple[3]) do + if not(type(pair[2]) == "table" and #pair[2] == 0) then -- skip nil values + properties[pair[1]] = pair[2]; + end + end + muc_room(tuple[2][1], tuple[2][2], properties); + end; config = function(tuple) if tuple[2] == "hosts" then local output = io.output(); io.output("prosody.cfg.lua"); -- cgit v1.2.3 From a5f500f63dbbd0e4fc4be5ce440ba8b282b43dc5 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 18 Jan 2014 20:14:05 +0100 Subject: MUC: Fire muc-room-destroyed event when the last participant leaves a non-persistent room --- plugins/muc/mod_muc.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/muc/mod_muc.lua b/plugins/muc/mod_muc.lua index edebf070..6e86ab73 100644 --- a/plugins/muc/mod_muc.lua +++ b/plugins/muc/mod_muc.lua @@ -163,6 +163,7 @@ function stanza_handler(event) if room then room:handle_stanza(origin, stanza); if not next(room._occupants) and not persistent_rooms[room.jid] then -- empty, non-persistent room + module:fire_event("muc-room-destroyed", { room = room }); rooms[bare] = nil; -- discard room end else -- cgit v1.2.3 From e9de1840d4cb557a8b373743a4b53c31efd66f56 Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Sat, 18 Jan 2014 17:24:10 -0500 Subject: =?UTF-8?q?tools/ejabberd2prosody:=20=E2=80=9Cxmlelement=E2=80=9D?= =?UTF-8?q?=20can=20be=20=E2=80=9Cxmlel=E2=80=9D=20in=20newer=20ejabberd?= =?UTF-8?q?=20(thanks=20cr).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tools/ejabberd2prosody.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/ejabberd2prosody.lua b/tools/ejabberd2prosody.lua index a8bfad0e..8312ebd1 100755 --- a/tools/ejabberd2prosody.lua +++ b/tools/ejabberd2prosody.lua @@ -30,7 +30,7 @@ dm.set_data_path("data"); function build_stanza(tuple, stanza) assert(type(tuple) == "table", "XML node is of unexpected type: "..type(tuple)); - if tuple[1] == "xmlelement" then + if tuple[1] == "xmlelement" or tuple[1] == "xmlel" then assert(type(tuple[2]) == "string", "element name has type: "..type(tuple[2])); assert(type(tuple[3]) == "table", "element attribute array has type: "..type(tuple[3])); assert(type(tuple[4]) == "table", "element children array has type: "..type(tuple[4])); -- cgit v1.2.3 From fbc659f70e4defe2ede78b7d57d00cddec039df7 Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Sat, 18 Jan 2014 17:26:02 -0500 Subject: tools/ejabberd2prosody: Disable generating a config, as the format it generates is completely out of date. --- tools/ejabberd2prosody.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/ejabberd2prosody.lua b/tools/ejabberd2prosody.lua index 8312ebd1..bc916fb8 100755 --- a/tools/ejabberd2prosody.lua +++ b/tools/ejabberd2prosody.lua @@ -247,7 +247,7 @@ local filters = { end muc_room(tuple[2][1], tuple[2][2], properties); end; - config = function(tuple) + --[=[config = function(tuple) if tuple[2] == "hosts" then local output = io.output(); io.output("prosody.cfg.lua"); io.write("-- Configuration imported from ejabberd --\n"); @@ -275,7 +275,7 @@ local filters = { io.output(output); print("prosody.cfg.lua created"); end - end; + end;]=] }; local arg = ...; -- cgit v1.2.3 From acedfc3c4a1df737fee8f4248d046fe077987fa9 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 27 Jan 2014 16:47:54 +0100 Subject: tools/ejabberd2prosody: Handle new room member format. --- tools/ejabberd2prosody.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/ejabberd2prosody.lua b/tools/ejabberd2prosody.lua index bc916fb8..be1504b2 100755 --- a/tools/ejabberd2prosody.lua +++ b/tools/ejabberd2prosody.lua @@ -163,7 +163,7 @@ end function muc_room(node, host, properties) local store = { jid = node.."@"..host, _data = {}, _affiliations = {} }; for _,aff in ipairs(properties.affiliations) do - store._affiliations[_table_to_jid(aff[1])] = aff[2]; + store._affiliations[_table_to_jid(aff[1])] = aff[2][1] or aff[2]; end store._data.subject = properties.subject; if properties.subject_author then -- cgit v1.2.3 From b3971532af8c7cee385bd5b2bf3efc61332a43b8 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 6 Feb 2014 10:44:21 +0100 Subject: mod_motd: Strip indentation only, leave multiple newlines --- plugins/mod_motd.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_motd.lua b/plugins/mod_motd.lua index ed78294b..3dd6b816 100644 --- a/plugins/mod_motd.lua +++ b/plugins/mod_motd.lua @@ -15,7 +15,7 @@ if not motd_text then return; end local st = require "util.stanza"; -motd_text = motd_text:gsub("^%s*(.-)%s*$", "%1"):gsub("\n%s+", "\n"); -- Strip indentation from the config +motd_text = motd_text:gsub("^%s*(.-)%s*$", "%1"):gsub("\n[ \t]+", "\n"); -- Strip indentation from the config module:hook("presence/bare", function (event) local session, stanza = event.origin, event.stanza; -- cgit v1.2.3 From 5eca01ae59084dd115e47bb8067657a0d82a9594 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 9 Feb 2014 15:13:46 +0100 Subject: mod_s2s: Log a warning if no local addresses are found, as this breaks s2sout --- plugins/mod_s2s/s2sout.lib.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/mod_s2s/s2sout.lib.lua b/plugins/mod_s2s/s2sout.lib.lua index 575d37ac..b24faf85 100644 --- a/plugins/mod_s2s/s2sout.lib.lua +++ b/plugins/mod_s2s/s2sout.lib.lua @@ -347,6 +347,9 @@ module:hook_global("service-added", function (event) has_ipv4 = true; end end + if not (has_ipv4 or has_ipv6) then + module:log("warn", "No local IPv4 or IPv6 addresses detected, outgoing connections may fail"); + end end); return s2sout; -- cgit v1.2.3 From b40e5a8cbc99069980cf4a0422f5027bf85f4f46 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 9 Feb 2014 15:17:01 +0100 Subject: mod_admin_telnet: Prep jids for user:create() etc. --- plugins/mod_admin_telnet.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index 131689c5..2572e982 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -23,8 +23,7 @@ local console_listener = { default_port = 5582; default_mode = "*a"; interface = local iterators = require "util.iterators"; local keys, values = iterators.keys, iterators.values; -local jid = require "util.jid"; -local jid_bare, jid_split = jid.bare, jid.split; +local jid_bare, jid_split = import("util.jid", "bare", "prepped_split"); local set, array = require "util.set", require "util.array"; local cert_verify_identity = require "util.x509".verify_identity; local envload = require "util.envload".envload; -- cgit v1.2.3 From 72fd4f9f67821523290a90486665de70ba059ef8 Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Mon, 17 Feb 2014 16:00:41 -0500 Subject: mod_auth_anonymous: Fixed a traceback in listing all users (issue#396). --- plugins/mod_auth_anonymous.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_auth_anonymous.lua b/plugins/mod_auth_anonymous.lua index c877d532..8de46f8c 100644 --- a/plugins/mod_auth_anonymous.lua +++ b/plugins/mod_auth_anonymous.lua @@ -43,7 +43,7 @@ function provider.get_sasl_handler() end function provider.users() - return next, hosts[host].sessions, nil; + return next, hosts[module.host].sessions, nil; end -- datamanager callback to disable writes -- cgit v1.2.3 From cb9212005995667177efc44b191682320a5872a2 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 18 Feb 2014 20:03:12 +0100 Subject: mod_compression: Only allow compression on authenticated streams --- plugins/mod_compression.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/mod_compression.lua b/plugins/mod_compression.lua index 92856099..531ea8ea 100644 --- a/plugins/mod_compression.lua +++ b/plugins/mod_compression.lua @@ -126,7 +126,7 @@ 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"); -- cgit v1.2.3 From b86b759546e03111a42d2f32e9f2c562e794a8d3 Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Tue, 18 Feb 2014 16:03:13 -0500 Subject: tools/ejabberd2prosody: Don't throw an error if XML CDATA is null ([] in Erlang, instead of a string or being missing). --- tools/ejabberd2prosody.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/ejabberd2prosody.lua b/tools/ejabberd2prosody.lua index be1504b2..d0675a65 100755 --- a/tools/ejabberd2prosody.lua +++ b/tools/ejabberd2prosody.lua @@ -44,8 +44,10 @@ function build_stanza(tuple, stanza) for _, a in ipairs(tuple[4]) do build_stanza(a, stanza); end if up then stanza:up(); else return stanza end elseif tuple[1] == "xmlcdata" then - assert(type(tuple[2]) == "string", "XML CDATA has unexpected type: "..type(tuple[2])); - stanza:text(tuple[2]); + if type(tuple[2]) ~= "table" then + assert(type(tuple[2]) == "string", "XML CDATA has unexpected type: "..type(tuple[2])); + stanza:text(tuple[2]); + end -- else it's [], i.e., the null value, used for the empty string else error("unknown element type: "..serialize(tuple)); end -- cgit v1.2.3 From 33973cf0ddebe3da6c0849ff4cc7104f8e8554f8 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 20 Feb 2014 19:08:55 +0100 Subject: mod_http: Use hostname from the correct context (thanks gryffus) --- plugins/mod_http.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index 0689634e..afcec069 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -42,7 +42,7 @@ local function get_base_path(host_module, app_name, default_app_path) return (normalize_path(host_module:get_option("http_paths", {})[app_name] -- Host or module:get_option("http_paths", {})[app_name] -- Global or default_app_path)) -- Default - :gsub("%$(%w+)", { host = module.host }); + :gsub("%$(%w+)", { host = host_module.host }); end local ports_by_scheme = { http = 80, https = 443, }; -- cgit v1.2.3 From 2581518210994e410d8163d6aeb32b010a8f1cde Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 26 Feb 2014 22:19:58 +0100 Subject: mod_http: Fix http_external_url setting without an explicit port --- plugins/mod_http.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index afcec069..86689aff 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -51,6 +51,9 @@ local ports_by_scheme = { http = 80, https = 443, }; function moduleapi.http_url(module, app_name, default_path) app_name = app_name or (module.name:gsub("^http_", "")); local external_url = url_parse(module:get_option_string("http_external_url")) or {}; + if external_url.scheme and external_url.port == nil then + external_url.port = ports_by_scheme[external_url.scheme]; + end local services = portmanager.get_active_services(); local http_services = services:get("https") or services:get("http") or {}; for interface, ports in pairs(http_services) do -- cgit v1.2.3 From d2b4655cdc3aa7c061f5562b2ee867cd76733b03 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 9 Mar 2014 22:15:40 +0100 Subject: util.pluginloader: Always use path separator from package.config (thanks Junne) --- util/pluginloader.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/util/pluginloader.lua b/util/pluginloader.lua index c10fdf65..112c0d52 100644 --- a/util/pluginloader.lua +++ b/util/pluginloader.lua @@ -39,10 +39,10 @@ function load_resource(plugin, resource) resource = resource or "mod_"..plugin..".lua"; local names = { - "mod_"..plugin.."/"..plugin.."/"..resource; -- mod_hello/hello/mod_hello.lua - "mod_"..plugin.."/"..resource; -- mod_hello/mod_hello.lua - plugin.."/"..resource; -- hello/mod_hello.lua - resource; -- mod_hello.lua + "mod_"..plugin..dir_sep..plugin..dir_sep..resource; -- mod_hello/hello/mod_hello.lua + "mod_"..plugin..dir_sep..resource; -- mod_hello/mod_hello.lua + plugin..dir_sep..resource; -- hello/mod_hello.lua + resource; -- mod_hello.lua }; return load_file(names); -- cgit v1.2.3 From 69351d5d2a2a1045278cc2f2069698eba470057c Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 9 Mar 2014 22:16:44 +0100 Subject: mod_http_files: Strip path separator from end of paths, was broken on Windows (thanks Junne) --- plugins/mod_http_files.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/mod_http_files.lua b/plugins/mod_http_files.lua index 6ab295ac..3a9368b9 100644 --- a/plugins/mod_http_files.lua +++ b/plugins/mod_http_files.lua @@ -14,6 +14,7 @@ local os_date = os.date; local open = io.open; local stat = lfs.attributes; local build_path = require"socket.url".build_path; +local path_sep = package.config:sub(1,1); local base_path = module:get_option_string("http_files_dir", module:get_option_string("http_path")); local dir_indices = module:get_option("http_index_files", { "index.html", "index.htm" }); @@ -61,7 +62,7 @@ function serve(opts) local request, response = event.request, event.response; local orig_path = request.path; local full_path = base_path .. (path and "/"..path or ""); - local attr = stat(full_path); + local attr = stat((full_path:gsub('%'..path_sep..'+$',''))); if not attr then return 404; end -- cgit v1.2.3 From 264d863f310678f89d54540f68de57dd542dfe61 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 22 Mar 2014 12:41:38 +0100 Subject: mod_saslauth: Only do c2s SASL on normal VirtualHosts --- plugins/mod_saslauth.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_saslauth.lua b/plugins/mod_saslauth.lua index 201cc477..c5d3dc91 100644 --- a/plugins/mod_saslauth.lua +++ b/plugins/mod_saslauth.lua @@ -197,7 +197,7 @@ module:hook("stanza/urn:ietf:params:xml:ns:xmpp-sasl:auth", function(event) return s2s_external_auth(session, stanza) end - if session.type ~= "c2s_unauthed" then return; end + if session.type ~= "c2s_unauthed" or module:get_host_type() ~= "local" then return; end if session.sasl_handler and session.sasl_handler.selected then session.sasl_handler = nil; -- allow starting a new SASL negotiation before completing an old one -- cgit v1.2.3 From 4a315c3d58d76cfff63070aa1db169efe7d310dd Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 22 Mar 2014 12:42:01 +0100 Subject: modulemanager: Load mod_saslauth on components by default --- core/modulemanager.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/modulemanager.lua b/core/modulemanager.lua index 535c227b..cddab647 100644 --- a/core/modulemanager.lua +++ b/core/modulemanager.lua @@ -30,7 +30,7 @@ pcall = function(f, ...) end local autoload_modules = {"presence", "message", "iq", "offline", "c2s", "s2s"}; -local component_inheritable_modules = {"tls", "dialback", "iq", "s2s"}; +local component_inheritable_modules = {"tls", "saslauth", "dialback", "iq", "s2s"}; -- We need this to let modules access the real global namespace local _G = _G; -- cgit v1.2.3 From 335f485c89ad69d23cb800b6a012834fc0b2f4cf Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 22 Mar 2014 12:02:11 +0100 Subject: prosodyctl: Show real error if certificate config file can't be opened --- prosodyctl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/prosodyctl b/prosodyctl index 247b099a..d341a75b 100755 --- a/prosodyctl +++ b/prosodyctl @@ -684,7 +684,12 @@ function cert_commands.config(arg) conf.distinguished_name[k] = nv ~= "." and nv or nil; end end - local conf_file = io.open(conf_filename, "w"); + local conf_file, err = io.open(conf_filename, "w"); + if not conf_file then + show_warning("Could not open OpenSSL config file for writing"); + show_warning(err); + os.exit(1); + end conf_file:write(conf:serialize()); conf_file:close(); print(""); -- cgit v1.2.3 From 99dbbce46c61b4db44eb518b982adbbff0149b22 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 27 Mar 2014 23:02:52 +0100 Subject: net.server_event: Rename conn:port() -> conn:clientport() to match server_select --- net/server_event.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/server_event.lua b/net/server_event.lua index e320b15c..c4aa7be4 100644 --- a/net/server_event.lua +++ b/net/server_event.lua @@ -352,7 +352,7 @@ do return self._server or self; end - function interface_mt:port() + function interface_mt:clientport() return self._port end -- cgit v1.2.3 From 6f72eb0531659475a4046e356edba7e29d1b3496 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sun, 30 Mar 2014 08:44:55 +0100 Subject: portmanager: Make maximum read size configurable, and default to 4KB --- core/portmanager.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/portmanager.lua b/core/portmanager.lua index 7a247452..421d7fc6 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 -- cgit v1.2.3 From 6adf23f6ca90d5e04117fb792a9dd2e42ee35dbc Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sun, 30 Mar 2014 09:14:39 +0100 Subject: util.xmppstream: Implement stanza size limiting, default limit 10MB --- util/xmppstream.lua | 86 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 80 insertions(+), 6 deletions(-) diff --git a/util/xmppstream.lua b/util/xmppstream.lua index 4909678c..9cdd6471 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 + #data --self:getcurrentbytecount(); + end t_insert(chardata, data); + elseif lxp_supports_bytecount then + cb_handleprogress(#data--[[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,8 +224,20 @@ 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); +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); local parse = parser.parse; @@ -179,10 +245,18 @@ function new(session, stream_callbacks) reset = function () parser = new_parser(handlers, ns_separator); 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; }; -- cgit v1.2.3 From 433578afe3864064b1200a84b7ad6243074c6327 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sun, 30 Mar 2014 09:15:28 +0100 Subject: util.dependencies: Log error when LuaExpat is not capable of enforcing stanza size limits --- util/dependencies.lua | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/util/dependencies.lua b/util/dependencies.lua index 53d2719d..e55b2405 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 -- cgit v1.2.3 From 3fd7b097c1a4272388f334abd36fdc05612dc939 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sun, 30 Mar 2014 09:16:27 +0100 Subject: Makefile: Change sed regex to be compatible with FreeBSD's odd sed, and change / to | to allow paths to be used in RUNWITH (thanks Ben) --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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)';|; \ -- cgit v1.2.3 From 70dbd61ac029634414d5baa7ca923c302a429aee Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 31 Mar 2014 19:38:06 +0200 Subject: Backed out changeset a5b5bce71a11 --- net/server_event.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/server_event.lua b/net/server_event.lua index c4aa7be4..e320b15c 100644 --- a/net/server_event.lua +++ b/net/server_event.lua @@ -352,7 +352,7 @@ do return self._server or self; end - function interface_mt:clientport() + function interface_mt:port() return self._port end -- cgit v1.2.3 From 2f22ec3870c0e7dfcd4008bcfc4740fe83186622 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 1 Apr 2014 15:26:40 +0200 Subject: net.server_{select,event}: Add compat code for supporting the same client port API on connections --- net/server_event.lua | 1 + net/server_select.lua | 1 + 2 files changed, 2 insertions(+) diff --git a/net/server_event.lua b/net/server_event.lua index e320b15c..25799640 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 22887265..4bda3ef0 100644 --- a/net/server_select.lua +++ b/net/server_select.lua @@ -397,6 +397,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 -- cgit v1.2.3 From 0c8605386437a149e30f5e23633e227607386da6 Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Tue, 1 Apr 2014 10:02:58 -0400 Subject: MUC: Fixed traceback when a JID not in a room requested a role change for an occupant. --- plugins/muc/muc.lib.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/muc/muc.lib.lua b/plugins/muc/muc.lib.lua index 0dbe81fa..8028f5ae 100644 --- a/plugins/muc/muc.lib.lua +++ b/plugins/muc/muc.lib.lua @@ -1060,7 +1060,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; -- cgit v1.2.3 -- cgit v1.2.3 From 85fa5325e2b7d3acdbb9c81bb87af2e811cf0871 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Wed, 2 Apr 2014 11:05:41 +0100 Subject: util.xmppstream: Disable LuaExpat's buffering (if possible) --- util/xmppstream.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/util/xmppstream.lua b/util/xmppstream.lua index 9cdd6471..a25891a9 100644 --- a/util/xmppstream.lua +++ b/util/xmppstream.lua @@ -157,11 +157,11 @@ function new_sax_handlers(session, stream_callbacks, cb_handleprogress) function xml_handlers:CharacterData(data) if stanza then if lxp_supports_bytecount then - stanza_size = stanza_size + #data --self:getcurrentbytecount(); + stanza_size = stanza_size + self:getcurrentbytecount(); end t_insert(chardata, data); elseif lxp_supports_bytecount then - cb_handleprogress(#data--[[self:getcurrentbytecount()]]); + cb_handleprogress(self:getcurrentbytecount()); end end function xml_handlers:EndElement(tagname) @@ -238,7 +238,7 @@ function new(session, stream_callbacks, stanza_size_limit) end local handlers, meta = new_sax_handlers(session, stream_callbacks, handle_progress); - local parser = new_parser(handlers, ns_separator); + local parser = new_parser(handlers, ns_separator, false); local parse = parser.parse; return { -- cgit v1.2.3 From 208fa9afdeb4b0273ac1271bfca738f802346e2d Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Wed, 2 Apr 2014 14:31:19 +0100 Subject: util.xmppstream: Also disable CharacterData merging after stream restarts --- util/xmppstream.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/xmppstream.lua b/util/xmppstream.lua index a25891a9..73f5e314 100644 --- a/util/xmppstream.lua +++ b/util/xmppstream.lua @@ -243,7 +243,7 @@ function new(session, stream_callbacks, stanza_size_limit) 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(); -- cgit v1.2.3 From 3f442f66f5c72e354c8e8ddd98e3695f4206ec7b Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 5 Apr 2014 15:05:40 +0100 Subject: mod_admin_telnet: muc:*: Fix nil index error when a room JID is passed with a non-existent host --- plugins/mod_admin_telnet.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index 2572e982..6f02f030 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -942,6 +942,9 @@ end function def_env.muc:create(room_jid) local room, host = check_muc(room_jid); + if not room_name then + return room_name, host; + end if not room then return nil, host end if hosts[host].modules.muc.rooms[room_jid] then return nil, "Room exists already" end return hosts[host].modules.muc.create_room(room_jid); @@ -949,6 +952,9 @@ end function def_env.muc:room(room_jid) local room_name, host = check_muc(room_jid); + if not room_name then + return room_name, host; + end local room_obj = hosts[host].modules.muc.rooms[room_jid]; if not room_obj then return nil, "No such room: "..room_jid; -- cgit v1.2.3 From c5e7b62d646e8982196a4bfa36ecd10e2f44e320 Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Wed, 9 Apr 2014 14:01:02 -0400 Subject: util.dependencies: Check for Lua 5.1. We don't currently support any other versions. LuaJIT identifies as 5.1. --- util/dependencies.lua | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/util/dependencies.lua b/util/dependencies.lua index e55b2405..4d50cf63 100644 --- a/util/dependencies.lua +++ b/util/dependencies.lua @@ -49,6 +49,14 @@ package.preload["util.ztact"] = function () end; function check_dependencies() + if _VERSION ~= "Lua 5.1" then + print "***********************************" + print("Unsupported Lua version: ".._VERSION); + print("Only Lua 5.1 is supported."); + print "***********************************" + return false; + end + local fatal; local lxp = softreq "lxp" -- cgit v1.2.3 From 0962e906950cd7977dd74c5bd2d7c1767b7a50c6 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 9 Apr 2014 20:46:39 +0200 Subject: prosody: Check dependencies later in the startup sequence --- prosody | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/prosody b/prosody index ee2baca5..446dbfb7 100755 --- a/prosody +++ b/prosody @@ -49,9 +49,6 @@ _G.prosody = prosody; -- Check dependencies local dependencies = require "util.dependencies"; -if not dependencies.check_dependencies() then - os.exit(1); -end -- Load the config-parsing module config = require "core.configmanager" @@ -116,6 +113,12 @@ function read_config() end end +function check_dependencies() + if not dependencies.check_dependencies() then + os.exit(1); + end +end + function load_libraries() -- Load socket framework server = require "net.server" @@ -388,6 +391,7 @@ init_logging(); sanity_check(); sandbox_require(); set_function_metatable(); +check_dependencies(); load_libraries(); init_global_state(); read_version(); -- cgit v1.2.3 From c426b4b499d959ceed46b199f6b27b9407e38072 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 22 Apr 2014 23:14:53 +0200 Subject: tools/jabberd14sql2prosody: Fix package.path (thanks daurnimator) --- tools/jabberd14sql2prosody.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/jabberd14sql2prosody.lua b/tools/jabberd14sql2prosody.lua index d6a6753f..386bdcf0 100644 --- a/tools/jabberd14sql2prosody.lua +++ b/tools/jabberd14sql2prosody.lua @@ -428,7 +428,7 @@ end end -- import modules -package.path = package.path.."..\?.lua;"; +package.path = package.path..";../?.lua;"; local my_name = arg[0]; if my_name:match("[/\\]") then -- cgit v1.2.3 From c2acedfc18b56e2f402759d0077246bc92fee6c1 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 22 Apr 2014 23:36:26 +0200 Subject: util.dataforms: Add support for XEP-0221: Data Forms Media Element --- util/dataforms.lua | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/util/dataforms.lua b/util/dataforms.lua index 52924841..01a8eef3 100644 --- a/util/dataforms.lua +++ b/util/dataforms.lua @@ -93,6 +93,15 @@ function form_t.form(layout, data, formtype) end end end + + local media = field.media; + if media then + form:tag("media", { xmlns = "urn:xmpp:media-element", height = media.height, width = media.width }); + for _, val in ipairs(media) do + form:tag("uri", { type = val.type }):text(val.uri):up() + end + form:up(); + end if field.required then form:tag("required"):up(); -- cgit v1.2.3 From 725f2eb056de1d3ea1b1d83f5245760dd2b2449d Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 25 Apr 2014 00:36:01 +0200 Subject: util.pposix: Fix error reporting from posix_fallocate, it doesn't use errno (thanks pro) --- util-src/pposix.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/util-src/pposix.c b/util-src/pposix.c index 4fb1fb56..a8654995 100644 --- a/util-src/pposix.c +++ b/util-src/pposix.c @@ -664,6 +664,7 @@ int lc_meminfo(lua_State* L) #if _XOPEN_SOURCE >= 600 || _POSIX_C_SOURCE >= 200112L || defined(_GNU_SOURCE) int lc_fallocate(lua_State* L) { + int ret; off_t offset, len; FILE *f = *(FILE**) luaL_checkudata(L, 1, LUA_FILEHANDLE); if (f == NULL) @@ -691,7 +692,8 @@ int lc_fallocate(lua_State* L) #warning Note that posix_fallocate() will still be used on filesystems that dont support fallocate() #endif - if(posix_fallocate(fileno(f), offset, len) == 0) + ret = posix_fallocate(fileno(f), offset, len); + if(ret == 0) { lua_pushboolean(L, 1); return 1; @@ -699,7 +701,7 @@ int lc_fallocate(lua_State* L) else { lua_pushnil(L); - lua_pushstring(L, strerror(errno)); + lua_pushstring(L, strerror(ret)); /* posix_fallocate() can leave a bunch of NULs at the end, so we cut that * this assumes that offset == length of the file */ ftruncate(fileno(f), offset); -- cgit v1.2.3 From cea75bb1a9b4ab93d366bd56d99fb3806ce25ac7 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 25 Apr 2014 02:41:55 +0200 Subject: util.pposix: Fix error reporting from really old Linux fallocate() that did not use errno for some reason (thanks pro) --- util-src/pposix.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/util-src/pposix.c b/util-src/pposix.c index a8654995..df814c28 100644 --- a/util-src/pposix.c +++ b/util-src/pposix.c @@ -674,11 +674,15 @@ int lc_fallocate(lua_State* L) len = luaL_checkinteger(L, 3); #if defined(__linux__) && defined(_GNU_SOURCE) - if(fallocate(fileno(f), FALLOC_FL_KEEP_SIZE, offset, len) == 0) + errno = 0; + ret = fallocate(fileno(f), FALLOC_FL_KEEP_SIZE, offset, len); + if(ret == 0) { lua_pushboolean(L, 1); return 1; } + /* Some old versions of Linux apparently use the return value instead of errno */ + if(errno == 0) errno = ret; if(errno != ENOSYS && errno != EOPNOTSUPP) { -- cgit v1.2.3 From 1a98bd392802a1110db235a90ca7e1432bdeb0e0 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 9 May 2014 19:59:49 +0200 Subject: configmanager: Delay importing LuaFileSystem until needed by an Include line --- core/configmanager.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/configmanager.lua b/core/configmanager.lua index d73bafa4..d175b54b 100644 --- a/core/configmanager.lua +++ b/core/configmanager.lua @@ -14,7 +14,7 @@ local format, math_max = string.format, math.max; local fire_event = prosody and prosody.events.fire_event or function () end; local envload = require"util.envload".envload; -local lfs = require "lfs"; +local deps = require"util.dependencies"; local path_sep = package.config:sub(1,1); module "configmanager" @@ -214,6 +214,10 @@ do function env.Include(file) if file:match("[*?]") then + local lfs = deps.softreq "lfs"; + if not lfs then + error(format("Error expanding wildcard pattern in Include %q - LuaFileSystem not available", file)); + end local path_pos, glob = file:match("()([^"..path_sep.."]+)$"); local path = file:sub(1, math_max(path_pos-2,0)); local config_path = config_file:gsub("[^"..path_sep.."]+$", ""); -- cgit v1.2.3 From 2e1c23fdc14e1369114d71677f872173e4783598 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 10 May 2014 02:12:51 +0200 Subject: mod_c2s: Fix traceback if c2s stream sent to component --- plugins/mod_c2s.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_c2s.lua b/plugins/mod_c2s.lua index b2a81592..5feb1f2c 100644 --- a/plugins/mod_c2s.lua +++ b/plugins/mod_c2s.lua @@ -50,7 +50,7 @@ function stream_callbacks.streamopened(session, attr) session.streamid = uuid_generate(); (session.log or session)("debug", "Client sent opening to %s", session.host); - if not hosts[session.host] then + if not hosts[session.host] or not hosts[session.host].users then -- We don't serve this host... session:close{ condition = "host-unknown", text = "This server does not serve "..tostring(session.host)}; return; -- cgit v1.2.3 From b83f137562de90aa0eda7460eac254c4bfc5f95b Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 17 Jun 2014 11:01:51 +0200 Subject: tools/ejabberd2prosody.lua: Fix JID building, node-less jids became @hostname in some cases --- tools/ejabberd2prosody.lua | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/tools/ejabberd2prosody.lua b/tools/ejabberd2prosody.lua index d0675a65..af87594e 100755 --- a/tools/ejabberd2prosody.lua +++ b/tools/ejabberd2prosody.lua @@ -56,6 +56,16 @@ function build_time(tuple) local Megaseconds,Seconds,Microseconds = unpack(tuple); return Megaseconds * 1000000 + Seconds; end +function build_jid(tuple, full) + local node, jid, resource = tuple[1], tuple[2], tuple[3] + if type(node) == "string" and node ~= "" then + jid = tuple[1] .. "@" .. jid; + end + if full and type(resource) == "string" and resource ~= "" then + jid = jid .. "/" .. resource; + end + return jid; +end function vcard(node, host, stanza) local ret, err = dm.store(node, host, "vcard", st.preserialize(stanza)); @@ -105,10 +115,7 @@ function privacy(node, host, default, lists) if _type == "jid" then if type(value) ~= "table" then print("[error] privacy: jid value is not valid: "..tostring(value)); break; end local _node, _host, _resource = value[1], value[2], value[3]; - if (type(_node) == "table") then _node = nil; end - if (type(_host) == "table") then _host = nil; end - if (type(_resource) == "table") then _resource = nil; end - value = (_node and _node.."@".._host or _host)..(_resource and "/".._resource or ""); + value = build_jid(value, true) elseif _type == "none" then _type = nil; value = nil; @@ -154,18 +161,10 @@ function privacy(node, host, default, lists) local ret, err = dm.store(node, host, "privacy", privacy); print("["..(err or "success").."] privacy: " ..node.."@"..host.." - "..count.." list(s)"); end -local function _table_to_jid(t) - if type(t[2]) == "string" then - local jid = t[2]; - if type(t[1]) == "string" then jid = t[1].."@"..jid; end - if type(t[3]) == "string" then jid = jid.."/"..t[3]; end - return jid; - end -end function muc_room(node, host, properties) local store = { jid = node.."@"..host, _data = {}, _affiliations = {} }; for _,aff in ipairs(properties.affiliations) do - store._affiliations[_table_to_jid(aff[1])] = aff[2][1] or aff[2]; + store._affiliations[build_jid(aff[1])] = aff[2][1] or aff[2]; end store._data.subject = properties.subject; if properties.subject_author then @@ -207,7 +206,7 @@ local filters = { end; roster = function(tuple) local node = tuple[3][1]; local host = tuple[3][2]; - local contact = (type(tuple[4][1]) == "table") and tuple[4][2] or tuple[4][1].."@"..tuple[4][2]; + local contact = build_jid(tuple[4]); local name = tuple[5]; local subscription = tuple[6]; local ask = tuple[7]; local groups = tuple[8]; if type(name) ~= type("") then name = nil; end -- cgit v1.2.3 From 4da1f7a763aa920735dfd82af3fcb638a824fe7f Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 25 Jun 2014 15:33:49 +0200 Subject: net.adns: Add missing local declaration --- net/adns.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/net/adns.lua b/net/adns.lua index 158747c6..2a3fa8ad 100644 --- a/net/adns.lua +++ b/net/adns.lua @@ -52,6 +52,7 @@ function new_async_socket(sock, resolver) local peername = ""; local listener = {}; local handler = {}; + local err; function listener.onincoming(conn, data) if data then dns.feed(handler, data); -- cgit v1.2.3 From 17281a6413be6411c4b6d2c007098886e4c44765 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 30 Jun 2014 12:45:53 +0200 Subject: net.dns: Fix duplicated cache insertions by limiting outstanding queries per name to one --- net/dns.lua | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/net/dns.lua b/net/dns.lua index cdd949a2..492bd1c5 100644 --- a/net/dns.lua +++ b/net/dns.lua @@ -715,6 +715,14 @@ end function resolver:query(qname, qtype, qclass) -- - - - - - - - - - -- query qname, qtype, qclass = standardize(qname, qtype, qclass) + local co = coroutine.running(); + local q = get(self.wanted, qclass, qtype, qname); + if co and q then + -- We are already waiting for a reply to an identical query. + set(self.wanted, qclass, qtype, qname, co, true); + return true; + end + if not self.server then self:adddefaultnameservers(); end local question = encodeQuestion(qname, qtype, qclass); @@ -735,7 +743,6 @@ function resolver:query(qname, qtype, qclass) -- - - - - - - - - - -- query self.active[id][question] = o; -- remember which coroutine wants the answer - local co = coroutine.running(); if co then set(self.wanted, qclass, qtype, qname, co, true); --set(self.yielded, co, qclass, qtype, qname, true); -- cgit v1.2.3 From 806a93a534621f8214089ba32c455019e5298bd2 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 3 Jul 2014 17:53:24 +0200 Subject: mod_register: get_child_text! (thanks Lloyd) --- plugins/mod_register.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/mod_register.lua b/plugins/mod_register.lua index 141a4997..3d7a068c 100644 --- a/plugins/mod_register.lua +++ b/plugins/mod_register.lua @@ -115,8 +115,8 @@ local function handle_registration_stanza(event) module:log("info", "User removed their account: %s@%s", username, host); module:fire_event("user-deregistered", { username = username, host = host, source = "mod_register", session = session }); else - local username = nodeprep(query:get_child("username"):get_text()); - local password = query:get_child("password"):get_text(); + local username = nodeprep(query:get_child_text("username")); + local password = query:get_child_text("password"); if username and password then if username == session.username then if usermanager_set_password(username, password, session.host) then -- cgit v1.2.3 From cba6599105da56bc0693346d358d04bd1831f507 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 25 Jul 2014 12:08:07 +0100 Subject: net.dns: Ensure all pending requests get notified of a timeout when looking up a record (fix for d122420542fb) --- net/dns.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/net/dns.lua b/net/dns.lua index 492bd1c5..906365ce 100644 --- a/net/dns.lua +++ b/net/dns.lua @@ -770,7 +770,7 @@ function resolver:query(qname, qtype, qclass) -- - - - - - - - - - -- query end end -- Tried everything, failed - self:cancel(qclass, qtype, qname, co, true); + self:cancel(qclass, qtype, qname); end end) end @@ -910,13 +910,13 @@ function resolver:feed(sock, packet, force) return response; end -function resolver:cancel(qclass, qtype, qname, co, call_handler) +function resolver:cancel(qclass, qtype, qname) local cos = get(self.wanted, qclass, qtype, qname); if cos then - if call_handler then - coroutine.resume(co); + for co in pairs(cos) do + if coroutine.status(co) == "suspended" then coroutine.resume(co); end end - cos[co] = nil; + set(self.wanted, qclass, qtype, qname, nil); end end -- cgit v1.2.3 From db6fe5d5ec2ab8156794fafddd989cddde1bffaf Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 25 Jul 2014 12:54:31 +0100 Subject: net.dns: Remove unused obsolete code --- net/dns.lua | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/net/dns.lua b/net/dns.lua index 906365ce..89bd3564 100644 --- a/net/dns.lua +++ b/net/dns.lua @@ -745,7 +745,6 @@ function resolver:query(qname, qtype, qclass) -- - - - - - - - - - -- query -- remember which coroutine wants the answer if co then set(self.wanted, qclass, qtype, qname, co, true); - --set(self.yielded, co, qclass, qtype, qname, true); end local conn, err = self:getsocket(o.server) @@ -858,7 +857,6 @@ function resolver:receive(rset) -- - - - - - - - - - - - - - - - - receive local cos = get(self.wanted, q.class, q.type, q.name); if cos then for co in pairs(cos) do - set(self.yielded, co, q.class, q.type, q.name, nil); if coroutine.status(co) == "suspended" then coroutine.resume(co); end end set(self.wanted, q.class, q.type, q.name, nil); @@ -899,7 +897,6 @@ function resolver:feed(sock, packet, force) local cos = get(self.wanted, q.class, q.type, q.name); if cos then for co in pairs(cos) do - set(self.yielded, co, q.class, q.type, q.name, nil); if coroutine.status(co) == "suspended" then coroutine.resume(co); end end set(self.wanted, q.class, q.type, q.name, nil); @@ -1037,7 +1034,7 @@ end function dns.resolver () -- - - - - - - - - - - - - - - - - - - - - resolver -- this function seems to be redundant with resolver.new () - local r = { active = {}, cache = {}, unsorted = {}, wanted = {}, yielded = {}, best_server = 1 }; + local r = { active = {}, cache = {}, unsorted = {}, wanted = {}, best_server = 1 }; setmetatable (r, resolver); setmetatable (r.cache, cache_metatable); setmetatable (r.unsorted, { __mode = 'kv' }); -- cgit v1.2.3 From 7de3834a31f0a2150cbdbb43a49ea1f84dba4e94 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 25 Jul 2014 13:59:17 +0200 Subject: mod_admin_telnet: Fix dns:(add,set)nameservers() --- plugins/mod_admin_telnet.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index 6f02f030..671b6d89 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -1058,12 +1058,12 @@ function def_env.dns:lookup(name, typ, class) end function def_env.dns:addnameserver(...) - dns.addnameserver(...) + dns._resolver:addnameserver(...) return true end function def_env.dns:setnameserver(...) - dns.setnameserver(...) + dns._resolver:setnameserver(...) return true end -- cgit v1.2.3 From 559d43393be7558632d5c4845bf5b9078a39c264 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 25 Jul 2014 13:53:39 +0100 Subject: net.server_select/event: Switch sender mode to *a when reading, to make sure we get all available data --- net/server_event.lua | 1 + net/server_select.lua | 1 + 2 files changed, 2 insertions(+) diff --git a/net/server_event.lua b/net/server_event.lua index 25799640..b05d1688 100644 --- a/net/server_event.lua +++ b/net/server_event.lua @@ -847,6 +847,7 @@ local function link(sender, receiver, buffersize) sender:pause(); end end + sender:set_mode("*a"); end return { diff --git a/net/server_select.lua b/net/server_select.lua index 4bda3ef0..e8964518 100644 --- a/net/server_select.lua +++ b/net/server_select.lua @@ -705,6 +705,7 @@ local function link(sender, receiver, buffersize) sender:lock_read(true); end end + sender:set_mode("*a"); end ----------------------------------// PUBLIC //-- -- cgit v1.2.3 From 4fc9f0b8f590f64c2dd00455237ef5d46ded0d08 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Thu, 31 Jul 2014 06:56:21 +0100 Subject: configmanager: nameprep VirtualHost and Component names --- core/configmanager.lua | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/configmanager.lua b/core/configmanager.lua index d175b54b..c8aa7b9a 100644 --- a/core/configmanager.lua +++ b/core/configmanager.lua @@ -17,6 +17,9 @@ local envload = require"util.envload".envload; local deps = require"util.dependencies"; local path_sep = package.config:sub(1,1); +local have_encodings, encodings = pcall(require, "util.encodings"); +local nameprep = have_encodings and encodings.stringprep.nameprep or function (host) return host:lower(); end + module "configmanager" local parsers = {}; @@ -170,6 +173,7 @@ do rawset(env, "__currenthost", "*") -- Default is global function env.VirtualHost(name) + name = nameprep(name); if rawget(config, name) and rawget(config[name], "component_module") then error(format("Host %q clashes with previously defined %s Component %q, for services use a sub-domain like conference.%s", name, config[name].component_module:gsub("^%a+$", { component = "external", muc = "MUC"}), name, name), 0); @@ -187,6 +191,7 @@ do env.Host, env.host = env.VirtualHost, env.VirtualHost; function env.Component(name) + name = nameprep(name); if rawget(config, name) and rawget(config[name], "defined") and not rawget(config[name], "component_module") then error(format("Component %q clashes with previously defined Host %q, for services use a sub-domain like conference.%s", name, name, name), 0); -- cgit v1.2.3 From b9d13e10f334f614d86cd219b689ff38a5aad01c Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Thu, 31 Jul 2014 06:58:15 +0100 Subject: prosodyctl: Improve JID splitting and normalization for adduser/passwd/deluser --- prosodyctl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/prosodyctl b/prosodyctl index d341a75b..6a6414f6 100755 --- a/prosodyctl +++ b/prosodyctl @@ -268,6 +268,8 @@ local show_yesno = prosodyctl.show_yesno; local show_prompt = prosodyctl.show_prompt; local read_password = prosodyctl.read_password; +local jid_split = require "util.jid".prepped_split; + local prosodyctl_timeout = (config.get("*", "prosodyctl_timeout") or 5) * 2; ----------------------- local commands = {}; @@ -278,7 +280,7 @@ function commands.adduser(arg) show_usage([[adduser JID]], [[Create the specified user account in Prosody]]); return 1; end - local user, host = arg[1]:match("([^@]+)@(.+)"); + local user, host = jid_split(arg[1]); if not user and host then show_message [[Failed to understand JID, please supply the JID you want to create]] show_usage [[adduser user@host]] @@ -317,7 +319,7 @@ function commands.passwd(arg) show_usage([[passwd JID]], [[Set the password for the specified user account in Prosody]]); return 1; end - local user, host = arg[1]:match("([^@]+)@(.+)"); + local user, host = jid_split(arg[1]) if not user and host then show_message [[Failed to understand JID, please supply the JID you want to set the password for]] show_usage [[passwd user@host]] @@ -356,7 +358,7 @@ function commands.deluser(arg) show_usage([[deluser JID]], [[Permanently remove the specified user account from Prosody]]); return 1; end - local user, host = arg[1]:match("([^@]+)@(.+)"); + local user, host = jid_split(arg[1]); if not user and host then show_message [[Failed to understand JID, please supply the JID you want to set the password for]] show_usage [[passwd user@host]] -- cgit v1.2.3 From d73585bca84dd9df894abebd2ef4cb722242ba5a Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Thu, 31 Jul 2014 06:59:12 +0100 Subject: prosodyctl: Remove nonsensical warning --- prosodyctl | 1 - 1 file changed, 1 deletion(-) diff --git a/prosodyctl b/prosodyctl index 6a6414f6..38dac363 100755 --- a/prosodyctl +++ b/prosodyctl @@ -372,7 +372,6 @@ function commands.deluser(arg) if not hosts[host] then show_warning("The host '%s' is not listed in the configuration file (or is not enabled).", host) - show_warning("The user will not be able to log in until this is changed."); hosts[host] = make_host(host); end -- cgit v1.2.3 From aea3b6d32d2ddc7bef8eaf6e07e6f490e86f46be Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 26 Aug 2014 12:00:51 +0200 Subject: prosodyctl: Verify that 'pidfile' is a string, show friendly error otherwise --- prosodyctl | 1 + util/prosodyctl.lua | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/prosodyctl b/prosodyctl index 38dac363..8580aaf6 100755 --- a/prosodyctl +++ b/prosodyctl @@ -220,6 +220,7 @@ local error_messages = setmetatable({ ["no-such-host"] = "The given hostname does not exist in the config"; ["unable-to-save-data"] = "Unable to store, perhaps you don't have permission?"; ["no-pidfile"] = "There is no 'pidfile' option in the configuration file, see http://prosody.im/doc/prosodyctl#pidfile for help"; + ["invalid-pidfile"] = "The 'pidfile' option in the configuration file is not a string, see http://prosody.im/doc/prosodyctl#pidfile for help"; ["no-posix"] = "The mod_posix module is not enabled in the Prosody config file, see http://prosody.im/doc/prosodyctl for more info"; ["no-such-method"] = "This module has no commands"; ["not-running"] = "Prosody is not running"; diff --git a/util/prosodyctl.lua b/util/prosodyctl.lua index b80a69f2..c6fe1986 100644 --- a/util/prosodyctl.lua +++ b/util/prosodyctl.lua @@ -188,6 +188,10 @@ function getpid() if not pidfile then return false, "no-pidfile"; end + + if type(pidfile) ~= "string" then + return false, "invalid-pidfile"; + end local modules_enabled = set.new(config.get("*", "modules_enabled")); if not modules_enabled:contains("posix") then -- cgit v1.2.3 From bdcf8cd9da18672454dd03c625f01ede579d8cd2 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 26 Aug 2014 12:02:41 +0200 Subject: mod_posix: Make sure that 'pidfile' is a string --- plugins/mod_posix.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_posix.lua b/plugins/mod_posix.lua index 28fd7f38..b289fa44 100644 --- a/plugins/mod_posix.lua +++ b/plugins/mod_posix.lua @@ -80,7 +80,7 @@ local function write_pidfile() if pidfile_handle then remove_pidfile(); end - pidfile = module:get_option("pidfile"); + pidfile = module:get_option_string("pidfile"); if pidfile then local err; local mode = stat(pidfile) and "r+" or "w+"; -- cgit v1.2.3 From 1f1971f1264664ef6efec8e9ebd474e1406447c8 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 26 Aug 2014 12:19:27 +0200 Subject: mod_compression: Handle compression setup errors by logging a warning about it (fixes #408) --- plugins/mod_compression.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/mod_compression.lua b/plugins/mod_compression.lua index 531ea8ea..1ec4c85a 100644 --- a/plugins/mod_compression.lua +++ b/plugins/mod_compression.lua @@ -147,6 +147,12 @@ module:hook("stanza/http://jabber.org/protocol/compress:compressed", function(ev end end); +module:hook("stanza/http://jabber.org/protocol/compress:failure", function(event) + local err = event.stanza:get_child(); + (event.origin.log or module._log)("warn", "Compression setup failed (%s)", err and err.name or "unknown reason"); + return true; +end); + module:hook("stanza/http://jabber.org/protocol/compress:compress", function(event) local session, stanza = event.origin, event.stanza; -- cgit v1.2.3 From 005b4aa6567836dad3da3d5ef3f357b10da9699f Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 26 Aug 2014 21:50:08 +0200 Subject: mod_s2s: Mark stream as opened earlier for outgoing connections, fixes double stream headers on policy failures --- plugins/mod_s2s/mod_s2s.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua index aa517bbd..d4864a38 100644 --- a/plugins/mod_s2s/mod_s2s.lua +++ b/plugins/mod_s2s/mod_s2s.lua @@ -362,7 +362,9 @@ function stream_callbacks.streamopened(session, attr) log("debug", "Sending stream features: %s", tostring(features)); send(features); end + session.notopen = nil; elseif session.direction == "outgoing" then + session.notopen = nil; -- If we are just using the connection for verifying dialback keys, we won't try and auth it if not attr.id then error("stream response did not give us a streamid!!!"); end session.streamid = attr.id; @@ -396,7 +398,6 @@ function stream_callbacks.streamopened(session, attr) end end end - session.notopen = nil; end function stream_callbacks.streamclosed(session) -- cgit v1.2.3 From 5820cd511ada29a82126c587bd2385bbc7b183a8 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 27 Aug 2014 10:44:45 +0200 Subject: net.http.server: Comment out a log message --- net/http/server.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/http/server.lua b/net/http/server.lua index 0f379e96..771adf10 100644 --- a/net/http/server.lua +++ b/net/http/server.lua @@ -98,7 +98,7 @@ function listener.onconnect(conn) local pending = {}; local waiting = false; local function process_next() - if waiting then log("debug", "can't process_next, waiting"); return; end + if waiting then return; end -- log("debug", "can't process_next, waiting"); waiting = true; while sessions[conn] and #pending > 0 do local request = t_remove(pending); -- cgit v1.2.3 From 5b27b1ab9e08ddb49468474a188e97683f232335 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 27 Aug 2014 10:46:22 +0200 Subject: modulemanager: Reduce warning to debug level message about modules already being loaded, it's probably just module:depends() --- core/modulemanager.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/modulemanager.lua b/core/modulemanager.lua index cddab647..4df95069 100644 --- a/core/modulemanager.lua +++ b/core/modulemanager.lua @@ -123,7 +123,7 @@ local function do_load_module(host, module_name, state) end if modulemap[host][module_name] then - log("warn", "%s is already loaded for %s, so not loading again", module_name, host); + log("debug", "%s is already loaded for %s, so not loading again", module_name, host); return nil, "module-already-loaded"; elseif modulemap["*"][module_name] then local mod = modulemap["*"][module_name]; -- cgit v1.2.3 From f1e1b7b337884c764657245a3e42b8a438ad2c1c Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 27 Aug 2014 13:20:08 +0200 Subject: mod_s2s: Reset stream ID when resetting stream [compliance] --- plugins/mod_s2s/mod_s2s.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua index d4864a38..c288d858 100644 --- a/plugins/mod_s2s/mod_s2s.lua +++ b/plugins/mod_s2s/mod_s2s.lua @@ -528,6 +528,7 @@ local function initialize_session(session) function session.reset_stream() session.notopen = true; + session.streamid = nil; session.stream:reset(); end -- cgit v1.2.3 From 443f33ae10d1230c9f0f78547ab73d1618fd44fe Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 23 Aug 2014 09:22:05 +0100 Subject: util.xmppstream: When error is 'no-stream', pass the received tagname to the error handler --- util/xmppstream.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/xmppstream.lua b/util/xmppstream.lua index 73f5e314..138c86b7 100644 --- a/util/xmppstream.lua +++ b/util/xmppstream.lua @@ -109,7 +109,7 @@ function new_sax_handlers(session, stream_callbacks, cb_handleprogress) end else -- Garbage before stream? - cb_error(session, "no-stream"); + cb_error(session, "no-stream", tagname); end return; end -- cgit v1.2.3 From 67e061cab521ceb6c22f3b91c57f78727701732a Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 23 Aug 2014 09:29:17 +0100 Subject: mod_c2s, mod_s2s: Log received invalid stream headers --- plugins/mod_c2s.lua | 2 +- plugins/mod_s2s/mod_s2s.lua | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/mod_c2s.lua b/plugins/mod_c2s.lua index 5feb1f2c..b6895f4b 100644 --- a/plugins/mod_c2s.lua +++ b/plugins/mod_c2s.lua @@ -91,7 +91,7 @@ end function stream_callbacks.error(session, error, data) if error == "no-stream" then - session.log("debug", "Invalid opening stream header"); + session.log("debug", "Invalid opening stream header (%s)", (data:gsub("^([^\1]+)\1", "{%1}"))); session:close("invalid-namespace"); elseif error == "parse-error" then (session.log or log)("debug", "Client XML parse error: %s", tostring(data)); diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua index c288d858..44334428 100644 --- a/plugins/mod_s2s/mod_s2s.lua +++ b/plugins/mod_s2s/mod_s2s.lua @@ -407,6 +407,7 @@ end function stream_callbacks.error(session, error, data) if error == "no-stream" then + session.log("debug", "Invalid opening stream header (%s)", (data:gsub("^([^\1]+)\1", "{%1}"))); session:close("invalid-namespace"); elseif error == "parse-error" then session.log("debug", "Server-to-server XML parse error: %s", tostring(error)); -- cgit v1.2.3 From 18972a28d852a6fa6a2e8b47f4fbcaac61ff6254 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Thu, 28 Aug 2014 09:17:07 +0100 Subject: mod_privacy: Fix to correctly sort privacy list rules by order (thanks Flow) --- plugins/mod_privacy.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_privacy.lua b/plugins/mod_privacy.lua index 31ace9f9..49c9427f 100644 --- a/plugins/mod_privacy.lua +++ b/plugins/mod_privacy.lua @@ -157,7 +157,7 @@ function createOrReplaceList (privacy_lists, origin, stanza, name, entries) list.items[#list.items + 1] = tmp; end - table.sort(list, function(a, b) return a.order < b.order; end); + table.sort(list.items, function(a, b) return a.order < b.order; end); origin.send(st.reply(stanza)); if bare_sessions[bare_jid] ~= nil then -- cgit v1.2.3 From 08a98f31738dbdca78b04722d5dc63d84754ef39 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Thu, 28 Aug 2014 09:20:33 +0100 Subject: util.filters: Ignore filters being added twice (fixes issues on removal) --- util/filters.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/util/filters.lua b/util/filters.lua index d24bd33e..6290e53b 100644 --- a/util/filters.lua +++ b/util/filters.lua @@ -45,6 +45,8 @@ function add_filter(session, type, callback, priority) if not filter_list then filter_list = {}; session.filters[type] = filter_list; + elseif filter_list[callback] then + return; -- Filter already added end priority = priority or 0; -- cgit v1.2.3 -- cgit v1.2.3 From f7fb69e5e53ce95d14f60d9e51d12fb09d15479c Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 2 Sep 2014 17:24:25 +0200 Subject: mod_s2s: Close offending s2s streams missing an 'id' attribute with a stream error instead of throwing an unhandled error --- plugins/mod_s2s/mod_s2s.lua | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua index 44334428..834e6a1c 100644 --- a/plugins/mod_s2s/mod_s2s.lua +++ b/plugins/mod_s2s/mod_s2s.lua @@ -365,8 +365,11 @@ function stream_callbacks.streamopened(session, attr) session.notopen = nil; elseif session.direction == "outgoing" then session.notopen = nil; - -- If we are just using the connection for verifying dialback keys, we won't try and auth it - if not attr.id then error("stream response did not give us a streamid!!!"); end + if not attr.id then + log("error", "Stream response did not give us a stream id!"); + session:close({ condition = "undefined-condition", text = "Missing stream ID" }); + return; + end session.streamid = attr.id; if session.secure and not session.cert_chain_status then -- cgit v1.2.3 From 0926e4557e9600392e4ad335239b399e0baa953f Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 29 Aug 2014 11:39:56 +0100 Subject: net.server_{select,event}: Add 'ondetach' callback for listener objects, to notify them when another listener is being assigned to a connection --- net/server_event.lua | 10 ++++++++-- net/server_select.lua | 5 +++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/net/server_event.lua b/net/server_event.lua index b05d1688..45938a13 100644 --- a/net/server_event.lua +++ b/net/server_event.lua @@ -438,8 +438,11 @@ do end function interface_mt:setlistener(listener) - self.onconnect, self.ondisconnect, self.onincoming, self.ontimeout, self.onstatus - = listener.onconnect, listener.ondisconnect, listener.onincoming, listener.ontimeout, listener.onstatus; + self:ondetach(); -- Notify listener that it is no longer responsible for this connection + self.onconnect, self.ondisconnect, self.onincoming, + self.ontimeout, self.onstatus, self.ondetach + = listener.onconnect, listener.ondisconnect, listener.onincoming, + listener.ontimeout, listener.onstatus, listener.ondetach; end -- Stub handlers @@ -453,6 +456,8 @@ do end function interface_mt:ondrain() end + function interface_mt:ondetach() + end function interface_mt:onstatus() end end @@ -479,6 +484,7 @@ do onincoming = listener.onincoming; -- will be called when client sends data ontimeout = listener.ontimeout; -- called when fatal socket timeout occurs ondrain = listener.ondrain; -- called when writebuffer is empty + ondetach = listener.ondetach; -- called when disassociating this listener from this connection onstatus = listener.onstatus; -- called for status changes (e.g. of SSL/TLS) eventread = false, eventwrite = false, eventclose = false, eventhandshake = false, eventstarthandshake = false; -- event handler diff --git a/net/server_select.lua b/net/server_select.lua index e8964518..2b23b4f0 100644 --- a/net/server_select.lua +++ b/net/server_select.lua @@ -284,6 +284,7 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport local status = listeners.onstatus local disconnect = listeners.ondisconnect local drain = listeners.ondrain + local detach = listener.ondetach local bufferqueue = { } -- buffer array local bufferqueuelen = 0 -- end of buffer array @@ -313,10 +314,14 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport return disconnect end handler.setlistener = function( self, listeners ) + if detach then + detach(self) -- Notify listener that it is no longer responsible for this connection + end dispatch = listeners.onincoming disconnect = listeners.ondisconnect status = listeners.onstatus drain = listeners.ondrain + detach = listeners.ondetach end handler.getstats = function( ) return readtraffic, sendtraffic -- cgit v1.2.3 From a76091c611089e18bf72d13e306a798d16c35645 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 29 Aug 2014 11:54:34 +0100 Subject: net.http, net.http.server, mod_c2s, mod_s2s, mod_component, mod_admin_telnet, mod_net_multiplex: Add ondetach to release connection from 'sessions' table (or equivalent) --- net/http.lua | 4 ++++ net/http/server.lua | 4 ++++ plugins/mod_admin_telnet.lua | 4 ++++ plugins/mod_c2s.lua | 4 ++++ plugins/mod_component.lua | 4 ++++ plugins/mod_net_multiplex.lua | 3 ++- plugins/mod_s2s/mod_s2s.lua | 4 ++++ 7 files changed, 26 insertions(+), 1 deletion(-) diff --git a/net/http.lua b/net/http.lua index 6ddb1900..9dde6062 100644 --- a/net/http.lua +++ b/net/http.lua @@ -72,6 +72,10 @@ function listener.ondisconnect(conn, err) requests[conn] = nil; end +function listener.ondetach(conn) + requests[conn] = nil; +end + local function request_reader(request, data, err) if not request.parser then local function error_cb(reason) diff --git a/net/http/server.lua b/net/http/server.lua index 771adf10..7937f87c 100644 --- a/net/http/server.lua +++ b/net/http/server.lua @@ -142,6 +142,10 @@ function listener.ondisconnect(conn) sessions[conn] = nil; end +function listener.ondetach(conn) + sessions[conn] = nil; +end + function listener.onincoming(conn, data) sessions[conn]:feed(data); end diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index 671b6d89..e4b5a045 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -163,6 +163,10 @@ function console_listener.ondisconnect(conn, err) end end +function console_listener.ondetach(conn) + sessions[conn] = nil; +end + -- Console commands -- -- These are simple commands, not valid standalone in Lua diff --git a/plugins/mod_c2s.lua b/plugins/mod_c2s.lua index b6895f4b..3d6487c9 100644 --- a/plugins/mod_c2s.lua +++ b/plugins/mod_c2s.lua @@ -266,6 +266,10 @@ function listener.associate_session(conn, session) sessions[conn] = session; end +function listener.ondetach(conn) + sessions[conn] = nil; +end + module:hook("server-stopping", function(event) local reason = event.reason; for _, session in pairs(sessions) do diff --git a/plugins/mod_component.lua b/plugins/mod_component.lua index c5a1da81..7bc0f5b7 100644 --- a/plugins/mod_component.lua +++ b/plugins/mod_component.lua @@ -319,6 +319,10 @@ function listener.ondisconnect(conn, err) end end +function listener.ondetach(conn) + sessions[conn] = nil; +end + module:provides("net", { name = "component"; private = true; diff --git a/plugins/mod_net_multiplex.lua b/plugins/mod_net_multiplex.lua index d666b907..0dd3dc67 100644 --- a/plugins/mod_net_multiplex.lua +++ b/plugins/mod_net_multiplex.lua @@ -34,7 +34,6 @@ end function listener.onincoming(conn, data) if not data then return; end local buf = buffers[conn]; - buffers[conn] = nil; buf = buf and buf..data or data; for service, multiplex_pattern in pairs(available_services) do if buf:match(multiplex_pattern) then @@ -57,6 +56,8 @@ function listener.ondisconnect(conn, err) buffers[conn] = nil; -- warn if no buffer? end +listener.ondetach = listener.ondisconnect; + module:provides("net", { name = "multiplex"; config_prefix = ""; diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua index 834e6a1c..ee03987d 100644 --- a/plugins/mod_s2s/mod_s2s.lua +++ b/plugins/mod_s2s/mod_s2s.lua @@ -638,6 +638,10 @@ function listener.register_outgoing(conn, session) initialize_session(session); end +function listener.ondetach(conn) + sessions[conn] = nil; +end + function check_auth_policy(event) local host, session = event.host, event.session; local must_secure = secure_auth; -- cgit v1.2.3 From 3af268b9b31b69c5c8704b1f22f41d9bf395073e Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 2 Sep 2014 17:23:44 +0100 Subject: net.server_select: 'listener'->'listeners' (fixes undefined global access) --- net/server_select.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/server_select.lua b/net/server_select.lua index 2b23b4f0..7ac41523 100644 --- a/net/server_select.lua +++ b/net/server_select.lua @@ -284,7 +284,7 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport local status = listeners.onstatus local disconnect = listeners.ondisconnect local drain = listeners.ondrain - local detach = listener.ondetach + local detach = listeners.ondetach local bufferqueue = { } -- buffer array local bufferqueuelen = 0 -- end of buffer array -- cgit v1.2.3 From f5bf37762b749a16cb9b87f3f72a1a4ed5540901 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Wed, 3 Sep 2014 18:49:41 +0100 Subject: net.http.parser: Support status code 101 and allow handling of the received data by someone else --- net/http/parser.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/net/http/parser.lua b/net/http/parser.lua index f9e6cea0..d896dff4 100644 --- a/net/http/parser.lua +++ b/net/http/parser.lua @@ -140,7 +140,11 @@ function httpstream.new(success_cb, error_cb, parser_type, options_cb) break; end elseif len and #buf >= len then - packet.body, buf = buf:sub(1, len), buf:sub(len + 1); + if packet.code == 101 then + packet.body, buf = buf, "" + else + packet.body, buf = buf:sub(1, len), buf:sub(len + 1); + end state = nil; success_cb(packet); else break; -- cgit v1.2.3 From f2e076f24db43401a687d9df3c219407bbfb121c Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 9 Sep 2014 14:42:10 +0200 Subject: core.stanza_router: Stricter validation of stanzas --- core/stanza_router.lua | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/core/stanza_router.lua b/core/stanza_router.lua index 94753678..bf5b11bc 100644 --- a/core/stanza_router.lua +++ b/core/stanza_router.lua @@ -29,24 +29,25 @@ deprecated_warning"core_post_stanza"; deprecated_warning"core_process_stanza"; deprecated_warning"core_route_stanza"; +local valid_stanzas = { message = true, presence = true, iq = true }; local function handle_unhandled_stanza(host, origin, stanza) local name, xmlns, origin_type = stanza.name, stanza.attr.xmlns or "jabber:client", origin.type; - if name == "iq" and xmlns == "jabber:client" then - if stanza.attr.type == "get" or stanza.attr.type == "set" then + if xmlns == "jabber:client" and valid_stanzas[name] then + -- A normal stanza + local st_type = stanza.attr.type; + if st_type == "error" or (name == "iq" and st_type == "result") then + log("debug", "Discarding %s from %s of type: %s", name, origin_type, st_type or ''); + return; + end + if name == "iq" and (st_type == "get" or st_type == "set") and stanza.tags[1] then xmlns = stanza.tags[1].attr.xmlns or "jabber:client"; - log("debug", "Stanza of type %s from %s has xmlns: %s", name, origin_type, xmlns); - else - log("debug", "Discarding %s from %s of type: %s", name, origin_type, stanza.attr.type); - return true; end - end - if stanza.attr.xmlns == nil and origin.send then - log("debug", "Unhandled %s stanza: %s; xmlns=%s", origin.type, stanza.name, xmlns); -- we didn't handle it - if stanza.attr.type ~= "error" and stanza.attr.type ~= "result" then + log("debug", "Unhandled %s stanza: %s; xmlns=%s", origin_type, name, xmlns); + if origin.send then origin.send(st.error_reply(stanza, "cancel", "service-unavailable")); end elseif not((name == "features" or name == "error") and xmlns == "http://etherx.jabber.org/streams") then -- FIXME remove check once we handle S2S features - log("warn", "Unhandled %s stream element or stanza: %s; xmlns=%s: %s", origin.type, stanza.name, xmlns, tostring(stanza)); -- we didn't handle it + log("warn", "Unhandled %s stream element or stanza: %s; xmlns=%s: %s", origin_type, name, xmlns, tostring(stanza)); -- we didn't handle it origin:close("unsupported-stanza-type"); end end @@ -55,19 +56,21 @@ local iq_types = { set=true, get=true, result=true, error=true }; function core_process_stanza(origin, stanza) (origin.log or log)("debug", "Received[%s]: %s", origin.type, stanza:top_tag()) - -- TODO verify validity of stanza (as well as JID validity) - if stanza.attr.type == "error" and #stanza.tags == 0 then return; end -- TODO invalid stanza, log - if stanza.name == "iq" then - if not stanza.attr.id then stanza.attr.id = ""; end -- COMPAT Jabiru doesn't send the id attribute on roster requests - if not iq_types[stanza.attr.type] or ((stanza.attr.type == "set" or stanza.attr.type == "get") and (#stanza.tags ~= 1)) then - origin.send(st.error_reply(stanza, "modify", "bad-request", "Invalid IQ type or incorrect number of children")); - return; + if origin.type == "c2s" and not stanza.attr.xmlns then + local name, st_type = stanza.name, stanza.attr.type; + if st_type == "error" and #stanza.tags == 0 then + return handle_unhandled_stanza(origin.host, origin, stanza); + end + if name == "iq" then + if not stanza.attr.id then stanza.attr.id = ""; end -- COMPAT Jabiru doesn't send the id attribute on roster requests + if not iq_types[st_type] or (st_type ~= "result" and #stanza.tags ~= 1) then + origin.send(st.error_reply(stanza, "modify", "bad-request", "Invalid IQ type or incorrect number of children")); + return; + end end - end - if origin.type == "c2s" and not stanza.attr.xmlns then if not origin.full_jid - and not(stanza.name == "iq" and stanza.attr.type == "set" and stanza.tags[1] and stanza.tags[1].name == "bind" + and not(name == "iq" and st_type == "set" and stanza.tags[1] and stanza.tags[1].name == "bind" and stanza.tags[1].attr.xmlns == "urn:ietf:params:xml:ns:xmpp-bind") then -- authenticated client isn't bound and current stanza is not a bind request if stanza.attr.type ~= "result" and stanza.attr.type ~= "error" then -- cgit v1.2.3 From 82b33b4906f7219dc19e2895ff5d1a30a68207bc Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 29 Sep 2014 11:02:06 +0200 Subject: mod_admin_adhoc: Mark 'accountjids' field as required in 'end user sessions' command (thanks Lloyd) --- plugins/mod_admin_adhoc.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_admin_adhoc.lua b/plugins/mod_admin_adhoc.lua index 2c6047da..704b2685 100644 --- a/plugins/mod_admin_adhoc.lua +++ b/plugins/mod_admin_adhoc.lua @@ -162,7 +162,7 @@ local end_user_session_layout = dataforms_new{ instructions = "Fill out this form to end a user's session."; { name = "FORM_TYPE", type = "hidden", value = "http://jabber.org/protocol/admin" }; - { name = "accountjids", type = "jid-multi", label = "The Jabber ID(s) for which to end sessions" }; + { name = "accountjids", type = "jid-multi", label = "The Jabber ID(s) for which to end sessions", required = true }; }; local end_user_session_handler = adhoc_simple(end_user_session_layout, function(fields, err) -- cgit v1.2.3 From 0ccb1f50b0a19d478470156eec62f2fa1767ed0d Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 29 Sep 2014 11:18:04 +0200 Subject: mod_admin_adhoc: Add required to field in user deletion form too --- plugins/mod_admin_adhoc.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_admin_adhoc.lua b/plugins/mod_admin_adhoc.lua index 704b2685..232fa5f7 100644 --- a/plugins/mod_admin_adhoc.lua +++ b/plugins/mod_admin_adhoc.lua @@ -118,7 +118,7 @@ local delete_user_layout = dataforms_new{ instructions = "Fill out this form to delete a user."; { name = "FORM_TYPE", type = "hidden", value = "http://jabber.org/protocol/admin" }; - { name = "accountjids", type = "jid-multi", label = "The Jabber ID(s) to delete" }; + { name = "accountjids", type = "jid-multi", required = true, label = "The Jabber ID(s) to delete" }; }; local delete_user_command_handler = adhoc_simple(delete_user_layout, function(fields, err) -- cgit v1.2.3 From 121b64847546320d919c0fb4e8997e2d6813b714 Mon Sep 17 00:00:00 2001 From: Florian Zeitz Date: Sun, 5 Oct 2014 14:28:40 +0200 Subject: net.dns: Avoid duplicate cache entries --- net/dns.lua | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/net/dns.lua b/net/dns.lua index 89bd3564..dc2da1b6 100644 --- a/net/dns.lua +++ b/net/dns.lua @@ -134,17 +134,19 @@ end local function prune(rrs, time, soft) -- - - - - - - - - - - - - - - prune time = time or socket.gettime(); - for i,rr in pairs(rrs) do + for i,rr in ipairs(rrs) do if rr.tod then -- rr.tod = rr.tod - 50 -- accelerated decripitude rr.ttl = math.floor(rr.tod - time); if rr.ttl <= 0 then + rrs[rr[rr.type:lower()]] = nil; table.remove(rrs, i); return prune(rrs, time, soft); -- Re-iterate end elseif soft == 'soft' then -- What is this? I forget! assert(rr.ttl == 0); - rrs[i] = nil; + rrs[rr[rr.type:lower()]] = nil; + table.remove(rrs, i); end end end @@ -187,7 +189,7 @@ end local rrs_metatable = {}; -- - - - - - - - - - - - - - - - - - rrs_metatable function rrs_metatable.__tostring(rrs) local t = {}; - for i,rr in pairs(rrs) do + for i,rr in ipairs(rrs) do append(t, tostring(rr)..'\n'); end return table.concat(t); @@ -674,7 +676,10 @@ function resolver:remember(rr, type) -- - - - - - - - - - - - - - remember self.cache = self.cache or setmetatable({}, cache_metatable); local rrs = get(self.cache, qclass, type, qname) or set(self.cache, qclass, type, qname, setmetatable({}, rrs_metatable)); - append(rrs, rr); + if not rrs[rr[qtype:lower()]] then + rrs[rr[qtype:lower()]] = true; + append(rrs, rr); + end if type == 'MX' then self.unsorted[rrs] = true; end end -- cgit v1.2.3 From 39d305e2ade0c259e6c93de0dd4aedce55b51057 Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Wed, 8 Oct 2014 15:56:11 -0400 Subject: util.stanza: Escape newlines and tabs (\r\n\t) when serializing stanzas. \r\n transforms into \n otherwise, and \r\n\t in attributes transforms into spaces. --- util/stanza.lua | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/util/stanza.lua b/util/stanza.lua index 7c214210..2fcf2c79 100644 --- a/util/stanza.lua +++ b/util/stanza.lua @@ -202,8 +202,19 @@ end local xml_escape do - local escape_table = { ["'"] = "'", ["\""] = """, ["<"] = "<", [">"] = ">", ["&"] = "&" }; - function xml_escape(str) return (s_gsub(str, "['&<>\"]", escape_table)); end + local escape_table = { + ["'"] = "'"; + ['"'] = """; + ["<"] = "<"; + [">"] = ">"; + ["&"] = "&"; + -- escape this whitespace because [\r\n\t] change into spaces in attributes + -- and \r\n changes into \n in text, and we want to preserve original bytes + ["\t"] = " "; + ["\n"] = " "; + ["\r"] = " "; + }; + function xml_escape(str) return (s_gsub(str, "['&<>\"\t\n\r]", escape_table)); end _M.xml_escape = xml_escape; end -- cgit v1.2.3 From 2549abdcab790961e50e970e7d55206ab1f95d66 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Tue, 7 Oct 2014 12:08:23 -0400 Subject: util/dataforms: Make sure we iterate over field tags --- util/dataforms.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/dataforms.lua b/util/dataforms.lua index 01a8eef3..ee37157a 100644 --- a/util/dataforms.lua +++ b/util/dataforms.lua @@ -121,7 +121,7 @@ function form_t.data(layout, stanza) for _, field in ipairs(layout) do local tag; - for field_tag in stanza:childtags() do + for field_tag in stanza:childtags("field") do if field.name == field_tag.attr.var then tag = field_tag; break; -- cgit v1.2.3 From 00661df08d750b8486ca5bb64c38aa5359073ee7 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 10 Oct 2014 00:56:53 +0200 Subject: mod_s2s: Capitalize log message --- plugins/mod_s2s/mod_s2s.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua index ee03987d..d8846a6f 100644 --- a/plugins/mod_s2s/mod_s2s.lua +++ b/plugins/mod_s2s/mod_s2s.lua @@ -49,7 +49,7 @@ local bouncy_stanzas = { message = true, presence = true, iq = true }; local function bounce_sendq(session, reason) local sendq = session.sendq; if not sendq then return; end - session.log("info", "sending error replies for "..#sendq.." queued stanzas because of failed outgoing connection to "..tostring(session.to_host)); + session.log("info", "Sending error replies for "..#sendq.." queued stanzas because of failed outgoing connection to "..tostring(session.to_host)); local dummy = { type = "s2sin"; send = function(s) -- cgit v1.2.3 From dbfcafeb754aa055d6017feff5659cbdc4c173bd Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 14 Oct 2014 10:58:11 +0100 Subject: mod_pubsub: Fix error type of 'forbidden' (change from 'cancel' to 'auth') --- plugins/mod_pubsub.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_pubsub.lua b/plugins/mod_pubsub.lua index 926ed4f2..04f2b615 100644 --- a/plugins/mod_pubsub.lua +++ b/plugins/mod_pubsub.lua @@ -39,7 +39,7 @@ local pubsub_errors = { ["nodeid-required"] = { "modify", "bad-request", nil, "nodeid-required" }; ["item-not-found"] = { "cancel", "item-not-found" }; ["not-subscribed"] = { "modify", "unexpected-request", nil, "not-subscribed" }; - ["forbidden"] = { "cancel", "forbidden" }; + ["forbidden"] = { "auth", "forbidden" }; }; function pubsub_error_reply(stanza, error) local e = pubsub_errors[error]; -- cgit v1.2.3 From b9a687e6efce1078586ca6c47b6e720366381e88 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 14 Oct 2014 18:55:08 +0100 Subject: certmanager, net.http: Disable SSLv3 by default --- core/certmanager.lua | 2 +- net/http.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/certmanager.lua b/core/certmanager.lua index d6784a96..624bd841 100644 --- a/core/certmanager.lua +++ b/core/certmanager.lua @@ -33,7 +33,7 @@ module "certmanager" local default_ssl_config = configmanager.get("*", "ssl"); local default_capath = "/etc/ssl/certs"; local default_verify = (ssl and ssl.x509 and { "peer", "client_once", }) or "none"; -local default_options = { "no_sslv2", "cipher_server_preference", luasec_has_noticket and "no_ticket" or nil }; +local default_options = { "no_sslv2", "no_sslv3", "cipher_server_preference", luasec_has_noticket and "no_ticket" or nil }; local default_verifyext = { "lsec_continue", "lsec_ignore_purpose" }; if ssl and not luasec_has_verifyext and ssl.x509 then diff --git a/net/http.lua b/net/http.lua index 9dde6062..8ce47494 100644 --- a/net/http.lua +++ b/net/http.lua @@ -175,7 +175,7 @@ function request(u, ex, callback) local sslctx = false; if using_https then - sslctx = ex and ex.sslctx or { mode = "client", protocol = "sslv23", options = { "no_sslv2" } }; + sslctx = ex and ex.sslctx or { mode = "client", protocol = "sslv23", options = { "no_sslv2", "no_sslv3" } }; end req.handler, req.conn = assert(server.wrapclient(conn, host, port_number, listener, "*a", sslctx)); -- cgit v1.2.3 -- cgit v1.2.3 From 30f8b752e65574ce57d0d0a59578fbd4f960e42e Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Sun, 19 Oct 2014 03:05:49 -0400 Subject: prosodyctl: Fix nil global access traceback in `prosodyctl about` (luarocks 2.2.0 no longer uses module()) --- prosodyctl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prosodyctl b/prosodyctl index 8580aaf6..4c3ae981 100755 --- a/prosodyctl +++ b/prosodyctl @@ -548,7 +548,7 @@ function commands.about(arg) print(" "..path); end print(""); - local luarocks_status = (pcall(require, "luarocks.loader") and "Installed ("..(luarocks.cfg.program_version or "2.x+")..")") + local luarocks_status = (pcall(require, "luarocks.loader") and "Installed ("..(package.loaded["luarocks.cfg"].program_version or "2.x+")..")") or (pcall(require, "luarocks.require") and "Installed (1.x)") or "Not installed"; print("LuaRocks: ", luarocks_status); -- cgit v1.2.3 From d8ae4fa9c91ecfc2ad45d5f214739801ec41b418 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 24 Oct 2014 23:20:06 +0100 Subject: Backout changeset 6e67c73f730c: not a major fix and it breaks interop with at least Isode M-Link, and possibly standards, while it's not clear it actually fixes the original problem either. --- util/stanza.lua | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/util/stanza.lua b/util/stanza.lua index 2fcf2c79..7c214210 100644 --- a/util/stanza.lua +++ b/util/stanza.lua @@ -202,19 +202,8 @@ end local xml_escape do - local escape_table = { - ["'"] = "'"; - ['"'] = """; - ["<"] = "<"; - [">"] = ">"; - ["&"] = "&"; - -- escape this whitespace because [\r\n\t] change into spaces in attributes - -- and \r\n changes into \n in text, and we want to preserve original bytes - ["\t"] = " "; - ["\n"] = " "; - ["\r"] = " "; - }; - function xml_escape(str) return (s_gsub(str, "['&<>\"\t\n\r]", escape_table)); end + local escape_table = { ["'"] = "'", ["\""] = """, ["<"] = "<", [">"] = ">", ["&"] = "&" }; + function xml_escape(str) return (s_gsub(str, "['&<>\"]", escape_table)); end _M.xml_escape = xml_escape; end -- cgit v1.2.3 -- cgit v1.2.3 From f0d995658b6030d3c5ff7a4adc1af71f534a2c75 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 30 Oct 2014 12:05:24 +0100 Subject: net.adns: Preserve error from setpeername --- net/adns.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/adns.lua b/net/adns.lua index 2a3fa8ad..da7981ba 100644 --- a/net/adns.lua +++ b/net/adns.lua @@ -76,7 +76,7 @@ function new_async_socket(sock, resolver) handler.settimeout = function () end handler.setsockname = function (_, ...) return sock:setsockname(...); end - handler.setpeername = function (_, ...) peername = (...); local ret = sock:setpeername(...); _:set_send(dummy_send); return ret; end + handler.setpeername = function (_, ...) peername = (...); local ret, err = sock:setpeername(...); _:set_send(dummy_send); return ret, err; end handler.connect = function (_, ...) return sock:connect(...) end --handler.send = function (_, data) _:write(data); return _.sendbuffer and _.sendbuffer(); end handler.send = function (_, data) -- cgit v1.2.3 From 7b339efd6373e26037c83d93ef750eb46c7b23f4 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 30 Oct 2014 12:08:05 +0100 Subject: net.adns: Log peername recorded from wrapped setpeername instead of calling sock:getpeername, it exists and throws an error on unconnected sockets (thanks wirehack7) --- net/adns.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/adns.lua b/net/adns.lua index da7981ba..3fc958f4 100644 --- a/net/adns.lua +++ b/net/adns.lua @@ -80,8 +80,7 @@ function new_async_socket(sock, resolver) handler.connect = function (_, ...) return sock:connect(...) end --handler.send = function (_, data) _:write(data); return _.sendbuffer and _.sendbuffer(); end handler.send = function (_, data) - local getpeername = sock.getpeername; - log("debug", "Sending DNS query to %s", (getpeername and getpeername(sock)) or ""); + log("debug", "Sending DNS query to %s", peername); return sock:send(data); end return handler; -- cgit v1.2.3 From 114448b637839bee9cf2b537fd60789c63bad586 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 30 Oct 2014 12:10:15 +0100 Subject: net.dns: Return new socket from servfail --- net/dns.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/dns.lua b/net/dns.lua index dc2da1b6..55622fc8 100644 --- a/net/dns.lua +++ b/net/dns.lua @@ -787,7 +787,7 @@ function resolver:servfail(sock) local num = self.socketset[sock] -- Socket is dead now - self:voidsocket(sock); + sock = self:voidsocket(sock); -- Find all requests to the down server, and retry on the next server self.time = socket.gettime(); @@ -804,8 +804,8 @@ function resolver:servfail(sock) --print('timeout'); queries[question] = nil; else - local _a = self:getsocket(o.server); - if _a then _a:send(o.packet); end + sock = self:getsocket(o.server); + if sock then sock:send(o.packet); end end end end @@ -821,6 +821,7 @@ function resolver:servfail(sock) self.best_server = 1; end end + return sock; end function resolver:settimeout(seconds) -- cgit v1.2.3 From 9c58aa6730a10d80712c27c1498907d69a2b7852 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 30 Oct 2014 12:28:07 +0100 Subject: net.dns: Try next server if peer name can not be set (thanks wirehack7) --- net/dns.lua | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/net/dns.lua b/net/dns.lua index 55622fc8..13417cee 100644 --- a/net/dns.lua +++ b/net/dns.lua @@ -622,7 +622,7 @@ function resolver:getsocket(servernum) -- - - - - - - - - - - - - getsocket local sock = self.socket[servernum]; if sock then return sock; end - local err; + local ok, err; sock, err = socket.udp(); if sock and self.socket_wrapper then sock, err = self.socket_wrapper(sock, self); end if not sock then @@ -630,10 +630,14 @@ function resolver:getsocket(servernum) -- - - - - - - - - - - - - getsocket end sock:settimeout(0); -- todo: attempt to use a random port, fallback to 0 - sock:setsockname('*', 0); - sock:setpeername(self.server[servernum], 53); self.socket[servernum] = sock; self.socketset[sock] = servernum; + -- set{sock,peer}name can fail, eg because of local routing table + -- if so, try the next server + ok, err = sock:setsockname('*', 0); + if not ok then return self:servfail(sock, err); end + ok, err = sock:setpeername(self.server[servernum], 53); + if not ok then return self:servfail(sock, err); end return sock; end @@ -781,7 +785,7 @@ function resolver:query(qname, qtype, qclass) -- - - - - - - - - - -- query return true; end -function resolver:servfail(sock) +function resolver:servfail(sock, err) -- Resend all queries for this server local num = self.socketset[sock] @@ -804,7 +808,7 @@ function resolver:servfail(sock) --print('timeout'); queries[question] = nil; else - sock = self:getsocket(o.server); + sock, err = self:getsocket(o.server); if sock then sock:send(o.packet); end end end @@ -821,7 +825,7 @@ function resolver:servfail(sock) self.best_server = 1; end end - return sock; + return sock, err; end function resolver:settimeout(seconds) -- cgit v1.2.3 From eadd8212168e903344f94d53c5762095cb9be8f5 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Mon, 10 Nov 2014 14:47:33 -0500 Subject: net.http.parser: Fix chunked encoding parsing across packet boundaries. --- net/http/parser.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/http/parser.lua b/net/http/parser.lua index d896dff4..056d4b60 100644 --- a/net/http/parser.lua +++ b/net/http/parser.lua @@ -132,7 +132,7 @@ function httpstream.new(success_cb, error_cb, parser_type, options_cb) state, chunk_size = nil, nil; buf = buf:gsub("^.-\r\n\r\n", ""); -- This ensure extensions and trailers are stripped success_cb(packet); - elseif #buf - chunk_start + 2 >= chunk_size then -- we have a chunk + elseif #buf - chunk_start - 2 >= chunk_size then -- we have a chunk packet.body = packet.body..buf:sub(chunk_start, chunk_start + (chunk_size-1)); buf = buf:sub(chunk_start + chunk_size + 2); chunk_size, chunk_start = nil, nil; -- cgit v1.2.3 From 5b8554f2b2736f9019f0e6321348ce144e75ff5a Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 18 Nov 2014 17:40:37 +0000 Subject: net.http.parser: Fix whitespace/indentation --- net/http/parser.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/net/http/parser.lua b/net/http/parser.lua index 056d4b60..6d7187da 100644 --- a/net/http/parser.lua +++ b/net/http/parser.lua @@ -140,11 +140,11 @@ function httpstream.new(success_cb, error_cb, parser_type, options_cb) break; end elseif len and #buf >= len then - if packet.code == 101 then - packet.body, buf = buf, "" - else - packet.body, buf = buf:sub(1, len), buf:sub(len + 1); - end + if packet.code == 101 then + packet.body, buf = buf, ""; + else + packet.body, buf = buf:sub(1, len), buf:sub(len + 1); + end state = nil; success_cb(packet); else break; -- cgit v1.2.3 From 6b34924c408380c4378c1ddb6e9a79d494d0944c Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 6 Jan 2015 17:39:47 +0100 Subject: stanza_router: Fix routing of 'error' IQs with multiple childs (thanks Pawel) --- core/stanza_router.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/stanza_router.lua b/core/stanza_router.lua index bf5b11bc..a2c7b396 100644 --- a/core/stanza_router.lua +++ b/core/stanza_router.lua @@ -63,7 +63,7 @@ function core_process_stanza(origin, stanza) end if name == "iq" then if not stanza.attr.id then stanza.attr.id = ""; end -- COMPAT Jabiru doesn't send the id attribute on roster requests - if not iq_types[st_type] or (st_type ~= "result" and #stanza.tags ~= 1) then + if not iq_types[st_type] or ((st_type == "set" or st_type == "get") and (#stanza.tags ~= 1)) then origin.send(st.error_reply(stanza, "modify", "bad-request", "Invalid IQ type or incorrect number of children")); return; end -- cgit v1.2.3 From 18340e3643bcf827c5dbe3e1f3353cb5f3ed40ab Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 20 Feb 2015 15:51:05 +0000 Subject: configure, Makefile: Add --libdir option to ./configure, allowing you to override the $PREFIX/lib/ default. Fixes #470. --- Makefile | 8 ++++---- configure | 7 +++++++ tools/migration/Makefile | 6 +++--- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index a1de1b6d..0b704e5a 100644 --- a/Makefile +++ b/Makefile @@ -3,14 +3,14 @@ include config.unix BIN = $(DESTDIR)$(PREFIX)/bin CONFIG = $(DESTDIR)$(SYSCONFDIR) -MODULES = $(DESTDIR)$(PREFIX)/lib/prosody/modules -SOURCE = $(DESTDIR)$(PREFIX)/lib/prosody +MODULES = $(DESTDIR)$(LIBDIR)/prosody/modules +SOURCE = $(DESTDIR)$(LIBDIR)/prosody DATA = $(DESTDIR)$(DATADIR) MAN = $(DESTDIR)$(PREFIX)/share/man -INSTALLEDSOURCE = $(PREFIX)/lib/prosody +INSTALLEDSOURCE = $(LIBDIR)/prosody INSTALLEDCONFIG = $(SYSCONFDIR) -INSTALLEDMODULES = $(PREFIX)/lib/prosody/modules +INSTALLEDMODULES = $(LIBDIR)/prosody/modules INSTALLEDDATA = $(DATADIR) .PHONY: all clean install diff --git a/configure b/configure index 822b046e..c27517fc 100755 --- a/configure +++ b/configure @@ -4,6 +4,7 @@ PREFIX=/usr/local SYSCONFDIR="$PREFIX/etc/prosody" +LIBDIR="$PREFIX/lib" DATADIR="$PREFIX/var/lib/prosody" LUA_SUFFIX="" LUA_DIR="/usr" @@ -36,6 +37,8 @@ Configure Prosody prior to building. Default is $PREFIX --sysconfdir=DIR Location where the config file should be installed. Default is \$PREFIX/etc/prosody +--libdir=DIR Location where the server files should be stored. + Default is \$PREFIX/lib --datadir=DIR Location where the server data should be stored. Default is \$PREFIX/var/lib/prosody --lua-suffix=SUFFIX Versioning suffix to use in Lua filenames. @@ -134,6 +137,9 @@ do then LUA_INCDIR="/usr/local/include"; fi ;; + --libdir=*) + LIBDIR="$value" + ;; --datadir=*) DATADIR="$value" DATADIR_SET=yes @@ -338,6 +344,7 @@ cat < config.unix PREFIX=$PREFIX SYSCONFDIR=$SYSCONFDIR +LIBDIR=$LIBDIR DATADIR=$DATADIR LUA_SUFFIX=$LUA_SUFFIX LUA_DIR=$LUA_DIR diff --git a/tools/migration/Makefile b/tools/migration/Makefile index ae402bd2..713831d2 100644 --- a/tools/migration/Makefile +++ b/tools/migration/Makefile @@ -3,13 +3,13 @@ include ../../config.unix BIN = $(DESTDIR)$(PREFIX)/bin CONFIG = $(DESTDIR)$(SYSCONFDIR) -SOURCE = $(DESTDIR)$(PREFIX)/lib/prosody +SOURCE = $(DESTDIR)$(LIBDIR)/prosody DATA = $(DESTDIR)$(DATADIR) MAN = $(DESTDIR)$(PREFIX)/share/man -INSTALLEDSOURCE = $(PREFIX)/lib/prosody +INSTALLEDSOURCE = $(LIBDIR)/prosody INSTALLEDCONFIG = $(SYSCONFDIR) -INSTALLEDMODULES = $(PREFIX)/lib/prosody/modules +INSTALLEDMODULES = $(LIBDIR)/prosody/modules INSTALLEDDATA = $(DATADIR) SOURCE_FILES = migrator/*.lua -- cgit v1.2.3 From ac4f7d8132a95026da6949ee5a0a1a660e2acbd7 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 20 Feb 2015 19:00:01 +0100 Subject: util.datamanager: Check that the global 'prosody' exists before using it (fixes nil indexing in use outside of prosody) --- util/datamanager.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/datamanager.lua b/util/datamanager.lua index 4a4d62b3..b82349f1 100644 --- a/util/datamanager.lua +++ b/util/datamanager.lua @@ -163,7 +163,7 @@ local function atomic_store(filename, data) return nil, msg; end -if prosody.platform ~= "posix" then +if prosody and prosody.platform ~= "posix" then -- os.rename does not overwrite existing files on Windows -- TODO We could use Transactional NTFS on Vista and above function atomic_store(filename, data) -- cgit v1.2.3 From 5bab5b528ace033b7bedd900e18ee05d3c51c59a Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 20 Feb 2015 22:53:12 +0000 Subject: mod_admin_telnet: Require util.pposix (fixes #471) --- plugins/mod_admin_telnet.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index e4b5a045..437ded01 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -313,6 +313,7 @@ local function human(kb) end function def_env.server:memory() + local pposix = require("util.pposix"); if not pposix.meminfo then return true, "Lua is using "..collectgarbage("count"); end -- cgit v1.2.3 From 45e9902b574edb798723299f05e77c54dffee68a Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 24 Feb 2015 15:19:20 +0000 Subject: configure: Fix for commit cd0088c73daf - update LIBDIR if --prefix is set and --libdir isn't (thanks Medics) --- configure | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/configure b/configure index c27517fc..199f5fcf 100755 --- a/configure +++ b/configure @@ -139,6 +139,7 @@ do ;; --libdir=*) LIBDIR="$value" + LIBDIR_SET=yes ;; --datadir=*) DATADIR="$value" @@ -213,6 +214,11 @@ then fi fi +if [ "$PREFIX_SET" = "yes" -a ! "$LIBDIR_SET" = "yes" ] +then + LIBDIR=$PREFIX/lib +fi + find_program() { path="$PATH" item="`echo "$path" | sed 's/\([^:]*\):.*/\1/'`" -- cgit v1.2.3 From 74895d955a0c123e6efbf386905b1a6b7971c518 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 14 Mar 2015 22:39:03 +0000 Subject: net.http.server: Log event name when firing a request event --- net/http/server.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/http/server.lua b/net/http/server.lua index 7937f87c..f091595c 100644 --- a/net/http/server.lua +++ b/net/http/server.lua @@ -217,7 +217,7 @@ function handle_request(conn, request, finish_cb) local event = request.method.." "..host..request.path:match("[^?]*"); local payload = { request = request, response = response }; - --log("debug", "Firing event: %s", event); + log("debug", "Firing event: %s", event); local result = events.fire_event(event, payload); if result ~= nil then if result ~= true then -- cgit v1.2.3 From 553a587fe3768241f5c8641a09c989e63423d4d5 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 14 Mar 2015 22:39:23 +0000 Subject: mod_http: Log event name when adding a HTTP app's hooks --- plugins/mod_http.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index 86689aff..610ae0ae 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -102,6 +102,7 @@ function module.add_host(module) end if not app_handlers[event_name] then app_handlers[event_name] = handler; + module:log("debug", "Adding app '%s' to handle %s", app_name, event_name); module:hook_object_event(server, event_name, handler); else module:log("warn", "App %s added handler twice for '%s', ignoring", app_name, event_name); -- cgit v1.2.3 From db215b810de415c15795356166061822748808e4 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 23 Mar 2015 14:26:34 +0100 Subject: util.encodings: Perform validation of UTF-8 strings before passing to libidn (Based on code from the utf8 library in Lua 5.3) --- util-src/encodings.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 67 insertions(+), 3 deletions(-) diff --git a/util-src/encodings.c b/util-src/encodings.c index b9b6160a..898add1a 100644 --- a/util-src/encodings.c +++ b/util-src/encodings.c @@ -1,6 +1,7 @@ /* Prosody IM -- Copyright (C) 2008-2010 Matthew Wild -- Copyright (C) 2008-2010 Waqas Hussain +-- Copyright (C) 1994-2015 Lua.org, PUC-Rio. -- -- This project is MIT/X11 licensed. Please see the -- COPYING file in the source package for more information. @@ -116,6 +117,65 @@ static const luaL_Reg Reg_base64[] = { NULL, NULL } }; +/******************* UTF-8 ********************/ + +/* + * Adapted from Lua 5.3 + * Needed because libidn does not validate that input is valid UTF-8 + */ + +#define MAXUNICODE 0x10FFFF + +/* + * Decode one UTF-8 sequence, returning NULL if byte sequence is invalid. + */ +static const char *utf8_decode (const char *o, int *val) { + static unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF}; + const unsigned char *s = (const unsigned char *)o; + unsigned int c = s[0]; + unsigned int res = 0; /* final result */ + if (c < 0x80) /* ascii? */ + res = c; + else { + int count = 0; /* to count number of continuation bytes */ + while (c & 0x40) { /* still have continuation bytes? */ + int cc = s[++count]; /* read next byte */ + if ((cc & 0xC0) != 0x80) /* not a continuation byte? */ + return NULL; /* invalid byte sequence */ + res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */ + c <<= 1; /* to test next bit */ + } + res |= ((c & 0x7F) << (count * 5)); /* add first byte */ + if (count > 3 || res > MAXUNICODE || res <= limits[count] || (0xd800 <= res && res <= 0xdfff) ) + return NULL; /* invalid byte sequence */ + s += count; /* skip continuation bytes read */ + } + if (val) *val = res; + return (const char *)s + 1; /* +1 to include first byte */ +} + +/* + * Check that a string is valid UTF-8 + * Returns NULL if not + */ +const char* check_utf8 (lua_State *L, int idx, size_t *l) { + size_t pos, len; + const char *s = luaL_checklstring(L, 1, &len); + pos = 0; + while (pos <= len) { + const char *s1 = utf8_decode(s + pos, NULL); + if (s1 == NULL) { /* conversion error? */ + return NULL; + } + pos = s1 - s; + } + if(l != NULL) { + *l = len; + } + return s; +} + + /***************** STRINGPREP *****************/ #ifdef USE_STRINGPREP_ICU @@ -212,8 +272,8 @@ static int stringprep_prep(lua_State *L, const Stringprep_profile *profile) lua_pushnil(L); return 1; } - s = lua_tolstring(L, 1, &len); - if (len >= 1024) { + s = check_utf8(L, 1, &len); + if (s == NULL || len >= 1024 || len != strlen(s)) { lua_pushnil(L); return 1; /* TODO return error message */ } @@ -320,7 +380,11 @@ static int Lidna_to_unicode(lua_State *L) /** idna.to_unicode(s) */ static int Lidna_to_ascii(lua_State *L) /** idna.to_ascii(s) */ { size_t len; - const char *s = luaL_checklstring(L, 1, &len); + const char *s = check_utf8(L, 1, &len); + if (s == NULL || len != strlen(s)) { + lua_pushnil(L); + return 1; /* TODO return error message */ + } char* output = NULL; int ret = idna_to_ascii_8z(s, &output, IDNA_USE_STD3_ASCII_RULES); if (ret == IDNA_SUCCESS) { -- cgit v1.2.3 From f36dbc165c7792941ebed5d0b4f7fd513bb0a4de Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 23 Mar 2015 14:27:30 +0100 Subject: util.encodings: Expose UTF-8 validation and length checking functions --- util-src/encodings.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/util-src/encodings.c b/util-src/encodings.c index 898add1a..91826ca4 100644 --- a/util-src/encodings.c +++ b/util-src/encodings.c @@ -175,6 +175,29 @@ const char* check_utf8 (lua_State *L, int idx, size_t *l) { return s; } +static int Lutf8_valid(lua_State *L) { + lua_pushboolean(L, check_utf8(L, 1, NULL) != NULL); + return 1; +} + +static int Lutf8_length(lua_State *L) { + size_t len; + if(!check_utf8(L, 1, &len)) { + lua_pushnil(L); + lua_pushliteral(L, "invalid utf8"); + return 2; + } + lua_pushinteger(L, len); + return 1; +} + +static const luaL_Reg Reg_utf8[] = +{ + { "valid", Lutf8_valid }, + { "length", Lutf8_length }, + { NULL, NULL } +}; + /***************** STRINGPREP *****************/ #ifdef USE_STRINGPREP_ICU @@ -452,6 +475,11 @@ LUALIB_API int luaopen_util_encodings(lua_State *L) luaL_register(L, NULL, Reg_idna); lua_settable(L,-3); + lua_pushliteral(L, "utf8"); + lua_newtable(L); + luaL_register(L, NULL, Reg_utf8); + lua_settable(L, -3); + lua_pushliteral(L, "version"); /** version */ lua_pushliteral(L, "-3.14"); lua_settable(L,-3); -- cgit v1.2.3 From f70ce48360c597c96aadce377625db25e1627ea8 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Mon, 23 Mar 2015 17:16:54 +0000 Subject: tests: Add UTF-8 validity tests --- tests/test.lua | 1 + tests/test_utf8.lua | 19 ++++++++++++++++++ tests/utf8_sequences.txt | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 tests/test_utf8.lua create mode 100644 tests/utf8_sequences.txt diff --git a/tests/test.lua b/tests/test.lua index db727ce1..de1e40fd 100644 --- a/tests/test.lua +++ b/tests/test.lua @@ -22,6 +22,7 @@ function run_all_tests() dotest "util.sasl.scram" dosingletest("test_sasl.lua", "latin1toutf8"); + dosingletest("test_utf8.lua", "valid"); end local verbosity = tonumber(arg[1]) or 2; diff --git a/tests/test_utf8.lua b/tests/test_utf8.lua new file mode 100644 index 00000000..481eff5d --- /dev/null +++ b/tests/test_utf8.lua @@ -0,0 +1,19 @@ +package.cpath = "../?.so" +package.path = "../?.lua"; + +function valid() + local encodings = require "util.encodings"; + local utf8 = assert(encodings.utf8, "no encodings.utf8 module"); + + for line in io.lines("utf8_sequences.txt") do + local data = line:match(":%s*([^#]+)"):gsub("%s+", ""):gsub("..", function (c) return string.char(tonumber(c, 16)); end) + local expect = line:match("(%S+):"); + if expect ~= "pass" and expect ~= "fail" then + error("unknown expectation: "..line:match("^[^:]+")); + end + local prefix, style = " ", valid_style; + local valid = utf8.valid(data); + assert_equal(valid, utf8.valid(data.." ")); + assert_equal(valid, expect == "pass", line); + end +end diff --git a/tests/utf8_sequences.txt b/tests/utf8_sequences.txt new file mode 100644 index 00000000..408b8f08 --- /dev/null +++ b/tests/utf8_sequences.txt @@ -0,0 +1,52 @@ +Should pass: 41 42 43 # Simple ASCII - abc +Should pass: 41 42 c3 87 # "ABÇ" +Should pass: 41 42 e1 b8 88 # "ABḈ" +Should pass: 41 42 f0 9d 9c 8d # "AB𝜍" +Should pass: F4 8F BF BF # Last valid sequence (U+10FFFF) +Should fail: F4 90 80 80 # First invalid sequence (U+110000) +Should fail: 80 81 82 83 # Invalid sequence (invalid start byte) +Should fail: C2 C3 # Invalid sequence (invalid continuation byte) +Should fail: C0 43 # Overlong sequence +Should fail: F5 80 80 80 # U+140000 (out of range) +Should fail: ED A0 80 # U+D800 (forbidden by RFC 3629) +Should fail: ED BF BF # U+DFFF (forbidden by RFC 3629) +Should pass: ED 9F BF # U+D7FF (U+D800 minus 1: allowed) +Should pass: EE 80 80 # U+E000 (U+D7FF plus 1: allowed) +Should fail: C0 # Invalid start byte +Should fail: C1 # Invalid start byte +Should fail: C2 # Incomplete sequence +Should fail: F8 88 80 80 80 # 6-byte sequence +Should pass: 7F # Last valid 1-byte sequence (U+00007F) +Should pass: DF BF # Last valid 2-byte sequence (U+0007FF) +Should pass: EF BF BF # Last valid 3-byte sequence (U+00FFFF) +Should pass: 00 # First valid 1-byte sequence (U+000000) +Should pass: C2 80 # First valid 2-byte sequence (U+000080) +Should pass: E0 A0 80 # First valid 3-byte sequence (U+000800) +Should pass: F0 90 80 80 # First valid 4-byte sequence (U+000800) +Should fail: F8 88 80 80 80 # First 5-byte sequence - invalid per RFC 3629 +Should fail: FC 84 80 80 80 80 # First 6-byte sequence - invalid per RFC 3629 +Should pass: EF BF BD # U+00FFFD (replacement character) +Should fail: 80 # First continuation byte +Should fail: BF # Last continuation byte +Should fail: 80 BF # 2 continuation bytes +Should fail: 80 BF 80 # 3 continuation bytes +Should fail: 80 BF 80 BF # 4 continuation bytes +Should fail: 80 BF 80 BF 80 # 5 continuation bytes +Should fail: 80 BF 80 BF 80 BF # 6 continuation bytes +Should fail: 80 BF 80 BF 80 BF 80 # 7 continuation bytes +Should fail: FE # Impossible byte +Should fail: FF # Impossible byte +Should fail: FE FE FF FF # Impossible bytes +Should fail: C0 AF # Overlong "/" +Should fail: E0 80 AF # Overlong "/" +Should fail: F0 80 80 AF # Overlong "/" +Should fail: F8 80 80 80 AF # Overlong "/" +Should fail: FC 80 80 80 80 AF # Overlong "/" +Should fail: C0 80 AF # Overlong "/" (invalid) +Should fail: C1 BF # Overlong +Should fail: E0 9F BF # Overlong +Should fail: F0 8F BF BF # Overlong +Should fail: F8 87 BF BF BF # Overlong +Should fail: FC 83 BF BF BF BF # Overlong +Should pass: EF BF BE # U+FFFE (invalid unicode, valid UTF-8) +Should fail: EF BF BF # U+FFFF (invalid unicode, valid UTF-8) -- cgit v1.2.3 From ebea1abf086e20124449a30e354018914ecd2267 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Mon, 23 Mar 2015 17:23:11 +0000 Subject: utf8_sequences.txt: Oops --- tests/utf8_sequences.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/utf8_sequences.txt b/tests/utf8_sequences.txt index 408b8f08..1b967b2e 100644 --- a/tests/utf8_sequences.txt +++ b/tests/utf8_sequences.txt @@ -49,4 +49,4 @@ Should fail: F0 8F BF BF # Overlong Should fail: F8 87 BF BF BF # Overlong Should fail: FC 83 BF BF BF BF # Overlong Should pass: EF BF BE # U+FFFE (invalid unicode, valid UTF-8) -Should fail: EF BF BF # U+FFFF (invalid unicode, valid UTF-8) +Should pass: EF BF BF # U+FFFF (invalid unicode, valid UTF-8) -- cgit v1.2.3 From a676aa5e4504b14062e5afa091d815911a779dd6 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 23 Mar 2015 18:40:12 +0100 Subject: Backout 7726b627c3ea --- plugins/mod_http.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index 610ae0ae..86689aff 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -102,7 +102,6 @@ function module.add_host(module) end if not app_handlers[event_name] then app_handlers[event_name] = handler; - module:log("debug", "Adding app '%s' to handle %s", app_name, event_name); module:hook_object_event(server, event_name, handler); else module:log("warn", "App %s added handler twice for '%s', ignoring", app_name, event_name); -- cgit v1.2.3 From 72f36b47688449a69477bece51919426b95d17bf Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 23 Mar 2015 18:44:12 +0100 Subject: mod_http: Log a debug message when adding new http apps and warn if no http ports are enabled --- plugins/mod_http.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index 86689aff..9ff3af74 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -110,6 +110,12 @@ function module.add_host(module) module:log("error", "Invalid route in %s, %q. See http://prosody.im/doc/developers/http#routes", app_name, key); end end + local services = portmanager.get_active_services(); + if services:get("https") or services:get("http") then + module:log("debug", "Serving '%s' at %s", app_name, module:http_url(app_name, app_path)); + else + module:log("warn", "Not listening on any ports, '%s' will be unreachable", app_name); + end end local function http_app_removed(event) -- cgit v1.2.3 From e9801c774da19f9d0722685973352a524f00f1af Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 23 Mar 2015 18:45:02 +0100 Subject: mod_http: Return a static string from module:http_url() when no ports are enabled and log a warning --- plugins/mod_http.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index 9ff3af74..9b574bc8 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -69,6 +69,8 @@ function moduleapi.http_url(module, app_name, default_path) return url_build(url); end end + module:log("warn", "No http ports enabled, can't generate an external URL"); + return "http://disabled.invalid/"; end function module.add_host(module) -- cgit v1.2.3 From 0f2c3101251622dc45e22ecc2d450a95cf562c93 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 24 Mar 2015 15:57:46 +0000 Subject: sessionmanager: Return 'not-allowed' error instead of the non-existent 'already-bound' error when client tries to bind a resource twice on the same stream (thanks Flow) fixes issue #484. --- core/sessionmanager.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/sessionmanager.lua b/core/sessionmanager.lua index 98ead07f..4b014d18 100644 --- a/core/sessionmanager.lua +++ b/core/sessionmanager.lua @@ -113,7 +113,7 @@ end -- returns nil, err_type, err, err_message on failure function bind_resource(session, resource) if not session.username then return nil, "auth", "not-authorized", "Cannot bind resource before authentication"; end - if session.resource then return nil, "cancel", "already-bound", "Cannot bind multiple resources on a single connection"; end + if session.resource then return nil, "cancel", "not-allowed", "Cannot bind multiple resources on a single connection"; end -- We don't support binding multiple resources resource = resourceprep(resource); -- cgit v1.2.3 From 85221efee2aa267f19ece529b56b2f94ce4df243 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 24 Mar 2015 16:03:37 +0000 Subject: mod_s2s: to/from attributes are required on s2s stream headers. Set them to '' when not available. Fixes #468. --- plugins/mod_s2s/mod_s2s.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua index d8846a6f..f5297efe 100644 --- a/plugins/mod_s2s/mod_s2s.lua +++ b/plugins/mod_s2s/mod_s2s.lua @@ -512,7 +512,7 @@ function session_open_stream(session, from, to) version = session.version and (session.version > 0 and "1.0" or nil), ["xml:lang"] = 'en', id = session.streamid, - from = from, to = to, + from = from or "", to = to or "", } if not from or (hosts[from] and hosts[from].modules.dialback) then attr["xmlns:db"] = 'jabber:server:dialback'; -- cgit v1.2.3 -- cgit v1.2.3 From 1626e0537bc7823f6f3521e9cdfcce4f2ffc017a Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 24 Apr 2015 14:14:01 +0200 Subject: net.dns, mod_s2s: Add chasing of CNAMEs to net.dns and remove it from mod_s2s --- net/dns.lua | 11 ++++++++--- plugins/mod_s2s/s2sout.lib.lua | 12 ------------ 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/net/dns.lua b/net/dns.lua index 13417cee..28cb4419 100644 --- a/net/dns.lua +++ b/net/dns.lua @@ -694,15 +694,20 @@ local function comp_mx(a, b) -- - - - - - - - - - - - - - - - - - - comp_mx end -function resolver:peek (qname, qtype, qclass) -- - - - - - - - - - - - peek +function resolver:peek (qname, qtype, qclass, n) -- - - - - - - - - - - - peek qname, qtype, qclass = standardize(qname, qtype, qclass); local rrs = get(self.cache, qclass, qtype, qname); - if not rrs then return nil; end + if not rrs then + if n then if n <= 0 then return end else n = 3 end + rrs = get(self.cache, qclass, "CNAME", qname); + if not (rrs and rrs[1]) then return end + return self:peek(rrs[1].cname, qtype, qclass, n - 1); + end if prune(rrs, socket.gettime()) and qtype == '*' or not next(rrs) then set(self.cache, qclass, qtype, qname, nil); return nil; end - if self.unsorted[rrs] then table.sort (rrs, comp_mx); end + if self.unsorted[rrs] then table.sort (rrs, comp_mx); self.unsorted[rrs] = nil; end return rrs; end diff --git a/plugins/mod_s2s/s2sout.lib.lua b/plugins/mod_s2s/s2sout.lib.lua index b24faf85..67b8fd0f 100644 --- a/plugins/mod_s2s/s2sout.lib.lua +++ b/plugins/mod_s2s/s2sout.lib.lua @@ -169,18 +169,6 @@ function s2sout.try_connect(host_session, connect_host, connect_port, err) handle4 = adns.lookup(function (reply, err) handle4 = nil; - -- COMPAT: This is a compromise for all you CNAME-(ab)users :) - if not (reply and reply[#reply] and reply[#reply].a) then - local count = max_dns_depth; - reply = dns.peek(connect_host, "CNAME", "IN"); - while count > 0 and reply and reply[#reply] and not reply[#reply].a and reply[#reply].cname do - log("debug", "Looking up %s (DNS depth is %d)", tostring(reply[#reply].cname), count); - reply = dns.peek(reply[#reply].cname, "A", "IN") or dns.peek(reply[#reply].cname, "CNAME", "IN"); - count = count - 1; - end - end - -- end of CNAME resolving - if reply and reply[#reply] and reply[#reply].a then for _, ip in ipairs(reply) do log("debug", "DNS reply for %s gives us %s", connect_host, ip.a); -- cgit v1.2.3 From 265eb868376d7cd9b836da7ed843855f9551d59c Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 3 Apr 2015 12:10:30 +0200 Subject: util.datamanager: Fix traceback due to %s in log message --- util/datamanager.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/datamanager.lua b/util/datamanager.lua index b82349f1..b4138638 100644 --- a/util/datamanager.lua +++ b/util/datamanager.lua @@ -293,7 +293,7 @@ function users(host, store, typ) local mode, err = lfs.attributes(store_dir, "mode"); if not mode then - return function() log("debug", err or (store_dir .. " does not exist")) end + return function() log("debug", "%s", err or (store_dir .. " does not exist")) end end local next, state = lfs.dir(store_dir); return function(state) -- cgit v1.2.3 From 8b049732c734a2146fa78b6982b5fe1eed84b974 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 26 Apr 2015 19:50:24 +0200 Subject: net.dns: Make sure argument to math.randomseed does not overflow a 32 bit *signed* int (blame Lua). Closes #439 --- net/dns.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/dns.lua b/net/dns.lua index 28cb4419..763ee9ec 100644 --- a/net/dns.lua +++ b/net/dns.lua @@ -225,7 +225,7 @@ end function dns.random(...) -- - - - - - - - - - - - - - - - - - - dns.random - math.randomseed(math.floor(10000*socket.gettime()) % 0x100000000); + math.randomseed(math.floor(10000*socket.gettime()) % 0x80000000); dns.random = math.random; return dns.random(...); end -- cgit v1.2.3 From c22dec3f1c5a28dcb7d71ecf16b48b545d1e5423 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 13 May 2015 21:43:05 +0200 Subject: mod_s2s/s2sout: Remove now unused config option dns_max_depth --- plugins/mod_s2s/s2sout.lib.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/mod_s2s/s2sout.lib.lua b/plugins/mod_s2s/s2sout.lib.lua index 67b8fd0f..dc122af7 100644 --- a/plugins/mod_s2s/s2sout.lib.lua +++ b/plugins/mod_s2s/s2sout.lib.lua @@ -29,7 +29,6 @@ local has_ipv4, has_ipv6; local dns_timeout = module:get_option_number("dns_timeout", 15); dns.settimeout(dns_timeout); -local max_dns_depth = module:get_option_number("dns_max_depth", 3); local s2sout = {}; -- cgit v1.2.3 From 8389ecb795287b1d0c053c76bb0e65badd48c2a6 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 13 May 2015 21:44:13 +0200 Subject: util.datamanager: Fix traceback from trying to purge when storage is empty or otherwise unaccessible (fixes #496) --- util/datamanager.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/util/datamanager.lua b/util/datamanager.lua index b4138638..a107d95c 100644 --- a/util/datamanager.lua +++ b/util/datamanager.lua @@ -348,8 +348,12 @@ end function purge(username, host) local host_dir = format("%s/%s/", data_path, encode(host)); + local ok, iter, state, var = pcall(lfs.dir, host_dir); + if not ok then + return ok, iter; + end local errs = {}; - for file in lfs.dir(host_dir) do + for file in iter, state, var do if lfs.attributes(host_dir..file, "mode") == "directory" then local store = decode(file); local ok, err = do_remove(getpath(username, host, store)); -- cgit v1.2.3 From 3391b867193c3c1c772d4b1b0a5a0940948b63f1 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 13 May 2015 21:47:39 +0200 Subject: mod_s2s/s2sout: Use the local address assigned to UDP sockets instead of util.net to enumerate possible source addresses --- plugins/mod_s2s/s2sout.lib.lua | 46 ++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/plugins/mod_s2s/s2sout.lib.lua b/plugins/mod_s2s/s2sout.lib.lua index dc122af7..5728f67b 100644 --- a/plugins/mod_s2s/s2sout.lib.lua +++ b/plugins/mod_s2s/s2sout.lib.lua @@ -18,13 +18,31 @@ local socket = require "socket"; local adns = require "net.adns"; local dns = require "net.dns"; local t_insert, t_sort, ipairs = table.insert, table.sort, ipairs; -local local_addresses = require "util.net".local_addresses; local s2s_destroy_session = require "core.s2smanager".destroy_session; local log = module._log; -local sources = {}; +local anysource = { IPv4 = "0.0.0.0", IPv6 = "::" }; +local function get_sources(addrs) + local sources = {}; + for _, IP in ipairs(addrs) do + local sock; + if IP.proto == "IPv4" then + sock = socket.udp(); + elseif IP.proto == "IPv6" then + sock = socket.udp6(); + end + sock:setpeername(IP.addr, 9); + local localaddr = sock:getsockname() or anysource[IP.proto]; + sock:close(); + if not sources[localaddr] then + sources[localaddr] = true; + t_insert(sources, new_ip(localaddr, IP.proto)); + end + end + return sources; +end local has_ipv4, has_ipv6; local dns_timeout = module:get_option_number("dns_timeout", 15); @@ -177,7 +195,7 @@ function s2sout.try_connect(host_session, connect_host, connect_port, err) if have_other_result then if #IPs > 0 then - rfc6724_dest(host_session.ip_hosts, sources); + rfc6724_dest(host_session.ip_hosts, get_sources(host_session.ip_hosts)); for i = 1, #IPs do IPs[i] = {ip = IPs[i], port = connect_port}; end @@ -213,7 +231,7 @@ function s2sout.try_connect(host_session, connect_host, connect_port, err) if have_other_result then if #IPs > 0 then - rfc6724_dest(host_session.ip_hosts, sources); + rfc6724_dest(host_session.ip_hosts, get_sources(host_session.ip_hosts)); for i = 1, #IPs do IPs[i] = {ip = IPs[i], port = connect_port}; end @@ -315,28 +333,12 @@ module:hook_global("service-added", function (event) return; end for source, _ in pairs(s2s_sources) do - if source == "*" or source == "0.0.0.0" then - for _, addr in ipairs(local_addresses("ipv4", true)) do - sources[#sources + 1] = new_ip(addr, "IPv4"); - end - elseif source == "::" then - for _, addr in ipairs(local_addresses("ipv6", true)) do - sources[#sources + 1] = new_ip(addr, "IPv6"); - end - else - sources[#sources + 1] = new_ip(source, (source:find(":") and "IPv6") or "IPv4"); - end - end - for i = 1,#sources do - if sources[i].proto == "IPv6" then + if source:find(":") then has_ipv6 = true; - elseif sources[i].proto == "IPv4" then + else has_ipv4 = true; end end - if not (has_ipv4 or has_ipv6) then - module:log("warn", "No local IPv4 or IPv6 addresses detected, outgoing connections may fail"); - end end); return s2sout; -- cgit v1.2.3 From cb22f32f7f348216f5da45a95e4c87f77a7c1b4d Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 13 May 2015 21:55:08 +0200 Subject: mod_s2s: Don't cache session.sends2s (or do it later), prevents sending data after session was closed --- plugins/mod_s2s/mod_s2s.lua | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua index f5297efe..1408fd5e 100644 --- a/plugins/mod_s2s/mod_s2s.lua +++ b/plugins/mod_s2s/mod_s2s.lua @@ -147,7 +147,7 @@ end -- Stream is authorised, and ready for normal stanzas function mark_connected(session) - local sendq, send = session.sendq, session.sends2s; + local sendq = session.sendq; local from, to = session.from_host, session.to_host; @@ -170,6 +170,7 @@ function mark_connected(session) if session.direction == "outgoing" then if sendq then session.log("debug", "sending %d queued stanzas across new outgoing connection to %s", #sendq, session.to_host); + local send = session.sends2s; for i, data in ipairs(sendq) do send(data[1]); sendq[i] = nil; @@ -269,8 +270,6 @@ local stream_callbacks = { default_ns = "jabber:server", handlestanza = core_pr local xmlns_xmpp_streams = "urn:ietf:params:xml:ns:xmpp-streams"; function stream_callbacks.streamopened(session, attr) - local send = session.sends2s; - session.version = tonumber(attr.version) or 0; -- TODO: Rename session.secure to session.encrypted @@ -360,7 +359,7 @@ function stream_callbacks.streamopened(session, attr) end log("debug", "Sending stream features: %s", tostring(features)); - send(features); + session.sends2s(features); end session.notopen = nil; elseif session.direction == "outgoing" then -- cgit v1.2.3 From ddc9a47072862ea93645917a23755935b7607690 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 13 May 2015 21:56:22 +0200 Subject: mod_s2s: Mark stream as opened directly after opening stream, prevents session.close opening it again --- plugins/mod_s2s/mod_s2s.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua index 1408fd5e..ee539a2a 100644 --- a/plugins/mod_s2s/mod_s2s.lua +++ b/plugins/mod_s2s/mod_s2s.lua @@ -349,6 +349,7 @@ function stream_callbacks.streamopened(session, attr) end session:open_stream(session.to_host, session.from_host) + session.notopen = nil; if session.version >= 1.0 then local features = st.stanza("stream:features"); @@ -361,7 +362,6 @@ function stream_callbacks.streamopened(session, attr) log("debug", "Sending stream features: %s", tostring(features)); session.sends2s(features); end - session.notopen = nil; elseif session.direction == "outgoing" then session.notopen = nil; if not attr.id then -- cgit v1.2.3 From fd5adf33d06749b124b2674f295826c2960d9995 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 14 May 2015 00:22:13 +0200 Subject: s2smanager: Make sure destroyed sessions have a sends2s method --- core/s2smanager.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/core/s2smanager.lua b/core/s2smanager.lua index 06d3f2c9..fb5c4299 100644 --- a/core/s2smanager.lua +++ b/core/s2smanager.lua @@ -64,6 +64,7 @@ function retire_session(session, reason) function session.send(data) log("debug", "Discarding data sent to resting session: %s", tostring(data)); end function session.data(data) log("debug", "Discarding data received from resting session: %s", tostring(data)); end + session.sends2s = session.send; return setmetatable(session, resting_session); end -- cgit v1.2.3 From e1fae3ac4a25cc0919874fd01a42bc4f1f58e52d Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 16 Jun 2015 15:13:47 +0200 Subject: MUC: Remove half of monkeypatch that was supposed to make admins always be room owners, fixes #458 --- plugins/muc/mod_muc.lua | 5 ----- 1 file changed, 5 deletions(-) diff --git a/plugins/muc/mod_muc.lua b/plugins/muc/mod_muc.lua index 6e86ab73..c932b0a4 100644 --- a/plugins/muc/mod_muc.lua +++ b/plugins/muc/mod_muc.lua @@ -44,16 +44,11 @@ local function is_admin(jid) return um_is_admin(jid, module.host); end -local _set_affiliation = muc_new_room.room_mt.set_affiliation; local _get_affiliation = muc_new_room.room_mt.get_affiliation; function muclib.room_mt:get_affiliation(jid) if is_admin(jid) then return "owner"; end return _get_affiliation(self, jid); end -function muclib.room_mt:set_affiliation(actor, jid, affiliation, callback, reason) - if is_admin(jid) then return nil, "modify", "not-acceptable"; end - return _set_affiliation(self, actor, jid, affiliation, callback, reason); -end local function room_route_stanza(room, stanza) module:send(stanza); end local function room_save(room, forced) -- cgit v1.2.3 From ff6a3b3aded5efed20e3fb42cd76a3c59460874d Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 25 Jun 2015 17:54:19 +0200 Subject: Backed out changeset bea3862b6bde in favor of a different approach --- plugins/muc/mod_muc.lua | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/muc/mod_muc.lua b/plugins/muc/mod_muc.lua index c932b0a4..6e86ab73 100644 --- a/plugins/muc/mod_muc.lua +++ b/plugins/muc/mod_muc.lua @@ -44,11 +44,16 @@ local function is_admin(jid) return um_is_admin(jid, module.host); end +local _set_affiliation = muc_new_room.room_mt.set_affiliation; local _get_affiliation = muc_new_room.room_mt.get_affiliation; function muclib.room_mt:get_affiliation(jid) if is_admin(jid) then return "owner"; end return _get_affiliation(self, jid); end +function muclib.room_mt:set_affiliation(actor, jid, affiliation, callback, reason) + if is_admin(jid) then return nil, "modify", "not-acceptable"; end + return _set_affiliation(self, actor, jid, affiliation, callback, reason); +end local function room_route_stanza(room, stanza) module:send(stanza); end local function room_save(room, forced) -- cgit v1.2.3 From d3ff677ce8be30231ee116bdde22633fe89c3bd3 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 25 Jun 2015 17:58:24 +0200 Subject: MUC: Prevent admins from being given affiliatons other than owner --- plugins/muc/mod_muc.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/muc/mod_muc.lua b/plugins/muc/mod_muc.lua index 6e86ab73..acc2da0d 100644 --- a/plugins/muc/mod_muc.lua +++ b/plugins/muc/mod_muc.lua @@ -51,7 +51,7 @@ function muclib.room_mt:get_affiliation(jid) return _get_affiliation(self, jid); end function muclib.room_mt:set_affiliation(actor, jid, affiliation, callback, reason) - if is_admin(jid) then return nil, "modify", "not-acceptable"; end + if affiliation ~= "owner" and is_admin(jid) then return nil, "modify", "not-acceptable"; end return _set_affiliation(self, actor, jid, affiliation, callback, reason); end -- cgit v1.2.3 From 051811cd38e05d63bd9c043e466ac744c0c58feb Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 10 Aug 2015 22:13:02 +0200 Subject: mod_component: Fire an event on successful component authentication (For Goffi) --- plugins/mod_component.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/mod_component.lua b/plugins/mod_component.lua index 7bc0f5b7..11abab79 100644 --- a/plugins/mod_component.lua +++ b/plugins/mod_component.lua @@ -85,6 +85,7 @@ function module.add_host(module) session.type = "component"; module:log("info", "External component successfully authenticated"); session.send(st.stanza("handshake")); + module:fire_event("component-authenticated", { session = session }); return true; end -- cgit v1.2.3 From 6ddc9bd28b18e77a4117eb7e272481f1e97795ea Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 20 Aug 2015 09:14:15 +0200 Subject: ejabberd2prosody: Support password stored as SCRAM hashes --- tools/ejabberd2prosody.lua | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tools/ejabberd2prosody.lua b/tools/ejabberd2prosody.lua index af87594e..069b5161 100755 --- a/tools/ejabberd2prosody.lua +++ b/tools/ejabberd2prosody.lua @@ -72,7 +72,22 @@ function vcard(node, host, stanza) print("["..(err or "success").."] vCard: "..node.."@"..host); end function password(node, host, password) - local ret, err = dm.store(node, host, "accounts", {password = password}); + local data = {}; + if type(password) == "string" then + data.password = password; + elseif type(password) == "table" and password[1] == "scram" then + local unb64 = require"mime".unb64; + local function hex(s) + return s:gsub(".", function (c) + return ("%02x"):format(c:byte()); + end); + end + data.stored_key = hex(unb64(password[2])); + data.server_key = hex(unb64(password[3])); + data.salt = unb64(password[4]); + data.iteration_count = password[5]; + end + local ret, err = dm.store(node, host, "accounts", data); print("["..(err or "success").."] accounts: "..node.."@"..host); end function roster(node, host, jid, item) -- cgit v1.2.3 From 3d5ee7cea93b3eb651a2bf52b0c0de8e2ed6ad37 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Mon, 25 May 2015 23:16:11 +0100 Subject: net.dns: Unconditionally cache records found in answers --- net/dns.lua | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/net/dns.lua b/net/dns.lua index 763ee9ec..7ec13c81 100644 --- a/net/dns.lua +++ b/net/dns.lua @@ -855,9 +855,7 @@ function resolver:receive(rset) -- - - - - - - - - - - - - - - - - receive --self.print(response); for j,rr in pairs(response.answer) do - if rr.name:sub(-#response.question[1].name, -1) == response.question[1].name then - self:remember(rr, response.question[1].type) - end + self:remember(rr, response.question[1].type) end -- retire the query -- cgit v1.2.3 From f2f24a13e074898e269169cbeb599cf3cb598dcc Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 4 Sep 2015 11:26:51 +0100 Subject: mod_pep: Document data structures, so I don't have to spend time remembering every time I work on this module --- plugins/mod_pep.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/mod_pep.lua b/plugins/mod_pep.lua index bdb742e3..7b4c5ddc 100644 --- a/plugins/mod_pep.lua +++ b/plugins/mod_pep.lua @@ -17,9 +17,13 @@ local type = type; local calculate_hash = require "util.caps".calculate_hash; local core_post_stanza = prosody.core_post_stanza; +-- Used as canonical 'empty table' local NULL = {}; +-- data[user_bare_jid][node] = item_stanza local data = {}; +--- recipients[user_bare_jid][contact_full_jid][subscribed_node] = true local recipients = {}; +-- hash_map[hash][subscribed_nodes] = true local hash_map = {}; module.save = function() -- cgit v1.2.3 From 853f18a9cbbc25b6830f7edabdf135f3165c60ec Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 25 Sep 2015 16:48:25 +0100 Subject: mod_pep: Don't store contacts' subscriptions to a user's nodes when that user is offline --- plugins/mod_pep.lua | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/plugins/mod_pep.lua b/plugins/mod_pep.lua index 7b4c5ddc..22790869 100644 --- a/plugins/mod_pep.lua +++ b/plugins/mod_pep.lua @@ -16,6 +16,7 @@ local next = next; local type = type; local calculate_hash = require "util.caps".calculate_hash; local core_post_stanza = prosody.core_post_stanza; +local bare_sessions = prosody.bare_sessions; -- Used as canonical 'empty table' local NULL = {}; @@ -122,6 +123,9 @@ module:hook("presence/bare", function(event) local t = stanza.attr.type; local self = not stanza.attr.to; + -- Only cache subscriptions if user is online + if not bare_sessions[user] then return; end + if not t then -- available presence if self or subscription_presence(user, stanza.attr.from) then local recipient = stanza.attr.from; @@ -283,3 +287,11 @@ module:hook("account-disco-items", function(event) end end end); + +module:hook("resource-unbind", function (event) + local user_bare_jid = event.session.username.."@"..event.session.host; + if not bare_sessions[user_bare_jid] then -- User went offline + -- We don't need this info cached anymore, clear it. + recipients[user_bare_jid] = nil; + end +end); -- cgit v1.2.3 From 971ea4fc066fce783b3c26655e39bc2a72ac0992 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 18 Sep 2015 16:14:43 +0200 Subject: xep227toprosody: Pass parser to callbacks (needed since addition of stanza size limits) --- tools/xep227toprosody.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/xep227toprosody.lua b/tools/xep227toprosody.lua index 0862b0c1..81c9863b 100755 --- a/tools/xep227toprosody.lua +++ b/tools/xep227toprosody.lua @@ -202,7 +202,7 @@ function lxp_handlers.StartElement(parser, elementname, attributes) --count = count + 1; if curr_host ~= "" then -- forward to xmlhandlers - user_handlers:StartElement(elementname, attributes); + user_handlers.StartElement(parser, elementname, attributes); elseif (curr_ns == xmlns_xep227) and (name == "host") then curr_host = attributes["jid"]; -- start of host element print("Begin parsing host "..curr_host); @@ -226,7 +226,7 @@ function lxp_handlers.EndElement(parser, elementname) curr_host = "" -- end of host element else -- forward to xmlhandlers - user_handlers:EndElement(elementname); + user_handlers.EndElement(parser, elementname); end elseif (curr_ns ~= xmlns_xep227) or (name ~= "server-data") then io.stderr:write("Unhandled XML element: ", name, "\n"); @@ -237,7 +237,7 @@ end function lxp_handlers.CharacterData(parser, string) if curr_host ~= "" then -- forward to xmlhandlers - user_handlers:CharacterData(string); + user_handlers.CharacterData(parser, string); end end -- cgit v1.2.3 From c6d0454e0f3c4b47ae37903727d8bec8926cacae Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 26 Sep 2015 19:34:58 +0200 Subject: mod_http_files: Strip trailing directory separator regardless of directionality of the slash (fixes #545) --- plugins/mod_http_files.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_http_files.lua b/plugins/mod_http_files.lua index 3a9368b9..9d81f540 100644 --- a/plugins/mod_http_files.lua +++ b/plugins/mod_http_files.lua @@ -62,7 +62,7 @@ function serve(opts) local request, response = event.request, event.response; local orig_path = request.path; local full_path = base_path .. (path and "/"..path or ""); - local attr = stat((full_path:gsub('%'..path_sep..'+$',''))); + local attr = stat(full_path:match("^.*[^\\/]")); -- Strip trailing path separator because Windows if not attr then return 404; end -- cgit v1.2.3 From 8caf3cf4120e361e27c4eff6c9ad93a59589425c Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 26 Sep 2015 19:35:56 +0200 Subject: mod_http_files: Translate forward slashes to local directory separators --- plugins/mod_http_files.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_http_files.lua b/plugins/mod_http_files.lua index 9d81f540..9839fed9 100644 --- a/plugins/mod_http_files.lua +++ b/plugins/mod_http_files.lua @@ -61,7 +61,7 @@ function serve(opts) local function serve_file(event, path) local request, response = event.request, event.response; local orig_path = request.path; - local full_path = base_path .. (path and "/"..path or ""); + local full_path = base_path .. (path and "/"..path or ""):gsub("/", path_sep); local attr = stat(full_path:match("^.*[^\\/]")); -- Strip trailing path separator because Windows if not attr then return 404; -- cgit v1.2.3 From b46b9dc13faac301799a394536a217034cb1aad0 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 11 Oct 2015 18:49:14 +0200 Subject: util.openssl: Separate extension sections into one for self-signed certs and one for requests --- util/openssl.lua | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/util/openssl.lua b/util/openssl.lua index ef3fba96..39fe99d6 100644 --- a/util/openssl.lua +++ b/util/openssl.lua @@ -18,8 +18,8 @@ function config.new() return setmetatable({ req = { distinguished_name = "distinguished_name", - req_extensions = "v3_extensions", - x509_extensions = "v3_extensions", + req_extensions = "certrequest", + x509_extensions = "selfsigned", prompt = "no", }, distinguished_name = { @@ -31,12 +31,16 @@ function config.new() commonName = "example.com", emailAddress = "xmpp@example.com", }, - v3_extensions = { + certrequest = { basicConstraints = "CA:FALSE", keyUsage = "digitalSignature,keyEncipherment", extendedKeyUsage = "serverAuth,clientAuth", subjectAltName = "@subject_alternative_name", }, + selfsigned = { + basicConstraints = "CA:TRUE", + subjectAltName = "@subject_alternative_name", + }, subject_alternative_name = { DNS = {}, otherName = {}, -- cgit v1.2.3 From 7b773fd7d8c3f0af2fe174a757539f17a987dd46 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 14 Oct 2015 20:55:26 +0200 Subject: Makefile: Use more specific globbing for core directory in Makefile (Thanks Robert Scheck) (fixes #532) --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0b704e5a..46a8f49d 100644 --- a/Makefile +++ b/Makefile @@ -29,7 +29,7 @@ install: prosody.install prosodyctl.install prosody.cfg.lua.install util/encodin install -d $(SOURCE)/core $(SOURCE)/net $(SOURCE)/util install -m755 ./prosody.install $(BIN)/prosody install -m755 ./prosodyctl.install $(BIN)/prosodyctl - install -m644 core/* $(SOURCE)/core + install -m644 core/*.lua $(SOURCE)/core install -m644 net/*.lua $(SOURCE)/net install -d $(SOURCE)/net/http install -m644 net/http/*.lua $(SOURCE)/net/http -- cgit v1.2.3 From 804359f606cb5b1fa133f895c287fc776816d154 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 9 Nov 2015 14:16:39 +0100 Subject: cert/openssl.cnf: Split CSR and self-signed extensions into separate sections (see d2d7ad2563f9) --- certs/openssl.cnf | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/certs/openssl.cnf b/certs/openssl.cnf index 091409c4..ee17b1cf 100644 --- a/certs/openssl.cnf +++ b/certs/openssl.cnf @@ -13,8 +13,8 @@ SRVName = 1.3.6.1.5.5.7.8.7 default_bits = 4096 default_keyfile = example.com.key distinguished_name = distinguished_name -req_extensions = v3_extensions -x509_extensions = v3_extensions +req_extensions = certrequest +x509_extensions = selfsigned # ask about the DN? prompt = no @@ -28,16 +28,22 @@ organizationName = Your Organisation organizationalUnitName = XMPP Department emailAddress = xmpp@example.com -[ v3_extensions ] +[ certrequest ] # for certificate requests (req_extensions) -# and self-signed certificates (x509_extensions) basicConstraints = CA:FALSE keyUsage = digitalSignature,keyEncipherment extendedKeyUsage = serverAuth,clientAuth subjectAltName = @subject_alternative_name +[ selfsigned ] + +# and self-signed certificates (x509_extensions) + +basicConstraints = CA:TRUE +subjectAltName = @subject_alternative_name + [ subject_alternative_name ] # See http://tools.ietf.org/html/rfc6120#section-13.7.1.2 for more info. -- cgit v1.2.3 From 6c57db9f1cf00482f5a788c33ca485b241cc5989 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 17 Nov 2015 17:01:25 +0000 Subject: muc.lib: Fix pattern so that it doesn't match hashes containing null bytes, causing dropped stanzas (thanks Jitsi folk!) --- plugins/muc/muc.lib.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/muc/muc.lib.lua b/plugins/muc/muc.lib.lua index 8028f5ae..d42fb2eb 100644 --- a/plugins/muc/muc.lib.lua +++ b/plugins/muc/muc.lib.lua @@ -361,7 +361,7 @@ local function construct_stanza_id(room, stanza) end local function deconstruct_stanza_id(room, stanza) local from_jid_possiblybare, to_nick = stanza.attr.from, stanza.attr.to; - local from_jid, id, to_jid_hash = (base64.decode(stanza.attr.id) or ""):match("^(.+)%z(.*)%z(.+)$"); + local from_jid, id, to_jid_hash = (base64.decode(stanza.attr.id) or ""):match("^(%Z+)%z(%Z*)%z(.+)$"); local from_nick = room._jid_nick[from_jid]; if not(from_nick) then return; end -- cgit v1.2.3 From 3b12de1122fe19b2d189fc4b8d2bf7bf505d3bcd Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 8 Dec 2015 23:20:37 +0100 Subject: util.uuid: Remove unused import --- util/uuid.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/util/uuid.lua b/util/uuid.lua index 796c8ee4..bb70d000 100644 --- a/util/uuid.lua +++ b/util/uuid.lua @@ -7,7 +7,6 @@ -- -local m_random = math.random; local tostring = tostring; local os_time = os.time; local os_clock = os.clock; -- cgit v1.2.3 From 6ca624cf7f05603cd1330241634e3f15842b6a65 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Wed, 16 Dec 2015 16:41:48 +0000 Subject: MUC: Fix incorrect nesting of status codes when room config changes (fixes #579) --- plugins/muc/muc.lib.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/muc/muc.lib.lua b/plugins/muc/muc.lib.lua index d42fb2eb..5879c256 100644 --- a/plugins/muc/muc.lib.lua +++ b/plugins/muc/muc.lib.lua @@ -736,7 +736,7 @@ function room_mt:process_form(origin, stanza) if dirty or whois_changed then local msg = st.message({type='groupchat', from=self.jid}) - :tag('x', {xmlns='http://jabber.org/protocol/muc#user'}):up() + :tag('x', {xmlns='http://jabber.org/protocol/muc#user'}); if dirty then msg.tags[1]:tag('status', {code = '104'}):up(); @@ -745,6 +745,7 @@ function room_mt:process_form(origin, stanza) local code = (whois == 'moderators') and "173" or "172"; msg.tags[1]:tag('status', {code = code}):up(); end + msg:up(); self:broadcast_message(msg, false) end -- cgit v1.2.3 From 03af283f59f517c47b613bff1e49691df3960e1b Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 22 Dec 2015 14:15:09 +0000 Subject: mod_admin_telnet: Backport 06696882d972 from 0.10 (this command greatly helps with debugging HTTP issues) --- plugins/mod_admin_telnet.lua | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index 437ded01..86403606 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -1081,6 +1081,33 @@ function def_env.dns:cache() return true, "Cache:\n"..tostring(dns.cache()) end +def_env.http = {}; + +function def_env.http:list() + local print = self.session.print; + + for host in pairs(prosody.hosts) do + local http_apps = modulemanager.get_items("http-provider", host); + if #http_apps > 0 then + local http_host = module:context(host):get_option("http_host"); + print("HTTP endpoints on "..host..(http_host and (" (using "..http_host.."):") or ":")); + for _, provider in ipairs(http_apps) do + local url = module:context(host):http_url(provider.name); + print("", url); + end + print(""); + end + end + + local default_host = module:get_option("http_default_host"); + if not default_host then + print("HTTP requests to unknown hosts will return 404 Not Found"); + else + print("HTTP requests to unknown hosts will be handled by "..default_host); + end + return true; +end + ------------- function printbanner(session) -- cgit v1.2.3 From f6cd82f1b5e93e88bfdb9ff2aecfa5e4a7efa8e3 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 23 Dec 2015 12:07:03 +0100 Subject: certs/Makefile: Run key generation with a stricter umask (fixes a race condition) --- certs/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/certs/Makefile b/certs/Makefile index f3854c5f..c709ff91 100644 --- a/certs/Makefile +++ b/certs/Makefile @@ -26,5 +26,5 @@ keysize=2048 sed 's,example\.com,$*,g' openssl.cnf > $@ %.key: - openssl genrsa $(keysize) > $@ - @chmod 400 $@ + umask 0077 && openssl genrsa -out $@ $(keysize) + @chmod 400 $@ -c -- cgit v1.2.3 From 0c0039271c9ac279c29318ca0337c8a9874462c6 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Wed, 6 Jan 2016 00:24:06 +0000 Subject: tests/test.lua: Fix fake module() function to prevent _M from being _G (test.lua's environment), which caused modules to break the sandbox when they set _M.* --- tests/test.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/test.lua b/tests/test.lua index de1e40fd..bb11ab26 100644 --- a/tests/test.lua +++ b/tests/test.lua @@ -137,7 +137,10 @@ function dotest(unitname) end local oldmodule, old_M = _fakeG.module, _fakeG._M; - _fakeG.module = function () _M = _G end + _fakeG.module = function () + setmetatable(unit, nil); + unit._M = unit; + end setfenv(chunk, unit); local success, err = pcall(chunk); _fakeG.module, _fakeG._M = oldmodule, old_M; -- cgit v1.2.3 From 88d3ddd8e0bbe3b8d6d7ee83661c844cef993560 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 17 May 2013 14:52:52 +0100 Subject: util.ip: Automatically determine protocol of IP address if none specified. Return error if invalid. [Backported from 0.10] --- util/ip.lua | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/util/ip.lua b/util/ip.lua index 856bf034..226432cc 100644 --- a/util/ip.lua +++ b/util/ip.lua @@ -12,7 +12,15 @@ local ip_mt = { __index = function (ip, key) return (ip_methods[key])(ip); end, local hex2bits = { ["0"] = "0000", ["1"] = "0001", ["2"] = "0010", ["3"] = "0011", ["4"] = "0100", ["5"] = "0101", ["6"] = "0110", ["7"] = "0111", ["8"] = "1000", ["9"] = "1001", ["A"] = "1010", ["B"] = "1011", ["C"] = "1100", ["D"] = "1101", ["E"] = "1110", ["F"] = "1111" }; local function new_ip(ipStr, proto) - if proto ~= "IPv4" and proto ~= "IPv6" then + if not proto then + local sep = ipStr:match("^%x+(.)"); + if sep == ":" then proto = "IPv6" + elseif sep == "." then proto = "IPv4" + end + if not proto then + return nil, "invalid address"; + end + elseif proto ~= "IPv4" and proto ~= "IPv6" then return nil, "invalid protocol"; end if proto == "IPv6" and ipStr:find('.', 1, true) then -- cgit v1.2.3 From 3df6c733c2b617b956abb70a6c1ad06e39caf057 Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Sat, 18 Jan 2014 17:24:10 -0500 Subject: =?UTF-8?q?tools/ejabberd2prosody:=20=E2=80=9Cxmlelement=E2=80=9D?= =?UTF-8?q?=20can=20be=20=E2=80=9Cxmlel=E2=80=9D=20in=20newer=20ejabberd?= =?UTF-8?q?=20(thanks=20cr).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tools/ejabberd2prosody.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/ejabberd2prosody.lua b/tools/ejabberd2prosody.lua index a8bfad0e..8312ebd1 100755 --- a/tools/ejabberd2prosody.lua +++ b/tools/ejabberd2prosody.lua @@ -30,7 +30,7 @@ dm.set_data_path("data"); function build_stanza(tuple, stanza) assert(type(tuple) == "table", "XML node is of unexpected type: "..type(tuple)); - if tuple[1] == "xmlelement" then + if tuple[1] == "xmlelement" or tuple[1] == "xmlel" then assert(type(tuple[2]) == "string", "element name has type: "..type(tuple[2])); assert(type(tuple[3]) == "table", "element attribute array has type: "..type(tuple[3])); assert(type(tuple[4]) == "table", "element children array has type: "..type(tuple[4])); -- cgit v1.2.3 From 323251c5b6f02b9381c809b7e96f57c8e53c5dda Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Sat, 18 Jan 2014 17:26:02 -0500 Subject: tools/ejabberd2prosody: Disable generating a config, as the format it generates is completely out of date. --- tools/ejabberd2prosody.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/ejabberd2prosody.lua b/tools/ejabberd2prosody.lua index 8312ebd1..bc916fb8 100755 --- a/tools/ejabberd2prosody.lua +++ b/tools/ejabberd2prosody.lua @@ -247,7 +247,7 @@ local filters = { end muc_room(tuple[2][1], tuple[2][2], properties); end; - config = function(tuple) + --[=[config = function(tuple) if tuple[2] == "hosts" then local output = io.output(); io.output("prosody.cfg.lua"); io.write("-- Configuration imported from ejabberd --\n"); @@ -275,7 +275,7 @@ local filters = { io.output(output); print("prosody.cfg.lua created"); end - end; + end;]=] }; local arg = ...; -- cgit v1.2.3 From 90e627327f0d5f37cc8d901018480f16b54b1dd8 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 27 Jan 2014 16:47:54 +0100 Subject: tools/ejabberd2prosody: Handle new room member format. --- tools/ejabberd2prosody.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/ejabberd2prosody.lua b/tools/ejabberd2prosody.lua index bc916fb8..be1504b2 100755 --- a/tools/ejabberd2prosody.lua +++ b/tools/ejabberd2prosody.lua @@ -163,7 +163,7 @@ end function muc_room(node, host, properties) local store = { jid = node.."@"..host, _data = {}, _affiliations = {} }; for _,aff in ipairs(properties.affiliations) do - store._affiliations[_table_to_jid(aff[1])] = aff[2]; + store._affiliations[_table_to_jid(aff[1])] = aff[2][1] or aff[2]; end store._data.subject = properties.subject; if properties.subject_author then -- cgit v1.2.3 From 9a9dd21edf4c6ad318fcd31c0fe740cf1b7dba81 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 6 Feb 2014 10:44:21 +0100 Subject: mod_motd: Strip indentation only, leave multiple newlines --- plugins/mod_motd.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_motd.lua b/plugins/mod_motd.lua index ed78294b..3dd6b816 100644 --- a/plugins/mod_motd.lua +++ b/plugins/mod_motd.lua @@ -15,7 +15,7 @@ if not motd_text then return; end local st = require "util.stanza"; -motd_text = motd_text:gsub("^%s*(.-)%s*$", "%1"):gsub("\n%s+", "\n"); -- Strip indentation from the config +motd_text = motd_text:gsub("^%s*(.-)%s*$", "%1"):gsub("\n[ \t]+", "\n"); -- Strip indentation from the config module:hook("presence/bare", function (event) local session, stanza = event.origin, event.stanza; -- cgit v1.2.3 From 9aaaa36f583b548763e55d18b56468d1d96e2e96 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 9 Feb 2014 15:13:46 +0100 Subject: mod_s2s: Log a warning if no local addresses are found, as this breaks s2sout --- plugins/mod_s2s/s2sout.lib.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/mod_s2s/s2sout.lib.lua b/plugins/mod_s2s/s2sout.lib.lua index 575d37ac..b24faf85 100644 --- a/plugins/mod_s2s/s2sout.lib.lua +++ b/plugins/mod_s2s/s2sout.lib.lua @@ -347,6 +347,9 @@ module:hook_global("service-added", function (event) has_ipv4 = true; end end + if not (has_ipv4 or has_ipv6) then + module:log("warn", "No local IPv4 or IPv6 addresses detected, outgoing connections may fail"); + end end); return s2sout; -- cgit v1.2.3 From 2b26bfbd44ebee1aa4f82078186f4aca495db328 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 9 Feb 2014 15:17:01 +0100 Subject: mod_admin_telnet: Prep jids for user:create() etc. --- plugins/mod_admin_telnet.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index 131689c5..2572e982 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -23,8 +23,7 @@ local console_listener = { default_port = 5582; default_mode = "*a"; interface = local iterators = require "util.iterators"; local keys, values = iterators.keys, iterators.values; -local jid = require "util.jid"; -local jid_bare, jid_split = jid.bare, jid.split; +local jid_bare, jid_split = import("util.jid", "bare", "prepped_split"); local set, array = require "util.set", require "util.array"; local cert_verify_identity = require "util.x509".verify_identity; local envload = require "util.envload".envload; -- cgit v1.2.3 From 0079772bde37cd77976aaa96678fdebfadfab7bc Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Mon, 17 Feb 2014 16:00:41 -0500 Subject: mod_auth_anonymous: Fixed a traceback in listing all users (issue#396). --- plugins/mod_auth_anonymous.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_auth_anonymous.lua b/plugins/mod_auth_anonymous.lua index c877d532..8de46f8c 100644 --- a/plugins/mod_auth_anonymous.lua +++ b/plugins/mod_auth_anonymous.lua @@ -43,7 +43,7 @@ function provider.get_sasl_handler() end function provider.users() - return next, hosts[host].sessions, nil; + return next, hosts[module.host].sessions, nil; end -- datamanager callback to disable writes -- cgit v1.2.3 From 37e76b46ed6b3b5fd9d6c3166e1d157e94d6d2d6 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 18 Feb 2014 20:03:12 +0100 Subject: mod_compression: Only allow compression on authenticated streams --- plugins/mod_compression.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/mod_compression.lua b/plugins/mod_compression.lua index 92856099..531ea8ea 100644 --- a/plugins/mod_compression.lua +++ b/plugins/mod_compression.lua @@ -126,7 +126,7 @@ 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"); -- cgit v1.2.3 From 9374daa820a5966105a7f94df055bf67e2bb0826 Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Tue, 18 Feb 2014 16:03:13 -0500 Subject: tools/ejabberd2prosody: Don't throw an error if XML CDATA is null ([] in Erlang, instead of a string or being missing). --- tools/ejabberd2prosody.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/ejabberd2prosody.lua b/tools/ejabberd2prosody.lua index be1504b2..d0675a65 100755 --- a/tools/ejabberd2prosody.lua +++ b/tools/ejabberd2prosody.lua @@ -44,8 +44,10 @@ function build_stanza(tuple, stanza) for _, a in ipairs(tuple[4]) do build_stanza(a, stanza); end if up then stanza:up(); else return stanza end elseif tuple[1] == "xmlcdata" then - assert(type(tuple[2]) == "string", "XML CDATA has unexpected type: "..type(tuple[2])); - stanza:text(tuple[2]); + if type(tuple[2]) ~= "table" then + assert(type(tuple[2]) == "string", "XML CDATA has unexpected type: "..type(tuple[2])); + stanza:text(tuple[2]); + end -- else it's [], i.e., the null value, used for the empty string else error("unknown element type: "..serialize(tuple)); end -- cgit v1.2.3 From 22491bb8547729758721d297218ea70dc36700e2 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 20 Feb 2014 19:08:55 +0100 Subject: mod_http: Use hostname from the correct context (thanks gryffus) --- plugins/mod_http.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index 0689634e..afcec069 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -42,7 +42,7 @@ local function get_base_path(host_module, app_name, default_app_path) return (normalize_path(host_module:get_option("http_paths", {})[app_name] -- Host or module:get_option("http_paths", {})[app_name] -- Global or default_app_path)) -- Default - :gsub("%$(%w+)", { host = module.host }); + :gsub("%$(%w+)", { host = host_module.host }); end local ports_by_scheme = { http = 80, https = 443, }; -- cgit v1.2.3 From 5a0abb726de37023b32ed168a42947ab3c948a28 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 26 Feb 2014 22:19:58 +0100 Subject: mod_http: Fix http_external_url setting without an explicit port --- plugins/mod_http.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index afcec069..86689aff 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -51,6 +51,9 @@ local ports_by_scheme = { http = 80, https = 443, }; function moduleapi.http_url(module, app_name, default_path) app_name = app_name or (module.name:gsub("^http_", "")); local external_url = url_parse(module:get_option_string("http_external_url")) or {}; + if external_url.scheme and external_url.port == nil then + external_url.port = ports_by_scheme[external_url.scheme]; + end local services = portmanager.get_active_services(); local http_services = services:get("https") or services:get("http") or {}; for interface, ports in pairs(http_services) do -- cgit v1.2.3 From 86f0b39c91f119d739ebaeb274c3666269085374 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 9 Mar 2014 22:15:40 +0100 Subject: util.pluginloader: Always use path separator from package.config (thanks Junne) --- util/pluginloader.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/util/pluginloader.lua b/util/pluginloader.lua index c10fdf65..112c0d52 100644 --- a/util/pluginloader.lua +++ b/util/pluginloader.lua @@ -39,10 +39,10 @@ function load_resource(plugin, resource) resource = resource or "mod_"..plugin..".lua"; local names = { - "mod_"..plugin.."/"..plugin.."/"..resource; -- mod_hello/hello/mod_hello.lua - "mod_"..plugin.."/"..resource; -- mod_hello/mod_hello.lua - plugin.."/"..resource; -- hello/mod_hello.lua - resource; -- mod_hello.lua + "mod_"..plugin..dir_sep..plugin..dir_sep..resource; -- mod_hello/hello/mod_hello.lua + "mod_"..plugin..dir_sep..resource; -- mod_hello/mod_hello.lua + plugin..dir_sep..resource; -- hello/mod_hello.lua + resource; -- mod_hello.lua }; return load_file(names); -- cgit v1.2.3 From 2a985b71f1c4546849ab97cd4eeed3bb1155df9a Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 9 Mar 2014 22:16:44 +0100 Subject: mod_http_files: Strip path separator from end of paths, was broken on Windows (thanks Junne) --- plugins/mod_http_files.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/mod_http_files.lua b/plugins/mod_http_files.lua index 6ab295ac..3a9368b9 100644 --- a/plugins/mod_http_files.lua +++ b/plugins/mod_http_files.lua @@ -14,6 +14,7 @@ local os_date = os.date; local open = io.open; local stat = lfs.attributes; local build_path = require"socket.url".build_path; +local path_sep = package.config:sub(1,1); local base_path = module:get_option_string("http_files_dir", module:get_option_string("http_path")); local dir_indices = module:get_option("http_index_files", { "index.html", "index.htm" }); @@ -61,7 +62,7 @@ function serve(opts) local request, response = event.request, event.response; local orig_path = request.path; local full_path = base_path .. (path and "/"..path or ""); - local attr = stat(full_path); + local attr = stat((full_path:gsub('%'..path_sep..'+$',''))); if not attr then return 404; end -- cgit v1.2.3 From b039c34e042aee9a76182f4be80bc22beaaa1908 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 22 Mar 2014 12:41:38 +0100 Subject: mod_saslauth: Only do c2s SASL on normal VirtualHosts --- plugins/mod_saslauth.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_saslauth.lua b/plugins/mod_saslauth.lua index 201cc477..c5d3dc91 100644 --- a/plugins/mod_saslauth.lua +++ b/plugins/mod_saslauth.lua @@ -197,7 +197,7 @@ module:hook("stanza/urn:ietf:params:xml:ns:xmpp-sasl:auth", function(event) return s2s_external_auth(session, stanza) end - if session.type ~= "c2s_unauthed" then return; end + if session.type ~= "c2s_unauthed" or module:get_host_type() ~= "local" then return; end if session.sasl_handler and session.sasl_handler.selected then session.sasl_handler = nil; -- allow starting a new SASL negotiation before completing an old one -- cgit v1.2.3 From 263cc93108f37c9e842ce4e518ffffe6ad112a9d Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 22 Mar 2014 12:42:01 +0100 Subject: modulemanager: Load mod_saslauth on components by default --- core/modulemanager.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/modulemanager.lua b/core/modulemanager.lua index 535c227b..cddab647 100644 --- a/core/modulemanager.lua +++ b/core/modulemanager.lua @@ -30,7 +30,7 @@ pcall = function(f, ...) end local autoload_modules = {"presence", "message", "iq", "offline", "c2s", "s2s"}; -local component_inheritable_modules = {"tls", "dialback", "iq", "s2s"}; +local component_inheritable_modules = {"tls", "saslauth", "dialback", "iq", "s2s"}; -- We need this to let modules access the real global namespace local _G = _G; -- cgit v1.2.3 From 97492cf6027e3db711f9d13812cbdc93a7d2c540 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 22 Mar 2014 12:02:11 +0100 Subject: prosodyctl: Show real error if certificate config file can't be opened --- prosodyctl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/prosodyctl b/prosodyctl index 247b099a..d341a75b 100755 --- a/prosodyctl +++ b/prosodyctl @@ -684,7 +684,12 @@ function cert_commands.config(arg) conf.distinguished_name[k] = nv ~= "." and nv or nil; end end - local conf_file = io.open(conf_filename, "w"); + local conf_file, err = io.open(conf_filename, "w"); + if not conf_file then + show_warning("Could not open OpenSSL config file for writing"); + show_warning(err); + os.exit(1); + end conf_file:write(conf:serialize()); conf_file:close(); print(""); -- cgit v1.2.3 From 483406f11d91a9d8ea336cf2bdbdcb8a6bf0192d Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 27 Mar 2014 23:02:52 +0100 Subject: net.server_event: Rename conn:port() -> conn:clientport() to match server_select --- net/server_event.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/server_event.lua b/net/server_event.lua index e320b15c..c4aa7be4 100644 --- a/net/server_event.lua +++ b/net/server_event.lua @@ -352,7 +352,7 @@ do return self._server or self; end - function interface_mt:port() + function interface_mt:clientport() return self._port end -- cgit v1.2.3 From 0de23a8c5460e72c2cd85f8ec4d5f1d27906864d Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sun, 30 Mar 2014 08:44:55 +0100 Subject: portmanager: Make maximum read size configurable, and default to 4KB --- core/portmanager.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/portmanager.lua b/core/portmanager.lua index 7a247452..421d7fc6 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 -- cgit v1.2.3 From 84ada024955a83d4b13ae4cd10e9ac7c07db3fd3 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sun, 30 Mar 2014 09:14:39 +0100 Subject: util.xmppstream: Implement stanza size limiting, default limit 10MB --- util/xmppstream.lua | 86 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 80 insertions(+), 6 deletions(-) diff --git a/util/xmppstream.lua b/util/xmppstream.lua index 4909678c..9cdd6471 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 + #data --self:getcurrentbytecount(); + end t_insert(chardata, data); + elseif lxp_supports_bytecount then + cb_handleprogress(#data--[[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,8 +224,20 @@ 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); +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); local parse = parser.parse; @@ -179,10 +245,18 @@ function new(session, stream_callbacks) reset = function () parser = new_parser(handlers, ns_separator); 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; }; -- cgit v1.2.3 From d3afde34b6983380d992947f65b9085d17e16f18 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sun, 30 Mar 2014 09:15:28 +0100 Subject: util.dependencies: Log error when LuaExpat is not capable of enforcing stanza size limits --- util/dependencies.lua | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/util/dependencies.lua b/util/dependencies.lua index 53d2719d..e55b2405 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 -- cgit v1.2.3 From e980309be346e4229c624f54735b0f82fc7813b4 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sun, 30 Mar 2014 09:16:27 +0100 Subject: Makefile: Change sed regex to be compatible with FreeBSD's odd sed, and change / to | to allow paths to be used in RUNWITH (thanks Ben) --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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)';|; \ -- cgit v1.2.3 From 62274b71f30db40007a0d23cfcbd596765cc256b Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 31 Mar 2014 19:38:06 +0200 Subject: Backed out changeset a5b5bce71a11 --- net/server_event.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/server_event.lua b/net/server_event.lua index c4aa7be4..e320b15c 100644 --- a/net/server_event.lua +++ b/net/server_event.lua @@ -352,7 +352,7 @@ do return self._server or self; end - function interface_mt:clientport() + function interface_mt:port() return self._port end -- cgit v1.2.3 From a447bea855199d910e39a82d7e0eda24befbbc7a Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 1 Apr 2014 15:26:40 +0200 Subject: net.server_{select,event}: Add compat code for supporting the same client port API on connections --- net/server_event.lua | 1 + net/server_select.lua | 1 + 2 files changed, 2 insertions(+) diff --git a/net/server_event.lua b/net/server_event.lua index e320b15c..25799640 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 22887265..4bda3ef0 100644 --- a/net/server_select.lua +++ b/net/server_select.lua @@ -397,6 +397,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 -- cgit v1.2.3 From 882dc829654a71a93eafadd4e6e2ee1eabaa2c8c Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Tue, 1 Apr 2014 10:02:58 -0400 Subject: MUC: Fixed traceback when a JID not in a room requested a role change for an occupant. --- plugins/muc/muc.lib.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/muc/muc.lib.lua b/plugins/muc/muc.lib.lua index 0dbe81fa..8028f5ae 100644 --- a/plugins/muc/muc.lib.lua +++ b/plugins/muc/muc.lib.lua @@ -1060,7 +1060,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; -- cgit v1.2.3 -- cgit v1.2.3 From 25db6d9b02e590afc386930911be1e15fca36625 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Wed, 2 Apr 2014 11:05:41 +0100 Subject: util.xmppstream: Disable LuaExpat's buffering (if possible) --- util/xmppstream.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/util/xmppstream.lua b/util/xmppstream.lua index 9cdd6471..a25891a9 100644 --- a/util/xmppstream.lua +++ b/util/xmppstream.lua @@ -157,11 +157,11 @@ function new_sax_handlers(session, stream_callbacks, cb_handleprogress) function xml_handlers:CharacterData(data) if stanza then if lxp_supports_bytecount then - stanza_size = stanza_size + #data --self:getcurrentbytecount(); + stanza_size = stanza_size + self:getcurrentbytecount(); end t_insert(chardata, data); elseif lxp_supports_bytecount then - cb_handleprogress(#data--[[self:getcurrentbytecount()]]); + cb_handleprogress(self:getcurrentbytecount()); end end function xml_handlers:EndElement(tagname) @@ -238,7 +238,7 @@ function new(session, stream_callbacks, stanza_size_limit) end local handlers, meta = new_sax_handlers(session, stream_callbacks, handle_progress); - local parser = new_parser(handlers, ns_separator); + local parser = new_parser(handlers, ns_separator, false); local parse = parser.parse; return { -- cgit v1.2.3 From e40d04fd3debc04469d2bacf086f3520ec2adf0b Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Wed, 2 Apr 2014 14:31:19 +0100 Subject: util.xmppstream: Also disable CharacterData merging after stream restarts --- util/xmppstream.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/xmppstream.lua b/util/xmppstream.lua index a25891a9..73f5e314 100644 --- a/util/xmppstream.lua +++ b/util/xmppstream.lua @@ -243,7 +243,7 @@ function new(session, stream_callbacks, stanza_size_limit) 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(); -- cgit v1.2.3 From 47345e7cd9342108b8500b479c1e5c91361e1bf6 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 5 Apr 2014 15:05:40 +0100 Subject: mod_admin_telnet: muc:*: Fix nil index error when a room JID is passed with a non-existent host --- plugins/mod_admin_telnet.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index 2572e982..6f02f030 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -942,6 +942,9 @@ end function def_env.muc:create(room_jid) local room, host = check_muc(room_jid); + if not room_name then + return room_name, host; + end if not room then return nil, host end if hosts[host].modules.muc.rooms[room_jid] then return nil, "Room exists already" end return hosts[host].modules.muc.create_room(room_jid); @@ -949,6 +952,9 @@ end function def_env.muc:room(room_jid) local room_name, host = check_muc(room_jid); + if not room_name then + return room_name, host; + end local room_obj = hosts[host].modules.muc.rooms[room_jid]; if not room_obj then return nil, "No such room: "..room_jid; -- cgit v1.2.3 From 1d5276058b9fd26db59cf894d926ec3e6d3f1ec8 Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Wed, 9 Apr 2014 14:01:02 -0400 Subject: util.dependencies: Check for Lua 5.1. We don't currently support any other versions. LuaJIT identifies as 5.1. --- util/dependencies.lua | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/util/dependencies.lua b/util/dependencies.lua index e55b2405..4d50cf63 100644 --- a/util/dependencies.lua +++ b/util/dependencies.lua @@ -49,6 +49,14 @@ package.preload["util.ztact"] = function () end; function check_dependencies() + if _VERSION ~= "Lua 5.1" then + print "***********************************" + print("Unsupported Lua version: ".._VERSION); + print("Only Lua 5.1 is supported."); + print "***********************************" + return false; + end + local fatal; local lxp = softreq "lxp" -- cgit v1.2.3 From 28e75923a0740236d865c5bbf30cf19fee25ec28 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 9 Apr 2014 20:46:39 +0200 Subject: prosody: Check dependencies later in the startup sequence --- prosody | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/prosody b/prosody index ee2baca5..446dbfb7 100755 --- a/prosody +++ b/prosody @@ -49,9 +49,6 @@ _G.prosody = prosody; -- Check dependencies local dependencies = require "util.dependencies"; -if not dependencies.check_dependencies() then - os.exit(1); -end -- Load the config-parsing module config = require "core.configmanager" @@ -116,6 +113,12 @@ function read_config() end end +function check_dependencies() + if not dependencies.check_dependencies() then + os.exit(1); + end +end + function load_libraries() -- Load socket framework server = require "net.server" @@ -388,6 +391,7 @@ init_logging(); sanity_check(); sandbox_require(); set_function_metatable(); +check_dependencies(); load_libraries(); init_global_state(); read_version(); -- cgit v1.2.3 From 275c5c97a856a534aa6d5f13ad9a10f563361ce2 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 22 Apr 2014 23:14:53 +0200 Subject: tools/jabberd14sql2prosody: Fix package.path (thanks daurnimator) --- tools/jabberd14sql2prosody.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/jabberd14sql2prosody.lua b/tools/jabberd14sql2prosody.lua index d6a6753f..386bdcf0 100644 --- a/tools/jabberd14sql2prosody.lua +++ b/tools/jabberd14sql2prosody.lua @@ -428,7 +428,7 @@ end end -- import modules -package.path = package.path.."..\?.lua;"; +package.path = package.path..";../?.lua;"; local my_name = arg[0]; if my_name:match("[/\\]") then -- cgit v1.2.3 From 4d6b64f4e1f5eb1c1eccaa72cac817a168c88c40 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 22 Apr 2014 23:36:26 +0200 Subject: util.dataforms: Add support for XEP-0221: Data Forms Media Element --- util/dataforms.lua | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/util/dataforms.lua b/util/dataforms.lua index 52924841..01a8eef3 100644 --- a/util/dataforms.lua +++ b/util/dataforms.lua @@ -93,6 +93,15 @@ function form_t.form(layout, data, formtype) end end end + + local media = field.media; + if media then + form:tag("media", { xmlns = "urn:xmpp:media-element", height = media.height, width = media.width }); + for _, val in ipairs(media) do + form:tag("uri", { type = val.type }):text(val.uri):up() + end + form:up(); + end if field.required then form:tag("required"):up(); -- cgit v1.2.3 From 504be3c65f8eda71428ac4da8e97e6450d44b1d9 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 25 Apr 2014 00:36:01 +0200 Subject: util.pposix: Fix error reporting from posix_fallocate, it doesn't use errno (thanks pro) --- util-src/pposix.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/util-src/pposix.c b/util-src/pposix.c index 4fb1fb56..a8654995 100644 --- a/util-src/pposix.c +++ b/util-src/pposix.c @@ -664,6 +664,7 @@ int lc_meminfo(lua_State* L) #if _XOPEN_SOURCE >= 600 || _POSIX_C_SOURCE >= 200112L || defined(_GNU_SOURCE) int lc_fallocate(lua_State* L) { + int ret; off_t offset, len; FILE *f = *(FILE**) luaL_checkudata(L, 1, LUA_FILEHANDLE); if (f == NULL) @@ -691,7 +692,8 @@ int lc_fallocate(lua_State* L) #warning Note that posix_fallocate() will still be used on filesystems that dont support fallocate() #endif - if(posix_fallocate(fileno(f), offset, len) == 0) + ret = posix_fallocate(fileno(f), offset, len); + if(ret == 0) { lua_pushboolean(L, 1); return 1; @@ -699,7 +701,7 @@ int lc_fallocate(lua_State* L) else { lua_pushnil(L); - lua_pushstring(L, strerror(errno)); + lua_pushstring(L, strerror(ret)); /* posix_fallocate() can leave a bunch of NULs at the end, so we cut that * this assumes that offset == length of the file */ ftruncate(fileno(f), offset); -- cgit v1.2.3 From ecf04ddb9a9531e6e53de5bb60c6fd46faf64323 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 25 Apr 2014 02:41:55 +0200 Subject: util.pposix: Fix error reporting from really old Linux fallocate() that did not use errno for some reason (thanks pro) --- util-src/pposix.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/util-src/pposix.c b/util-src/pposix.c index a8654995..df814c28 100644 --- a/util-src/pposix.c +++ b/util-src/pposix.c @@ -674,11 +674,15 @@ int lc_fallocate(lua_State* L) len = luaL_checkinteger(L, 3); #if defined(__linux__) && defined(_GNU_SOURCE) - if(fallocate(fileno(f), FALLOC_FL_KEEP_SIZE, offset, len) == 0) + errno = 0; + ret = fallocate(fileno(f), FALLOC_FL_KEEP_SIZE, offset, len); + if(ret == 0) { lua_pushboolean(L, 1); return 1; } + /* Some old versions of Linux apparently use the return value instead of errno */ + if(errno == 0) errno = ret; if(errno != ENOSYS && errno != EOPNOTSUPP) { -- cgit v1.2.3 From 335280f51d99e8c62315b92907516b58a1bfb9d0 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 9 May 2014 19:59:49 +0200 Subject: configmanager: Delay importing LuaFileSystem until needed by an Include line --- core/configmanager.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/configmanager.lua b/core/configmanager.lua index d73bafa4..d175b54b 100644 --- a/core/configmanager.lua +++ b/core/configmanager.lua @@ -14,7 +14,7 @@ local format, math_max = string.format, math.max; local fire_event = prosody and prosody.events.fire_event or function () end; local envload = require"util.envload".envload; -local lfs = require "lfs"; +local deps = require"util.dependencies"; local path_sep = package.config:sub(1,1); module "configmanager" @@ -214,6 +214,10 @@ do function env.Include(file) if file:match("[*?]") then + local lfs = deps.softreq "lfs"; + if not lfs then + error(format("Error expanding wildcard pattern in Include %q - LuaFileSystem not available", file)); + end local path_pos, glob = file:match("()([^"..path_sep.."]+)$"); local path = file:sub(1, math_max(path_pos-2,0)); local config_path = config_file:gsub("[^"..path_sep.."]+$", ""); -- cgit v1.2.3 From d0e66328f95dc2635ddb1892b815c54254c3f05f Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 10 May 2014 02:12:51 +0200 Subject: mod_c2s: Fix traceback if c2s stream sent to component --- plugins/mod_c2s.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_c2s.lua b/plugins/mod_c2s.lua index b2a81592..5feb1f2c 100644 --- a/plugins/mod_c2s.lua +++ b/plugins/mod_c2s.lua @@ -50,7 +50,7 @@ function stream_callbacks.streamopened(session, attr) session.streamid = uuid_generate(); (session.log or session)("debug", "Client sent opening to %s", session.host); - if not hosts[session.host] then + if not hosts[session.host] or not hosts[session.host].users then -- We don't serve this host... session:close{ condition = "host-unknown", text = "This server does not serve "..tostring(session.host)}; return; -- cgit v1.2.3 From b04b5f7e0c7dff4f992e071b69b008d59916765c Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 17 Jun 2014 11:01:51 +0200 Subject: tools/ejabberd2prosody.lua: Fix JID building, node-less jids became @hostname in some cases --- tools/ejabberd2prosody.lua | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/tools/ejabberd2prosody.lua b/tools/ejabberd2prosody.lua index d0675a65..af87594e 100755 --- a/tools/ejabberd2prosody.lua +++ b/tools/ejabberd2prosody.lua @@ -56,6 +56,16 @@ function build_time(tuple) local Megaseconds,Seconds,Microseconds = unpack(tuple); return Megaseconds * 1000000 + Seconds; end +function build_jid(tuple, full) + local node, jid, resource = tuple[1], tuple[2], tuple[3] + if type(node) == "string" and node ~= "" then + jid = tuple[1] .. "@" .. jid; + end + if full and type(resource) == "string" and resource ~= "" then + jid = jid .. "/" .. resource; + end + return jid; +end function vcard(node, host, stanza) local ret, err = dm.store(node, host, "vcard", st.preserialize(stanza)); @@ -105,10 +115,7 @@ function privacy(node, host, default, lists) if _type == "jid" then if type(value) ~= "table" then print("[error] privacy: jid value is not valid: "..tostring(value)); break; end local _node, _host, _resource = value[1], value[2], value[3]; - if (type(_node) == "table") then _node = nil; end - if (type(_host) == "table") then _host = nil; end - if (type(_resource) == "table") then _resource = nil; end - value = (_node and _node.."@".._host or _host)..(_resource and "/".._resource or ""); + value = build_jid(value, true) elseif _type == "none" then _type = nil; value = nil; @@ -154,18 +161,10 @@ function privacy(node, host, default, lists) local ret, err = dm.store(node, host, "privacy", privacy); print("["..(err or "success").."] privacy: " ..node.."@"..host.." - "..count.." list(s)"); end -local function _table_to_jid(t) - if type(t[2]) == "string" then - local jid = t[2]; - if type(t[1]) == "string" then jid = t[1].."@"..jid; end - if type(t[3]) == "string" then jid = jid.."/"..t[3]; end - return jid; - end -end function muc_room(node, host, properties) local store = { jid = node.."@"..host, _data = {}, _affiliations = {} }; for _,aff in ipairs(properties.affiliations) do - store._affiliations[_table_to_jid(aff[1])] = aff[2][1] or aff[2]; + store._affiliations[build_jid(aff[1])] = aff[2][1] or aff[2]; end store._data.subject = properties.subject; if properties.subject_author then @@ -207,7 +206,7 @@ local filters = { end; roster = function(tuple) local node = tuple[3][1]; local host = tuple[3][2]; - local contact = (type(tuple[4][1]) == "table") and tuple[4][2] or tuple[4][1].."@"..tuple[4][2]; + local contact = build_jid(tuple[4]); local name = tuple[5]; local subscription = tuple[6]; local ask = tuple[7]; local groups = tuple[8]; if type(name) ~= type("") then name = nil; end -- cgit v1.2.3 From c79abd49278fad35330df2aeae2120d76239a43b Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 25 Jun 2014 15:33:49 +0200 Subject: net.adns: Add missing local declaration --- net/adns.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/net/adns.lua b/net/adns.lua index 158747c6..2a3fa8ad 100644 --- a/net/adns.lua +++ b/net/adns.lua @@ -52,6 +52,7 @@ function new_async_socket(sock, resolver) local peername = ""; local listener = {}; local handler = {}; + local err; function listener.onincoming(conn, data) if data then dns.feed(handler, data); -- cgit v1.2.3 From 6b1e013d0302f406b66b3ab9ce7dd83d42baf978 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 30 Jun 2014 12:45:53 +0200 Subject: net.dns: Fix duplicated cache insertions by limiting outstanding queries per name to one --- net/dns.lua | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/net/dns.lua b/net/dns.lua index cdd949a2..492bd1c5 100644 --- a/net/dns.lua +++ b/net/dns.lua @@ -715,6 +715,14 @@ end function resolver:query(qname, qtype, qclass) -- - - - - - - - - - -- query qname, qtype, qclass = standardize(qname, qtype, qclass) + local co = coroutine.running(); + local q = get(self.wanted, qclass, qtype, qname); + if co and q then + -- We are already waiting for a reply to an identical query. + set(self.wanted, qclass, qtype, qname, co, true); + return true; + end + if not self.server then self:adddefaultnameservers(); end local question = encodeQuestion(qname, qtype, qclass); @@ -735,7 +743,6 @@ function resolver:query(qname, qtype, qclass) -- - - - - - - - - - -- query self.active[id][question] = o; -- remember which coroutine wants the answer - local co = coroutine.running(); if co then set(self.wanted, qclass, qtype, qname, co, true); --set(self.yielded, co, qclass, qtype, qname, true); -- cgit v1.2.3 From dd05fccf9da99cd45f7d0a11fe01d5f4e8680c05 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 3 Jul 2014 17:53:24 +0200 Subject: mod_register: get_child_text! (thanks Lloyd) --- plugins/mod_register.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/mod_register.lua b/plugins/mod_register.lua index 141a4997..3d7a068c 100644 --- a/plugins/mod_register.lua +++ b/plugins/mod_register.lua @@ -115,8 +115,8 @@ local function handle_registration_stanza(event) module:log("info", "User removed their account: %s@%s", username, host); module:fire_event("user-deregistered", { username = username, host = host, source = "mod_register", session = session }); else - local username = nodeprep(query:get_child("username"):get_text()); - local password = query:get_child("password"):get_text(); + local username = nodeprep(query:get_child_text("username")); + local password = query:get_child_text("password"); if username and password then if username == session.username then if usermanager_set_password(username, password, session.host) then -- cgit v1.2.3 From 93109dabe2ec37d34d983b818176dd962741d33a Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 25 Jul 2014 12:08:07 +0100 Subject: net.dns: Ensure all pending requests get notified of a timeout when looking up a record (fix for d122420542fb) --- net/dns.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/net/dns.lua b/net/dns.lua index 492bd1c5..906365ce 100644 --- a/net/dns.lua +++ b/net/dns.lua @@ -770,7 +770,7 @@ function resolver:query(qname, qtype, qclass) -- - - - - - - - - - -- query end end -- Tried everything, failed - self:cancel(qclass, qtype, qname, co, true); + self:cancel(qclass, qtype, qname); end end) end @@ -910,13 +910,13 @@ function resolver:feed(sock, packet, force) return response; end -function resolver:cancel(qclass, qtype, qname, co, call_handler) +function resolver:cancel(qclass, qtype, qname) local cos = get(self.wanted, qclass, qtype, qname); if cos then - if call_handler then - coroutine.resume(co); + for co in pairs(cos) do + if coroutine.status(co) == "suspended" then coroutine.resume(co); end end - cos[co] = nil; + set(self.wanted, qclass, qtype, qname, nil); end end -- cgit v1.2.3 From 57e194d079de58d627d81502d22aaec5dfb6b82a Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 25 Jul 2014 12:54:31 +0100 Subject: net.dns: Remove unused obsolete code --- net/dns.lua | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/net/dns.lua b/net/dns.lua index 906365ce..89bd3564 100644 --- a/net/dns.lua +++ b/net/dns.lua @@ -745,7 +745,6 @@ function resolver:query(qname, qtype, qclass) -- - - - - - - - - - -- query -- remember which coroutine wants the answer if co then set(self.wanted, qclass, qtype, qname, co, true); - --set(self.yielded, co, qclass, qtype, qname, true); end local conn, err = self:getsocket(o.server) @@ -858,7 +857,6 @@ function resolver:receive(rset) -- - - - - - - - - - - - - - - - - receive local cos = get(self.wanted, q.class, q.type, q.name); if cos then for co in pairs(cos) do - set(self.yielded, co, q.class, q.type, q.name, nil); if coroutine.status(co) == "suspended" then coroutine.resume(co); end end set(self.wanted, q.class, q.type, q.name, nil); @@ -899,7 +897,6 @@ function resolver:feed(sock, packet, force) local cos = get(self.wanted, q.class, q.type, q.name); if cos then for co in pairs(cos) do - set(self.yielded, co, q.class, q.type, q.name, nil); if coroutine.status(co) == "suspended" then coroutine.resume(co); end end set(self.wanted, q.class, q.type, q.name, nil); @@ -1037,7 +1034,7 @@ end function dns.resolver () -- - - - - - - - - - - - - - - - - - - - - resolver -- this function seems to be redundant with resolver.new () - local r = { active = {}, cache = {}, unsorted = {}, wanted = {}, yielded = {}, best_server = 1 }; + local r = { active = {}, cache = {}, unsorted = {}, wanted = {}, best_server = 1 }; setmetatable (r, resolver); setmetatable (r.cache, cache_metatable); setmetatable (r.unsorted, { __mode = 'kv' }); -- cgit v1.2.3 From 9c43680bdd509bc4137372ee29e636721867735a Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 25 Jul 2014 13:59:17 +0200 Subject: mod_admin_telnet: Fix dns:(add,set)nameservers() --- plugins/mod_admin_telnet.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index 6f02f030..671b6d89 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -1058,12 +1058,12 @@ function def_env.dns:lookup(name, typ, class) end function def_env.dns:addnameserver(...) - dns.addnameserver(...) + dns._resolver:addnameserver(...) return true end function def_env.dns:setnameserver(...) - dns.setnameserver(...) + dns._resolver:setnameserver(...) return true end -- cgit v1.2.3 From 575404af1c8ddad0a6bb9894d74f7a61a0e8f3d1 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 25 Jul 2014 13:53:39 +0100 Subject: net.server_select/event: Switch sender mode to *a when reading, to make sure we get all available data --- net/server_event.lua | 1 + net/server_select.lua | 1 + 2 files changed, 2 insertions(+) diff --git a/net/server_event.lua b/net/server_event.lua index 25799640..b05d1688 100644 --- a/net/server_event.lua +++ b/net/server_event.lua @@ -847,6 +847,7 @@ local function link(sender, receiver, buffersize) sender:pause(); end end + sender:set_mode("*a"); end return { diff --git a/net/server_select.lua b/net/server_select.lua index 4bda3ef0..e8964518 100644 --- a/net/server_select.lua +++ b/net/server_select.lua @@ -705,6 +705,7 @@ local function link(sender, receiver, buffersize) sender:lock_read(true); end end + sender:set_mode("*a"); end ----------------------------------// PUBLIC //-- -- cgit v1.2.3 From 2990b9027915b38cb82d9e811218b6b8c483798c Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Thu, 31 Jul 2014 06:56:21 +0100 Subject: configmanager: nameprep VirtualHost and Component names --- core/configmanager.lua | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/configmanager.lua b/core/configmanager.lua index d175b54b..c8aa7b9a 100644 --- a/core/configmanager.lua +++ b/core/configmanager.lua @@ -17,6 +17,9 @@ local envload = require"util.envload".envload; local deps = require"util.dependencies"; local path_sep = package.config:sub(1,1); +local have_encodings, encodings = pcall(require, "util.encodings"); +local nameprep = have_encodings and encodings.stringprep.nameprep or function (host) return host:lower(); end + module "configmanager" local parsers = {}; @@ -170,6 +173,7 @@ do rawset(env, "__currenthost", "*") -- Default is global function env.VirtualHost(name) + name = nameprep(name); if rawget(config, name) and rawget(config[name], "component_module") then error(format("Host %q clashes with previously defined %s Component %q, for services use a sub-domain like conference.%s", name, config[name].component_module:gsub("^%a+$", { component = "external", muc = "MUC"}), name, name), 0); @@ -187,6 +191,7 @@ do env.Host, env.host = env.VirtualHost, env.VirtualHost; function env.Component(name) + name = nameprep(name); if rawget(config, name) and rawget(config[name], "defined") and not rawget(config[name], "component_module") then error(format("Component %q clashes with previously defined Host %q, for services use a sub-domain like conference.%s", name, name, name), 0); -- cgit v1.2.3 From 12a04208d404d354f4eb37cead8b27aa8854764b Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Thu, 31 Jul 2014 06:58:15 +0100 Subject: prosodyctl: Improve JID splitting and normalization for adduser/passwd/deluser --- prosodyctl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/prosodyctl b/prosodyctl index d341a75b..6a6414f6 100755 --- a/prosodyctl +++ b/prosodyctl @@ -268,6 +268,8 @@ local show_yesno = prosodyctl.show_yesno; local show_prompt = prosodyctl.show_prompt; local read_password = prosodyctl.read_password; +local jid_split = require "util.jid".prepped_split; + local prosodyctl_timeout = (config.get("*", "prosodyctl_timeout") or 5) * 2; ----------------------- local commands = {}; @@ -278,7 +280,7 @@ function commands.adduser(arg) show_usage([[adduser JID]], [[Create the specified user account in Prosody]]); return 1; end - local user, host = arg[1]:match("([^@]+)@(.+)"); + local user, host = jid_split(arg[1]); if not user and host then show_message [[Failed to understand JID, please supply the JID you want to create]] show_usage [[adduser user@host]] @@ -317,7 +319,7 @@ function commands.passwd(arg) show_usage([[passwd JID]], [[Set the password for the specified user account in Prosody]]); return 1; end - local user, host = arg[1]:match("([^@]+)@(.+)"); + local user, host = jid_split(arg[1]) if not user and host then show_message [[Failed to understand JID, please supply the JID you want to set the password for]] show_usage [[passwd user@host]] @@ -356,7 +358,7 @@ function commands.deluser(arg) show_usage([[deluser JID]], [[Permanently remove the specified user account from Prosody]]); return 1; end - local user, host = arg[1]:match("([^@]+)@(.+)"); + local user, host = jid_split(arg[1]); if not user and host then show_message [[Failed to understand JID, please supply the JID you want to set the password for]] show_usage [[passwd user@host]] -- cgit v1.2.3 From 0f2be259eeaeee58b7d969508703848527a50792 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Thu, 31 Jul 2014 06:59:12 +0100 Subject: prosodyctl: Remove nonsensical warning --- prosodyctl | 1 - 1 file changed, 1 deletion(-) diff --git a/prosodyctl b/prosodyctl index 6a6414f6..38dac363 100755 --- a/prosodyctl +++ b/prosodyctl @@ -372,7 +372,6 @@ function commands.deluser(arg) if not hosts[host] then show_warning("The host '%s' is not listed in the configuration file (or is not enabled).", host) - show_warning("The user will not be able to log in until this is changed."); hosts[host] = make_host(host); end -- cgit v1.2.3 From 55415894e9b60d81eff760e4a70b1a6e92031899 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 26 Aug 2014 12:00:51 +0200 Subject: prosodyctl: Verify that 'pidfile' is a string, show friendly error otherwise --- prosodyctl | 1 + util/prosodyctl.lua | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/prosodyctl b/prosodyctl index 38dac363..8580aaf6 100755 --- a/prosodyctl +++ b/prosodyctl @@ -220,6 +220,7 @@ local error_messages = setmetatable({ ["no-such-host"] = "The given hostname does not exist in the config"; ["unable-to-save-data"] = "Unable to store, perhaps you don't have permission?"; ["no-pidfile"] = "There is no 'pidfile' option in the configuration file, see http://prosody.im/doc/prosodyctl#pidfile for help"; + ["invalid-pidfile"] = "The 'pidfile' option in the configuration file is not a string, see http://prosody.im/doc/prosodyctl#pidfile for help"; ["no-posix"] = "The mod_posix module is not enabled in the Prosody config file, see http://prosody.im/doc/prosodyctl for more info"; ["no-such-method"] = "This module has no commands"; ["not-running"] = "Prosody is not running"; diff --git a/util/prosodyctl.lua b/util/prosodyctl.lua index b80a69f2..c6fe1986 100644 --- a/util/prosodyctl.lua +++ b/util/prosodyctl.lua @@ -188,6 +188,10 @@ function getpid() if not pidfile then return false, "no-pidfile"; end + + if type(pidfile) ~= "string" then + return false, "invalid-pidfile"; + end local modules_enabled = set.new(config.get("*", "modules_enabled")); if not modules_enabled:contains("posix") then -- cgit v1.2.3 From 2434ee1718f79a372c278083352c651c6b2c9433 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 26 Aug 2014 12:02:41 +0200 Subject: mod_posix: Make sure that 'pidfile' is a string --- plugins/mod_posix.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_posix.lua b/plugins/mod_posix.lua index 28fd7f38..b289fa44 100644 --- a/plugins/mod_posix.lua +++ b/plugins/mod_posix.lua @@ -80,7 +80,7 @@ local function write_pidfile() if pidfile_handle then remove_pidfile(); end - pidfile = module:get_option("pidfile"); + pidfile = module:get_option_string("pidfile"); if pidfile then local err; local mode = stat(pidfile) and "r+" or "w+"; -- cgit v1.2.3 From 08d298926a6e28d059d20245bad69b10cb9af01d Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 26 Aug 2014 12:19:27 +0200 Subject: mod_compression: Handle compression setup errors by logging a warning about it (fixes #408) --- plugins/mod_compression.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/mod_compression.lua b/plugins/mod_compression.lua index 531ea8ea..1ec4c85a 100644 --- a/plugins/mod_compression.lua +++ b/plugins/mod_compression.lua @@ -147,6 +147,12 @@ module:hook("stanza/http://jabber.org/protocol/compress:compressed", function(ev end end); +module:hook("stanza/http://jabber.org/protocol/compress:failure", function(event) + local err = event.stanza:get_child(); + (event.origin.log or module._log)("warn", "Compression setup failed (%s)", err and err.name or "unknown reason"); + return true; +end); + module:hook("stanza/http://jabber.org/protocol/compress:compress", function(event) local session, stanza = event.origin, event.stanza; -- cgit v1.2.3 From efdd626685a72db73f5f4de91bdb1963c7902d86 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 26 Aug 2014 21:50:08 +0200 Subject: mod_s2s: Mark stream as opened earlier for outgoing connections, fixes double stream headers on policy failures --- plugins/mod_s2s/mod_s2s.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua index aa517bbd..d4864a38 100644 --- a/plugins/mod_s2s/mod_s2s.lua +++ b/plugins/mod_s2s/mod_s2s.lua @@ -362,7 +362,9 @@ function stream_callbacks.streamopened(session, attr) log("debug", "Sending stream features: %s", tostring(features)); send(features); end + session.notopen = nil; elseif session.direction == "outgoing" then + session.notopen = nil; -- If we are just using the connection for verifying dialback keys, we won't try and auth it if not attr.id then error("stream response did not give us a streamid!!!"); end session.streamid = attr.id; @@ -396,7 +398,6 @@ function stream_callbacks.streamopened(session, attr) end end end - session.notopen = nil; end function stream_callbacks.streamclosed(session) -- cgit v1.2.3 From 3d8d94df1aa69ba913514a11ffb842e9f62952ca Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 27 Aug 2014 10:44:45 +0200 Subject: net.http.server: Comment out a log message --- net/http/server.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/http/server.lua b/net/http/server.lua index 0f379e96..771adf10 100644 --- a/net/http/server.lua +++ b/net/http/server.lua @@ -98,7 +98,7 @@ function listener.onconnect(conn) local pending = {}; local waiting = false; local function process_next() - if waiting then log("debug", "can't process_next, waiting"); return; end + if waiting then return; end -- log("debug", "can't process_next, waiting"); waiting = true; while sessions[conn] and #pending > 0 do local request = t_remove(pending); -- cgit v1.2.3 From a1f03e4a9cc8bcae1eb6cf9e25b990d7b57532f8 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 27 Aug 2014 10:46:22 +0200 Subject: modulemanager: Reduce warning to debug level message about modules already being loaded, it's probably just module:depends() --- core/modulemanager.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/modulemanager.lua b/core/modulemanager.lua index cddab647..4df95069 100644 --- a/core/modulemanager.lua +++ b/core/modulemanager.lua @@ -123,7 +123,7 @@ local function do_load_module(host, module_name, state) end if modulemap[host][module_name] then - log("warn", "%s is already loaded for %s, so not loading again", module_name, host); + log("debug", "%s is already loaded for %s, so not loading again", module_name, host); return nil, "module-already-loaded"; elseif modulemap["*"][module_name] then local mod = modulemap["*"][module_name]; -- cgit v1.2.3 From 48d7d7fd122ede3ace09d62e65f7770007c2e221 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 27 Aug 2014 13:20:08 +0200 Subject: mod_s2s: Reset stream ID when resetting stream [compliance] --- plugins/mod_s2s/mod_s2s.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua index d4864a38..c288d858 100644 --- a/plugins/mod_s2s/mod_s2s.lua +++ b/plugins/mod_s2s/mod_s2s.lua @@ -528,6 +528,7 @@ local function initialize_session(session) function session.reset_stream() session.notopen = true; + session.streamid = nil; session.stream:reset(); end -- cgit v1.2.3 From 038b399e6a9d463af7e323f572e218bafa9a613d Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 23 Aug 2014 09:22:05 +0100 Subject: util.xmppstream: When error is 'no-stream', pass the received tagname to the error handler --- util/xmppstream.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/xmppstream.lua b/util/xmppstream.lua index 73f5e314..138c86b7 100644 --- a/util/xmppstream.lua +++ b/util/xmppstream.lua @@ -109,7 +109,7 @@ function new_sax_handlers(session, stream_callbacks, cb_handleprogress) end else -- Garbage before stream? - cb_error(session, "no-stream"); + cb_error(session, "no-stream", tagname); end return; end -- cgit v1.2.3 From 2a6c5e98cf0c6968d9a48b3a21e02ff25f5abee5 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 23 Aug 2014 09:29:17 +0100 Subject: mod_c2s, mod_s2s: Log received invalid stream headers --- plugins/mod_c2s.lua | 2 +- plugins/mod_s2s/mod_s2s.lua | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/mod_c2s.lua b/plugins/mod_c2s.lua index 5feb1f2c..b6895f4b 100644 --- a/plugins/mod_c2s.lua +++ b/plugins/mod_c2s.lua @@ -91,7 +91,7 @@ end function stream_callbacks.error(session, error, data) if error == "no-stream" then - session.log("debug", "Invalid opening stream header"); + session.log("debug", "Invalid opening stream header (%s)", (data:gsub("^([^\1]+)\1", "{%1}"))); session:close("invalid-namespace"); elseif error == "parse-error" then (session.log or log)("debug", "Client XML parse error: %s", tostring(data)); diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua index c288d858..44334428 100644 --- a/plugins/mod_s2s/mod_s2s.lua +++ b/plugins/mod_s2s/mod_s2s.lua @@ -407,6 +407,7 @@ end function stream_callbacks.error(session, error, data) if error == "no-stream" then + session.log("debug", "Invalid opening stream header (%s)", (data:gsub("^([^\1]+)\1", "{%1}"))); session:close("invalid-namespace"); elseif error == "parse-error" then session.log("debug", "Server-to-server XML parse error: %s", tostring(error)); -- cgit v1.2.3 From bc7eb5a275612742ce7508dea93b6e5953016ac1 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Thu, 28 Aug 2014 09:17:07 +0100 Subject: mod_privacy: Fix to correctly sort privacy list rules by order (thanks Flow) --- plugins/mod_privacy.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_privacy.lua b/plugins/mod_privacy.lua index 31ace9f9..49c9427f 100644 --- a/plugins/mod_privacy.lua +++ b/plugins/mod_privacy.lua @@ -157,7 +157,7 @@ function createOrReplaceList (privacy_lists, origin, stanza, name, entries) list.items[#list.items + 1] = tmp; end - table.sort(list, function(a, b) return a.order < b.order; end); + table.sort(list.items, function(a, b) return a.order < b.order; end); origin.send(st.reply(stanza)); if bare_sessions[bare_jid] ~= nil then -- cgit v1.2.3 From f1d4d574065e8489c53e81cdae95cf0c4ce3b495 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Thu, 28 Aug 2014 09:20:33 +0100 Subject: util.filters: Ignore filters being added twice (fixes issues on removal) --- util/filters.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/util/filters.lua b/util/filters.lua index d24bd33e..6290e53b 100644 --- a/util/filters.lua +++ b/util/filters.lua @@ -45,6 +45,8 @@ function add_filter(session, type, callback, priority) if not filter_list then filter_list = {}; session.filters[type] = filter_list; + elseif filter_list[callback] then + return; -- Filter already added end priority = priority or 0; -- cgit v1.2.3 -- cgit v1.2.3 From 316e35bb4f68a30174276fdc053a49f16aeca8ca Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 2 Sep 2014 17:24:25 +0200 Subject: mod_s2s: Close offending s2s streams missing an 'id' attribute with a stream error instead of throwing an unhandled error --- plugins/mod_s2s/mod_s2s.lua | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua index 44334428..834e6a1c 100644 --- a/plugins/mod_s2s/mod_s2s.lua +++ b/plugins/mod_s2s/mod_s2s.lua @@ -365,8 +365,11 @@ function stream_callbacks.streamopened(session, attr) session.notopen = nil; elseif session.direction == "outgoing" then session.notopen = nil; - -- If we are just using the connection for verifying dialback keys, we won't try and auth it - if not attr.id then error("stream response did not give us a streamid!!!"); end + if not attr.id then + log("error", "Stream response did not give us a stream id!"); + session:close({ condition = "undefined-condition", text = "Missing stream ID" }); + return; + end session.streamid = attr.id; if session.secure and not session.cert_chain_status then -- cgit v1.2.3 From a9f0fe436fe6427addf0c10fe7d02ac921a5c50b Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 29 Aug 2014 11:39:56 +0100 Subject: net.server_{select,event}: Add 'ondetach' callback for listener objects, to notify them when another listener is being assigned to a connection --- net/server_event.lua | 10 ++++++++-- net/server_select.lua | 5 +++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/net/server_event.lua b/net/server_event.lua index b05d1688..45938a13 100644 --- a/net/server_event.lua +++ b/net/server_event.lua @@ -438,8 +438,11 @@ do end function interface_mt:setlistener(listener) - self.onconnect, self.ondisconnect, self.onincoming, self.ontimeout, self.onstatus - = listener.onconnect, listener.ondisconnect, listener.onincoming, listener.ontimeout, listener.onstatus; + self:ondetach(); -- Notify listener that it is no longer responsible for this connection + self.onconnect, self.ondisconnect, self.onincoming, + self.ontimeout, self.onstatus, self.ondetach + = listener.onconnect, listener.ondisconnect, listener.onincoming, + listener.ontimeout, listener.onstatus, listener.ondetach; end -- Stub handlers @@ -453,6 +456,8 @@ do end function interface_mt:ondrain() end + function interface_mt:ondetach() + end function interface_mt:onstatus() end end @@ -479,6 +484,7 @@ do onincoming = listener.onincoming; -- will be called when client sends data ontimeout = listener.ontimeout; -- called when fatal socket timeout occurs ondrain = listener.ondrain; -- called when writebuffer is empty + ondetach = listener.ondetach; -- called when disassociating this listener from this connection onstatus = listener.onstatus; -- called for status changes (e.g. of SSL/TLS) eventread = false, eventwrite = false, eventclose = false, eventhandshake = false, eventstarthandshake = false; -- event handler diff --git a/net/server_select.lua b/net/server_select.lua index e8964518..2b23b4f0 100644 --- a/net/server_select.lua +++ b/net/server_select.lua @@ -284,6 +284,7 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport local status = listeners.onstatus local disconnect = listeners.ondisconnect local drain = listeners.ondrain + local detach = listener.ondetach local bufferqueue = { } -- buffer array local bufferqueuelen = 0 -- end of buffer array @@ -313,10 +314,14 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport return disconnect end handler.setlistener = function( self, listeners ) + if detach then + detach(self) -- Notify listener that it is no longer responsible for this connection + end dispatch = listeners.onincoming disconnect = listeners.ondisconnect status = listeners.onstatus drain = listeners.ondrain + detach = listeners.ondetach end handler.getstats = function( ) return readtraffic, sendtraffic -- cgit v1.2.3 From 137a86280935c8ee19c44d0a1a1bf9ed50df4323 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 29 Aug 2014 11:54:34 +0100 Subject: net.http, net.http.server, mod_c2s, mod_s2s, mod_component, mod_admin_telnet, mod_net_multiplex: Add ondetach to release connection from 'sessions' table (or equivalent) --- net/http.lua | 4 ++++ net/http/server.lua | 4 ++++ plugins/mod_admin_telnet.lua | 4 ++++ plugins/mod_c2s.lua | 4 ++++ plugins/mod_component.lua | 4 ++++ plugins/mod_net_multiplex.lua | 3 ++- plugins/mod_s2s/mod_s2s.lua | 4 ++++ 7 files changed, 26 insertions(+), 1 deletion(-) diff --git a/net/http.lua b/net/http.lua index 6ddb1900..9dde6062 100644 --- a/net/http.lua +++ b/net/http.lua @@ -72,6 +72,10 @@ function listener.ondisconnect(conn, err) requests[conn] = nil; end +function listener.ondetach(conn) + requests[conn] = nil; +end + local function request_reader(request, data, err) if not request.parser then local function error_cb(reason) diff --git a/net/http/server.lua b/net/http/server.lua index 771adf10..7937f87c 100644 --- a/net/http/server.lua +++ b/net/http/server.lua @@ -142,6 +142,10 @@ function listener.ondisconnect(conn) sessions[conn] = nil; end +function listener.ondetach(conn) + sessions[conn] = nil; +end + function listener.onincoming(conn, data) sessions[conn]:feed(data); end diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index 671b6d89..e4b5a045 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -163,6 +163,10 @@ function console_listener.ondisconnect(conn, err) end end +function console_listener.ondetach(conn) + sessions[conn] = nil; +end + -- Console commands -- -- These are simple commands, not valid standalone in Lua diff --git a/plugins/mod_c2s.lua b/plugins/mod_c2s.lua index b6895f4b..3d6487c9 100644 --- a/plugins/mod_c2s.lua +++ b/plugins/mod_c2s.lua @@ -266,6 +266,10 @@ function listener.associate_session(conn, session) sessions[conn] = session; end +function listener.ondetach(conn) + sessions[conn] = nil; +end + module:hook("server-stopping", function(event) local reason = event.reason; for _, session in pairs(sessions) do diff --git a/plugins/mod_component.lua b/plugins/mod_component.lua index c5a1da81..7bc0f5b7 100644 --- a/plugins/mod_component.lua +++ b/plugins/mod_component.lua @@ -319,6 +319,10 @@ function listener.ondisconnect(conn, err) end end +function listener.ondetach(conn) + sessions[conn] = nil; +end + module:provides("net", { name = "component"; private = true; diff --git a/plugins/mod_net_multiplex.lua b/plugins/mod_net_multiplex.lua index d666b907..0dd3dc67 100644 --- a/plugins/mod_net_multiplex.lua +++ b/plugins/mod_net_multiplex.lua @@ -34,7 +34,6 @@ end function listener.onincoming(conn, data) if not data then return; end local buf = buffers[conn]; - buffers[conn] = nil; buf = buf and buf..data or data; for service, multiplex_pattern in pairs(available_services) do if buf:match(multiplex_pattern) then @@ -57,6 +56,8 @@ function listener.ondisconnect(conn, err) buffers[conn] = nil; -- warn if no buffer? end +listener.ondetach = listener.ondisconnect; + module:provides("net", { name = "multiplex"; config_prefix = ""; diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua index 834e6a1c..ee03987d 100644 --- a/plugins/mod_s2s/mod_s2s.lua +++ b/plugins/mod_s2s/mod_s2s.lua @@ -638,6 +638,10 @@ function listener.register_outgoing(conn, session) initialize_session(session); end +function listener.ondetach(conn) + sessions[conn] = nil; +end + function check_auth_policy(event) local host, session = event.host, event.session; local must_secure = secure_auth; -- cgit v1.2.3 From 6bceea0b5cc310d948a0571b9a0bb3216cb2763f Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 2 Sep 2014 17:23:44 +0100 Subject: net.server_select: 'listener'->'listeners' (fixes undefined global access) --- net/server_select.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/server_select.lua b/net/server_select.lua index 2b23b4f0..7ac41523 100644 --- a/net/server_select.lua +++ b/net/server_select.lua @@ -284,7 +284,7 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport local status = listeners.onstatus local disconnect = listeners.ondisconnect local drain = listeners.ondrain - local detach = listener.ondetach + local detach = listeners.ondetach local bufferqueue = { } -- buffer array local bufferqueuelen = 0 -- end of buffer array -- cgit v1.2.3 From d8be2de62de4863557aeb0add87a53f60447f4ff Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Wed, 3 Sep 2014 18:49:41 +0100 Subject: net.http.parser: Support status code 101 and allow handling of the received data by someone else --- net/http/parser.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/net/http/parser.lua b/net/http/parser.lua index f9e6cea0..d896dff4 100644 --- a/net/http/parser.lua +++ b/net/http/parser.lua @@ -140,7 +140,11 @@ function httpstream.new(success_cb, error_cb, parser_type, options_cb) break; end elseif len and #buf >= len then - packet.body, buf = buf:sub(1, len), buf:sub(len + 1); + if packet.code == 101 then + packet.body, buf = buf, "" + else + packet.body, buf = buf:sub(1, len), buf:sub(len + 1); + end state = nil; success_cb(packet); else break; -- cgit v1.2.3 From d47a864352b942da6dd307e30e54cb40c333c2e1 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 9 Sep 2014 14:42:10 +0200 Subject: core.stanza_router: Stricter validation of stanzas --- core/stanza_router.lua | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/core/stanza_router.lua b/core/stanza_router.lua index 94753678..bf5b11bc 100644 --- a/core/stanza_router.lua +++ b/core/stanza_router.lua @@ -29,24 +29,25 @@ deprecated_warning"core_post_stanza"; deprecated_warning"core_process_stanza"; deprecated_warning"core_route_stanza"; +local valid_stanzas = { message = true, presence = true, iq = true }; local function handle_unhandled_stanza(host, origin, stanza) local name, xmlns, origin_type = stanza.name, stanza.attr.xmlns or "jabber:client", origin.type; - if name == "iq" and xmlns == "jabber:client" then - if stanza.attr.type == "get" or stanza.attr.type == "set" then + if xmlns == "jabber:client" and valid_stanzas[name] then + -- A normal stanza + local st_type = stanza.attr.type; + if st_type == "error" or (name == "iq" and st_type == "result") then + log("debug", "Discarding %s from %s of type: %s", name, origin_type, st_type or ''); + return; + end + if name == "iq" and (st_type == "get" or st_type == "set") and stanza.tags[1] then xmlns = stanza.tags[1].attr.xmlns or "jabber:client"; - log("debug", "Stanza of type %s from %s has xmlns: %s", name, origin_type, xmlns); - else - log("debug", "Discarding %s from %s of type: %s", name, origin_type, stanza.attr.type); - return true; end - end - if stanza.attr.xmlns == nil and origin.send then - log("debug", "Unhandled %s stanza: %s; xmlns=%s", origin.type, stanza.name, xmlns); -- we didn't handle it - if stanza.attr.type ~= "error" and stanza.attr.type ~= "result" then + log("debug", "Unhandled %s stanza: %s; xmlns=%s", origin_type, name, xmlns); + if origin.send then origin.send(st.error_reply(stanza, "cancel", "service-unavailable")); end elseif not((name == "features" or name == "error") and xmlns == "http://etherx.jabber.org/streams") then -- FIXME remove check once we handle S2S features - log("warn", "Unhandled %s stream element or stanza: %s; xmlns=%s: %s", origin.type, stanza.name, xmlns, tostring(stanza)); -- we didn't handle it + log("warn", "Unhandled %s stream element or stanza: %s; xmlns=%s: %s", origin_type, name, xmlns, tostring(stanza)); -- we didn't handle it origin:close("unsupported-stanza-type"); end end @@ -55,19 +56,21 @@ local iq_types = { set=true, get=true, result=true, error=true }; function core_process_stanza(origin, stanza) (origin.log or log)("debug", "Received[%s]: %s", origin.type, stanza:top_tag()) - -- TODO verify validity of stanza (as well as JID validity) - if stanza.attr.type == "error" and #stanza.tags == 0 then return; end -- TODO invalid stanza, log - if stanza.name == "iq" then - if not stanza.attr.id then stanza.attr.id = ""; end -- COMPAT Jabiru doesn't send the id attribute on roster requests - if not iq_types[stanza.attr.type] or ((stanza.attr.type == "set" or stanza.attr.type == "get") and (#stanza.tags ~= 1)) then - origin.send(st.error_reply(stanza, "modify", "bad-request", "Invalid IQ type or incorrect number of children")); - return; + if origin.type == "c2s" and not stanza.attr.xmlns then + local name, st_type = stanza.name, stanza.attr.type; + if st_type == "error" and #stanza.tags == 0 then + return handle_unhandled_stanza(origin.host, origin, stanza); + end + if name == "iq" then + if not stanza.attr.id then stanza.attr.id = ""; end -- COMPAT Jabiru doesn't send the id attribute on roster requests + if not iq_types[st_type] or (st_type ~= "result" and #stanza.tags ~= 1) then + origin.send(st.error_reply(stanza, "modify", "bad-request", "Invalid IQ type or incorrect number of children")); + return; + end end - end - if origin.type == "c2s" and not stanza.attr.xmlns then if not origin.full_jid - and not(stanza.name == "iq" and stanza.attr.type == "set" and stanza.tags[1] and stanza.tags[1].name == "bind" + and not(name == "iq" and st_type == "set" and stanza.tags[1] and stanza.tags[1].name == "bind" and stanza.tags[1].attr.xmlns == "urn:ietf:params:xml:ns:xmpp-bind") then -- authenticated client isn't bound and current stanza is not a bind request if stanza.attr.type ~= "result" and stanza.attr.type ~= "error" then -- cgit v1.2.3 From 08cd74ece8926fc1596c7c40fc626d643663eea7 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 29 Sep 2014 11:02:06 +0200 Subject: mod_admin_adhoc: Mark 'accountjids' field as required in 'end user sessions' command (thanks Lloyd) --- plugins/mod_admin_adhoc.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_admin_adhoc.lua b/plugins/mod_admin_adhoc.lua index 2c6047da..704b2685 100644 --- a/plugins/mod_admin_adhoc.lua +++ b/plugins/mod_admin_adhoc.lua @@ -162,7 +162,7 @@ local end_user_session_layout = dataforms_new{ instructions = "Fill out this form to end a user's session."; { name = "FORM_TYPE", type = "hidden", value = "http://jabber.org/protocol/admin" }; - { name = "accountjids", type = "jid-multi", label = "The Jabber ID(s) for which to end sessions" }; + { name = "accountjids", type = "jid-multi", label = "The Jabber ID(s) for which to end sessions", required = true }; }; local end_user_session_handler = adhoc_simple(end_user_session_layout, function(fields, err) -- cgit v1.2.3 From b9dbb1fb361c253776210678f34d7d19a7920da0 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 29 Sep 2014 11:18:04 +0200 Subject: mod_admin_adhoc: Add required to field in user deletion form too --- plugins/mod_admin_adhoc.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_admin_adhoc.lua b/plugins/mod_admin_adhoc.lua index 704b2685..232fa5f7 100644 --- a/plugins/mod_admin_adhoc.lua +++ b/plugins/mod_admin_adhoc.lua @@ -118,7 +118,7 @@ local delete_user_layout = dataforms_new{ instructions = "Fill out this form to delete a user."; { name = "FORM_TYPE", type = "hidden", value = "http://jabber.org/protocol/admin" }; - { name = "accountjids", type = "jid-multi", label = "The Jabber ID(s) to delete" }; + { name = "accountjids", type = "jid-multi", required = true, label = "The Jabber ID(s) to delete" }; }; local delete_user_command_handler = adhoc_simple(delete_user_layout, function(fields, err) -- cgit v1.2.3 From d8136ff52d2eb03397dfaa0df8e23e9047744429 Mon Sep 17 00:00:00 2001 From: Florian Zeitz Date: Sun, 5 Oct 2014 14:28:40 +0200 Subject: net.dns: Avoid duplicate cache entries --- net/dns.lua | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/net/dns.lua b/net/dns.lua index 89bd3564..dc2da1b6 100644 --- a/net/dns.lua +++ b/net/dns.lua @@ -134,17 +134,19 @@ end local function prune(rrs, time, soft) -- - - - - - - - - - - - - - - prune time = time or socket.gettime(); - for i,rr in pairs(rrs) do + for i,rr in ipairs(rrs) do if rr.tod then -- rr.tod = rr.tod - 50 -- accelerated decripitude rr.ttl = math.floor(rr.tod - time); if rr.ttl <= 0 then + rrs[rr[rr.type:lower()]] = nil; table.remove(rrs, i); return prune(rrs, time, soft); -- Re-iterate end elseif soft == 'soft' then -- What is this? I forget! assert(rr.ttl == 0); - rrs[i] = nil; + rrs[rr[rr.type:lower()]] = nil; + table.remove(rrs, i); end end end @@ -187,7 +189,7 @@ end local rrs_metatable = {}; -- - - - - - - - - - - - - - - - - - rrs_metatable function rrs_metatable.__tostring(rrs) local t = {}; - for i,rr in pairs(rrs) do + for i,rr in ipairs(rrs) do append(t, tostring(rr)..'\n'); end return table.concat(t); @@ -674,7 +676,10 @@ function resolver:remember(rr, type) -- - - - - - - - - - - - - - remember self.cache = self.cache or setmetatable({}, cache_metatable); local rrs = get(self.cache, qclass, type, qname) or set(self.cache, qclass, type, qname, setmetatable({}, rrs_metatable)); - append(rrs, rr); + if not rrs[rr[qtype:lower()]] then + rrs[rr[qtype:lower()]] = true; + append(rrs, rr); + end if type == 'MX' then self.unsorted[rrs] = true; end end -- cgit v1.2.3 From b2ef2d1e60d73cb2ebf89cc21a9aed87e530307c Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Wed, 8 Oct 2014 15:56:11 -0400 Subject: util.stanza: Escape newlines and tabs (\r\n\t) when serializing stanzas. \r\n transforms into \n otherwise, and \r\n\t in attributes transforms into spaces. --- util/stanza.lua | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/util/stanza.lua b/util/stanza.lua index 7c214210..2fcf2c79 100644 --- a/util/stanza.lua +++ b/util/stanza.lua @@ -202,8 +202,19 @@ end local xml_escape do - local escape_table = { ["'"] = "'", ["\""] = """, ["<"] = "<", [">"] = ">", ["&"] = "&" }; - function xml_escape(str) return (s_gsub(str, "['&<>\"]", escape_table)); end + local escape_table = { + ["'"] = "'"; + ['"'] = """; + ["<"] = "<"; + [">"] = ">"; + ["&"] = "&"; + -- escape this whitespace because [\r\n\t] change into spaces in attributes + -- and \r\n changes into \n in text, and we want to preserve original bytes + ["\t"] = " "; + ["\n"] = " "; + ["\r"] = " "; + }; + function xml_escape(str) return (s_gsub(str, "['&<>\"\t\n\r]", escape_table)); end _M.xml_escape = xml_escape; end -- cgit v1.2.3 From 0496411c59d86a4e2fc41fdf2ec594426dd898c2 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Tue, 7 Oct 2014 12:08:23 -0400 Subject: util/dataforms: Make sure we iterate over field tags --- util/dataforms.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/dataforms.lua b/util/dataforms.lua index 01a8eef3..ee37157a 100644 --- a/util/dataforms.lua +++ b/util/dataforms.lua @@ -121,7 +121,7 @@ function form_t.data(layout, stanza) for _, field in ipairs(layout) do local tag; - for field_tag in stanza:childtags() do + for field_tag in stanza:childtags("field") do if field.name == field_tag.attr.var then tag = field_tag; break; -- cgit v1.2.3 From d68a8ec44de50ec5e0e5954c2211109b3f374b5a Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 10 Oct 2014 00:56:53 +0200 Subject: mod_s2s: Capitalize log message --- plugins/mod_s2s/mod_s2s.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua index ee03987d..d8846a6f 100644 --- a/plugins/mod_s2s/mod_s2s.lua +++ b/plugins/mod_s2s/mod_s2s.lua @@ -49,7 +49,7 @@ local bouncy_stanzas = { message = true, presence = true, iq = true }; local function bounce_sendq(session, reason) local sendq = session.sendq; if not sendq then return; end - session.log("info", "sending error replies for "..#sendq.." queued stanzas because of failed outgoing connection to "..tostring(session.to_host)); + session.log("info", "Sending error replies for "..#sendq.." queued stanzas because of failed outgoing connection to "..tostring(session.to_host)); local dummy = { type = "s2sin"; send = function(s) -- cgit v1.2.3 From a211c6772706424c5fb8d19ea2de2c0e0af10da4 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 14 Oct 2014 10:58:11 +0100 Subject: mod_pubsub: Fix error type of 'forbidden' (change from 'cancel' to 'auth') --- plugins/mod_pubsub.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_pubsub.lua b/plugins/mod_pubsub.lua index 926ed4f2..04f2b615 100644 --- a/plugins/mod_pubsub.lua +++ b/plugins/mod_pubsub.lua @@ -39,7 +39,7 @@ local pubsub_errors = { ["nodeid-required"] = { "modify", "bad-request", nil, "nodeid-required" }; ["item-not-found"] = { "cancel", "item-not-found" }; ["not-subscribed"] = { "modify", "unexpected-request", nil, "not-subscribed" }; - ["forbidden"] = { "cancel", "forbidden" }; + ["forbidden"] = { "auth", "forbidden" }; }; function pubsub_error_reply(stanza, error) local e = pubsub_errors[error]; -- cgit v1.2.3 From cc4e899808c88f286cd888644127abc2c9530b41 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 14 Oct 2014 18:55:08 +0100 Subject: certmanager, net.http: Disable SSLv3 by default --- core/certmanager.lua | 2 +- net/http.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/certmanager.lua b/core/certmanager.lua index d6784a96..624bd841 100644 --- a/core/certmanager.lua +++ b/core/certmanager.lua @@ -33,7 +33,7 @@ module "certmanager" local default_ssl_config = configmanager.get("*", "ssl"); local default_capath = "/etc/ssl/certs"; local default_verify = (ssl and ssl.x509 and { "peer", "client_once", }) or "none"; -local default_options = { "no_sslv2", "cipher_server_preference", luasec_has_noticket and "no_ticket" or nil }; +local default_options = { "no_sslv2", "no_sslv3", "cipher_server_preference", luasec_has_noticket and "no_ticket" or nil }; local default_verifyext = { "lsec_continue", "lsec_ignore_purpose" }; if ssl and not luasec_has_verifyext and ssl.x509 then diff --git a/net/http.lua b/net/http.lua index 9dde6062..8ce47494 100644 --- a/net/http.lua +++ b/net/http.lua @@ -175,7 +175,7 @@ function request(u, ex, callback) local sslctx = false; if using_https then - sslctx = ex and ex.sslctx or { mode = "client", protocol = "sslv23", options = { "no_sslv2" } }; + sslctx = ex and ex.sslctx or { mode = "client", protocol = "sslv23", options = { "no_sslv2", "no_sslv3" } }; end req.handler, req.conn = assert(server.wrapclient(conn, host, port_number, listener, "*a", sslctx)); -- cgit v1.2.3 -- cgit v1.2.3 From 98711177ce7db4fac8cf7da6baecf57effaccc8e Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Sun, 19 Oct 2014 03:05:49 -0400 Subject: prosodyctl: Fix nil global access traceback in `prosodyctl about` (luarocks 2.2.0 no longer uses module()) --- prosodyctl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prosodyctl b/prosodyctl index 8580aaf6..4c3ae981 100755 --- a/prosodyctl +++ b/prosodyctl @@ -548,7 +548,7 @@ function commands.about(arg) print(" "..path); end print(""); - local luarocks_status = (pcall(require, "luarocks.loader") and "Installed ("..(luarocks.cfg.program_version or "2.x+")..")") + local luarocks_status = (pcall(require, "luarocks.loader") and "Installed ("..(package.loaded["luarocks.cfg"].program_version or "2.x+")..")") or (pcall(require, "luarocks.require") and "Installed (1.x)") or "Not installed"; print("LuaRocks: ", luarocks_status); -- cgit v1.2.3 From dead315be1801fb62a0a0d9ec5a39c895345e147 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 24 Oct 2014 23:20:06 +0100 Subject: Backout changeset 6e67c73f730c: not a major fix and it breaks interop with at least Isode M-Link, and possibly standards, while it's not clear it actually fixes the original problem either. --- util/stanza.lua | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/util/stanza.lua b/util/stanza.lua index 2fcf2c79..7c214210 100644 --- a/util/stanza.lua +++ b/util/stanza.lua @@ -202,19 +202,8 @@ end local xml_escape do - local escape_table = { - ["'"] = "'"; - ['"'] = """; - ["<"] = "<"; - [">"] = ">"; - ["&"] = "&"; - -- escape this whitespace because [\r\n\t] change into spaces in attributes - -- and \r\n changes into \n in text, and we want to preserve original bytes - ["\t"] = " "; - ["\n"] = " "; - ["\r"] = " "; - }; - function xml_escape(str) return (s_gsub(str, "['&<>\"\t\n\r]", escape_table)); end + local escape_table = { ["'"] = "'", ["\""] = """, ["<"] = "<", [">"] = ">", ["&"] = "&" }; + function xml_escape(str) return (s_gsub(str, "['&<>\"]", escape_table)); end _M.xml_escape = xml_escape; end -- cgit v1.2.3 -- cgit v1.2.3 From 988d1cb8caf071f07efb6c894942a711eaa92290 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 30 Oct 2014 12:05:24 +0100 Subject: net.adns: Preserve error from setpeername --- net/adns.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/adns.lua b/net/adns.lua index 2a3fa8ad..da7981ba 100644 --- a/net/adns.lua +++ b/net/adns.lua @@ -76,7 +76,7 @@ function new_async_socket(sock, resolver) handler.settimeout = function () end handler.setsockname = function (_, ...) return sock:setsockname(...); end - handler.setpeername = function (_, ...) peername = (...); local ret = sock:setpeername(...); _:set_send(dummy_send); return ret; end + handler.setpeername = function (_, ...) peername = (...); local ret, err = sock:setpeername(...); _:set_send(dummy_send); return ret, err; end handler.connect = function (_, ...) return sock:connect(...) end --handler.send = function (_, data) _:write(data); return _.sendbuffer and _.sendbuffer(); end handler.send = function (_, data) -- cgit v1.2.3 From e80a093c767df87055de3ec8aca97c0224c19aed Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 30 Oct 2014 12:08:05 +0100 Subject: net.adns: Log peername recorded from wrapped setpeername instead of calling sock:getpeername, it exists and throws an error on unconnected sockets (thanks wirehack7) --- net/adns.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/adns.lua b/net/adns.lua index da7981ba..3fc958f4 100644 --- a/net/adns.lua +++ b/net/adns.lua @@ -80,8 +80,7 @@ function new_async_socket(sock, resolver) handler.connect = function (_, ...) return sock:connect(...) end --handler.send = function (_, data) _:write(data); return _.sendbuffer and _.sendbuffer(); end handler.send = function (_, data) - local getpeername = sock.getpeername; - log("debug", "Sending DNS query to %s", (getpeername and getpeername(sock)) or ""); + log("debug", "Sending DNS query to %s", peername); return sock:send(data); end return handler; -- cgit v1.2.3 From 68cb0636cbfd94f1915c8e084105a742758c54e2 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 30 Oct 2014 12:10:15 +0100 Subject: net.dns: Return new socket from servfail --- net/dns.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/dns.lua b/net/dns.lua index dc2da1b6..55622fc8 100644 --- a/net/dns.lua +++ b/net/dns.lua @@ -787,7 +787,7 @@ function resolver:servfail(sock) local num = self.socketset[sock] -- Socket is dead now - self:voidsocket(sock); + sock = self:voidsocket(sock); -- Find all requests to the down server, and retry on the next server self.time = socket.gettime(); @@ -804,8 +804,8 @@ function resolver:servfail(sock) --print('timeout'); queries[question] = nil; else - local _a = self:getsocket(o.server); - if _a then _a:send(o.packet); end + sock = self:getsocket(o.server); + if sock then sock:send(o.packet); end end end end @@ -821,6 +821,7 @@ function resolver:servfail(sock) self.best_server = 1; end end + return sock; end function resolver:settimeout(seconds) -- cgit v1.2.3 From 8a81d68c0715ed02c3558883a9f6030c5286cc5c Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 30 Oct 2014 12:28:07 +0100 Subject: net.dns: Try next server if peer name can not be set (thanks wirehack7) --- net/dns.lua | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/net/dns.lua b/net/dns.lua index 55622fc8..13417cee 100644 --- a/net/dns.lua +++ b/net/dns.lua @@ -622,7 +622,7 @@ function resolver:getsocket(servernum) -- - - - - - - - - - - - - getsocket local sock = self.socket[servernum]; if sock then return sock; end - local err; + local ok, err; sock, err = socket.udp(); if sock and self.socket_wrapper then sock, err = self.socket_wrapper(sock, self); end if not sock then @@ -630,10 +630,14 @@ function resolver:getsocket(servernum) -- - - - - - - - - - - - - getsocket end sock:settimeout(0); -- todo: attempt to use a random port, fallback to 0 - sock:setsockname('*', 0); - sock:setpeername(self.server[servernum], 53); self.socket[servernum] = sock; self.socketset[sock] = servernum; + -- set{sock,peer}name can fail, eg because of local routing table + -- if so, try the next server + ok, err = sock:setsockname('*', 0); + if not ok then return self:servfail(sock, err); end + ok, err = sock:setpeername(self.server[servernum], 53); + if not ok then return self:servfail(sock, err); end return sock; end @@ -781,7 +785,7 @@ function resolver:query(qname, qtype, qclass) -- - - - - - - - - - -- query return true; end -function resolver:servfail(sock) +function resolver:servfail(sock, err) -- Resend all queries for this server local num = self.socketset[sock] @@ -804,7 +808,7 @@ function resolver:servfail(sock) --print('timeout'); queries[question] = nil; else - sock = self:getsocket(o.server); + sock, err = self:getsocket(o.server); if sock then sock:send(o.packet); end end end @@ -821,7 +825,7 @@ function resolver:servfail(sock) self.best_server = 1; end end - return sock; + return sock, err; end function resolver:settimeout(seconds) -- cgit v1.2.3 From 23ec109ef66add1502ff0f2d53d84ad35bd0f4d3 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Mon, 10 Nov 2014 14:47:33 -0500 Subject: net.http.parser: Fix chunked encoding parsing across packet boundaries. --- net/http/parser.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/http/parser.lua b/net/http/parser.lua index d896dff4..056d4b60 100644 --- a/net/http/parser.lua +++ b/net/http/parser.lua @@ -132,7 +132,7 @@ function httpstream.new(success_cb, error_cb, parser_type, options_cb) state, chunk_size = nil, nil; buf = buf:gsub("^.-\r\n\r\n", ""); -- This ensure extensions and trailers are stripped success_cb(packet); - elseif #buf - chunk_start + 2 >= chunk_size then -- we have a chunk + elseif #buf - chunk_start - 2 >= chunk_size then -- we have a chunk packet.body = packet.body..buf:sub(chunk_start, chunk_start + (chunk_size-1)); buf = buf:sub(chunk_start + chunk_size + 2); chunk_size, chunk_start = nil, nil; -- cgit v1.2.3 From b874ec14c853c6fd8fa053f707ef2f0cd837bba4 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 18 Nov 2014 17:40:37 +0000 Subject: net.http.parser: Fix whitespace/indentation --- net/http/parser.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/net/http/parser.lua b/net/http/parser.lua index 056d4b60..6d7187da 100644 --- a/net/http/parser.lua +++ b/net/http/parser.lua @@ -140,11 +140,11 @@ function httpstream.new(success_cb, error_cb, parser_type, options_cb) break; end elseif len and #buf >= len then - if packet.code == 101 then - packet.body, buf = buf, "" - else - packet.body, buf = buf:sub(1, len), buf:sub(len + 1); - end + if packet.code == 101 then + packet.body, buf = buf, ""; + else + packet.body, buf = buf:sub(1, len), buf:sub(len + 1); + end state = nil; success_cb(packet); else break; -- cgit v1.2.3 From 52ecc631731c503a3a270eb9a98e01d9a8a58875 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 6 Jan 2015 17:39:47 +0100 Subject: stanza_router: Fix routing of 'error' IQs with multiple childs (thanks Pawel) --- core/stanza_router.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/stanza_router.lua b/core/stanza_router.lua index bf5b11bc..a2c7b396 100644 --- a/core/stanza_router.lua +++ b/core/stanza_router.lua @@ -63,7 +63,7 @@ function core_process_stanza(origin, stanza) end if name == "iq" then if not stanza.attr.id then stanza.attr.id = ""; end -- COMPAT Jabiru doesn't send the id attribute on roster requests - if not iq_types[st_type] or (st_type ~= "result" and #stanza.tags ~= 1) then + if not iq_types[st_type] or ((st_type == "set" or st_type == "get") and (#stanza.tags ~= 1)) then origin.send(st.error_reply(stanza, "modify", "bad-request", "Invalid IQ type or incorrect number of children")); return; end -- cgit v1.2.3 From 9c6dec2e049172dc09a844d5a1c9e3d41d3a7d42 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 20 Feb 2015 15:51:05 +0000 Subject: configure, Makefile: Add --libdir option to ./configure, allowing you to override the $PREFIX/lib/ default. Fixes #470. --- Makefile | 8 ++++---- configure | 7 +++++++ tools/migration/Makefile | 6 +++--- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index a1de1b6d..0b704e5a 100644 --- a/Makefile +++ b/Makefile @@ -3,14 +3,14 @@ include config.unix BIN = $(DESTDIR)$(PREFIX)/bin CONFIG = $(DESTDIR)$(SYSCONFDIR) -MODULES = $(DESTDIR)$(PREFIX)/lib/prosody/modules -SOURCE = $(DESTDIR)$(PREFIX)/lib/prosody +MODULES = $(DESTDIR)$(LIBDIR)/prosody/modules +SOURCE = $(DESTDIR)$(LIBDIR)/prosody DATA = $(DESTDIR)$(DATADIR) MAN = $(DESTDIR)$(PREFIX)/share/man -INSTALLEDSOURCE = $(PREFIX)/lib/prosody +INSTALLEDSOURCE = $(LIBDIR)/prosody INSTALLEDCONFIG = $(SYSCONFDIR) -INSTALLEDMODULES = $(PREFIX)/lib/prosody/modules +INSTALLEDMODULES = $(LIBDIR)/prosody/modules INSTALLEDDATA = $(DATADIR) .PHONY: all clean install diff --git a/configure b/configure index 822b046e..c27517fc 100755 --- a/configure +++ b/configure @@ -4,6 +4,7 @@ PREFIX=/usr/local SYSCONFDIR="$PREFIX/etc/prosody" +LIBDIR="$PREFIX/lib" DATADIR="$PREFIX/var/lib/prosody" LUA_SUFFIX="" LUA_DIR="/usr" @@ -36,6 +37,8 @@ Configure Prosody prior to building. Default is $PREFIX --sysconfdir=DIR Location where the config file should be installed. Default is \$PREFIX/etc/prosody +--libdir=DIR Location where the server files should be stored. + Default is \$PREFIX/lib --datadir=DIR Location where the server data should be stored. Default is \$PREFIX/var/lib/prosody --lua-suffix=SUFFIX Versioning suffix to use in Lua filenames. @@ -134,6 +137,9 @@ do then LUA_INCDIR="/usr/local/include"; fi ;; + --libdir=*) + LIBDIR="$value" + ;; --datadir=*) DATADIR="$value" DATADIR_SET=yes @@ -338,6 +344,7 @@ cat < config.unix PREFIX=$PREFIX SYSCONFDIR=$SYSCONFDIR +LIBDIR=$LIBDIR DATADIR=$DATADIR LUA_SUFFIX=$LUA_SUFFIX LUA_DIR=$LUA_DIR diff --git a/tools/migration/Makefile b/tools/migration/Makefile index ae402bd2..713831d2 100644 --- a/tools/migration/Makefile +++ b/tools/migration/Makefile @@ -3,13 +3,13 @@ include ../../config.unix BIN = $(DESTDIR)$(PREFIX)/bin CONFIG = $(DESTDIR)$(SYSCONFDIR) -SOURCE = $(DESTDIR)$(PREFIX)/lib/prosody +SOURCE = $(DESTDIR)$(LIBDIR)/prosody DATA = $(DESTDIR)$(DATADIR) MAN = $(DESTDIR)$(PREFIX)/share/man -INSTALLEDSOURCE = $(PREFIX)/lib/prosody +INSTALLEDSOURCE = $(LIBDIR)/prosody INSTALLEDCONFIG = $(SYSCONFDIR) -INSTALLEDMODULES = $(PREFIX)/lib/prosody/modules +INSTALLEDMODULES = $(LIBDIR)/prosody/modules INSTALLEDDATA = $(DATADIR) SOURCE_FILES = migrator/*.lua -- cgit v1.2.3 From 0979b1c30a9c02dbb34635c7d7b96e27d731eb39 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 20 Feb 2015 19:00:01 +0100 Subject: util.datamanager: Check that the global 'prosody' exists before using it (fixes nil indexing in use outside of prosody) --- util/datamanager.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/datamanager.lua b/util/datamanager.lua index 4a4d62b3..b82349f1 100644 --- a/util/datamanager.lua +++ b/util/datamanager.lua @@ -163,7 +163,7 @@ local function atomic_store(filename, data) return nil, msg; end -if prosody.platform ~= "posix" then +if prosody and prosody.platform ~= "posix" then -- os.rename does not overwrite existing files on Windows -- TODO We could use Transactional NTFS on Vista and above function atomic_store(filename, data) -- cgit v1.2.3 From e9f44e3d6599644b6c33011fb775fd7b381c4ef0 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 20 Feb 2015 22:53:12 +0000 Subject: mod_admin_telnet: Require util.pposix (fixes #471) --- plugins/mod_admin_telnet.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index e4b5a045..437ded01 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -313,6 +313,7 @@ local function human(kb) end function def_env.server:memory() + local pposix = require("util.pposix"); if not pposix.meminfo then return true, "Lua is using "..collectgarbage("count"); end -- cgit v1.2.3 From cb8fbcd0ca8c0951d30e9f1b2c0744598b2ad484 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 24 Feb 2015 15:19:20 +0000 Subject: configure: Fix for commit cd0088c73daf - update LIBDIR if --prefix is set and --libdir isn't (thanks Medics) --- configure | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/configure b/configure index c27517fc..199f5fcf 100755 --- a/configure +++ b/configure @@ -139,6 +139,7 @@ do ;; --libdir=*) LIBDIR="$value" + LIBDIR_SET=yes ;; --datadir=*) DATADIR="$value" @@ -213,6 +214,11 @@ then fi fi +if [ "$PREFIX_SET" = "yes" -a ! "$LIBDIR_SET" = "yes" ] +then + LIBDIR=$PREFIX/lib +fi + find_program() { path="$PATH" item="`echo "$path" | sed 's/\([^:]*\):.*/\1/'`" -- cgit v1.2.3 From 8e316d605a7a5c20542bf636e93cec1a0877f4c7 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 14 Mar 2015 22:39:03 +0000 Subject: net.http.server: Log event name when firing a request event --- net/http/server.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/http/server.lua b/net/http/server.lua index 7937f87c..f091595c 100644 --- a/net/http/server.lua +++ b/net/http/server.lua @@ -217,7 +217,7 @@ function handle_request(conn, request, finish_cb) local event = request.method.." "..host..request.path:match("[^?]*"); local payload = { request = request, response = response }; - --log("debug", "Firing event: %s", event); + log("debug", "Firing event: %s", event); local result = events.fire_event(event, payload); if result ~= nil then if result ~= true then -- cgit v1.2.3 From b68a3c35f1249f31350f11e3ee290c81e855b031 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 14 Mar 2015 22:39:23 +0000 Subject: mod_http: Log event name when adding a HTTP app's hooks --- plugins/mod_http.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index 86689aff..610ae0ae 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -102,6 +102,7 @@ function module.add_host(module) end if not app_handlers[event_name] then app_handlers[event_name] = handler; + module:log("debug", "Adding app '%s' to handle %s", app_name, event_name); module:hook_object_event(server, event_name, handler); else module:log("warn", "App %s added handler twice for '%s', ignoring", app_name, event_name); -- cgit v1.2.3 From a7a6e3d77345586de54621baa2f539e214a5bac7 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 23 Mar 2015 14:26:34 +0100 Subject: util.encodings: Perform validation of UTF-8 strings before passing to libidn (Based on code from the utf8 library in Lua 5.3) --- util-src/encodings.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 67 insertions(+), 3 deletions(-) diff --git a/util-src/encodings.c b/util-src/encodings.c index b9b6160a..898add1a 100644 --- a/util-src/encodings.c +++ b/util-src/encodings.c @@ -1,6 +1,7 @@ /* Prosody IM -- Copyright (C) 2008-2010 Matthew Wild -- Copyright (C) 2008-2010 Waqas Hussain +-- Copyright (C) 1994-2015 Lua.org, PUC-Rio. -- -- This project is MIT/X11 licensed. Please see the -- COPYING file in the source package for more information. @@ -116,6 +117,65 @@ static const luaL_Reg Reg_base64[] = { NULL, NULL } }; +/******************* UTF-8 ********************/ + +/* + * Adapted from Lua 5.3 + * Needed because libidn does not validate that input is valid UTF-8 + */ + +#define MAXUNICODE 0x10FFFF + +/* + * Decode one UTF-8 sequence, returning NULL if byte sequence is invalid. + */ +static const char *utf8_decode (const char *o, int *val) { + static unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF}; + const unsigned char *s = (const unsigned char *)o; + unsigned int c = s[0]; + unsigned int res = 0; /* final result */ + if (c < 0x80) /* ascii? */ + res = c; + else { + int count = 0; /* to count number of continuation bytes */ + while (c & 0x40) { /* still have continuation bytes? */ + int cc = s[++count]; /* read next byte */ + if ((cc & 0xC0) != 0x80) /* not a continuation byte? */ + return NULL; /* invalid byte sequence */ + res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */ + c <<= 1; /* to test next bit */ + } + res |= ((c & 0x7F) << (count * 5)); /* add first byte */ + if (count > 3 || res > MAXUNICODE || res <= limits[count] || (0xd800 <= res && res <= 0xdfff) ) + return NULL; /* invalid byte sequence */ + s += count; /* skip continuation bytes read */ + } + if (val) *val = res; + return (const char *)s + 1; /* +1 to include first byte */ +} + +/* + * Check that a string is valid UTF-8 + * Returns NULL if not + */ +const char* check_utf8 (lua_State *L, int idx, size_t *l) { + size_t pos, len; + const char *s = luaL_checklstring(L, 1, &len); + pos = 0; + while (pos <= len) { + const char *s1 = utf8_decode(s + pos, NULL); + if (s1 == NULL) { /* conversion error? */ + return NULL; + } + pos = s1 - s; + } + if(l != NULL) { + *l = len; + } + return s; +} + + /***************** STRINGPREP *****************/ #ifdef USE_STRINGPREP_ICU @@ -212,8 +272,8 @@ static int stringprep_prep(lua_State *L, const Stringprep_profile *profile) lua_pushnil(L); return 1; } - s = lua_tolstring(L, 1, &len); - if (len >= 1024) { + s = check_utf8(L, 1, &len); + if (s == NULL || len >= 1024 || len != strlen(s)) { lua_pushnil(L); return 1; /* TODO return error message */ } @@ -320,7 +380,11 @@ static int Lidna_to_unicode(lua_State *L) /** idna.to_unicode(s) */ static int Lidna_to_ascii(lua_State *L) /** idna.to_ascii(s) */ { size_t len; - const char *s = luaL_checklstring(L, 1, &len); + const char *s = check_utf8(L, 1, &len); + if (s == NULL || len != strlen(s)) { + lua_pushnil(L); + return 1; /* TODO return error message */ + } char* output = NULL; int ret = idna_to_ascii_8z(s, &output, IDNA_USE_STD3_ASCII_RULES); if (ret == IDNA_SUCCESS) { -- cgit v1.2.3 From aab2887e2c47bb2fc62a10e693c04b93c9d22415 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 23 Mar 2015 14:27:30 +0100 Subject: util.encodings: Expose UTF-8 validation and length checking functions --- util-src/encodings.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/util-src/encodings.c b/util-src/encodings.c index 898add1a..91826ca4 100644 --- a/util-src/encodings.c +++ b/util-src/encodings.c @@ -175,6 +175,29 @@ const char* check_utf8 (lua_State *L, int idx, size_t *l) { return s; } +static int Lutf8_valid(lua_State *L) { + lua_pushboolean(L, check_utf8(L, 1, NULL) != NULL); + return 1; +} + +static int Lutf8_length(lua_State *L) { + size_t len; + if(!check_utf8(L, 1, &len)) { + lua_pushnil(L); + lua_pushliteral(L, "invalid utf8"); + return 2; + } + lua_pushinteger(L, len); + return 1; +} + +static const luaL_Reg Reg_utf8[] = +{ + { "valid", Lutf8_valid }, + { "length", Lutf8_length }, + { NULL, NULL } +}; + /***************** STRINGPREP *****************/ #ifdef USE_STRINGPREP_ICU @@ -452,6 +475,11 @@ LUALIB_API int luaopen_util_encodings(lua_State *L) luaL_register(L, NULL, Reg_idna); lua_settable(L,-3); + lua_pushliteral(L, "utf8"); + lua_newtable(L); + luaL_register(L, NULL, Reg_utf8); + lua_settable(L, -3); + lua_pushliteral(L, "version"); /** version */ lua_pushliteral(L, "-3.14"); lua_settable(L,-3); -- cgit v1.2.3 From 78bd6a632210f642e50576da8c7e76691ceb8047 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Mon, 23 Mar 2015 17:16:54 +0000 Subject: tests: Add UTF-8 validity tests --- tests/test.lua | 1 + tests/test_utf8.lua | 19 ++++++++++++++++++ tests/utf8_sequences.txt | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 tests/test_utf8.lua create mode 100644 tests/utf8_sequences.txt diff --git a/tests/test.lua b/tests/test.lua index db727ce1..de1e40fd 100644 --- a/tests/test.lua +++ b/tests/test.lua @@ -22,6 +22,7 @@ function run_all_tests() dotest "util.sasl.scram" dosingletest("test_sasl.lua", "latin1toutf8"); + dosingletest("test_utf8.lua", "valid"); end local verbosity = tonumber(arg[1]) or 2; diff --git a/tests/test_utf8.lua b/tests/test_utf8.lua new file mode 100644 index 00000000..481eff5d --- /dev/null +++ b/tests/test_utf8.lua @@ -0,0 +1,19 @@ +package.cpath = "../?.so" +package.path = "../?.lua"; + +function valid() + local encodings = require "util.encodings"; + local utf8 = assert(encodings.utf8, "no encodings.utf8 module"); + + for line in io.lines("utf8_sequences.txt") do + local data = line:match(":%s*([^#]+)"):gsub("%s+", ""):gsub("..", function (c) return string.char(tonumber(c, 16)); end) + local expect = line:match("(%S+):"); + if expect ~= "pass" and expect ~= "fail" then + error("unknown expectation: "..line:match("^[^:]+")); + end + local prefix, style = " ", valid_style; + local valid = utf8.valid(data); + assert_equal(valid, utf8.valid(data.." ")); + assert_equal(valid, expect == "pass", line); + end +end diff --git a/tests/utf8_sequences.txt b/tests/utf8_sequences.txt new file mode 100644 index 00000000..408b8f08 --- /dev/null +++ b/tests/utf8_sequences.txt @@ -0,0 +1,52 @@ +Should pass: 41 42 43 # Simple ASCII - abc +Should pass: 41 42 c3 87 # "ABÇ" +Should pass: 41 42 e1 b8 88 # "ABḈ" +Should pass: 41 42 f0 9d 9c 8d # "AB𝜍" +Should pass: F4 8F BF BF # Last valid sequence (U+10FFFF) +Should fail: F4 90 80 80 # First invalid sequence (U+110000) +Should fail: 80 81 82 83 # Invalid sequence (invalid start byte) +Should fail: C2 C3 # Invalid sequence (invalid continuation byte) +Should fail: C0 43 # Overlong sequence +Should fail: F5 80 80 80 # U+140000 (out of range) +Should fail: ED A0 80 # U+D800 (forbidden by RFC 3629) +Should fail: ED BF BF # U+DFFF (forbidden by RFC 3629) +Should pass: ED 9F BF # U+D7FF (U+D800 minus 1: allowed) +Should pass: EE 80 80 # U+E000 (U+D7FF plus 1: allowed) +Should fail: C0 # Invalid start byte +Should fail: C1 # Invalid start byte +Should fail: C2 # Incomplete sequence +Should fail: F8 88 80 80 80 # 6-byte sequence +Should pass: 7F # Last valid 1-byte sequence (U+00007F) +Should pass: DF BF # Last valid 2-byte sequence (U+0007FF) +Should pass: EF BF BF # Last valid 3-byte sequence (U+00FFFF) +Should pass: 00 # First valid 1-byte sequence (U+000000) +Should pass: C2 80 # First valid 2-byte sequence (U+000080) +Should pass: E0 A0 80 # First valid 3-byte sequence (U+000800) +Should pass: F0 90 80 80 # First valid 4-byte sequence (U+000800) +Should fail: F8 88 80 80 80 # First 5-byte sequence - invalid per RFC 3629 +Should fail: FC 84 80 80 80 80 # First 6-byte sequence - invalid per RFC 3629 +Should pass: EF BF BD # U+00FFFD (replacement character) +Should fail: 80 # First continuation byte +Should fail: BF # Last continuation byte +Should fail: 80 BF # 2 continuation bytes +Should fail: 80 BF 80 # 3 continuation bytes +Should fail: 80 BF 80 BF # 4 continuation bytes +Should fail: 80 BF 80 BF 80 # 5 continuation bytes +Should fail: 80 BF 80 BF 80 BF # 6 continuation bytes +Should fail: 80 BF 80 BF 80 BF 80 # 7 continuation bytes +Should fail: FE # Impossible byte +Should fail: FF # Impossible byte +Should fail: FE FE FF FF # Impossible bytes +Should fail: C0 AF # Overlong "/" +Should fail: E0 80 AF # Overlong "/" +Should fail: F0 80 80 AF # Overlong "/" +Should fail: F8 80 80 80 AF # Overlong "/" +Should fail: FC 80 80 80 80 AF # Overlong "/" +Should fail: C0 80 AF # Overlong "/" (invalid) +Should fail: C1 BF # Overlong +Should fail: E0 9F BF # Overlong +Should fail: F0 8F BF BF # Overlong +Should fail: F8 87 BF BF BF # Overlong +Should fail: FC 83 BF BF BF BF # Overlong +Should pass: EF BF BE # U+FFFE (invalid unicode, valid UTF-8) +Should fail: EF BF BF # U+FFFF (invalid unicode, valid UTF-8) -- cgit v1.2.3 From 04ed996c8a36bbfadf076fde459a22d40190a532 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Mon, 23 Mar 2015 17:23:11 +0000 Subject: utf8_sequences.txt: Oops --- tests/utf8_sequences.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/utf8_sequences.txt b/tests/utf8_sequences.txt index 408b8f08..1b967b2e 100644 --- a/tests/utf8_sequences.txt +++ b/tests/utf8_sequences.txt @@ -49,4 +49,4 @@ Should fail: F0 8F BF BF # Overlong Should fail: F8 87 BF BF BF # Overlong Should fail: FC 83 BF BF BF BF # Overlong Should pass: EF BF BE # U+FFFE (invalid unicode, valid UTF-8) -Should fail: EF BF BF # U+FFFF (invalid unicode, valid UTF-8) +Should pass: EF BF BF # U+FFFF (invalid unicode, valid UTF-8) -- cgit v1.2.3 From f097ae0d0f2189363cc6f8acc8b4072657326cc4 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 23 Mar 2015 18:40:12 +0100 Subject: Backout 7726b627c3ea --- plugins/mod_http.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index 610ae0ae..86689aff 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -102,7 +102,6 @@ function module.add_host(module) end if not app_handlers[event_name] then app_handlers[event_name] = handler; - module:log("debug", "Adding app '%s' to handle %s", app_name, event_name); module:hook_object_event(server, event_name, handler); else module:log("warn", "App %s added handler twice for '%s', ignoring", app_name, event_name); -- cgit v1.2.3 From 84cdf3f61dc9aee854548da34929273d595bdba1 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 23 Mar 2015 18:44:12 +0100 Subject: mod_http: Log a debug message when adding new http apps and warn if no http ports are enabled --- plugins/mod_http.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index 86689aff..9ff3af74 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -110,6 +110,12 @@ function module.add_host(module) module:log("error", "Invalid route in %s, %q. See http://prosody.im/doc/developers/http#routes", app_name, key); end end + local services = portmanager.get_active_services(); + if services:get("https") or services:get("http") then + module:log("debug", "Serving '%s' at %s", app_name, module:http_url(app_name, app_path)); + else + module:log("warn", "Not listening on any ports, '%s' will be unreachable", app_name); + end end local function http_app_removed(event) -- cgit v1.2.3 From 0e041ac943e80bece48ed5cb5788e201ca4de98a Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 23 Mar 2015 18:45:02 +0100 Subject: mod_http: Return a static string from module:http_url() when no ports are enabled and log a warning --- plugins/mod_http.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index 9ff3af74..9b574bc8 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -69,6 +69,8 @@ function moduleapi.http_url(module, app_name, default_path) return url_build(url); end end + module:log("warn", "No http ports enabled, can't generate an external URL"); + return "http://disabled.invalid/"; end function module.add_host(module) -- cgit v1.2.3 From a5e6058fdad58e1dcd564fa04d4d5128a6dbc30c Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 24 Mar 2015 15:57:46 +0000 Subject: sessionmanager: Return 'not-allowed' error instead of the non-existent 'already-bound' error when client tries to bind a resource twice on the same stream (thanks Flow) fixes issue #484. --- core/sessionmanager.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/sessionmanager.lua b/core/sessionmanager.lua index 98ead07f..4b014d18 100644 --- a/core/sessionmanager.lua +++ b/core/sessionmanager.lua @@ -113,7 +113,7 @@ end -- returns nil, err_type, err, err_message on failure function bind_resource(session, resource) if not session.username then return nil, "auth", "not-authorized", "Cannot bind resource before authentication"; end - if session.resource then return nil, "cancel", "already-bound", "Cannot bind multiple resources on a single connection"; end + if session.resource then return nil, "cancel", "not-allowed", "Cannot bind multiple resources on a single connection"; end -- We don't support binding multiple resources resource = resourceprep(resource); -- cgit v1.2.3 From 6abbc2ab5823a10e33b1fd33b0b9e8466f7922fe Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 24 Mar 2015 16:03:37 +0000 Subject: mod_s2s: to/from attributes are required on s2s stream headers. Set them to '' when not available. Fixes #468. --- plugins/mod_s2s/mod_s2s.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua index d8846a6f..f5297efe 100644 --- a/plugins/mod_s2s/mod_s2s.lua +++ b/plugins/mod_s2s/mod_s2s.lua @@ -512,7 +512,7 @@ function session_open_stream(session, from, to) version = session.version and (session.version > 0 and "1.0" or nil), ["xml:lang"] = 'en', id = session.streamid, - from = from, to = to, + from = from or "", to = to or "", } if not from or (hosts[from] and hosts[from].modules.dialback) then attr["xmlns:db"] = 'jabber:server:dialback'; -- cgit v1.2.3 -- cgit v1.2.3 From 6f7c379a26a6c2cdb27f95f90e0eaee2979fa08a Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 24 Apr 2015 14:14:01 +0200 Subject: net.dns, mod_s2s: Add chasing of CNAMEs to net.dns and remove it from mod_s2s --- net/dns.lua | 11 ++++++++--- plugins/mod_s2s/s2sout.lib.lua | 12 ------------ 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/net/dns.lua b/net/dns.lua index 13417cee..28cb4419 100644 --- a/net/dns.lua +++ b/net/dns.lua @@ -694,15 +694,20 @@ local function comp_mx(a, b) -- - - - - - - - - - - - - - - - - - - comp_mx end -function resolver:peek (qname, qtype, qclass) -- - - - - - - - - - - - peek +function resolver:peek (qname, qtype, qclass, n) -- - - - - - - - - - - - peek qname, qtype, qclass = standardize(qname, qtype, qclass); local rrs = get(self.cache, qclass, qtype, qname); - if not rrs then return nil; end + if not rrs then + if n then if n <= 0 then return end else n = 3 end + rrs = get(self.cache, qclass, "CNAME", qname); + if not (rrs and rrs[1]) then return end + return self:peek(rrs[1].cname, qtype, qclass, n - 1); + end if prune(rrs, socket.gettime()) and qtype == '*' or not next(rrs) then set(self.cache, qclass, qtype, qname, nil); return nil; end - if self.unsorted[rrs] then table.sort (rrs, comp_mx); end + if self.unsorted[rrs] then table.sort (rrs, comp_mx); self.unsorted[rrs] = nil; end return rrs; end diff --git a/plugins/mod_s2s/s2sout.lib.lua b/plugins/mod_s2s/s2sout.lib.lua index b24faf85..67b8fd0f 100644 --- a/plugins/mod_s2s/s2sout.lib.lua +++ b/plugins/mod_s2s/s2sout.lib.lua @@ -169,18 +169,6 @@ function s2sout.try_connect(host_session, connect_host, connect_port, err) handle4 = adns.lookup(function (reply, err) handle4 = nil; - -- COMPAT: This is a compromise for all you CNAME-(ab)users :) - if not (reply and reply[#reply] and reply[#reply].a) then - local count = max_dns_depth; - reply = dns.peek(connect_host, "CNAME", "IN"); - while count > 0 and reply and reply[#reply] and not reply[#reply].a and reply[#reply].cname do - log("debug", "Looking up %s (DNS depth is %d)", tostring(reply[#reply].cname), count); - reply = dns.peek(reply[#reply].cname, "A", "IN") or dns.peek(reply[#reply].cname, "CNAME", "IN"); - count = count - 1; - end - end - -- end of CNAME resolving - if reply and reply[#reply] and reply[#reply].a then for _, ip in ipairs(reply) do log("debug", "DNS reply for %s gives us %s", connect_host, ip.a); -- cgit v1.2.3 From 87f8b27d746e20d0c65ddb6a9d0c0a4b88d26770 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 3 Apr 2015 12:10:30 +0200 Subject: util.datamanager: Fix traceback due to %s in log message --- util/datamanager.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/datamanager.lua b/util/datamanager.lua index b82349f1..b4138638 100644 --- a/util/datamanager.lua +++ b/util/datamanager.lua @@ -293,7 +293,7 @@ function users(host, store, typ) local mode, err = lfs.attributes(store_dir, "mode"); if not mode then - return function() log("debug", err or (store_dir .. " does not exist")) end + return function() log("debug", "%s", err or (store_dir .. " does not exist")) end end local next, state = lfs.dir(store_dir); return function(state) -- cgit v1.2.3 From ec5368f87acebd037399ebbb5be488ed154b8cff Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 26 Apr 2015 19:50:24 +0200 Subject: net.dns: Make sure argument to math.randomseed does not overflow a 32 bit *signed* int (blame Lua). Closes #439 --- net/dns.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/dns.lua b/net/dns.lua index 28cb4419..763ee9ec 100644 --- a/net/dns.lua +++ b/net/dns.lua @@ -225,7 +225,7 @@ end function dns.random(...) -- - - - - - - - - - - - - - - - - - - dns.random - math.randomseed(math.floor(10000*socket.gettime()) % 0x100000000); + math.randomseed(math.floor(10000*socket.gettime()) % 0x80000000); dns.random = math.random; return dns.random(...); end -- cgit v1.2.3 From 94868d065c4db18c7617447a48484d4d1daccdad Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 13 May 2015 21:43:05 +0200 Subject: mod_s2s/s2sout: Remove now unused config option dns_max_depth --- plugins/mod_s2s/s2sout.lib.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/mod_s2s/s2sout.lib.lua b/plugins/mod_s2s/s2sout.lib.lua index 67b8fd0f..dc122af7 100644 --- a/plugins/mod_s2s/s2sout.lib.lua +++ b/plugins/mod_s2s/s2sout.lib.lua @@ -29,7 +29,6 @@ local has_ipv4, has_ipv6; local dns_timeout = module:get_option_number("dns_timeout", 15); dns.settimeout(dns_timeout); -local max_dns_depth = module:get_option_number("dns_max_depth", 3); local s2sout = {}; -- cgit v1.2.3 From f5f621749be1d544ca1cdf1ad6cda7acbc1ec27b Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 13 May 2015 21:44:13 +0200 Subject: util.datamanager: Fix traceback from trying to purge when storage is empty or otherwise unaccessible (fixes #496) --- util/datamanager.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/util/datamanager.lua b/util/datamanager.lua index b4138638..a107d95c 100644 --- a/util/datamanager.lua +++ b/util/datamanager.lua @@ -348,8 +348,12 @@ end function purge(username, host) local host_dir = format("%s/%s/", data_path, encode(host)); + local ok, iter, state, var = pcall(lfs.dir, host_dir); + if not ok then + return ok, iter; + end local errs = {}; - for file in lfs.dir(host_dir) do + for file in iter, state, var do if lfs.attributes(host_dir..file, "mode") == "directory" then local store = decode(file); local ok, err = do_remove(getpath(username, host, store)); -- cgit v1.2.3 From 7227eb122a6ac2c2647314c390c961cabecf63b9 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 13 May 2015 21:47:39 +0200 Subject: mod_s2s/s2sout: Use the local address assigned to UDP sockets instead of util.net to enumerate possible source addresses --- plugins/mod_s2s/s2sout.lib.lua | 46 ++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/plugins/mod_s2s/s2sout.lib.lua b/plugins/mod_s2s/s2sout.lib.lua index dc122af7..5728f67b 100644 --- a/plugins/mod_s2s/s2sout.lib.lua +++ b/plugins/mod_s2s/s2sout.lib.lua @@ -18,13 +18,31 @@ local socket = require "socket"; local adns = require "net.adns"; local dns = require "net.dns"; local t_insert, t_sort, ipairs = table.insert, table.sort, ipairs; -local local_addresses = require "util.net".local_addresses; local s2s_destroy_session = require "core.s2smanager".destroy_session; local log = module._log; -local sources = {}; +local anysource = { IPv4 = "0.0.0.0", IPv6 = "::" }; +local function get_sources(addrs) + local sources = {}; + for _, IP in ipairs(addrs) do + local sock; + if IP.proto == "IPv4" then + sock = socket.udp(); + elseif IP.proto == "IPv6" then + sock = socket.udp6(); + end + sock:setpeername(IP.addr, 9); + local localaddr = sock:getsockname() or anysource[IP.proto]; + sock:close(); + if not sources[localaddr] then + sources[localaddr] = true; + t_insert(sources, new_ip(localaddr, IP.proto)); + end + end + return sources; +end local has_ipv4, has_ipv6; local dns_timeout = module:get_option_number("dns_timeout", 15); @@ -177,7 +195,7 @@ function s2sout.try_connect(host_session, connect_host, connect_port, err) if have_other_result then if #IPs > 0 then - rfc6724_dest(host_session.ip_hosts, sources); + rfc6724_dest(host_session.ip_hosts, get_sources(host_session.ip_hosts)); for i = 1, #IPs do IPs[i] = {ip = IPs[i], port = connect_port}; end @@ -213,7 +231,7 @@ function s2sout.try_connect(host_session, connect_host, connect_port, err) if have_other_result then if #IPs > 0 then - rfc6724_dest(host_session.ip_hosts, sources); + rfc6724_dest(host_session.ip_hosts, get_sources(host_session.ip_hosts)); for i = 1, #IPs do IPs[i] = {ip = IPs[i], port = connect_port}; end @@ -315,28 +333,12 @@ module:hook_global("service-added", function (event) return; end for source, _ in pairs(s2s_sources) do - if source == "*" or source == "0.0.0.0" then - for _, addr in ipairs(local_addresses("ipv4", true)) do - sources[#sources + 1] = new_ip(addr, "IPv4"); - end - elseif source == "::" then - for _, addr in ipairs(local_addresses("ipv6", true)) do - sources[#sources + 1] = new_ip(addr, "IPv6"); - end - else - sources[#sources + 1] = new_ip(source, (source:find(":") and "IPv6") or "IPv4"); - end - end - for i = 1,#sources do - if sources[i].proto == "IPv6" then + if source:find(":") then has_ipv6 = true; - elseif sources[i].proto == "IPv4" then + else has_ipv4 = true; end end - if not (has_ipv4 or has_ipv6) then - module:log("warn", "No local IPv4 or IPv6 addresses detected, outgoing connections may fail"); - end end); return s2sout; -- cgit v1.2.3 From 54e6e73b9c65d2e6a649e33d815959a9ceac8ddd Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 13 May 2015 21:55:08 +0200 Subject: mod_s2s: Don't cache session.sends2s (or do it later), prevents sending data after session was closed --- plugins/mod_s2s/mod_s2s.lua | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua index f5297efe..1408fd5e 100644 --- a/plugins/mod_s2s/mod_s2s.lua +++ b/plugins/mod_s2s/mod_s2s.lua @@ -147,7 +147,7 @@ end -- Stream is authorised, and ready for normal stanzas function mark_connected(session) - local sendq, send = session.sendq, session.sends2s; + local sendq = session.sendq; local from, to = session.from_host, session.to_host; @@ -170,6 +170,7 @@ function mark_connected(session) if session.direction == "outgoing" then if sendq then session.log("debug", "sending %d queued stanzas across new outgoing connection to %s", #sendq, session.to_host); + local send = session.sends2s; for i, data in ipairs(sendq) do send(data[1]); sendq[i] = nil; @@ -269,8 +270,6 @@ local stream_callbacks = { default_ns = "jabber:server", handlestanza = core_pr local xmlns_xmpp_streams = "urn:ietf:params:xml:ns:xmpp-streams"; function stream_callbacks.streamopened(session, attr) - local send = session.sends2s; - session.version = tonumber(attr.version) or 0; -- TODO: Rename session.secure to session.encrypted @@ -360,7 +359,7 @@ function stream_callbacks.streamopened(session, attr) end log("debug", "Sending stream features: %s", tostring(features)); - send(features); + session.sends2s(features); end session.notopen = nil; elseif session.direction == "outgoing" then -- cgit v1.2.3 From eb5f70d68e06daf5d3ef6bcef9163fcabc5ce02a Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 13 May 2015 21:56:22 +0200 Subject: mod_s2s: Mark stream as opened directly after opening stream, prevents session.close opening it again --- plugins/mod_s2s/mod_s2s.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua index 1408fd5e..ee539a2a 100644 --- a/plugins/mod_s2s/mod_s2s.lua +++ b/plugins/mod_s2s/mod_s2s.lua @@ -349,6 +349,7 @@ function stream_callbacks.streamopened(session, attr) end session:open_stream(session.to_host, session.from_host) + session.notopen = nil; if session.version >= 1.0 then local features = st.stanza("stream:features"); @@ -361,7 +362,6 @@ function stream_callbacks.streamopened(session, attr) log("debug", "Sending stream features: %s", tostring(features)); session.sends2s(features); end - session.notopen = nil; elseif session.direction == "outgoing" then session.notopen = nil; if not attr.id then -- cgit v1.2.3 From 835f4fbffc133104d90ff0c4382aef2605e60c1e Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 14 May 2015 00:22:13 +0200 Subject: s2smanager: Make sure destroyed sessions have a sends2s method --- core/s2smanager.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/core/s2smanager.lua b/core/s2smanager.lua index 06d3f2c9..fb5c4299 100644 --- a/core/s2smanager.lua +++ b/core/s2smanager.lua @@ -64,6 +64,7 @@ function retire_session(session, reason) function session.send(data) log("debug", "Discarding data sent to resting session: %s", tostring(data)); end function session.data(data) log("debug", "Discarding data received from resting session: %s", tostring(data)); end + session.sends2s = session.send; return setmetatable(session, resting_session); end -- cgit v1.2.3 From 37efc0dcf60fc34f896589af363d8b6f02866f08 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 16 Jun 2015 15:13:47 +0200 Subject: MUC: Remove half of monkeypatch that was supposed to make admins always be room owners, fixes #458 --- plugins/muc/mod_muc.lua | 5 ----- 1 file changed, 5 deletions(-) diff --git a/plugins/muc/mod_muc.lua b/plugins/muc/mod_muc.lua index 6e86ab73..c932b0a4 100644 --- a/plugins/muc/mod_muc.lua +++ b/plugins/muc/mod_muc.lua @@ -44,16 +44,11 @@ local function is_admin(jid) return um_is_admin(jid, module.host); end -local _set_affiliation = muc_new_room.room_mt.set_affiliation; local _get_affiliation = muc_new_room.room_mt.get_affiliation; function muclib.room_mt:get_affiliation(jid) if is_admin(jid) then return "owner"; end return _get_affiliation(self, jid); end -function muclib.room_mt:set_affiliation(actor, jid, affiliation, callback, reason) - if is_admin(jid) then return nil, "modify", "not-acceptable"; end - return _set_affiliation(self, actor, jid, affiliation, callback, reason); -end local function room_route_stanza(room, stanza) module:send(stanza); end local function room_save(room, forced) -- cgit v1.2.3 From 82da4b5fce4f6a7f29e608ba2358bba0f1f861fb Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 25 Jun 2015 17:54:19 +0200 Subject: Backed out changeset bea3862b6bde in favor of a different approach --- plugins/muc/mod_muc.lua | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/muc/mod_muc.lua b/plugins/muc/mod_muc.lua index c932b0a4..6e86ab73 100644 --- a/plugins/muc/mod_muc.lua +++ b/plugins/muc/mod_muc.lua @@ -44,11 +44,16 @@ local function is_admin(jid) return um_is_admin(jid, module.host); end +local _set_affiliation = muc_new_room.room_mt.set_affiliation; local _get_affiliation = muc_new_room.room_mt.get_affiliation; function muclib.room_mt:get_affiliation(jid) if is_admin(jid) then return "owner"; end return _get_affiliation(self, jid); end +function muclib.room_mt:set_affiliation(actor, jid, affiliation, callback, reason) + if is_admin(jid) then return nil, "modify", "not-acceptable"; end + return _set_affiliation(self, actor, jid, affiliation, callback, reason); +end local function room_route_stanza(room, stanza) module:send(stanza); end local function room_save(room, forced) -- cgit v1.2.3 From e3c03ec01dad027c320e4d0505add077fe7f1f29 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 25 Jun 2015 17:58:24 +0200 Subject: MUC: Prevent admins from being given affiliatons other than owner --- plugins/muc/mod_muc.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/muc/mod_muc.lua b/plugins/muc/mod_muc.lua index 6e86ab73..acc2da0d 100644 --- a/plugins/muc/mod_muc.lua +++ b/plugins/muc/mod_muc.lua @@ -51,7 +51,7 @@ function muclib.room_mt:get_affiliation(jid) return _get_affiliation(self, jid); end function muclib.room_mt:set_affiliation(actor, jid, affiliation, callback, reason) - if is_admin(jid) then return nil, "modify", "not-acceptable"; end + if affiliation ~= "owner" and is_admin(jid) then return nil, "modify", "not-acceptable"; end return _set_affiliation(self, actor, jid, affiliation, callback, reason); end -- cgit v1.2.3 From 42f35e0009b0097b628268d7c4ea10fbdd63a49f Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 10 Aug 2015 22:13:02 +0200 Subject: mod_component: Fire an event on successful component authentication (For Goffi) --- plugins/mod_component.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/mod_component.lua b/plugins/mod_component.lua index 7bc0f5b7..11abab79 100644 --- a/plugins/mod_component.lua +++ b/plugins/mod_component.lua @@ -85,6 +85,7 @@ function module.add_host(module) session.type = "component"; module:log("info", "External component successfully authenticated"); session.send(st.stanza("handshake")); + module:fire_event("component-authenticated", { session = session }); return true; end -- cgit v1.2.3 From 3384ae63d933177621a0ba864095fc37d5ed751b Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 20 Aug 2015 09:14:15 +0200 Subject: ejabberd2prosody: Support password stored as SCRAM hashes --- tools/ejabberd2prosody.lua | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tools/ejabberd2prosody.lua b/tools/ejabberd2prosody.lua index af87594e..069b5161 100755 --- a/tools/ejabberd2prosody.lua +++ b/tools/ejabberd2prosody.lua @@ -72,7 +72,22 @@ function vcard(node, host, stanza) print("["..(err or "success").."] vCard: "..node.."@"..host); end function password(node, host, password) - local ret, err = dm.store(node, host, "accounts", {password = password}); + local data = {}; + if type(password) == "string" then + data.password = password; + elseif type(password) == "table" and password[1] == "scram" then + local unb64 = require"mime".unb64; + local function hex(s) + return s:gsub(".", function (c) + return ("%02x"):format(c:byte()); + end); + end + data.stored_key = hex(unb64(password[2])); + data.server_key = hex(unb64(password[3])); + data.salt = unb64(password[4]); + data.iteration_count = password[5]; + end + local ret, err = dm.store(node, host, "accounts", data); print("["..(err or "success").."] accounts: "..node.."@"..host); end function roster(node, host, jid, item) -- cgit v1.2.3 From fbd3b9ada4df1acf4ed8e93493c60b37ecea7868 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Mon, 25 May 2015 23:16:11 +0100 Subject: net.dns: Unconditionally cache records found in answers --- net/dns.lua | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/net/dns.lua b/net/dns.lua index 763ee9ec..7ec13c81 100644 --- a/net/dns.lua +++ b/net/dns.lua @@ -855,9 +855,7 @@ function resolver:receive(rset) -- - - - - - - - - - - - - - - - - receive --self.print(response); for j,rr in pairs(response.answer) do - if rr.name:sub(-#response.question[1].name, -1) == response.question[1].name then - self:remember(rr, response.question[1].type) - end + self:remember(rr, response.question[1].type) end -- retire the query -- cgit v1.2.3 From 46fa6a1d17e3efbd7ffd77987810a5e1b1d20d09 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 4 Sep 2015 11:26:51 +0100 Subject: mod_pep: Document data structures, so I don't have to spend time remembering every time I work on this module --- plugins/mod_pep.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/mod_pep.lua b/plugins/mod_pep.lua index bdb742e3..7b4c5ddc 100644 --- a/plugins/mod_pep.lua +++ b/plugins/mod_pep.lua @@ -17,9 +17,13 @@ local type = type; local calculate_hash = require "util.caps".calculate_hash; local core_post_stanza = prosody.core_post_stanza; +-- Used as canonical 'empty table' local NULL = {}; +-- data[user_bare_jid][node] = item_stanza local data = {}; +--- recipients[user_bare_jid][contact_full_jid][subscribed_node] = true local recipients = {}; +-- hash_map[hash][subscribed_nodes] = true local hash_map = {}; module.save = function() -- cgit v1.2.3 From a6f64405217d5bd89d60794eca0324844e5e48ef Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 25 Sep 2015 16:48:25 +0100 Subject: mod_pep: Don't store contacts' subscriptions to a user's nodes when that user is offline --- plugins/mod_pep.lua | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/plugins/mod_pep.lua b/plugins/mod_pep.lua index 7b4c5ddc..22790869 100644 --- a/plugins/mod_pep.lua +++ b/plugins/mod_pep.lua @@ -16,6 +16,7 @@ local next = next; local type = type; local calculate_hash = require "util.caps".calculate_hash; local core_post_stanza = prosody.core_post_stanza; +local bare_sessions = prosody.bare_sessions; -- Used as canonical 'empty table' local NULL = {}; @@ -122,6 +123,9 @@ module:hook("presence/bare", function(event) local t = stanza.attr.type; local self = not stanza.attr.to; + -- Only cache subscriptions if user is online + if not bare_sessions[user] then return; end + if not t then -- available presence if self or subscription_presence(user, stanza.attr.from) then local recipient = stanza.attr.from; @@ -283,3 +287,11 @@ module:hook("account-disco-items", function(event) end end end); + +module:hook("resource-unbind", function (event) + local user_bare_jid = event.session.username.."@"..event.session.host; + if not bare_sessions[user_bare_jid] then -- User went offline + -- We don't need this info cached anymore, clear it. + recipients[user_bare_jid] = nil; + end +end); -- cgit v1.2.3 From 9ef58d26781742a3b120364f7f828bb717af3882 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 18 Sep 2015 16:14:43 +0200 Subject: xep227toprosody: Pass parser to callbacks (needed since addition of stanza size limits) --- tools/xep227toprosody.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/xep227toprosody.lua b/tools/xep227toprosody.lua index 0862b0c1..81c9863b 100755 --- a/tools/xep227toprosody.lua +++ b/tools/xep227toprosody.lua @@ -202,7 +202,7 @@ function lxp_handlers.StartElement(parser, elementname, attributes) --count = count + 1; if curr_host ~= "" then -- forward to xmlhandlers - user_handlers:StartElement(elementname, attributes); + user_handlers.StartElement(parser, elementname, attributes); elseif (curr_ns == xmlns_xep227) and (name == "host") then curr_host = attributes["jid"]; -- start of host element print("Begin parsing host "..curr_host); @@ -226,7 +226,7 @@ function lxp_handlers.EndElement(parser, elementname) curr_host = "" -- end of host element else -- forward to xmlhandlers - user_handlers:EndElement(elementname); + user_handlers.EndElement(parser, elementname); end elseif (curr_ns ~= xmlns_xep227) or (name ~= "server-data") then io.stderr:write("Unhandled XML element: ", name, "\n"); @@ -237,7 +237,7 @@ end function lxp_handlers.CharacterData(parser, string) if curr_host ~= "" then -- forward to xmlhandlers - user_handlers:CharacterData(string); + user_handlers.CharacterData(parser, string); end end -- cgit v1.2.3 From db90c1c0787046114aa61b004af941581f2cd6d8 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 26 Sep 2015 19:34:58 +0200 Subject: mod_http_files: Strip trailing directory separator regardless of directionality of the slash (fixes #545) --- plugins/mod_http_files.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_http_files.lua b/plugins/mod_http_files.lua index 3a9368b9..9d81f540 100644 --- a/plugins/mod_http_files.lua +++ b/plugins/mod_http_files.lua @@ -62,7 +62,7 @@ function serve(opts) local request, response = event.request, event.response; local orig_path = request.path; local full_path = base_path .. (path and "/"..path or ""); - local attr = stat((full_path:gsub('%'..path_sep..'+$',''))); + local attr = stat(full_path:match("^.*[^\\/]")); -- Strip trailing path separator because Windows if not attr then return 404; end -- cgit v1.2.3 From 3945d3f2f8ad4eb04d9acc7c3b8fccb18e37dae1 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 26 Sep 2015 19:35:56 +0200 Subject: mod_http_files: Translate forward slashes to local directory separators --- plugins/mod_http_files.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_http_files.lua b/plugins/mod_http_files.lua index 9d81f540..9839fed9 100644 --- a/plugins/mod_http_files.lua +++ b/plugins/mod_http_files.lua @@ -61,7 +61,7 @@ function serve(opts) local function serve_file(event, path) local request, response = event.request, event.response; local orig_path = request.path; - local full_path = base_path .. (path and "/"..path or ""); + local full_path = base_path .. (path and "/"..path or ""):gsub("/", path_sep); local attr = stat(full_path:match("^.*[^\\/]")); -- Strip trailing path separator because Windows if not attr then return 404; -- cgit v1.2.3 From 40775d4c4574ddca914459f9a993f3c8d3e16774 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 11 Oct 2015 18:49:14 +0200 Subject: util.openssl: Separate extension sections into one for self-signed certs and one for requests --- util/openssl.lua | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/util/openssl.lua b/util/openssl.lua index ef3fba96..39fe99d6 100644 --- a/util/openssl.lua +++ b/util/openssl.lua @@ -18,8 +18,8 @@ function config.new() return setmetatable({ req = { distinguished_name = "distinguished_name", - req_extensions = "v3_extensions", - x509_extensions = "v3_extensions", + req_extensions = "certrequest", + x509_extensions = "selfsigned", prompt = "no", }, distinguished_name = { @@ -31,12 +31,16 @@ function config.new() commonName = "example.com", emailAddress = "xmpp@example.com", }, - v3_extensions = { + certrequest = { basicConstraints = "CA:FALSE", keyUsage = "digitalSignature,keyEncipherment", extendedKeyUsage = "serverAuth,clientAuth", subjectAltName = "@subject_alternative_name", }, + selfsigned = { + basicConstraints = "CA:TRUE", + subjectAltName = "@subject_alternative_name", + }, subject_alternative_name = { DNS = {}, otherName = {}, -- cgit v1.2.3 From 5f7129b28bf6f6945e035dbac1731e1dc3096978 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 14 Oct 2015 20:55:26 +0200 Subject: Makefile: Use more specific globbing for core directory in Makefile (Thanks Robert Scheck) (fixes #532) --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0b704e5a..46a8f49d 100644 --- a/Makefile +++ b/Makefile @@ -29,7 +29,7 @@ install: prosody.install prosodyctl.install prosody.cfg.lua.install util/encodin install -d $(SOURCE)/core $(SOURCE)/net $(SOURCE)/util install -m755 ./prosody.install $(BIN)/prosody install -m755 ./prosodyctl.install $(BIN)/prosodyctl - install -m644 core/* $(SOURCE)/core + install -m644 core/*.lua $(SOURCE)/core install -m644 net/*.lua $(SOURCE)/net install -d $(SOURCE)/net/http install -m644 net/http/*.lua $(SOURCE)/net/http -- cgit v1.2.3 From 67e6c8ceae722d153207a89bc3c3eca452fa2874 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 9 Nov 2015 14:16:39 +0100 Subject: cert/openssl.cnf: Split CSR and self-signed extensions into separate sections (see d2d7ad2563f9) --- certs/openssl.cnf | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/certs/openssl.cnf b/certs/openssl.cnf index 091409c4..ee17b1cf 100644 --- a/certs/openssl.cnf +++ b/certs/openssl.cnf @@ -13,8 +13,8 @@ SRVName = 1.3.6.1.5.5.7.8.7 default_bits = 4096 default_keyfile = example.com.key distinguished_name = distinguished_name -req_extensions = v3_extensions -x509_extensions = v3_extensions +req_extensions = certrequest +x509_extensions = selfsigned # ask about the DN? prompt = no @@ -28,16 +28,22 @@ organizationName = Your Organisation organizationalUnitName = XMPP Department emailAddress = xmpp@example.com -[ v3_extensions ] +[ certrequest ] # for certificate requests (req_extensions) -# and self-signed certificates (x509_extensions) basicConstraints = CA:FALSE keyUsage = digitalSignature,keyEncipherment extendedKeyUsage = serverAuth,clientAuth subjectAltName = @subject_alternative_name +[ selfsigned ] + +# and self-signed certificates (x509_extensions) + +basicConstraints = CA:TRUE +subjectAltName = @subject_alternative_name + [ subject_alternative_name ] # See http://tools.ietf.org/html/rfc6120#section-13.7.1.2 for more info. -- cgit v1.2.3 From 5feba6765f7b51377e94eb45b5ae90a89d629c78 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 17 Nov 2015 17:01:25 +0000 Subject: muc.lib: Fix pattern so that it doesn't match hashes containing null bytes, causing dropped stanzas (thanks Jitsi folk!) --- plugins/muc/muc.lib.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/muc/muc.lib.lua b/plugins/muc/muc.lib.lua index 8028f5ae..d42fb2eb 100644 --- a/plugins/muc/muc.lib.lua +++ b/plugins/muc/muc.lib.lua @@ -361,7 +361,7 @@ local function construct_stanza_id(room, stanza) end local function deconstruct_stanza_id(room, stanza) local from_jid_possiblybare, to_nick = stanza.attr.from, stanza.attr.to; - local from_jid, id, to_jid_hash = (base64.decode(stanza.attr.id) or ""):match("^(.+)%z(.*)%z(.+)$"); + local from_jid, id, to_jid_hash = (base64.decode(stanza.attr.id) or ""):match("^(%Z+)%z(%Z*)%z(.+)$"); local from_nick = room._jid_nick[from_jid]; if not(from_nick) then return; end -- cgit v1.2.3 From 1944f70088f12274f4e69cf41e601b47dd73348e Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 8 Dec 2015 23:20:37 +0100 Subject: util.uuid: Remove unused import --- util/uuid.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/util/uuid.lua b/util/uuid.lua index 796c8ee4..bb70d000 100644 --- a/util/uuid.lua +++ b/util/uuid.lua @@ -7,7 +7,6 @@ -- -local m_random = math.random; local tostring = tostring; local os_time = os.time; local os_clock = os.clock; -- cgit v1.2.3 From 17d6ea116ea31334f034d5f2433c2c4cff79e2ff Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Wed, 16 Dec 2015 16:41:48 +0000 Subject: MUC: Fix incorrect nesting of status codes when room config changes (fixes #579) --- plugins/muc/muc.lib.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/muc/muc.lib.lua b/plugins/muc/muc.lib.lua index d42fb2eb..5879c256 100644 --- a/plugins/muc/muc.lib.lua +++ b/plugins/muc/muc.lib.lua @@ -736,7 +736,7 @@ function room_mt:process_form(origin, stanza) if dirty or whois_changed then local msg = st.message({type='groupchat', from=self.jid}) - :tag('x', {xmlns='http://jabber.org/protocol/muc#user'}):up() + :tag('x', {xmlns='http://jabber.org/protocol/muc#user'}); if dirty then msg.tags[1]:tag('status', {code = '104'}):up(); @@ -745,6 +745,7 @@ function room_mt:process_form(origin, stanza) local code = (whois == 'moderators') and "173" or "172"; msg.tags[1]:tag('status', {code = code}):up(); end + msg:up(); self:broadcast_message(msg, false) end -- cgit v1.2.3 From aea8550ca241793e04baa6d717202edc50d7d9c2 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 22 Dec 2015 14:15:09 +0000 Subject: mod_admin_telnet: Backport 06696882d972 from 0.10 (this command greatly helps with debugging HTTP issues) --- plugins/mod_admin_telnet.lua | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index 437ded01..86403606 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -1081,6 +1081,33 @@ function def_env.dns:cache() return true, "Cache:\n"..tostring(dns.cache()) end +def_env.http = {}; + +function def_env.http:list() + local print = self.session.print; + + for host in pairs(prosody.hosts) do + local http_apps = modulemanager.get_items("http-provider", host); + if #http_apps > 0 then + local http_host = module:context(host):get_option("http_host"); + print("HTTP endpoints on "..host..(http_host and (" (using "..http_host.."):") or ":")); + for _, provider in ipairs(http_apps) do + local url = module:context(host):http_url(provider.name); + print("", url); + end + print(""); + end + end + + local default_host = module:get_option("http_default_host"); + if not default_host then + print("HTTP requests to unknown hosts will return 404 Not Found"); + else + print("HTTP requests to unknown hosts will be handled by "..default_host); + end + return true; +end + ------------- function printbanner(session) -- cgit v1.2.3 From 930cf01a13bef18ffc9ea70af0467687ec279e02 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 23 Dec 2015 12:07:03 +0100 Subject: certs/Makefile: Run key generation with a stricter umask (fixes a race condition) --- certs/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/certs/Makefile b/certs/Makefile index f3854c5f..c709ff91 100644 --- a/certs/Makefile +++ b/certs/Makefile @@ -26,5 +26,5 @@ keysize=2048 sed 's,example\.com,$*,g' openssl.cnf > $@ %.key: - openssl genrsa $(keysize) > $@ - @chmod 400 $@ + umask 0077 && openssl genrsa -out $@ $(keysize) + @chmod 400 $@ -c -- cgit v1.2.3 From d72c401d45e94b2a70187acfdc4880e975457469 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Wed, 6 Jan 2016 00:24:06 +0000 Subject: tests/test.lua: Fix fake module() function to prevent _M from being _G (test.lua's environment), which caused modules to break the sandbox when they set _M.* --- tests/test.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/test.lua b/tests/test.lua index de1e40fd..bb11ab26 100644 --- a/tests/test.lua +++ b/tests/test.lua @@ -137,7 +137,10 @@ function dotest(unitname) end local oldmodule, old_M = _fakeG.module, _fakeG._M; - _fakeG.module = function () _M = _G end + _fakeG.module = function () + setmetatable(unit, nil); + unit._M = unit; + end setfenv(chunk, unit); local success, err = pcall(chunk); _fakeG.module, _fakeG._M = oldmodule, old_M; -- cgit v1.2.3 From 87364cb8cd7d8914ef243fac42385648982412ac Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 17 May 2013 14:52:52 +0100 Subject: util.ip: Automatically determine protocol of IP address if none specified. Return error if invalid. [Backported from 0.10] --- util/ip.lua | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/util/ip.lua b/util/ip.lua index 856bf034..226432cc 100644 --- a/util/ip.lua +++ b/util/ip.lua @@ -12,7 +12,15 @@ local ip_mt = { __index = function (ip, key) return (ip_methods[key])(ip); end, local hex2bits = { ["0"] = "0000", ["1"] = "0001", ["2"] = "0010", ["3"] = "0011", ["4"] = "0100", ["5"] = "0101", ["6"] = "0110", ["7"] = "0111", ["8"] = "1000", ["9"] = "1001", ["A"] = "1010", ["B"] = "1011", ["C"] = "1100", ["D"] = "1101", ["E"] = "1110", ["F"] = "1111" }; local function new_ip(ipStr, proto) - if proto ~= "IPv4" and proto ~= "IPv6" then + if not proto then + local sep = ipStr:match("^%x+(.)"); + if sep == ":" then proto = "IPv6" + elseif sep == "." then proto = "IPv4" + end + if not proto then + return nil, "invalid address"; + end + elseif proto ~= "IPv4" and proto ~= "IPv6" then return nil, "invalid protocol"; end if proto == "IPv6" and ipStr:find('.', 1, true) then -- cgit v1.2.3 From 63b5f5553703fde25387fe002054fa8658ae24fc Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 18 May 2013 21:41:17 +0100 Subject: util.ip: Fix protocol detection of IPv6 addresses beginning with : [Backported from 0.10] --- util/ip.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/util/ip.lua b/util/ip.lua index 226432cc..043303ee 100644 --- a/util/ip.lua +++ b/util/ip.lua @@ -14,8 +14,10 @@ local hex2bits = { ["0"] = "0000", ["1"] = "0001", ["2"] = "0010", ["3"] = "0011 local function new_ip(ipStr, proto) if not proto then local sep = ipStr:match("^%x+(.)"); - if sep == ":" then proto = "IPv6" - elseif sep == "." then proto = "IPv4" + if sep == ":" or (not(sep) and ipStr:sub(1,1) == ":") then + proto = "IPv6" + elseif sep == "." then + proto = "IPv4" end if not proto then return nil, "invalid address"; -- cgit v1.2.3 From 08a3d63a95960b865184972700e0ce1cf13cf6f7 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 18 May 2013 21:41:17 +0100 Subject: util.ip: Fix protocol detection of IPv6 addresses beginning with : [Backported from 0.10] --- util/ip.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/util/ip.lua b/util/ip.lua index 226432cc..043303ee 100644 --- a/util/ip.lua +++ b/util/ip.lua @@ -14,8 +14,10 @@ local hex2bits = { ["0"] = "0000", ["1"] = "0001", ["2"] = "0010", ["3"] = "0011 local function new_ip(ipStr, proto) if not proto then local sep = ipStr:match("^%x+(.)"); - if sep == ":" then proto = "IPv6" - elseif sep == "." then proto = "IPv4" + if sep == ":" or (not(sep) and ipStr:sub(1,1) == ":") then + proto = "IPv6" + elseif sep == "." then + proto = "IPv4" end if not proto then return nil, "invalid address"; -- cgit v1.2.3 From 0f126b9952078c0194677fd9c4ada56ca020b25f Mon Sep 17 00:00:00 2001 From: Florian Zeitz Date: Tue, 18 Jun 2013 23:02:20 +0200 Subject: net.dns: Support IPv6 addresses in resolv.conf [Backported from 0.10] --- net/dns.lua | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/net/dns.lua b/net/dns.lua index 7ec13c81..9d90c24c 100644 --- a/net/dns.lua +++ b/net/dns.lua @@ -14,6 +14,7 @@ local socket = require "socket"; local timer = require "util.timer"; +local new_ip = require "util.ip".new_ip; local _, windows = pcall(require, "util.windows"); local is_windows = (_ and windows) or os.getenv("WINDIR"); @@ -599,11 +600,12 @@ function resolver:adddefaultnameservers() -- - - - - adddefaultnameservers if resolv_conf then for line in resolv_conf:lines() do line = line:gsub("#.*$", "") - :match('^%s*nameserver%s+(.*)%s*$'); + :match('^%s*nameserver%s+([%x:%.]*)%s*$'); if line then - line:gsub("%f[%d.](%d+%.%d+%.%d+%.%d+)%f[^%d.]", function (address) - self:addnameserver(address) - end); + local ip = new_ip(line); + if ip then + self:addnameserver(ip.addr); + end end end end @@ -623,7 +625,12 @@ function resolver:getsocket(servernum) -- - - - - - - - - - - - - getsocket if sock then return sock; end local ok, err; - sock, err = socket.udp(); + local peer = self.server[servernum]; + if peer:find(":") then + sock, err = socket.udp6(); + else + sock, err = socket.udp(); + end if sock and self.socket_wrapper then sock, err = self.socket_wrapper(sock, self); end if not sock then return nil, err; @@ -636,7 +643,7 @@ function resolver:getsocket(servernum) -- - - - - - - - - - - - - getsocket -- if so, try the next server ok, err = sock:setsockname('*', 0); if not ok then return self:servfail(sock, err); end - ok, err = sock:setpeername(self.server[servernum], 53); + ok, err = sock:setpeername(peer, 53); if not ok then return self:servfail(sock, err); end return sock; end -- cgit v1.2.3 From 60aa072e84e30fde745e5c7761bfb2c3bd0f4100 Mon Sep 17 00:00:00 2001 From: Florian Zeitz Date: Tue, 18 Jun 2013 23:02:20 +0200 Subject: net.dns: Support IPv6 addresses in resolv.conf [Backported from 0.10] --- net/dns.lua | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/net/dns.lua b/net/dns.lua index 7ec13c81..9d90c24c 100644 --- a/net/dns.lua +++ b/net/dns.lua @@ -14,6 +14,7 @@ local socket = require "socket"; local timer = require "util.timer"; +local new_ip = require "util.ip".new_ip; local _, windows = pcall(require, "util.windows"); local is_windows = (_ and windows) or os.getenv("WINDIR"); @@ -599,11 +600,12 @@ function resolver:adddefaultnameservers() -- - - - - adddefaultnameservers if resolv_conf then for line in resolv_conf:lines() do line = line:gsub("#.*$", "") - :match('^%s*nameserver%s+(.*)%s*$'); + :match('^%s*nameserver%s+([%x:%.]*)%s*$'); if line then - line:gsub("%f[%d.](%d+%.%d+%.%d+%.%d+)%f[^%d.]", function (address) - self:addnameserver(address) - end); + local ip = new_ip(line); + if ip then + self:addnameserver(ip.addr); + end end end end @@ -623,7 +625,12 @@ function resolver:getsocket(servernum) -- - - - - - - - - - - - - getsocket if sock then return sock; end local ok, err; - sock, err = socket.udp(); + local peer = self.server[servernum]; + if peer:find(":") then + sock, err = socket.udp6(); + else + sock, err = socket.udp(); + end if sock and self.socket_wrapper then sock, err = self.socket_wrapper(sock, self); end if not sock then return nil, err; @@ -636,7 +643,7 @@ function resolver:getsocket(servernum) -- - - - - - - - - - - - - getsocket -- if so, try the next server ok, err = sock:setsockname('*', 0); if not ok then return self:servfail(sock, err); end - ok, err = sock:setpeername(self.server[servernum], 53); + ok, err = sock:setpeername(peer, 53); if not ok then return self:servfail(sock, err); end return sock; end -- cgit v1.2.3 From 5e3000f44c586ec081944e4a131c31b1dbf548da Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 4 Jan 2016 17:47:40 +0100 Subject: util.ip: Support zone id syntax in IPv6 addresses --- util/ip.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/util/ip.lua b/util/ip.lua index 043303ee..acfd7f24 100644 --- a/util/ip.lua +++ b/util/ip.lua @@ -25,6 +25,10 @@ local function new_ip(ipStr, proto) elseif proto ~= "IPv4" and proto ~= "IPv6" then return nil, "invalid protocol"; end + local zone; + if proto == "IPv6" and ipStr:find('%', 1, true) then + ipStr, zone = ipStr:match("^(.-)%%(.*)"); + end if proto == "IPv6" and ipStr:find('.', 1, true) then local changed; ipStr, changed = ipStr:gsub(":(%d+)%.(%d+)%.(%d+)%.(%d+)$", function(a,b,c,d) @@ -33,7 +37,7 @@ local function new_ip(ipStr, proto) if changed ~= 1 then return nil, "invalid-address"; end end - return setmetatable({ addr = ipStr, proto = proto }, ip_mt); + return setmetatable({ addr = ipStr, proto = proto, zone = zone }, ip_mt); end local function toBits(ip) -- cgit v1.2.3 From 26afa1e5853c7443b64fe69609c37dc13a30cfec Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 4 Jan 2016 15:46:06 +0100 Subject: net.dns: Allow a zone id in resolv.conf (eg like %eth0) --- net/dns.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/dns.lua b/net/dns.lua index 9d90c24c..49958ed7 100644 --- a/net/dns.lua +++ b/net/dns.lua @@ -600,7 +600,7 @@ function resolver:adddefaultnameservers() -- - - - - adddefaultnameservers if resolv_conf then for line in resolv_conf:lines() do line = line:gsub("#.*$", "") - :match('^%s*nameserver%s+([%x:%.]*)%s*$'); + :match('^%s*nameserver%s+([%x:%.]*%%?%S*)%s*$'); if line then local ip = new_ip(line); if ip then -- cgit v1.2.3 From 277db4f6dd327525d50ea1fff0a7e0247d77903e Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 4 Jan 2016 17:47:40 +0100 Subject: util.ip: Support zone id syntax in IPv6 addresses --- util/ip.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/util/ip.lua b/util/ip.lua index 043303ee..acfd7f24 100644 --- a/util/ip.lua +++ b/util/ip.lua @@ -25,6 +25,10 @@ local function new_ip(ipStr, proto) elseif proto ~= "IPv4" and proto ~= "IPv6" then return nil, "invalid protocol"; end + local zone; + if proto == "IPv6" and ipStr:find('%', 1, true) then + ipStr, zone = ipStr:match("^(.-)%%(.*)"); + end if proto == "IPv6" and ipStr:find('.', 1, true) then local changed; ipStr, changed = ipStr:gsub(":(%d+)%.(%d+)%.(%d+)%.(%d+)$", function(a,b,c,d) @@ -33,7 +37,7 @@ local function new_ip(ipStr, proto) if changed ~= 1 then return nil, "invalid-address"; end end - return setmetatable({ addr = ipStr, proto = proto }, ip_mt); + return setmetatable({ addr = ipStr, proto = proto, zone = zone }, ip_mt); end local function toBits(ip) -- cgit v1.2.3 From b09b431ed67be619e9573735f73f3af0c2c38e9a Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 4 Jan 2016 15:46:06 +0100 Subject: net.dns: Allow a zone id in resolv.conf (eg like %eth0) --- net/dns.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/dns.lua b/net/dns.lua index 9d90c24c..49958ed7 100644 --- a/net/dns.lua +++ b/net/dns.lua @@ -600,7 +600,7 @@ function resolver:adddefaultnameservers() -- - - - - adddefaultnameservers if resolv_conf then for line in resolv_conf:lines() do line = line:gsub("#.*$", "") - :match('^%s*nameserver%s+([%x:%.]*)%s*$'); + :match('^%s*nameserver%s+([%x:%.]*%%?%S*)%s*$'); if line then local ip = new_ip(line); if ip then -- cgit v1.2.3 From 25e96d193528ead16d0e8cbf9ae5ef34b04619d8 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 6 Jan 2016 02:46:47 +0100 Subject: util.uuid: Use /dev/urandom --- util/uuid.lua | 43 ++++++++++++++++--------------------------- 1 file changed, 16 insertions(+), 27 deletions(-) diff --git a/util/uuid.lua b/util/uuid.lua index bb70d000..58f792fd 100644 --- a/util/uuid.lua +++ b/util/uuid.lua @@ -6,44 +6,33 @@ -- COPYING file in the source package for more information. -- - -local tostring = tostring; -local os_time = os.time; -local os_clock = os.clock; -local sha1 = require "util.hashes".sha1; +local error = error; +local round_up = math.ceil; +local urandom, urandom_err = io.open("/dev/urandom", "r+"); module "uuid" -local last_uniq_time = 0; -local function uniq_time() - local new_uniq_time = os_time(); - if last_uniq_time >= new_uniq_time then new_uniq_time = last_uniq_time + 1; end - last_uniq_time = new_uniq_time; - return new_uniq_time; -end - -local function new_random(x) - return sha1(x..os_clock()..tostring({}), true); -end - -local buffer = new_random(uniq_time()); -local function _seed(x) - buffer = new_random(buffer..x); -end local function get_nibbles(n) - if #buffer < n then _seed(uniq_time()); end - local r = buffer:sub(0, n); - buffer = buffer:sub(n+1); - return r; + local binary_random = urandom:read(round_up(n/2)); + local hex_random = binary_random:gsub(".", + function (x) return ("%02x"):format(x:byte()) end); + return hex_random:sub(1, n); end local function get_twobits() - return ("%x"):format(get_nibbles(1):byte() % 4 + 8); + return ("%x"):format(urandom:read(1):byte() % 4 + 8); end function generate() + if not urandom then + error("Unable to obtain a secure random number generator, please see https://prosody.im/doc/random ("..urandom_err..")"); + end -- generate RFC 4122 complaint UUIDs (version 4 - random) return get_nibbles(8).."-"..get_nibbles(4).."-4"..get_nibbles(3).."-"..(get_twobits())..get_nibbles(3).."-"..get_nibbles(12); end -seed = _seed; + +function seed(x) + urandom:write(x); + urandom:flush(); +end return _M; -- cgit v1.2.3 From 9df17387ef9ce78bd05d94ee7ccd4ef4599df910 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 6 Jan 2016 02:46:47 +0100 Subject: util.uuid: Use /dev/urandom --- util/uuid.lua | 43 ++++++++++++++++--------------------------- 1 file changed, 16 insertions(+), 27 deletions(-) diff --git a/util/uuid.lua b/util/uuid.lua index bb70d000..58f792fd 100644 --- a/util/uuid.lua +++ b/util/uuid.lua @@ -6,44 +6,33 @@ -- COPYING file in the source package for more information. -- - -local tostring = tostring; -local os_time = os.time; -local os_clock = os.clock; -local sha1 = require "util.hashes".sha1; +local error = error; +local round_up = math.ceil; +local urandom, urandom_err = io.open("/dev/urandom", "r+"); module "uuid" -local last_uniq_time = 0; -local function uniq_time() - local new_uniq_time = os_time(); - if last_uniq_time >= new_uniq_time then new_uniq_time = last_uniq_time + 1; end - last_uniq_time = new_uniq_time; - return new_uniq_time; -end - -local function new_random(x) - return sha1(x..os_clock()..tostring({}), true); -end - -local buffer = new_random(uniq_time()); -local function _seed(x) - buffer = new_random(buffer..x); -end local function get_nibbles(n) - if #buffer < n then _seed(uniq_time()); end - local r = buffer:sub(0, n); - buffer = buffer:sub(n+1); - return r; + local binary_random = urandom:read(round_up(n/2)); + local hex_random = binary_random:gsub(".", + function (x) return ("%02x"):format(x:byte()) end); + return hex_random:sub(1, n); end local function get_twobits() - return ("%x"):format(get_nibbles(1):byte() % 4 + 8); + return ("%x"):format(urandom:read(1):byte() % 4 + 8); end function generate() + if not urandom then + error("Unable to obtain a secure random number generator, please see https://prosody.im/doc/random ("..urandom_err..")"); + end -- generate RFC 4122 complaint UUIDs (version 4 - random) return get_nibbles(8).."-"..get_nibbles(4).."-4"..get_nibbles(3).."-"..(get_twobits())..get_nibbles(3).."-"..get_nibbles(12); end -seed = _seed; + +function seed(x) + urandom:write(x); + urandom:flush(); +end return _M; -- cgit v1.2.3 From 78d296cfe9cc363e74aa33c21b38e6764377f9f6 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Thu, 7 Jan 2016 15:37:47 +0000 Subject: mod_http_files: Santize the path relative to our base URL before translating it to a filesystem path, fixes a relative path traversal vulnerability --- plugins/mod_http_files.lua | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/plugins/mod_http_files.lua b/plugins/mod_http_files.lua index 9839fed9..6275cca5 100644 --- a/plugins/mod_http_files.lua +++ b/plugins/mod_http_files.lua @@ -49,6 +49,34 @@ if not mime_map then end end +local forbidden_chars_pattern = "[/%z]"; +if prosody.platform == "windows" then + forbidden_chars_pattern = "[/%z\001-\031\127\"*:<>?|]" +end + +local urldecode = require "util.http".urldecode; +function sanitize_path(path) + local out = {}; + + local c = 0; + for component in path:gmatch("([^/]+)") do + component = urldecode(component); + if component:find(forbidden_chars_pattern) then + return nil; + elseif component == ".." then + if c <= 0 then + return nil; + end + out[c] = nil; + c = c - 1; + elseif component ~= "." then + c = c + 1; + out[c] = component; + end + end + return "/"..table.concat(out, "/"); +end + local cache = setmetatable({}, { __mode = "kv" }); -- Let the garbage collector have it if it wants to. function serve(opts) @@ -60,7 +88,11 @@ function serve(opts) local directory_index = opts.directory_index; local function serve_file(event, path) local request, response = event.request, event.response; - local orig_path = request.path; + path = sanitize_path(path); + if not path then + return 400; + end + local orig_path = sanitize_path(request.path); local full_path = base_path .. (path and "/"..path or ""):gsub("/", path_sep); local attr = stat(full_path:match("^.*[^\\/]")); -- Strip trailing path separator because Windows if not attr then -- cgit v1.2.3 From 759f20d3c8c6432bd01d14d705dbf04ef2a73af7 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Thu, 7 Jan 2016 15:37:47 +0000 Subject: mod_http_files: Santize the path relative to our base URL before translating it to a filesystem path, fixes a relative path traversal vulnerability --- plugins/mod_http_files.lua | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/plugins/mod_http_files.lua b/plugins/mod_http_files.lua index 9839fed9..6275cca5 100644 --- a/plugins/mod_http_files.lua +++ b/plugins/mod_http_files.lua @@ -49,6 +49,34 @@ if not mime_map then end end +local forbidden_chars_pattern = "[/%z]"; +if prosody.platform == "windows" then + forbidden_chars_pattern = "[/%z\001-\031\127\"*:<>?|]" +end + +local urldecode = require "util.http".urldecode; +function sanitize_path(path) + local out = {}; + + local c = 0; + for component in path:gmatch("([^/]+)") do + component = urldecode(component); + if component:find(forbidden_chars_pattern) then + return nil; + elseif component == ".." then + if c <= 0 then + return nil; + end + out[c] = nil; + c = c - 1; + elseif component ~= "." then + c = c + 1; + out[c] = component; + end + end + return "/"..table.concat(out, "/"); +end + local cache = setmetatable({}, { __mode = "kv" }); -- Let the garbage collector have it if it wants to. function serve(opts) @@ -60,7 +88,11 @@ function serve(opts) local directory_index = opts.directory_index; local function serve_file(event, path) local request, response = event.request, event.response; - local orig_path = request.path; + path = sanitize_path(path); + if not path then + return 400; + end + local orig_path = sanitize_path(request.path); local full_path = base_path .. (path and "/"..path or ""):gsub("/", path_sep); local attr = stat(full_path:match("^.*[^\\/]")); -- Strip trailing path separator because Windows if not attr then -- cgit v1.2.3 From 05b70955fafbd15f7f9d0d395ba644b98e5bb227 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 8 Jan 2016 13:01:27 +0000 Subject: Backout 88d54bec26b7 prior to release, as it certainly requires more testing --- net/dns.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/dns.lua b/net/dns.lua index 49958ed7..f56157d0 100644 --- a/net/dns.lua +++ b/net/dns.lua @@ -862,7 +862,9 @@ function resolver:receive(rset) -- - - - - - - - - - - - - - - - - receive --self.print(response); for j,rr in pairs(response.answer) do - self:remember(rr, response.question[1].type) + if rr.name:sub(-#response.question[1].name, -1) == response.question[1].name then + self:remember(rr, response.question[1].type) + end end -- retire the query -- cgit v1.2.3 From fe9dfb80d33e9f7c7d96a2eb7aa76117503a27fa Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 8 Jan 2016 13:01:27 +0000 Subject: Backout 88d54bec26b7 prior to release, as it certainly requires more testing --- net/dns.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/dns.lua b/net/dns.lua index 49958ed7..f56157d0 100644 --- a/net/dns.lua +++ b/net/dns.lua @@ -862,7 +862,9 @@ function resolver:receive(rset) -- - - - - - - - - - - - - - - - - receive --self.print(response); for j,rr in pairs(response.answer) do - self:remember(rr, response.question[1].type) + if rr.name:sub(-#response.question[1].name, -1) == response.question[1].name then + self:remember(rr, response.question[1].type) + end end -- retire the query -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 From b46dc8fc37e92651098c72fefa6fc64a29691f16 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 10 Jan 2016 23:21:34 +0100 Subject: util.uuid: Open /dev/urandom read-only, make seed() a noop --- util/uuid.lua | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/util/uuid.lua b/util/uuid.lua index 58f792fd..3576be8f 100644 --- a/util/uuid.lua +++ b/util/uuid.lua @@ -8,7 +8,7 @@ local error = error; local round_up = math.ceil; -local urandom, urandom_err = io.open("/dev/urandom", "r+"); +local urandom, urandom_err = io.open("/dev/urandom", "r"); module "uuid" @@ -30,9 +30,7 @@ function generate() return get_nibbles(8).."-"..get_nibbles(4).."-4"..get_nibbles(3).."-"..(get_twobits())..get_nibbles(3).."-"..get_nibbles(12); end -function seed(x) - urandom:write(x); - urandom:flush(); +function seed() end return _M; -- cgit v1.2.3 From 7680c15d991c05e2a06842471d39a29725b27742 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 10 Jan 2016 23:21:34 +0100 Subject: util.uuid: Open /dev/urandom read-only, make seed() a noop --- util/uuid.lua | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/util/uuid.lua b/util/uuid.lua index 58f792fd..3576be8f 100644 --- a/util/uuid.lua +++ b/util/uuid.lua @@ -8,7 +8,7 @@ local error = error; local round_up = math.ceil; -local urandom, urandom_err = io.open("/dev/urandom", "r+"); +local urandom, urandom_err = io.open("/dev/urandom", "r"); module "uuid" @@ -30,9 +30,7 @@ function generate() return get_nibbles(8).."-"..get_nibbles(4).."-4"..get_nibbles(3).."-"..(get_twobits())..get_nibbles(3).."-"..get_nibbles(12); end -function seed(x) - urandom:write(x); - urandom:flush(); +function seed() end return _M; -- cgit v1.2.3 From 656287afd88564bfec4250bc2f77497f877c8f42 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 10 Jan 2016 23:25:00 +0100 Subject: core: Increase default read size to "all of it", in practice 8K (size of LuaSockets buffer) --- core/portmanager.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/portmanager.lua b/core/portmanager.lua index 421d7fc6..37442a31 100644 --- a/core/portmanager.lua +++ b/core/portmanager.lua @@ -29,7 +29,7 @@ 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; +local default_mode = config.get("*", "network_default_read_size") or "*a"; --- Private state -- cgit v1.2.3 From 84c0572c498cdfac5dacbe7bdf2be4605e82f601 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 10 Jan 2016 23:25:00 +0100 Subject: core: Increase default read size to "all of it", in practice 8K (size of LuaSockets buffer) --- core/portmanager.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/portmanager.lua b/core/portmanager.lua index 421d7fc6..37442a31 100644 --- a/core/portmanager.lua +++ b/core/portmanager.lua @@ -29,7 +29,7 @@ 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; +local default_mode = config.get("*", "network_default_read_size") or "*a"; --- Private state -- cgit v1.2.3 From 375bc82d743c305d2b714bd96c453826dbce2a9a Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 19 Jan 2016 21:31:02 +0100 Subject: mod_dialback: Follow XEP-0185 and use HMAC --- plugins/mod_dialback.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/mod_dialback.lua b/plugins/mod_dialback.lua index 9dcb0ed5..dc3c3f10 100644 --- a/plugins/mod_dialback.lua +++ b/plugins/mod_dialback.lua @@ -12,6 +12,7 @@ local log = module._log; local st = require "util.stanza"; local sha256_hash = require "util.hashes".sha256; +local sha256_hmac = require "util.hashes".hmac_sha256; local nameprep = require "util.encodings".stringprep.nameprep; local xmlns_stream = "http://etherx.jabber.org/streams"; @@ -19,7 +20,7 @@ local xmlns_stream = "http://etherx.jabber.org/streams"; local dialback_requests = setmetatable({}, { __mode = 'v' }); function generate_dialback(id, to, from) - return sha256_hash(id..to..from..hosts[from].dialback_secret, true); + return sha256_hmac(sha256_hash(hosts[from].dialback_secret), to .. ' ' .. from .. ' ' .. id, true); end function initiate_dialback(session) -- cgit v1.2.3 From 990c17c4433e4ec453cd1060eb60bb07cd0cb4ea Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 21 Jan 2016 22:21:19 +0100 Subject: Backout 63f5870f9afe, no longer needed since Windows is currently unsupported --- plugins/mod_s2s/s2sout.lib.lua | 46 ++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/plugins/mod_s2s/s2sout.lib.lua b/plugins/mod_s2s/s2sout.lib.lua index 5728f67b..dc122af7 100644 --- a/plugins/mod_s2s/s2sout.lib.lua +++ b/plugins/mod_s2s/s2sout.lib.lua @@ -18,31 +18,13 @@ local socket = require "socket"; local adns = require "net.adns"; local dns = require "net.dns"; local t_insert, t_sort, ipairs = table.insert, table.sort, ipairs; +local local_addresses = require "util.net".local_addresses; local s2s_destroy_session = require "core.s2smanager".destroy_session; local log = module._log; -local anysource = { IPv4 = "0.0.0.0", IPv6 = "::" }; -local function get_sources(addrs) - local sources = {}; - for _, IP in ipairs(addrs) do - local sock; - if IP.proto == "IPv4" then - sock = socket.udp(); - elseif IP.proto == "IPv6" then - sock = socket.udp6(); - end - sock:setpeername(IP.addr, 9); - local localaddr = sock:getsockname() or anysource[IP.proto]; - sock:close(); - if not sources[localaddr] then - sources[localaddr] = true; - t_insert(sources, new_ip(localaddr, IP.proto)); - end - end - return sources; -end +local sources = {}; local has_ipv4, has_ipv6; local dns_timeout = module:get_option_number("dns_timeout", 15); @@ -195,7 +177,7 @@ function s2sout.try_connect(host_session, connect_host, connect_port, err) if have_other_result then if #IPs > 0 then - rfc6724_dest(host_session.ip_hosts, get_sources(host_session.ip_hosts)); + rfc6724_dest(host_session.ip_hosts, sources); for i = 1, #IPs do IPs[i] = {ip = IPs[i], port = connect_port}; end @@ -231,7 +213,7 @@ function s2sout.try_connect(host_session, connect_host, connect_port, err) if have_other_result then if #IPs > 0 then - rfc6724_dest(host_session.ip_hosts, get_sources(host_session.ip_hosts)); + rfc6724_dest(host_session.ip_hosts, sources); for i = 1, #IPs do IPs[i] = {ip = IPs[i], port = connect_port}; end @@ -333,12 +315,28 @@ module:hook_global("service-added", function (event) return; end for source, _ in pairs(s2s_sources) do - if source:find(":") then - has_ipv6 = true; + if source == "*" or source == "0.0.0.0" then + for _, addr in ipairs(local_addresses("ipv4", true)) do + sources[#sources + 1] = new_ip(addr, "IPv4"); + end + elseif source == "::" then + for _, addr in ipairs(local_addresses("ipv6", true)) do + sources[#sources + 1] = new_ip(addr, "IPv6"); + end else + sources[#sources + 1] = new_ip(source, (source:find(":") and "IPv6") or "IPv4"); + end + end + for i = 1,#sources do + if sources[i].proto == "IPv6" then + has_ipv6 = true; + elseif sources[i].proto == "IPv4" then has_ipv4 = true; end end + if not (has_ipv4 or has_ipv6) then + module:log("warn", "No local IPv4 or IPv6 addresses detected, outgoing connections may fail"); + end end); return s2sout; -- cgit v1.2.3 From 463a20214229e415c776f19d853bd445b1e178a5 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 21 Jan 2016 22:26:46 +0100 Subject: net.dns: Remember query only after it was sent, in case it was not (fixes #598) --- net/dns.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/net/dns.lua b/net/dns.lua index f56157d0..d123731c 100644 --- a/net/dns.lua +++ b/net/dns.lua @@ -763,16 +763,16 @@ function resolver:query(qname, qtype, qclass) -- - - - - - - - - - -- query self.active[id] = self.active[id] or {}; self.active[id][question] = o; - -- remember which coroutine wants the answer - if co then - set(self.wanted, qclass, qtype, qname, co, true); - end - local conn, err = self:getsocket(o.server) if not conn then return nil, err; end conn:send (o.packet) + + -- remember which coroutine wants the answer + if co then + set(self.wanted, qclass, qtype, qname, co, true); + end if timer and self.timeout then local num_servers = #self.server; -- cgit v1.2.3 From b7f10aac181443e6a9deba703629f9df8100a58a Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 22 Jan 2016 01:58:39 +0100 Subject: server_select: Keep track of which server listeners are full --- net/server_select.lua | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/server_select.lua b/net/server_select.lua index 7ac41523..0a060c9e 100644 --- a/net/server_select.lua +++ b/net/server_select.lua @@ -88,6 +88,7 @@ local _socketlist local _closelist local _readtimes local _writetimes +local _fullservers --// simple data types //-- @@ -130,6 +131,7 @@ _socketlist = { } -- key = socket, value = wrapped socket (handlers) _readtimes = { } -- key = handler, value = timestamp of last data reading _writetimes = { } -- key = handler, value = timestamp of last data writing/sending _closelist = { } -- handlers to close +_fullservers = { } -- servers in a paused state while there are too many clients _readlistlen = 0 -- length of readlist _sendlistlen = 0 -- length of sendlist @@ -219,6 +221,7 @@ wrapserver = function( listeners, socket, ip, serverport, pattern, sslctx ) -- t end _readlistlen = addsocket(_readlist, socket, _readlistlen) _socketlist[ socket ] = handler + _fullservers[ handler ] = nil handler.paused = false; end end @@ -234,6 +237,7 @@ wrapserver = function( listeners, socket, ip, serverport, pattern, sslctx ) -- t handler.readbuffer = function( ) if _readlistlen >= _maxselectlen or _sendlistlen >= _maxselectlen then handler.pause( ) + _fullservers[ handler ] = _currenttime out_put( "server.lua: refused new client connection: server full" ) return false end @@ -264,6 +268,7 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport out_error("server.lua: Disallowed FD number: "..socket:getfd()) -- PROTIP: Switch to libevent socket:close( ) -- Should we send some kind of error here? if server then + _fullservers[ server ] = _currenttime server.pause( ) end return nil, nil, "fd-too-large" -- cgit v1.2.3 From 554ca8bd8c97fa6e38d7cc76176ba16ab6889502 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 22 Jan 2016 01:59:25 +0100 Subject: server_select: Retry accepting clients from full servers after 10s (matches libevent behaviour) --- net/server.lua | 2 +- net/server_select.lua | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/net/server.lua b/net/server.lua index 375e7081..9b0d27e1 100644 --- a/net/server.lua +++ b/net/server.lua @@ -50,7 +50,7 @@ if prosody then local settings = config_get("*", "network_settings") or {}; if use_luaevent then local event_settings = { - ACCEPT_DELAY = settings.event_accept_retry_interval; + ACCEPT_DELAY = settings.accept_retry_interval; ACCEPT_QUEUE = settings.tcp_backlog; CLEAR_DELAY = settings.event_clear_interval; CONNECT_TIMEOUT = settings.connect_timeout; diff --git a/net/server_select.lua b/net/server_select.lua index 0a060c9e..f9d8dba1 100644 --- a/net/server_select.lua +++ b/net/server_select.lua @@ -103,6 +103,7 @@ local _readtraffic local _selecttimeout local _sleeptime local _tcpbacklog +local _accepretry local _starttime local _currenttime @@ -143,6 +144,7 @@ _readtraffic = 0 _selecttimeout = 1 -- timeout of socket.select _sleeptime = 0 -- time to wait at the end of every loop _tcpbacklog = 128 -- some kind of hint to the OS +_accepretry = 10 -- seconds to wait until the next attempt of a full server to accept _maxsendlen = 51000 * 1024 -- max len of send buffer _maxreadlen = 25000 * 1024 -- max len of read buffer @@ -798,6 +800,7 @@ getsettings = function( ) max_connections = _maxselectlen; max_ssl_handshake_roundtrips = _maxsslhandshake; highest_allowed_fd = _maxfd; + accept_retry_interval = _accepretry; } end @@ -813,6 +816,7 @@ changesettings = function( new ) _tcpbacklog = tonumber( new.tcp_backlog ) or _tcpbacklog _sendtimeout = tonumber( new.send_timeout ) or _sendtimeout _readtimeout = tonumber( new.read_timeout ) or _readtimeout + _accepretry = tonumber( new.accept_retry_interval ) or _accepretry _maxselectlen = new.max_connections or _maxselectlen _maxsslhandshake = new.max_ssl_handshake_roundtrips or _maxsslhandshake _maxfd = new.highest_allowed_fd or _maxfd @@ -901,6 +905,13 @@ loop = function(once) -- this is the main loop of the program next_timer_time = next_timer_time - (_currenttime - _timer); end + for server, paused_time in pairs( _fullservers ) do + if _currenttime - paused_time > _accepretry then + _fullservers[ server ] = nil; + server.resume(); + end + end + -- wait some time (0 by default) socket_sleep( _sleeptime ) until quitting; -- cgit v1.2.3 From b1075a138daa14e71580fbeb4c3d7896947ca3d7 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 22 Jan 2016 02:00:27 +0100 Subject: server_select: Pause and mark server as full if accepting a client fails (fixes #597) --- net/server_select.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/server_select.lua b/net/server_select.lua index f9d8dba1..891151ac 100644 --- a/net/server_select.lua +++ b/net/server_select.lua @@ -258,6 +258,8 @@ wrapserver = function( listeners, socket, ip, serverport, pattern, sslctx ) -- t return; elseif err then -- maybe timeout or something else out_put( "server.lua: error with new client connection: ", tostring(err) ) + handler.pause( ) + _fullservers[ handler ] = _currenttime return false end end -- cgit v1.2.3 From b6881235ed42e490852f99d7b0d69996fde437f0 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 22 Jan 2016 02:00:43 +0100 Subject: server_select: Add logging of when servers are paused and resumed --- net/server_select.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/server_select.lua b/net/server_select.lua index 891151ac..c50a6ce1 100644 --- a/net/server_select.lua +++ b/net/server_select.lua @@ -213,6 +213,7 @@ wrapserver = function( listeners, socket, ip, serverport, pattern, sslctx ) -- t socket = nil; end handler.paused = true; + out_put("server.lua: server [", ip, "]:", serverport, " paused") end end handler.resume = function( ) @@ -225,6 +226,7 @@ wrapserver = function( listeners, socket, ip, serverport, pattern, sslctx ) -- t _socketlist[ socket ] = handler _fullservers[ handler ] = nil handler.paused = false; + out_put("server.lua: server [", ip, "]:", serverport, " resumed") end end handler.ip = function( ) -- cgit v1.2.3 From 1d210c380d7b383b0751eda28971d81ab8c39531 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 26 Jan 2016 00:28:07 +0100 Subject: mod_c2s, mod_s2s: Lower priority of session shutdown to negative, so that plugins hooking at the default priority run first (fixes #601) --- plugins/mod_c2s.lua | 2 +- plugins/mod_s2s/mod_s2s.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/mod_c2s.lua b/plugins/mod_c2s.lua index 3d6487c9..8524c37e 100644 --- a/plugins/mod_c2s.lua +++ b/plugins/mod_c2s.lua @@ -275,7 +275,7 @@ module:hook("server-stopping", function(event) for _, session in pairs(sessions) do session:close{ condition = "system-shutdown", text = reason }; end -end, 1000); +end, -100); diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua index ee539a2a..4173fcfa 100644 --- a/plugins/mod_s2s/mod_s2s.lua +++ b/plugins/mod_s2s/mod_s2s.lua @@ -671,7 +671,7 @@ module:hook("server-stopping", function(event) for _, session in pairs(sessions) do session:close{ condition = "system-shutdown", text = reason }; end -end,500); +end, -200); -- cgit v1.2.3 -- cgit v1.2.3 From 1d8ea01038bf60258881ccca49d719cfc5f67399 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 25 Feb 2016 22:36:42 +0100 Subject: util.datamanager: Unreference file handle after closing it to prevent trying to close it again (fixes #632) --- util/datamanager.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/util/datamanager.lua b/util/datamanager.lua index a107d95c..c69ecd25 100644 --- a/util/datamanager.lua +++ b/util/datamanager.lua @@ -152,6 +152,7 @@ local function atomic_store(filename, data) if not ok then break end ok, msg = f:close(); + f = nil; -- no longer valid if not ok then break end return os_rename(scratch, filename); -- cgit v1.2.3 From 68ec17f38ea127093af720f6769ef992094a1678 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 2 Mar 2016 16:28:11 +0100 Subject: mod_c2s: Remove connection object from session object when connection disconnected to prevent accidental use (see #590) --- plugins/mod_c2s.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/mod_c2s.lua b/plugins/mod_c2s.lua index 8524c37e..30a017c0 100644 --- a/plugins/mod_c2s.lua +++ b/plugins/mod_c2s.lua @@ -258,6 +258,7 @@ function listener.ondisconnect(conn, err) if session then (session.log or log)("info", "Client disconnected: %s", err or "connection closed"); sm_destroy_session(session, err); + session.conn = nil; sessions[conn] = nil; end end -- cgit v1.2.3 From 59566bdf10939405ed0404ee036a046db859abae Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 2 Mar 2016 16:30:05 +0100 Subject: net.server_event: Prevent resuming connections without readcallback, eg closed connections (fixes #590) --- net/server_event.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/server_event.lua b/net/server_event.lua index 45938a13..a60de08e 100644 --- a/net/server_event.lua +++ b/net/server_event.lua @@ -289,7 +289,7 @@ do function interface_mt:resume() self:_lock(self.nointerface, false, self.nowriting); - if not self.eventread then + if self.readcallback and not self.eventread then self.eventread = addevent( base, self.conn, EV_READ, self.readcallback, cfg.READ_TIMEOUT ); -- register callback end end -- cgit v1.2.3 From 7296f7773ccba9b7cd3735c48f6490d854c17d8a Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 2 Mar 2016 16:30:46 +0100 Subject: net.server_event: Return true from conn:resume() to indicate success --- net/server_event.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/net/server_event.lua b/net/server_event.lua index a60de08e..d505825d 100644 --- a/net/server_event.lua +++ b/net/server_event.lua @@ -291,6 +291,7 @@ do self:_lock(self.nointerface, false, self.nowriting); if self.readcallback and not self.eventread then self.eventread = addevent( base, self.conn, EV_READ, self.readcallback, cfg.READ_TIMEOUT ); -- register callback + return true; end end -- cgit v1.2.3 From 57449a42cc2eaec8f1069f40988c761d986ae98a Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 3 Mar 2016 15:28:07 +0100 Subject: mod_http_files: Fix traceback when serving a non-wildcard path (fixes #611) --- plugins/mod_http_files.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/mod_http_files.lua b/plugins/mod_http_files.lua index 6275cca5..097f8346 100644 --- a/plugins/mod_http_files.lua +++ b/plugins/mod_http_files.lua @@ -56,6 +56,7 @@ end local urldecode = require "util.http".urldecode; function sanitize_path(path) + if not path then return end local out = {}; local c = 0; @@ -88,10 +89,11 @@ function serve(opts) local directory_index = opts.directory_index; local function serve_file(event, path) local request, response = event.request, event.response; - path = sanitize_path(path); - if not path then + local sanitized_path = sanitize_path(path); + if path and not sanitized_path then return 400; end + path = sanitized_path; local orig_path = sanitize_path(request.path); local full_path = base_path .. (path and "/"..path or ""):gsub("/", path_sep); local attr = stat(full_path:match("^.*[^\\/]")); -- Strip trailing path separator because Windows -- cgit v1.2.3 From 2f1867aeb26582383f2494bb0ad8fffdd4310f84 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 3 Mar 2016 15:30:00 +0100 Subject: mod_http_files: Don't prepend / to path twice, sanitize path does this already --- plugins/mod_http_files.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_http_files.lua b/plugins/mod_http_files.lua index 097f8346..fc39628c 100644 --- a/plugins/mod_http_files.lua +++ b/plugins/mod_http_files.lua @@ -95,7 +95,7 @@ function serve(opts) end path = sanitized_path; local orig_path = sanitize_path(request.path); - local full_path = base_path .. (path and "/"..path or ""):gsub("/", path_sep); + local full_path = base_path .. (path or ""):gsub("/", path_sep); local attr = stat(full_path:match("^.*[^\\/]")); -- Strip trailing path separator because Windows if not attr then return 404; -- cgit v1.2.3 From d5eb6240a71463bca1b15ea1b24d600a73c86560 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 3 Mar 2016 15:31:46 +0100 Subject: mod_http_files: Preserve a trailing / in paths (fixes #639) --- plugins/mod_http_files.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/mod_http_files.lua b/plugins/mod_http_files.lua index fc39628c..53b6469b 100644 --- a/plugins/mod_http_files.lua +++ b/plugins/mod_http_files.lua @@ -75,6 +75,9 @@ function sanitize_path(path) out[c] = component; end end + if path:sub(-1,-1) == "/" then + out[c+1] = ""; + end return "/"..table.concat(out, "/"); end -- cgit v1.2.3 From 7978442457dfe918f6b46cdeea5fc1ef01c5dfee Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 3 Apr 2016 15:18:21 +0200 Subject: mod_c2s: Just destroy the session when it has no connection (see #641) --- plugins/mod_c2s.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/mod_c2s.lua b/plugins/mod_c2s.lua index 30a017c0..2bb919f8 100644 --- a/plugins/mod_c2s.lua +++ b/plugins/mod_c2s.lua @@ -175,6 +175,9 @@ local function session_close(session, reason) sm_destroy_session(session, reason); conn:close(); end + else + local reason = (reason and (reason.name or reason.text or reason.condition)) or reason; + sm_destroy_session(session, reason); end end -- cgit v1.2.3 From 719894dc32640ea7da3b2697eee0035ef5ef42e4 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 19 Apr 2016 17:20:39 +0200 Subject: MUC: Accept missing form as "instant room" request (fixes #377) --- plugins/muc/muc.lib.lua | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plugins/muc/muc.lib.lua b/plugins/muc/muc.lib.lua index 5879c256..f8e8f74d 100644 --- a/plugins/muc/muc.lib.lua +++ b/plugins/muc/muc.lib.lua @@ -668,6 +668,14 @@ function room_mt:process_form(origin, stanza) if form.attr.type == "cancel" then origin.send(st.reply(stanza)); return; end if form.attr.type ~= "submit" then origin.send(st.error_reply(stanza, "cancel", "bad-request", "Not a submitted form")); return; end + if form.tags[1] == nil then + -- instant room + if self.save then self:save(true); end + origin.send(st.reply(stanza)); + return true; + end + + local fields = self:get_form_layout():data(form); if fields.FORM_TYPE ~= "http://jabber.org/protocol/muc#roomconfig" then origin.send(st.error_reply(stanza, "cancel", "bad-request", "Form is not of type room configuration")); return; end -- cgit v1.2.3 From 427dea0f3aab1fb05172629d60ac27412f7ddeb9 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 19 Apr 2016 17:24:00 +0200 Subject: net.server_event: Re-add write event if writebuffer is non-empty after write (eg due to writes from ondrain callback) (fixes #661) --- net/server_event.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/server_event.lua b/net/server_event.lua index d505825d..1c6f1547 100644 --- a/net/server_event.lua +++ b/net/server_event.lua @@ -548,6 +548,10 @@ do elseif interface.eventreadtimeout then return EV_WRITE, EV_TIMEOUT end + if interface.writebuffer ~= 0 then + -- data possibly written from ondrain + return EV_WRITE, cfg.WRITE_TIMEOUT + end interface.eventwrite = nil return -1 elseif byte and (err == "timeout" or err == "wantwrite") then -- want write again -- cgit v1.2.3 From 57df704bb87cd5dcabde5e941b1e91631dc4ac2a Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 19 Apr 2016 18:18:57 +0200 Subject: net.server_event: Fix traceback if event re-added during starttls --- net/server_event.lua | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/net/server_event.lua b/net/server_event.lua index 1c6f1547..9da2e910 100644 --- a/net/server_event.lua +++ b/net/server_event.lua @@ -545,12 +545,11 @@ do elseif interface.startsslcallback then -- start ssl connection if needed debug "starting ssl handshake after writing" interface.eventstarthandshake = addevent( base, nil, EV_TIMEOUT, interface.startsslcallback, 0 ) - elseif interface.eventreadtimeout then - return EV_WRITE, EV_TIMEOUT - end - if interface.writebuffer ~= 0 then + elseif interface.writebuffer ~= 0 then -- data possibly written from ondrain return EV_WRITE, cfg.WRITE_TIMEOUT + elseif interface.eventreadtimeout then + return EV_WRITE, EV_TIMEOUT end interface.eventwrite = nil return -1 -- cgit v1.2.3 From 66970561d010c558a5abf3a86dbaf59e65b454bc Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 19 Apr 2016 18:20:39 +0200 Subject: net.server_event: Return the correct value as timeout --- net/server_event.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/server_event.lua b/net/server_event.lua index 9da2e910..59bd269a 100644 --- a/net/server_event.lua +++ b/net/server_event.lua @@ -549,7 +549,7 @@ do -- data possibly written from ondrain return EV_WRITE, cfg.WRITE_TIMEOUT elseif interface.eventreadtimeout then - return EV_WRITE, EV_TIMEOUT + return EV_WRITE, cfg.WRITE_TIMEOUT end interface.eventwrite = nil return -1 -- cgit v1.2.3 From c960febdd809ad86256ce42a1cea7acec66b1c30 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 19 Apr 2016 18:58:30 +0200 Subject: net.server_event: Check the buffer *length*, not the buffer itself (Fixes 100% cpu usage introduced in 65abd9d7bf88) --- net/server_event.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/server_event.lua b/net/server_event.lua index 59bd269a..882d10ed 100644 --- a/net/server_event.lua +++ b/net/server_event.lua @@ -545,7 +545,7 @@ do elseif interface.startsslcallback then -- start ssl connection if needed debug "starting ssl handshake after writing" interface.eventstarthandshake = addevent( base, nil, EV_TIMEOUT, interface.startsslcallback, 0 ) - elseif interface.writebuffer ~= 0 then + elseif interface.writebufferlen ~= 0 then -- data possibly written from ondrain return EV_WRITE, cfg.WRITE_TIMEOUT elseif interface.eventreadtimeout then -- cgit v1.2.3 From b588c60d8a34e0735ca918fa0f819e8993dd9f77 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 21 May 2016 19:10:03 +0200 Subject: mod_presence: Re-probe for contacts presence after outgoing 'subscribed' (fixes #673) --- plugins/mod_presence.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/mod_presence.lua b/plugins/mod_presence.lua index 8dac2d35..a5b4f282 100644 --- a/plugins/mod_presence.lua +++ b/plugins/mod_presence.lua @@ -201,6 +201,7 @@ function handle_outbound_presence_subscriptions_and_probes(origin, stanza, from_ end core_post_stanza(origin, stanza); send_presence_of_available_resources(node, host, to_bare, origin); + core_post_stanza(origin, st.presence({ type = "probe", from = from_bare, to = to_bare })); elseif stanza.attr.type == "unsubscribed" then -- 1. send unavailable -- 2. route stanza -- cgit v1.2.3 From 8368fb1935d99a2aa4ca2a9d57fb400ac9e9cd87 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 22 Jun 2016 22:22:29 +0200 Subject: mod_privacy: Fix selecting the top resource (fixes #694) --- plugins/mod_privacy.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_privacy.lua b/plugins/mod_privacy.lua index 49c9427f..f95dfa50 100644 --- a/plugins/mod_privacy.lua +++ b/plugins/mod_privacy.lua @@ -397,7 +397,7 @@ function preCheckIncoming(e) local prio = 0; if bare_sessions[node.."@"..host] ~= nil then for resource, session_ in pairs(bare_sessions[node.."@"..host].sessions) do - if session_.priority ~= nil and session_.priority > prio then + if session_.priority ~= nil and session_.priority >= prio then session = session_; prio = session_.priority; end -- cgit v1.2.3 From 43b4d853780af81289d67b28fc0a333ce6dab887 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 21 Sep 2015 23:19:48 +0200 Subject: sessionmanager: Make session.send() return true unless there really is an error [backported from 0.10] --- core/sessionmanager.lua | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/sessionmanager.lua b/core/sessionmanager.lua index 4b014d18..67ceb739 100644 --- a/core/sessionmanager.lua +++ b/core/sessionmanager.lua @@ -37,9 +37,15 @@ function new_session(conn) if t then t = filter("bytes/out", tostring(t)); if t then - return w(conn, t); + local ret, err = w(conn, t); + if not ret then + session.log("debug", "Write-error: %s", tostring(err)); + return false; + end + return true; end end + return true; end session.ip = conn:ip(); local conn_name = "c2s"..tostring(session):match("[a-f0-9]+$"); -- cgit v1.2.3 From 8daf86767cc381f059402ba9ba334638345bec48 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 13 Aug 2016 20:19:08 +0200 Subject: net.http.parser: Buffer into a table to reduce GC pressure, collapse to string when needed (fixes #603) --- net/http/parser.lua | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/net/http/parser.lua b/net/http/parser.lua index 6d7187da..af43e7a0 100644 --- a/net/http/parser.lua +++ b/net/http/parser.lua @@ -1,5 +1,6 @@ local tonumber = tonumber; local assert = assert; +local t_insert, t_concat = table.insert, table.concat; local url_parse = require "socket.url".parse; local urldecode = require "util.http".urldecode; @@ -27,7 +28,7 @@ local httpstream = {}; function httpstream.new(success_cb, error_cb, parser_type, options_cb) local client = true; if not parser_type or parser_type == "server" then client = false; else assert(parser_type == "client", "Invalid parser type"); end - local buf = ""; + local buf, buflen, buftable = {}, 0, true; local chunked, chunk_size, chunk_start; local state = nil; local packet; @@ -38,6 +39,7 @@ function httpstream.new(success_cb, error_cb, parser_type, options_cb) feed = function(self, data) if error then return nil, "parse has failed"; end if not data then -- EOF + if buftable then buf, buftable = t_concat(buf), false; end if state and client and not len then -- reading client body until EOF packet.body = buf; success_cb(packet); @@ -46,9 +48,16 @@ function httpstream.new(success_cb, error_cb, parser_type, options_cb) end return; end - buf = buf..data; - while #buf > 0 do + if buftable then + t_insert(buf, data); + else + buf = { buf, data }; + buftable = true; + end + buflen = buflen + #data; + while buflen > 0 do if state == nil then -- read request + if buftable then buf, buftable = t_concat(buf), false; end local index = buf:find("\r\n\r\n", nil, true); if not index then return; end -- not enough data local method, path, httpversion, status_code, reason_phrase; @@ -115,11 +124,13 @@ function httpstream.new(success_cb, error_cb, parser_type, options_cb) }; end buf = buf:sub(index + 4); + buflen = #buf; state = true; end if state then -- read body if client then if chunked then + if buftable then buf, buftable = t_concat(buf), false; end if not buf:find("\r\n", nil, true) then return; end -- not enough data @@ -132,25 +143,29 @@ function httpstream.new(success_cb, error_cb, parser_type, options_cb) state, chunk_size = nil, nil; buf = buf:gsub("^.-\r\n\r\n", ""); -- This ensure extensions and trailers are stripped success_cb(packet); - elseif #buf - chunk_start - 2 >= chunk_size then -- we have a chunk + elseif buflen - chunk_start - 2 >= chunk_size then -- we have a chunk packet.body = packet.body..buf:sub(chunk_start, chunk_start + (chunk_size-1)); buf = buf:sub(chunk_start + chunk_size + 2); chunk_size, chunk_start = nil, nil; else -- Partial chunk remaining break; end - elseif len and #buf >= len then + elseif len and buflen >= len then + if buftable then buf, buftable = t_concat(buf), false; end if packet.code == 101 then - packet.body, buf = buf, ""; + packet.body, buf, buflen, buftable = buf, {}, 0, true; else packet.body, buf = buf:sub(1, len), buf:sub(len + 1); + buflen = #buf; end state = nil; success_cb(packet); else break; end - elseif #buf >= len then + elseif buflen >= len then + if buftable then buf, buftable = t_concat(buf), false; end packet.body, buf = buf:sub(1, len), buf:sub(len + 1); + buflen = #buf; state = nil; success_cb(packet); else break; -- cgit v1.2.3 From 72573b8d101668e946bc7aedd6cfdf90acf18663 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 18 Aug 2016 14:47:58 +0200 Subject: net.http.parser: Add a limit on content length, default to 10M --- net/http/parser.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/http/parser.lua b/net/http/parser.lua index af43e7a0..0f764d12 100644 --- a/net/http/parser.lua +++ b/net/http/parser.lua @@ -29,6 +29,7 @@ function httpstream.new(success_cb, error_cb, parser_type, options_cb) local client = true; if not parser_type or parser_type == "server" then client = false; else assert(parser_type == "client", "Invalid parser type"); end local buf, buflen, buftable = {}, 0, true; + local bodylimit = 10*1024*1024; local chunked, chunk_size, chunk_start; local state = nil; local packet; @@ -88,6 +89,7 @@ function httpstream.new(success_cb, error_cb, parser_type, options_cb) if not first_line then error = true; return error_cb("invalid-status-line"); end chunked = have_body and headers["transfer-encoding"] == "chunked"; len = tonumber(headers["content-length"]); -- TODO check for invalid len + if len and len > bodylimit then error = true; return error_cb("content-length-limit-exceeded"); end if client then -- FIXME handle '100 Continue' response (by skipping it) if not have_body then len = 0; end -- cgit v1.2.3 From 1fa724111054d024e48c6d65cd8dce92a3d8fdd5 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 18 Aug 2016 14:48:42 +0200 Subject: net.http.parser: Add a limit on maximum buffer size, default to 20M --- net/http/parser.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/http/parser.lua b/net/http/parser.lua index 0f764d12..e3a2554f 100644 --- a/net/http/parser.lua +++ b/net/http/parser.lua @@ -30,6 +30,7 @@ function httpstream.new(success_cb, error_cb, parser_type, options_cb) if not parser_type or parser_type == "server" then client = false; else assert(parser_type == "client", "Invalid parser type"); end local buf, buflen, buftable = {}, 0, true; local bodylimit = 10*1024*1024; + local buflimit = bodylimit * 2; local chunked, chunk_size, chunk_start; local state = nil; local packet; @@ -56,6 +57,7 @@ function httpstream.new(success_cb, error_cb, parser_type, options_cb) buftable = true; end buflen = buflen + #data; + if buflen > buflimit then error = true; return error_cb("max-buffer-size-exceeded"); end while buflen > 0 do if state == nil then -- read request if buftable then buf, buftable = t_concat(buf), false; end -- cgit v1.2.3 From 098ea9989523cccbb6cad103ad37ddd785a044ee Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 18 Aug 2016 14:50:06 +0200 Subject: net.http.parser: Allow limits to be configurable via options callback --- net/http/parser.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/http/parser.lua b/net/http/parser.lua index e3a2554f..1e698728 100644 --- a/net/http/parser.lua +++ b/net/http/parser.lua @@ -29,8 +29,8 @@ function httpstream.new(success_cb, error_cb, parser_type, options_cb) local client = true; if not parser_type or parser_type == "server" then client = false; else assert(parser_type == "client", "Invalid parser type"); end local buf, buflen, buftable = {}, 0, true; - local bodylimit = 10*1024*1024; - local buflimit = bodylimit * 2; + local bodylimit = tonumber(options_cb and options_cb().body_size_limit) or 10*1024*1024; + local buflimit = tonumber(options_cb and options_cb().buffer_size_limit) or bodylimit * 2; local chunked, chunk_size, chunk_start; local state = nil; local packet; -- cgit v1.2.3 From 38139d0312ba9d0573cd93bb7c7a63c4e37e34db Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 18 Aug 2016 14:50:39 +0200 Subject: net.http.server: Expose way to set http server options --- net/http/server.lua | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/net/http/server.lua b/net/http/server.lua index f091595c..32cda8aa 100644 --- a/net/http/server.lua +++ b/net/http/server.lua @@ -19,6 +19,7 @@ local sessions = {}; local listener = {}; local hosts = {}; local default_host; +local options = {}; local function is_wildcard_event(event) return event:sub(-2, -1) == "/*"; @@ -130,7 +131,10 @@ function listener.onconnect(conn) sessions[conn] = nil; conn:close(); end - sessions[conn] = parser_new(success_cb, error_cb); + local function options_cb() + return options; + end + sessions[conn] = parser_new(success_cb, error_cb, "server", options_cb); end function listener.ondisconnect(conn) @@ -300,6 +304,9 @@ end function _M.fire_event(event, ...) return events.fire_event(event, ...); end +function _M.set_option(name, value) + options[name] = value; +end _M.listener = listener; _M.codes = codes; -- cgit v1.2.3 From 175e6d9e280dbed493874545e0c14f848686cca5 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 18 Aug 2016 14:51:11 +0200 Subject: mod_http: Allow configuring http parser size limits --- plugins/mod_http.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index 9b574bc8..03b23480 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -18,6 +18,9 @@ local server = require "net.http.server"; server.set_default_host(module:get_option_string("http_default_host")); +server.set_option("body_size_limit", module:get_option_number("http_max_content_size")); +server.set_option("buffer_size_limit", module:get_option_number("http_max_buffer_size")); + local function normalize_path(path) if path:sub(-1,-1) == "/" then path = path:sub(1, -2); end if path:sub(1,1) ~= "/" then path = "/"..path; end -- cgit v1.2.3 From dee6ced516c3b111d5e838bc0cfd9ae00a7e2f21 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 23 Sep 2016 16:09:46 +0200 Subject: util.dependencies: Set global 'ssl' for compat with LuaSec 0.6 (fixes #749) --- util/dependencies.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/util/dependencies.lua b/util/dependencies.lua index 4d50cf63..9ea211dd 100644 --- a/util/dependencies.lua +++ b/util/dependencies.lua @@ -99,6 +99,9 @@ function check_dependencies() ["luarocks"] = "luarocks install luasec"; ["Source"] = "http://www.inf.puc-rio.br/~brunoos/luasec/"; }, "SSL/TLS support will not be available"); + elseif not _G.ssl then + _G.ssl = ssl; + _G.ssl.context = require "ssl.context"; end local encodings, err = softreq "util.encodings" -- cgit v1.2.3 From f2763a36e743df8ea1bb14e20103c710511e1102 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 27 Sep 2016 22:01:13 +0100 Subject: prosodyctl: Fix copy/paste error in help text for deluser command --- prosodyctl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/prosodyctl b/prosodyctl index 4c3ae981..e736b13e 100755 --- a/prosodyctl +++ b/prosodyctl @@ -361,8 +361,8 @@ function commands.deluser(arg) end local user, host = jid_split(arg[1]); if not user and host then - show_message [[Failed to understand JID, please supply the JID you want to set the password for]] - show_usage [[passwd user@host]] + show_message [[Failed to understand JID, please supply the JID to the user account you want to delete]] + show_usage [[deluser user@host]] return 1; end -- cgit v1.2.3 From 0ceec83b55fb2b868797dfd0651634c28ddf518f Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 27 Sep 2016 22:01:46 +0100 Subject: mod_s2s: Lower log message to 'warn' level, standard for remotely-triggered protocol issues --- plugins/mod_s2s/mod_s2s.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua index 4173fcfa..e038e5b4 100644 --- a/plugins/mod_s2s/mod_s2s.lua +++ b/plugins/mod_s2s/mod_s2s.lua @@ -365,7 +365,7 @@ function stream_callbacks.streamopened(session, attr) elseif session.direction == "outgoing" then session.notopen = nil; if not attr.id then - log("error", "Stream response did not give us a stream id!"); + log("warn", "Stream response did not give us a stream id!"); session:close({ condition = "undefined-condition", text = "Missing stream ID" }); return; end -- cgit v1.2.3 -- cgit v1.2.3 From 7bf4a51024a37862fd58dacc6086960912e8b58c Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 3 Nov 2016 23:51:40 +0100 Subject: certs/Makefile: Remove -c flag to chmod, which appears to be a GNUism ... again (thanks waqas) --- certs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/certs/Makefile b/certs/Makefile index c709ff91..587fadc6 100644 --- a/certs/Makefile +++ b/certs/Makefile @@ -27,4 +27,4 @@ keysize=2048 %.key: umask 0077 && openssl genrsa -out $@ $(keysize) - @chmod 400 $@ -c + @chmod 400 $@ -- cgit v1.2.3 From 421f71c745a594b1e832075f856a328149cc8e84 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 22 Nov 2016 15:28:24 +0100 Subject: net.server_select: Prevent writes after a handler is closed (fixes #783 I hope) --- net/server_select.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/net/server_select.lua b/net/server_select.lua index c50a6ce1..39640a83 100644 --- a/net/server_select.lua +++ b/net/server_select.lua @@ -415,6 +415,7 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport end handler.port = handler.clientport -- COMPAT server_event local write = function( self, data ) + if not handler then return false end bufferlen = bufferlen + #data if bufferlen > maxsendlen then _closelist[ handler ] = "send buffer exceeded" -- cannot close the client at the moment, have to wait to the end of the cycle -- cgit v1.2.3 From b66085658d0806343556084c03e5ee093ec8bc4a Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 28 Nov 2016 14:27:59 +0100 Subject: util.dependencies: Set ssl.x509 so core.certmanager knows that LuaSec is capable of certificate validation (fixes #781) --- util/dependencies.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/util/dependencies.lua b/util/dependencies.lua index 9ea211dd..491bfd9b 100644 --- a/util/dependencies.lua +++ b/util/dependencies.lua @@ -102,6 +102,7 @@ function check_dependencies() elseif not _G.ssl then _G.ssl = ssl; _G.ssl.context = require "ssl.context"; + _G.ssl.x509 = softreq "ssl.x509"; end local encodings, err = softreq "util.encodings" -- cgit v1.2.3 -- cgit v1.2.3 From c9677481b8a622de34c3fc436a58ab8a08cd6069 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 9 Dec 2016 15:15:10 +0100 Subject: core.rostermanager: Add method for checking if the user is subscribed to a contact --- core/rostermanager.lua | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/core/rostermanager.lua b/core/rostermanager.lua index 5e06e3f7..a846fea6 100644 --- a/core/rostermanager.lua +++ b/core/rostermanager.lua @@ -210,6 +210,18 @@ function is_contact_subscribed(username, host, jid) local item = roster[jid]; return item and (item.subscription == "from" or item.subscription == "both"), err; end +function is_user_subscribed(username, host, jid) + do + local selfjid = username.."@"..host; + local user_subscription = _get_online_roster_subscription(selfjid, jid); + if user_subscription then return (user_subscription == "both" or user_subscription == "to"); end + local contact_subscription = _get_online_roster_subscription(jid, selfjid); + if contact_subscription then return (contact_subscription == "both" or contact_subscription == "from"); end + end + local roster, err = load_roster(username, host); + local item = roster[jid]; + return item and (item.subscription == "to" or item.subscription == "both"), err; +end function is_contact_pending_in(username, host, jid) local roster = load_roster(username, host); -- cgit v1.2.3 From a6330999225f9f1ded218887ef04fafd868b4953 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 8 Dec 2016 20:49:35 +0100 Subject: mod_presence: Send probe once subscribed (fixes #794) --- plugins/mod_presence.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/mod_presence.lua b/plugins/mod_presence.lua index a5b4f282..6df56fe0 100644 --- a/plugins/mod_presence.lua +++ b/plugins/mod_presence.lua @@ -201,7 +201,9 @@ function handle_outbound_presence_subscriptions_and_probes(origin, stanza, from_ end core_post_stanza(origin, stanza); send_presence_of_available_resources(node, host, to_bare, origin); - core_post_stanza(origin, st.presence({ type = "probe", from = from_bare, to = to_bare })); + if rostermanager.is_user_subscribed(node, host, to_bare) then + core_post_stanza(origin, st.presence({ type = "probe", from = from_bare, to = to_bare })); + end elseif stanza.attr.type == "unsubscribed" then -- 1. send unavailable -- 2. route stanza -- cgit v1.2.3 From fd9337419751cdcbc9ad156ffddb496c7ab9a165 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 21 Dec 2016 11:02:17 +0100 Subject: mod_net_multiplex: Enable SSL on the SSL port (fixes #803) --- plugins/mod_net_multiplex.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/mod_net_multiplex.lua b/plugins/mod_net_multiplex.lua index 0dd3dc67..a66ab31f 100644 --- a/plugins/mod_net_multiplex.lua +++ b/plugins/mod_net_multiplex.lua @@ -67,5 +67,6 @@ module:provides("net", { module:provides("net", { name = "multiplex_ssl"; config_prefix = "ssl"; + encryption = "ssl"; listener = listener; }); -- cgit v1.2.3 From ef0efd6f0cb3f6713e7c1898efbdf0a5f634b923 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 21 Feb 2017 18:54:44 +0100 Subject: mod_register: Require encryption before registration if c2s_require_encryption is set (fixes #595) --- plugins/mod_register.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/mod_register.lua b/plugins/mod_register.lua index 3d7a068c..63d0b077 100644 --- a/plugins/mod_register.lua +++ b/plugins/mod_register.lua @@ -20,6 +20,7 @@ local jid_bare = require "util.jid".bare; local compat = module:get_option_boolean("registration_compat", true); local allow_registration = module:get_option_boolean("allow_registration", false); local additional_fields = module:get_option("additional_registration_fields", {}); +local require_encryption = module:get_option("c2s_require_encryption") or module:get_option("require_encryption"); local account_details = module:open_store("account_details"); @@ -75,7 +76,7 @@ module:hook("stream-features", function(event) local session, features = event.origin, event.features; -- Advertise registration to unauthorized clients only. - if not(allow_registration) or session.type ~= "c2s_unauthed" then + if not(allow_registration) or session.type ~= "c2s_unauthed" or (require_encryption and not session.secure) then return end @@ -183,6 +184,8 @@ module:hook("stanza/iq/jabber:iq:register:query", function(event) if not(allow_registration) or session.type ~= "c2s_unauthed" then session.send(st.error_reply(stanza, "cancel", "service-unavailable")); + elseif require_encryption and not session.secure then + session.send(st.error_reply(stanza, "modify", "policy-violation", "Encryption is required")); else local query = stanza.tags[1]; if stanza.attr.type == "get" then -- cgit v1.2.3 From bcc0390cb6e9230472f7dae878f84ca7d6017de2 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 2 Mar 2017 15:17:32 +0100 Subject: mod_saslauth: Log SASL failure reason --- plugins/mod_saslauth.lua | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/plugins/mod_saslauth.lua b/plugins/mod_saslauth.lua index c5d3dc91..d374633e 100644 --- a/plugins/mod_saslauth.lua +++ b/plugins/mod_saslauth.lua @@ -96,8 +96,19 @@ end) module:hook_stanza(xmlns_sasl, "failure", function (session, stanza) if session.type ~= "s2sout_unauthed" or session.external_auth ~= "attempting" then return; end - module:log("info", "SASL EXTERNAL with %s failed", session.to_host) - -- TODO: Log the failure reason + local text = stanza:get_child_text("text"); + local condition = "unknown-condition"; + for child in stanza:childtags() do + if child.name ~= "text" then + condition = child.name; + break; + end + end + if text and condition then + condition = connection .. ": " .. text; + end + module:log("info", "SASL EXTERNAL with %s failed: %s", session.to_host, condition); + session.external_auth = "failed" end, 500) -- cgit v1.2.3 From b1131ced697722379faff3f5871f24a385fe666f Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 24 Mar 2017 00:25:49 +0100 Subject: mod_disco: Correctly set the 'node' attr (fixes #449) --- plugins/mod_disco.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_disco.lua b/plugins/mod_disco.lua index 72c9a34c..b41f9651 100644 --- a/plugins/mod_disco.lua +++ b/plugins/mod_disco.lua @@ -99,7 +99,7 @@ module:hook("iq/host/http://jabber.org/protocol/disco#info:query", function(even local node = stanza.tags[1].attr.node; if node and node ~= "" and node ~= "http://prosody.im#"..get_server_caps_hash() then return; end -- TODO fire event? local reply_query = get_server_disco_info(); - reply_query.node = node; + reply_query.attr.node = node; local reply = st.reply(stanza):add_child(reply_query); origin.send(reply); return true; -- cgit v1.2.3 From 97e5c31b8e7d8455ce0b2af476153b311f0d9c29 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 17 Apr 2017 21:40:06 +0200 Subject: mod_bosh: Update session.conn to point to the current connection (fixes #890) --- plugins/mod_bosh.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/mod_bosh.lua b/plugins/mod_bosh.lua index d9c8defd..1eb95e90 100644 --- a/plugins/mod_bosh.lua +++ b/plugins/mod_bosh.lua @@ -247,7 +247,7 @@ function stream_callbacks.streamopened(context, attr) -- New session sid = new_uuid(); local session = { - type = "c2s_unauthed", conn = {}, sid = sid, rid = tonumber(attr.rid)-1, host = attr.to, + type = "c2s_unauthed", conn = request.conn, sid = sid, rid = tonumber(attr.rid)-1, host = attr.to, bosh_version = attr.ver, bosh_wait = math_min(attr.wait, bosh_max_wait), streamid = sid, bosh_hold = BOSH_DEFAULT_HOLD, bosh_max_inactive = BOSH_DEFAULT_INACTIVITY, requests = { }, send_buffer = {}, reset_stream = bosh_reset_stream, @@ -316,6 +316,8 @@ function stream_callbacks.streamopened(context, attr) context.notopen = nil; return; end + + session.conn = request.conn; if session.rid then local rid = tonumber(attr.rid); -- cgit v1.2.3 From 2128b374fd84705ff5a71fe8d0037151e899806b Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 22 May 2017 05:32:11 +0200 Subject: net.dns: Simplify expiry calculation (fixes #919) --- net/dns.lua | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/net/dns.lua b/net/dns.lua index d123731c..5e29e906 100644 --- a/net/dns.lua +++ b/net/dns.lua @@ -137,9 +137,7 @@ local function prune(rrs, time, soft) -- - - - - - - - - - - - - - - prune time = time or socket.gettime(); for i,rr in ipairs(rrs) do if rr.tod then - -- rr.tod = rr.tod - 50 -- accelerated decripitude - rr.ttl = math.floor(rr.tod - time); - if rr.ttl <= 0 then + if rr.tod < time then rrs[rr[rr.type:lower()]] = nil; table.remove(rrs, i); return prune(rrs, time, soft); -- Re-iterate @@ -515,11 +513,7 @@ function resolver:rr() -- - - - - - - - - - - - - - - - - - - - - - - - rr rr.ttl = 0x10000*self:word() + self:word(); rr.rdlength = self:word(); - if rr.ttl <= 0 then - rr.tod = self.time + 30; - else - rr.tod = self.time + rr.ttl; - end + rr.tod = self.time + rr.ttl; local remember = self.offset; local rr_parser = self[dns.type[rr.type]]; -- cgit v1.2.3 From 2922e3c9a097f34ff14618c6344e4a705036a4c9 Mon Sep 17 00:00:00 2001 From: Emmanuel Gil Peyrot Date: Sat, 27 May 2017 14:23:43 +0100 Subject: mod_watchregistrations: Return the pointer to the root of the stanza, fixes #922. --- plugins/mod_watchregistrations.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/mod_watchregistrations.lua b/plugins/mod_watchregistrations.lua index abca90bd..0e9d2fca 100644 --- a/plugins/mod_watchregistrations.lua +++ b/plugins/mod_watchregistrations.lua @@ -21,7 +21,8 @@ module:hook("user-registered", function (user) :tag("body") :text(registration_notification:gsub("%$(%w+)", function (v) return user[v] or user.session and user.session[v] or nil; - end)); + end)) + :up(); for jid in registration_watchers do module:log("debug", "Notifying %s", jid); message.attr.to = jid; -- cgit v1.2.3 From bd0e511eb8ea7f5d3628b92f7521f6a6770810dd Mon Sep 17 00:00:00 2001 From: Emmanuel Gil Peyrot Date: Sat, 27 May 2017 15:53:30 +0100 Subject: mod_disco: Add an account/registered identity on subscribed accounts, fixes #826. --- plugins/mod_disco.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/mod_disco.lua b/plugins/mod_disco.lua index b41f9651..71a04a2d 100644 --- a/plugins/mod_disco.lua +++ b/plugins/mod_disco.lua @@ -138,6 +138,7 @@ module:hook("iq/bare/http://jabber.org/protocol/disco#info:query", function(even if not stanza.attr.to or is_contact_subscribed(username, module.host, jid_bare(stanza.attr.from)) then local reply = st.reply(stanza):tag('query', {xmlns='http://jabber.org/protocol/disco#info'}); if not reply.attr.from then reply.attr.from = origin.username.."@"..origin.host; end -- COMPAT To satisfy Psi when querying own account + reply:tag('identity', {category='account', type='registered'}):up(); module:fire_event("account-disco-info", { origin = origin, stanza = reply }); origin.send(reply); return true; -- cgit v1.2.3 From 607db2c49605096528c4937a0576d745d78acc64 Mon Sep 17 00:00:00 2001 From: Emmanuel Gil Peyrot Date: Tue, 30 May 2017 20:52:22 +0100 Subject: mod_welcome: Return the pointer to the root of the stanza, fixes a bug similar to #922. --- plugins/mod_welcome.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/mod_welcome.lua b/plugins/mod_welcome.lua index e498f0b3..c4ebaf30 100644 --- a/plugins/mod_welcome.lua +++ b/plugins/mod_welcome.lua @@ -14,8 +14,8 @@ local st = require "util.stanza"; module:hook("user-registered", function (user) local welcome_stanza = - st.message({ to = user.username.."@"..user.host, from = host }) - :tag("body"):text(welcome_text:gsub("$(%w+)", user)); + st.message({ to = user.username.."@"..user.host, from = host }, + welcome_text:gsub("$(%w+)", user)); module:send(welcome_stanza); module:log("debug", "Welcomed user %s@%s", user.username, user.host); end); -- cgit v1.2.3 From af87a0a196774b3bf6b7dccf0b82069a4ae04d3d Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 13 Jun 2017 16:36:47 +0200 Subject: net.dns: Prevent answers from immediately expiring even if TTL=0 (see #919) --- net/dns.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/dns.lua b/net/dns.lua index 5e29e906..0d6a828c 100644 --- a/net/dns.lua +++ b/net/dns.lua @@ -513,7 +513,7 @@ function resolver:rr() -- - - - - - - - - - - - - - - - - - - - - - - - rr rr.ttl = 0x10000*self:word() + self:word(); rr.rdlength = self:word(); - rr.tod = self.time + rr.ttl; + rr.tod = self.time + math.min(rr.ttl, 1); local remember = self.offset; local rr_parser = self[dns.type[rr.type]]; -- cgit v1.2.3 From 6f2c8d8664cd341b7845d726be6a1cd0e0305ef8 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 8 Jul 2017 18:21:45 +0200 Subject: mod_saslauth: Use correct varible name (thanks Roi) --- plugins/mod_saslauth.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mod_saslauth.lua b/plugins/mod_saslauth.lua index d374633e..a23d1f53 100644 --- a/plugins/mod_saslauth.lua +++ b/plugins/mod_saslauth.lua @@ -105,7 +105,7 @@ module:hook_stanza(xmlns_sasl, "failure", function (session, stanza) end end if text and condition then - condition = connection .. ": " .. text; + condition = condition .. ": " .. text; end module:log("info", "SASL EXTERNAL with %s failed: %s", session.to_host, condition); -- cgit v1.2.3 From be92d92ad720c90767daf5c14c2221b6c6ab288b Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 25 Jul 2017 13:16:31 +0200 Subject: util.dependencies: Add compatibility code for LuaSocket no longer exporting as a global --- util/dependencies.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/util/dependencies.lua b/util/dependencies.lua index 491bfd9b..a259c263 100644 --- a/util/dependencies.lua +++ b/util/dependencies.lua @@ -79,6 +79,9 @@ function check_dependencies() ["Source"] = "http://www.tecgraf.puc-rio.br/~diego/professional/luasocket/"; }); fatal = true; + elseif not _G.socket then + -- COMPAT Code expecting LuaSocket to export as a global + _G.socket = socket; end local lfs, err = softreq "lfs" -- cgit v1.2.3 From 0a64a2f9a8d3765a7f7126dc3d295b831fb1a8c7 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 25 Jul 2017 13:25:49 +0200 Subject: util.dependencies: Add comment about LuaSec compat --- util/dependencies.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/util/dependencies.lua b/util/dependencies.lua index a259c263..7ec56022 100644 --- a/util/dependencies.lua +++ b/util/dependencies.lua @@ -103,6 +103,7 @@ function check_dependencies() ["Source"] = "http://www.inf.puc-rio.br/~brunoos/luasec/"; }, "SSL/TLS support will not be available"); elseif not _G.ssl then + -- COMPAT Code expecting LuaSec to export as a global (see #749) _G.ssl = ssl; _G.ssl.context = require "ssl.context"; _G.ssl.x509 = softreq "ssl.x509"; -- cgit v1.2.3 From c9bf59191b8e4eb56979b0711cea51179f29b729 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 13 Sep 2017 18:18:57 +0200 Subject: mod_c2s: Iterate over child tags instead of child nodes in stream error (fixes traceback from #987) --- plugins/mod_c2s.lua | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/plugins/mod_c2s.lua b/plugins/mod_c2s.lua index 2bb919f8..fdb3b211 100644 --- a/plugins/mod_c2s.lua +++ b/plugins/mod_c2s.lua @@ -98,16 +98,14 @@ function stream_callbacks.error(session, error, data) session:close("not-well-formed"); elseif error == "stream-error" then local condition, text = "undefined-condition"; - for child in data:children() do - if child.attr.xmlns == xmlns_xmpp_streams then - if child.name ~= "text" then - condition = child.name; - else - text = child:get_text(); - end - if condition ~= "undefined-condition" and text then - break; - end + for child in data:childtags(nil, xmlns_xmpp_streams) do + if child.name ~= "text" then + condition = child.name; + else + text = child:get_text(); + end + if condition ~= "undefined-condition" and text then + break; end end text = condition .. (text and (" ("..text..")") or ""); -- cgit v1.2.3 From ed9dafe47250ee388867c429d6cef7965e1689da Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 14 Sep 2017 01:27:36 +0200 Subject: mod_component, mod_s2s: Iterate over child tags instead of child nodes (can include text) in stream error (same as 176b7f4e4ac9) --- plugins/mod_component.lua | 18 ++++++++---------- plugins/mod_s2s/mod_s2s.lua | 18 ++++++++---------- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/plugins/mod_component.lua b/plugins/mod_component.lua index 11abab79..acd70c60 100644 --- a/plugins/mod_component.lua +++ b/plugins/mod_component.lua @@ -151,16 +151,14 @@ function stream_callbacks.error(session, error, data, data2) session:close("not-well-formed"); elseif error == "stream-error" then local condition, text = "undefined-condition"; - for child in data:children() do - if child.attr.xmlns == xmlns_xmpp_streams then - if child.name ~= "text" then - condition = child.name; - else - text = child:get_text(); - end - if condition ~= "undefined-condition" and text then - break; - end + for child in data:childtags(nil, xmlns_xmpp_streams) do + if child.name ~= "text" then + condition = child.name; + else + text = child:get_text(); + end + if condition ~= "undefined-condition" and text then + break; end end text = condition .. (text and (" ("..text..")") or ""); diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua index e038e5b4..10b81a17 100644 --- a/plugins/mod_s2s/mod_s2s.lua +++ b/plugins/mod_s2s/mod_s2s.lua @@ -416,16 +416,14 @@ function stream_callbacks.error(session, error, data) session:close("not-well-formed"); elseif error == "stream-error" then local condition, text = "undefined-condition"; - for child in data:children() do - if child.attr.xmlns == xmlns_xmpp_streams then - if child.name ~= "text" then - condition = child.name; - else - text = child:get_text(); - end - if condition ~= "undefined-condition" and text then - break; - end + for child in data:childtags(nil, xmlns_xmpp_streams) do + if child.name ~= "text" then + condition = child.name; + else + text = child:get_text(); + end + if condition ~= "undefined-condition" and text then + break; end end text = condition .. (text and (" ("..text..")") or ""); -- cgit v1.2.3