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 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 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 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 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 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 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 -- 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 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 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