--- a/mod_auth_ccert/mod_auth_ccert.lua Wed Feb 26 13:08:47 2014 -0800
+++ b/mod_auth_ccert/mod_auth_ccert.lua Fri Feb 28 15:36:06 2014 +0100
@@ -60,7 +60,7 @@
function get_sasl_handler(session)
return new_sasl(module.host, {
external = session.secure and function(authz)
- if not session.secure then
+ if not session.secure or not session.conn:ssl() then
-- getpeercertificate() on a TCP connection would be bad, abort!
(session.log or log)("error", "How did you manage to select EXTERNAL without TLS?");
return nil, false;
--- a/mod_auth_dovecot/auth_dovecot/sasl_dovecot.lib.lua Wed Feb 26 13:08:47 2014 -0800
+++ b/mod_auth_dovecot/auth_dovecot/sasl_dovecot.lib.lua Fri Feb 28 15:36:06 2014 +0100
@@ -62,8 +62,8 @@
end
if not ok then
- return false, "error connecting to dovecot "..tostring(socket_type).." socket at '"
- ..tostring(socket_path or socket_info).."'. error was '"..tostring(err).."'";
+ log("error", "error connecting to dovecot %s socket at '%s'. error was '%s'", socket_type, socket_path or socket_info, err);
+ return false;
end
-- Send our handshake
@@ -95,6 +95,7 @@
local major_version = parts();
if major_version ~= "1" then
+ log("error", "dovecot server version is not 1.x. it is %s.x", major_version);
conn:close();
return false, "dovecot server version is not 1.x. it is "..tostring(major_version)..".x";
end
--- a/mod_block_strangers/mod_block_strangers.lua Wed Feb 26 13:08:47 2014 -0800
+++ b/mod_block_strangers/mod_block_strangers.lua Fri Feb 28 15:36:06 2014 +0100
@@ -2,6 +2,7 @@
local jid_split = require "util.jid".split;
local jid_bare = require "util.jid".bare;
local is_contact_subscribed = require "core.rostermanager".is_contact_subscribed;
+local error_reply = require "util.stanza".error_reply;
function check_subscribed(event)
local stanza = event.stanza;
@@ -11,7 +12,7 @@
if to_resource and stanza.attr.type == "groupchat" then
return nil; -- Pass through
end
- return true; -- Drop stanza
+ return error_reply("auth", "forbidden", "Subscription required"); -- Bounce with error
end
end
--- a/mod_carbons/mod_carbons.lua Wed Feb 26 13:08:47 2014 -0800
+++ b/mod_carbons/mod_carbons.lua Fri Feb 28 15:36:06 2014 +0100
@@ -62,10 +62,11 @@
return -- No use in sending carbons to an offline user
end
- if stanza:get_child("private", xmlns_carbons) then
+ local private_tag = stanza:child_with_name("private");
+ if private_tag and private.attr.xmlns == xmlns_carbons or private.attr.xmlns == xmlns_carbons_old then
if not c2s then
stanza:maptags(function(tag)
- if not ( tag.attr.xmlns == xmlns_carbons and tag.name == "private" ) then
+ if tag ~= private_tag then
return tag;
end
end);
--- a/mod_default_bookmarks/mod_default_bookmarks.lua Wed Feb 26 13:08:47 2014 -0800
+++ b/mod_default_bookmarks/mod_default_bookmarks.lua Fri Feb 28 15:36:06 2014 +0100
@@ -13,37 +13,34 @@
local dm_load = require "util.datamanager".load
local jid_split = require "util.jid".split
-module:hook("iq/self/jabber:iq:private:query", function(event)
+local private_bookmarks_ns = "storage:storage:bookmarks";
+
+local bookmarks = module:get_option("default_bookmarks");
+
+module:hook("iq-get/self/jabber:iq:private:query", function(event)
local origin, stanza = event.origin, event.stanza;
- local typ = stanza.attr.type;
local from = stanza.attr.from;
- local query = stanza.tags[1];
- if #query.tags == 1 and typ == "get" then
- local tag = query.tags[1];
- local key = tag.name..":"..tag.attr.xmlns;
- if key == "storage:storage:bookmarks" then
- local data, err = dm_load(origin.username, origin.host, "private");
- if not(data and data[key]) then
- local bookmarks = module:get_option("default_bookmarks");
- if bookmarks and #bookmarks > 0 then
- local reply = st.reply(stanza):tag("query", {xmlns = "jabber:iq:private"})
- :tag("storage", { xmlns = "storage:bookmarks" });
- local nick = jid_split(from);
- for i=1,#bookmarks do
- local bookmark = bookmarks[i];
- if type(bookmark) ~= "table" then -- assume it's only a jid
- bookmark = { jid = bookmark, name = jid_split(bookmark) };
- end
- reply:tag("conference", {
- jid = bookmark.jid,
- name = bookmark.name,
- autojoin = "1",
- }):tag("nick"):text(nick):up():up();
- end
- origin.send(reply);
- return true;
- end
- end
+ if not stanza.tags[1]:get_child("storage", "storage:bookmarks") then return end
+ local data, err = dm_load(origin.username, origin.host, "private");
+ if data and data[private_bookmarks_ns] then return end
+
+ local reply = st.reply(stanza):tag("query", {xmlns = "jabber:iq:private"})
+ :tag("storage", { xmlns = "storage:bookmarks" });
+
+ local nick = jid_split(from);
+
+ local bookmark;
+ for i=1,#bookmarks do
+ bookmark = bookmarks[i];
+ if type(bookmark) ~= "table" then -- assume it's only a jid
+ bookmark = { jid = bookmark, name = jid_split(bookmark) };
end
+ reply:tag("conference", {
+ jid = bookmark.jid,
+ name = bookmark.name,
+ autojoin = "1",
+ }):tag("nick"):text(nick):up():up();
end
+ origin.send(reply);
+ return true;
end, 1);
--- a/mod_firewall/mod_firewall.lua Wed Feb 26 13:08:47 2014 -0800
+++ b/mod_firewall/mod_firewall.lua Fri Feb 28 15:36:06 2014 +0100
@@ -27,6 +27,10 @@
type = "event"; "route/remote";
priority = 0.1;
};
+ send_remote = { -- FIXME name
+ type = "filter"; "s2sout";
+ priority = 0.1;
+ };
};
local function idsafe(name)
@@ -372,9 +376,13 @@
module:log("error", "Compilation error for %s: %s", script, err);
else
local chain_definition = chains[chain];
- if chain_definition and chain_definition.type == "event" then
- for _, event_name in ipairs(chain_definition) do
- module:hook(event_name, handler, chain_definition.priority);
+ if chain_definition then
+ if chain_definition.type == "event" then
+ for _, event_name in ipairs(chain_definition) do
+ module:hook(event_name, handler, chain_definition.priority);
+ end
+ elseif chain_definition.type == "filter" then
+ -- TODO
end
elseif not chain:match("^user/") then
module:log("warn", "Unknown chain %q", chain);
--- a/mod_http_altconnect/mod_http_altconnect.lua Wed Feb 26 13:08:47 2014 -0800
+++ b/mod_http_altconnect/mod_http_altconnect.lua Fri Feb 28 15:36:06 2014 +0100
@@ -6,16 +6,20 @@
local json = require"util.json";
local st = require"util.stanza";
local array = require"util.array";
+local it = require"util.iterators";
local host_modules = hosts[module.host].modules;
local function get_supported()
- local uris = array();
- if host_modules["bosh"] then
- uris:push({ rel = "urn:xmpp:alt-connections:xbosh", href = module:http_url("bosh", "/http-bind") });
- end
- if host_modules["websocket"] then
- uris:push({ rel = "urn:xmpp:alt-connections:websocket", href = module:http_url("websocket", "xmpp-websocket"):gsub("^http", "ws") });
+ local uris = array(it.values(module:get_host_items("alt-conn-method")));
+ if #uris == 0 then
+ -- COMPAT for with before item array was added
+ if host_modules["bosh"] then
+ uris:push({ rel = "urn:xmpp:alt-connections:xbosh", href = module:http_url("bosh", "/http-bind") });
+ end
+ if host_modules["websocket"] then
+ uris:push({ rel = "urn:xmpp:alt-connections:websocket", href = module:http_url("websocket", "xmpp-websocket"):gsub("^http", "ws") });
+ end
end
return uris;
end
--- a/mod_http_dir_listing/http_dir_listing/resources/style.css Wed Feb 26 13:08:47 2014 -0800
+++ b/mod_http_dir_listing/http_dir_listing/resources/style.css Fri Feb 28 15:36:06 2014 +0100
@@ -5,6 +5,12 @@
a:link:hover,a:visited:hover{color:#3465a4;}
.filelist{background-color:white;padding:1em;list-style-position:inside;-moz-column-width:20em;-webkit-column-width:20em;-ms-column-width:20em;column-width:20em;}
.file{list-style-image:url(text-x-generic.png);}
+.file.image{list-style-image:url(image-x-generic.png);}
+.file.video{list-style-image:url(video-x-generic.png);}
+.file.audio{list-style-image:url(audio-x-generic.png);}
+.file.vcf{list-style-image:url(x-office-address-book.png);}
+.file.text.html{list-style-image:url(text-html.png);}
+.file.application{list-style-image:url(application-x-executable.png);}
.directory{list-style-image:url(folder.png);}
.parent{list-style-image:url(user-home.png);}
footer{margin-top:1ex;font-size:smaller;color:#babdb6;}
--- a/mod_http_dir_listing/http_dir_listing/resources/template.html Wed Feb 26 13:08:47 2014 -0800
+++ b/mod_http_dir_listing/http_dir_listing/resources/template.html Fri Feb 28 15:36:06 2014 +0100
@@ -6,9 +6,9 @@
</head>
<body>
<h1>Index of {path}</h1>
-
- {filelist}
-
+ <article>
+ {filelist}
+ </article>
<footer>{footer}</footer>
</body>
</html>
--- a/mod_mam/mod_mam.lua Wed Feb 26 13:08:47 2014 -0800
+++ b/mod_mam/mod_mam.lua Fri Feb 28 15:36:06 2014 +0100
@@ -1,9 +1,9 @@
-- XEP-0313: Message Archive Management for Prosody
--- Copyright (C) 2011-2012 Kim Alvefur
+-- Copyright (C) 2011-2014 Kim Alvefur
--
-- This file is MIT/X11 licensed.
-local xmlns_mam = "urn:xmpp:mam:tmp";
+local xmlns_mam = "urn:xmpp:mam:0" or ":1";
local xmlns_delay = "urn:xmpp:delay";
local xmlns_forward = "urn:xmpp:forward:0";
@@ -16,6 +16,7 @@
local jid_bare = require "util.jid".bare;
local jid_split = require "util.jid".split;
local jid_prep = require "util.jid".prep;
+local dataform = require "util.dataforms".new;
local host = module.host;
local rm_load_roster = require "core.rostermanager".load_roster;
@@ -61,18 +62,37 @@
end
end);
+local query_form = dataform {
+ { name = "FORM_TYPE"; type = "hidden"; value = "urn:xmpp:mam:0"; };
+ { name = "with"; type = "jid-single"; };
+ { name = "start"; type = "text-single" };
+ { name = "end"; type = "text-single"; };
+};
+
+-- Serve form
+module:hook("iq-get/self/"..xmlns_mam..":query", function(event)
+ local origin, stanza = event.origin, event.stanza;
+ return origin.send(st.reply(stanza):add_child(query_form:form()));
+end);
+
-- Handle archive queries
-module:hook("iq-get/self/"..xmlns_mam..":query", function(event)
+module:hook("iq-set/self/"..xmlns_mam..":query", function(event)
local origin, stanza = event.origin, event.stanza;
local query = stanza.tags[1];
local qid = query.attr.queryid;
-- Search query parameters
- local qwith = query:get_child_text("with");
- local qstart = query:get_child_text("start");
- local qend = query:get_child_text("end");
- module:log("debug", "Archive query, id %s with %s from %s until %s)",
- tostring(qid), qwith or "anyone", qstart or "the dawn of time", qend or "now");
+ local qwith, qstart, qend;
+ local form = query:get_child("x", "jabber:x:data");
+ if form then
+ local err;
+ form, err = query_form:data(form);
+ if err then
+ return origin.send(st.error_reply(stanza, "modify", "bad-request", select(2, next(err))))
+ end
+ qwith, qstart, qend = form["with"], form["start"], form["end"];
+ qwith = qwith and jid_bare(qwith);
+ end
if qstart or qend then -- Validate timestamps
local vstart, vend = (qstart and timestamp_parse(qstart)), (qend and timestamp_parse(qend))
@@ -83,14 +103,8 @@
qstart, qend = vstart, vend;
end
- if qwith then -- Validate the 'with' jid
- local pwith = qwith and jid_prep(qwith);
- if pwith and not qwith then -- it failed prepping
- origin.send(st.error_reply(stanza, "modify", "bad-request", "Invalid JID"))
- return true
- end
- qwith = jid_bare(pwith);
- end
+ module:log("debug", "Archive query, id %s with %s from %s until %s)",
+ tostring(qid), qwith or "anyone", qstart or "the dawn of time", qend or "now");
-- RSM stuff
local qset = rsm.get(query);
@@ -116,7 +130,7 @@
local count = err;
-- Wrap it in stuff and deliver
- local first, last;
+ local first_id, last_id, first_time, last_time;
for id, item, when in data do
local fwd_st = st.message{ to = origin.full_jid }
:tag("result", { xmlns = xmlns_mam, queryid = qid, id = id })
@@ -129,18 +143,27 @@
item.attr.xmlns = "jabber:client";
fwd_st:add_child(item);
- if not first then first = id; end
- last = id;
+ if not first_id then
+ first_id = id;
+ first_time = when;
+ end
+ last_id = id;
+ last_time = when;
origin.send(fwd_st);
end
-- That's all folks!
module:log("debug", "Archive query %s completed", tostring(qid));
- if reverse then first, last = last, first; end
+ if reverse then
+ first_id, last_id, first_time, last_time =
+ last_id, first_id, last_time, first_time;
+ end
return origin.send(st.reply(stanza)
- :query(xmlns_mam):add_child(rsm.generate {
- first = first, last = last, count = count }));
+ :query(xmlns_mam)
+ :add_child(query_form:form({ start = timestamp(first_time), ["end"] = timestamp(last_time), with = qwith }))
+ :add_child(rsm.generate {
+ first = first_id, last = last_id, count = count }));
end);
local function has_in_roster(user, who)
--- a/mod_mam_muc/mod_mam_muc.lua Wed Feb 26 13:08:47 2014 -0800
+++ b/mod_mam_muc/mod_mam_muc.lua Fri Feb 28 15:36:06 2014 +0100
@@ -111,6 +111,36 @@
end);
end
+module:hook("muc-config-form", function(event)
+ local room, form = event.room, event.form;
+ local mam_query = room._data.mam_query or 'anyone';
+ table.insert(form, {
+ name = muc_form_allow_who,
+ type = 'list-single',
+ label = 'Who may query the archive?',
+ value = {
+ { value = 'moderators', label = 'Moderators Only', default = mam_query == 'moderators' },
+ { value = 'members', label = 'Members', default = mam_query == 'members' },
+ { value = 'anyone', label = 'Anyone who can join', default = mam_query == 'anyone' },
+ }
+ }
+ );
+end);
+
+module:hook("muc-config-submitted", function(event)
+ local room, fields, changed = event.room, event.fields, event.changed;
+ local new = fields[muc_form_allow_who];
+ if new ~= room._data.mam_query then
+ room._data.mam_query = new;
+ if type(changed) == "table" then
+ changed[muc_form_allow_who] = true;
+ else
+ event.changed = true;
+ end
+ end
+end);
+
+
-- Handle archive queries
module:hook("iq-get/bare/"..xmlns_mam..":query", function(event)
local origin, stanza = event.origin, event.stanza;
@@ -126,8 +156,11 @@
-- Banned or not a member of a members-only room?
local from_affiliation = room_obj:get_affiliation(from);
+ local allowed_to_query = room_obj._data.mam_query or "anyone";
if from_affiliation == "outcast" -- banned
- or room_obj:get_members_only() and not from_affiliation then -- members-only, not a member
+ or room_obj:get_members_only() and not from_affiliation -- members-only, not a member
+ or allowed_to_query == "moderators" and not (from_affiliation == "owner" or from_affiliation == "admin" )
+ or allowed_to_query ~= "anyone" then
return origin.send(st.error_reply(stanza, "auth", "forbidden"))
end
--- a/mod_manifesto/mod_manifesto.lua Wed Feb 26 13:08:47 2014 -0800
+++ b/mod_manifesto/mod_manifesto.lua Fri Feb 28 15:36:06 2014 +0100
@@ -57,14 +57,18 @@
module:hook("resource-bind", function (event)
local session = event.session;
+ module:log("debug", "mod_%s sees that %s logged in", module.name, session.username);
local now = time();
local last_notify = notified[session.username] or 0;
if last_notify > ( now - 86400 * 7 ) then
+ module:log("debug", "Already notified %s", session.username);
return
end
+ module:log("debug", "Waiting 15 seconds");
timer.add_task(15, function ()
+ module:log("debug", "15 seconds later... session.type is %q", session.type);
if session.type ~= "c2s" then return end -- user quit already
local bad_contacts, bad_hosts = {}, {};
for contact_jid, item in pairs(session.roster or {}) do
@@ -96,6 +100,7 @@
end
end
end
+ module:log("debug", "%s has %d bad contacts", session.username, #bad_contacts);
if #bad_contacts > 0 then
local vars = {
HOST = host;
@@ -103,6 +108,7 @@
SERVICES = " "..table.concat(bad_hosts, "\n ");
CONTACTVIA = contact_method, CONTACT = contact;
};
+ module:log("debug", "Sending notification to %s", session.username);
session.send(st.message({ type = "headline", from = host }):tag("body"):text(message:gsub("$(%w+)", vars)));
notified[session.username] = now;
end
@@ -159,7 +165,7 @@
config_set(host, "s2s_require_encryption", true);
for _, session in pairs(s2s_sessions) do
- if not session.secure then
+ if session.type == "s2sin" or session.type == "s2sout" and not session.secure then
(session.close or s2s_destroy_session)(session);
end
end
--- a/mod_muc_log/mod_muc_log.lua Wed Feb 26 13:08:47 2014 -0800
+++ b/mod_muc_log/mod_muc_log.lua Fri Feb 28 15:36:06 2014 +0100
@@ -96,6 +96,7 @@
end
end
end
+ datamanager.getpath(node, host, datastore, nil, true); -- create the datastore dir
data_store(node, host, datastore .. "/" .. today, data);
end
end
--- a/mod_pubsub_feeds/mod_pubsub_feeds.lua Wed Feb 26 13:08:47 2014 -0800
+++ b/mod_pubsub_feeds/mod_pubsub_feeds.lua Fri Feb 28 15:36:06 2014 +0100
@@ -17,8 +17,8 @@
local pubsub = module:depends"pubsub";
-local date, time = os.date, os.time;
-local dt_parse, dt_datetime = require "util.datetime".parse, require "util.datetime".datetime;
+local date, time = import("os", "date", "time");
+local dt_parse, dt_datetime = import("util.datetime", "parse", "datetime");
local uuid = require "util.uuid".generate;
local hmac_sha1 = require "util.hashes".hmac_sha1;
local parse_feed = require "feeds".feed_from_string;
--- a/mod_pubsub_hub/mod_pubsub_hub.lua Wed Feb 26 13:08:47 2014 -0800
+++ b/mod_pubsub_hub/mod_pubsub_hub.lua Fri Feb 28 15:36:06 2014 +0100
@@ -2,15 +2,14 @@
--
-- This file is MIT/X11 licensed.
-local http = require "net.http";
-local formdecode = http.formdecode;
-local formencode = http.formencode;
+local http_request, formdecode, formencode = import("net.http", "request", "formdecode", "formencode");
local uuid = require "util.uuid".generate;
local hmac_sha1 = require "util.hmac".sha1;
local json_encode = require "util.json".encode;
local time = os.time;
local m_min, m_max = math.min, math.max;
local tostring = tostring;
+
local xmlns_pubsub = "http://jabber.org/protocol/pubsub";
local xmlns_pubsub_event = xmlns_pubsub .. "#event";
local subs_by_topic = module:shared"subscriptions";
@@ -91,7 +90,7 @@
module:log("debug", require"util.serialization".serialize(verify_modes));
if verify_modes["async"] then
module:log("debug", "Sending async verification request to %s for %s", tostring(callback_url), tostring(subscription));
- http.request(callback_url, nil, function(body, code)
+ http_request(callback_url, nil, function(body, code)
if body == challenge and code > 199 and code < 300 then
if not subscription.want_state then
module:log("warn", "Verification of already verified request, probably");
@@ -109,7 +108,7 @@
end)
return 202;
elseif verify_modes["sync"] then
- http.request(callback_url, nil, function(body, code)
+ http_request(callback_url, nil, function(body, code)
if body == challenge and code > 199 and code < 300 then
if not subscription.want_state then
module:log("warn", "Verification of already verified request, probably");
@@ -161,7 +160,7 @@
["hub.lease_seconds"] = subscription.lease_seconds,
["hub.verify_token"] = subscription.verify_token,
}
- http.request(callback_url, nil, function(body, code)
+ http_request(callback_url, nil, function(body, code)
if body == challenge and code > 199 and code < 300 then
subscription.expires = now + subscription.lease_seconds;
end
@@ -201,7 +200,7 @@
if subscription.secret then
headers["X-Hub-Signature"] = "sha1="..hmac_sha1(subscription.secret, body, true);
end
- http.request(subscription.callback, { method = "POST", body = body, headers = headers }, function(body, code)
+ http_request(subscription.callback, { method = "POST", body = body, headers = headers }, function(body, code)
if code >= 200 and code <= 299 then
module:log("debug", "Delivered");
else
--- a/mod_s2s_auth_dane/mod_s2s_auth_dane.lua Wed Feb 26 13:08:47 2014 -0800
+++ b/mod_s2s_auth_dane/mod_s2s_auth_dane.lua Fri Feb 28 15:36:06 2014 +0100
@@ -25,6 +25,7 @@
-- TODO Things to test/handle:
-- Negative or bogus answers
-- No SRV records
+-- No encryption offered
function s2sout.try_connect(host_session, connect_host, connect_port, err)
local srv_hosts = host_session.srv_hosts;
--- a/mod_s2s_auth_fingerprint/mod_s2s_auth_fingerprint.lua Wed Feb 26 13:08:47 2014 -0800
+++ b/mod_s2s_auth_fingerprint/mod_s2s_auth_fingerprint.lua Fri Feb 28 15:36:06 2014 +0100
@@ -5,6 +5,7 @@
local digest_algo = module:get_option_string(module:get_name().."_digest", "sha1");
local must_match = module:get_option_boolean("s2s_pin_fingerprints", false);
+local tofu = module:get_option_boolean("s2s_tofu", false);
local fingerprints = {};
@@ -38,5 +39,20 @@
session.cert_chain_status = "invalid";
session.cert_identity_status = "invalid";
end
+ elseif tofu
+ and ( session.cert_chain_status ~= "valid"
+ or session.cert_identity_status ~= "valid" ) then
+ local digest = cert and cert:digest(digest_algo);
+ fingerprints[host] = {
+ [digest] = true;
+ }
end
end);
+
+function module.save()
+ return { fingerprints = fingerprints };
+end
+
+function module.restore(state)
+ fingerprints = state.fingerprints;
+end
--- a/mod_s2s_blacklist/mod_s2s_blacklist.lua Wed Feb 26 13:08:47 2014 -0800
+++ b/mod_s2s_blacklist/mod_s2s_blacklist.lua Fri Feb 28 15:36:06 2014 +0100
@@ -1,16 +1,16 @@
local st = require "util.stanza";
-local blacklist = module:get_option_inherited_set("s2s_blacklist", {});
+local whitelist = module:get_option_inherited_set("s2s_whitelist", {});
module:hook("route/remote", function (event)
- if blacklist:contains(event.to_host) then
+ if not whitelist:contains(event.to_host) then
module:send(st.error_reply(event.stanza, "cancel", "not-allowed", "Communication with this domain is restricted"));
return true;
end
end, 100);
module:hook("s2s-stream-features", function (event)
- if blacklist:contains(event.origin.from_host) then
+ if not whitelist:contains(event.origin.from_host) then
event.origin:close({
condition = "policy-violation";
text = "Communication with this domain is restricted";
--- a/mod_s2s_keysize_policy/mod_s2s_keysize_policy.lua Wed Feb 26 13:08:47 2014 -0800
+++ b/mod_s2s_keysize_policy/mod_s2s_keysize_policy.lua Fri Feb 28 15:36:06 2014 +0100
@@ -26,9 +26,9 @@
if cert and cert.pubkey then
local _, key_type, key_size = cert:pubkey();
if key_size < ( weak_key_size[key_type] or 0 ) then
- local issued = parse_x509_datetime(cert:notbefore());
- if issued > weak_key_cutoff then
- session.log("error", "%s has a %s-bit %s key issued after 31 December 2013, invalidating trust!", host, key_size, key_type);
+ local expires = parse_x509_datetime(cert:notafter());
+ if expires > weak_key_cutoff then
+ session.log("error", "%s has a %s-bit %s key valid after 31 December 2013, invalidating trust!", host, key_size, key_type);
session.cert_chain_status = "invalid";
session.cert_identity_status = "invalid";
else
--- a/mod_smacks/mod_smacks.lua Wed Feb 26 13:08:47 2014 -0800
+++ b/mod_smacks/mod_smacks.lua Fri Feb 28 15:36:06 2014 +0100
@@ -8,6 +8,7 @@
local add_filter = require "util.filters".add_filter;
local timer = require "util.timer";
local datetime = require "util.datetime";
+local tb = require"util.debug".traceback;
local xmlns_sm2 = "urn:xmpp:sm:2";
local xmlns_sm3 = "urn:xmpp:sm:3";
@@ -84,6 +85,7 @@
local function new_send(stanza)
local attr = stanza.attr;
if attr and not attr.xmlns then -- Stanza in default stream namespace
+ session.log("debug", "Sending stanza %s", stanza:top_tag());
local cached_stanza = st.clone(stanza);
if cached_stanza and cached_stanza:get_child("delay", xmlns_delay) == nil then
@@ -91,8 +93,10 @@
end
queue[#queue+1] = cached_stanza;
+ session.log("debug", "#queue = %d", #queue);
end
if session.hibernating then
+ session.log("debug", "hibernating, stanza queued")
-- The session is hibernating, no point in sending the stanza
-- over a dead connection. It will be delivered upon resumption.
return true;
@@ -204,6 +208,7 @@
for i=1,math_min(handled_stanza_count,#queue) do
t_remove(origin.outgoing_stanza_queue, 1);
end
+ origin.log("debug", "#queue = %d", #queue);
origin.last_acknowledged_stanza = origin.last_acknowledged_stanza + handled_stanza_count;
return true;
end
@@ -333,9 +338,11 @@
-- Ok, we need to re-send any stanzas that the client didn't see
-- ...they are what is now left in the outgoing stanza queue
local queue = original_session.outgoing_stanza_queue;
+ session.log("debug", "#queue = %d", #queue);
for i=1,#queue do
session.send(queue[i]);
end
+ session.log("debug", "#queue = %d -- after send", #queue);
else
module:log("warn", "Client %s@%s[%s] tried to resume stream for %s@%s[%s]",
session.username or "?", session.host or "?", session.type,
--- a/mod_srvinjection/mod_srvinjection.lua Wed Feb 26 13:08:47 2014 -0800
+++ b/mod_srvinjection/mod_srvinjection.lua Fri Feb 28 15:36:06 2014 +0100
@@ -1,3 +1,4 @@
+local s = require"util.serialization".new"oneline".serialize;
module:set_global();
@@ -25,8 +26,12 @@
local original_lookup = adns.lookup;
function adns.lookup(handler, qname, qtype, qclass)
+ module:log("debug", "adns.lookup(%s, %s, %s)", s(qname), s(qtype), s(qclass));
if qtype == "SRV" then
local host = qname:match("^_xmpp%-server%._tcp%.(.*)%.$");
+ module:log("debug", "qname:match(...) → %s", s(host));
+ local mapping = map[host] or map["*"];
+ module:log("debug", "map[%s] → %s", s(host), s(mapping));
local mapping = map[host] or map["*"];
if mapping then
handler(mapping);
--- a/mod_storage_mongodb/mod_storage_mongodb.lua Wed Feb 26 13:08:47 2014 -0800
+++ b/mod_storage_mongodb/mod_storage_mongodb.lua Fri Feb 28 15:36:06 2014 +0100
@@ -1,5 +1,8 @@
local next = next;
local setmetatable = setmetatable;
+local set = require"util.set";
+local it = require"util.iterators";
+local array = require"util.array";
local params = assert ( module:get_option("mongodb") , "mongodb configuration not found" );
@@ -46,6 +49,75 @@
end;
end
+local roster_store = {};
+roster_store.__index = roster_store;
+
+function roster_store:get(username)
+ local host = module.host or "_global";
+ local store = self.store;
+
+ -- The database name can't have a period in it (hence it can't be a host/ip)
+ local namespace = params.dbname .. "." .. host;
+ local v = { _id = { store = store ; username = username } };
+
+ local cursor , err = conn:query ( namespace , v );
+ if not cursor then return nil , err end;
+
+ local r , err = cursor:next ( );
+ if not r then return nil , err end;
+ local roster = {
+ [false] = {
+ version = r.version;
+ };
+ pending = set.new( r.pending )._items;
+ };
+ local items = r.items;
+ for i = 1, #items do
+ local item = items[i];
+ roster[item.jid] = {
+ subscription = item.subscription;
+ groups = set.new( item.groups )._items;
+ ask = item.ask;
+ name = item.name;
+ }
+ end
+ return roster;
+end
+
+function roster_store:set(username, data)
+ local host = module.host or "_global";
+ local store = self.store;
+
+ -- The database name can't have a period in it (hence it can't be a host/ip)
+ local namespace = params.dbname .. "." .. host;
+ local v = { _id = { store = store ; username = username } };
+
+ if data == nil or next(data) == nil then -- delete data
+ return conn:remove ( namespace , v );
+ end
+
+ v.version = data[false].version
+ if data.pending then
+ v.pending = array(it.keys(v.pending))
+ end
+
+ local items = {}
+ for jid, item in pairs(data) do
+ if jid and jid ~= "pending" then
+ table.insert(items, {
+ jid = jid;
+ subscription = item.subscription;
+ groups = array(it.keys( item.groups ));
+ name = item.name;
+ ask = item.ask;
+ });
+ end
+ end
+ v.items = items;
+
+ return conn:insert ( namespace , v );
+end
+
local driver = {};
function driver:open(store, typ)
@@ -58,6 +130,9 @@
end
if not typ then -- default key-value store
+ if store == "roster" then
+ return setmetatable({ store = store }, roster_store);
+ end
return setmetatable({ store = store }, keyval_store);
end;
return nil, "unsupported-store";
--- a/mod_turncredentials/mod_turncredentials.lua Wed Feb 26 13:08:47 2014 -0800
+++ b/mod_turncredentials/mod_turncredentials.lua Fri Feb 28 15:36:06 2014 +0100
@@ -15,6 +15,8 @@
return;
end
+module:add_feature("urn:xmpp:extdisco:1");
+
module:hook("iq-get/host/urn:xmpp:extdisco:1:services", function(event)
local origin, stanza = event.origin, event.stanza;
if origin.type ~= "c2s" then
--- a/mod_websocket/mod_websocket.lua Wed Feb 26 13:08:47 2014 -0800
+++ b/mod_websocket/mod_websocket.lua Fri Feb 28 15:36:06 2014 +0100
@@ -242,6 +242,7 @@
c2s_listener.onconnect(conn);
local session = sessions[conn];
+ session._http_request_headers = request.headers;
session.secure = consider_websocket_secure or session.secure;
@@ -285,4 +286,11 @@
["GET /"] = handle_request;
};
});
+
+ module:add_item("alt-conn-method", {
+ rel = "urn:xmpp:altconnect:websocket";
+ href = module:http_url(nil, "xmpp-websocket"):gsub("^http", "ws");
+ });
end
+
+