# HG changeset patch # User Kim Alvefur # Date 1409690072 -7200 # Node ID ec8878113907c6fb36cdac2b4d7e99900db9a27a # Parent 305226a9e5814fd779170e75670d2fd5261e3d55# Parent 57d23c26039b87a31d7ade5d14e803560c71fa7c Merge 0.10->trunk diff -r 305226a9e581 -r ec8878113907 net/http.lua --- a/net/http.lua Sun Aug 31 20:33:47 2014 +0200 +++ b/net/http.lua Tue Sep 02 22:34:32 2014 +0200 @@ -71,6 +71,10 @@ 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 -r 305226a9e581 -r ec8878113907 net/http/server.lua --- a/net/http/server.lua Sun Aug 31 20:33:47 2014 +0200 +++ b/net/http/server.lua Tue Sep 02 22:34:32 2014 +0200 @@ -142,6 +142,10 @@ sessions[conn] = nil; end +function listener.ondetach(conn) + sessions[conn] = nil; +end + function listener.onincoming(conn, data) sessions[conn]:feed(data); end diff -r 305226a9e581 -r ec8878113907 net/server_event.lua --- a/net/server_event.lua Sun Aug 31 20:33:47 2014 +0200 +++ b/net/server_event.lua Tue Sep 02 22:34:32 2014 +0200 @@ -439,9 +439,11 @@ end function interface_mt:setlistener(listener) - self.onconnect, self.ondisconnect, self.onincoming, self.ontimeout, self.onreadtimeout, self.onstatus - = listener.onconnect, listener.ondisconnect, listener.onincoming, - listener.ontimeout, listener.onreadtimeout, listener.onstatus; + self:ondetach(); -- Notify listener that it is no longer responsible for this connection + self.onconnect, self.ondisconnect, self.onincoming, self.ontimeout, + self.onreadtimeout, self.onstatus, self.ondetach + = listener.onconnect, listener.ondisconnect, listener.onincoming, listener.ontimeout, + listener.onreadtimeout, listener.onstatus, listener.ondetach; end -- Stub handlers @@ -461,6 +463,8 @@ end function interface_mt:ondrain() end + function interface_mt:ondetach() + end function interface_mt:onstatus() end end @@ -488,6 +492,7 @@ ontimeout = listener.ontimeout; -- called when fatal socket timeout occurs onreadtimeout = listener.onreadtimeout; -- called when socket inactivity 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 -r 305226a9e581 -r ec8878113907 net/server_select.lua --- a/net/server_select.lua Sun Aug 31 20:33:47 2014 +0200 +++ b/net/server_select.lua Tue Sep 02 22:34:32 2014 +0200 @@ -286,6 +286,7 @@ local disconnect = listeners.ondisconnect local drain = listeners.ondrain local onreadtimeout = listeners.onreadtimeout; + local detach = listeners.ondetach local bufferqueue = { } -- buffer array local bufferqueuelen = 0 -- end of buffer array @@ -317,11 +318,15 @@ handler.onreadtimeout = onreadtimeout; 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 handler.onreadtimeout = listeners.onreadtimeout + detach = listeners.ondetach end handler.getstats = function( ) return readtraffic, sendtraffic diff -r 305226a9e581 -r ec8878113907 plugins/mod_admin_telnet.lua --- a/plugins/mod_admin_telnet.lua Sun Aug 31 20:33:47 2014 +0200 +++ b/plugins/mod_admin_telnet.lua Tue Sep 02 22:34:32 2014 +0200 @@ -170,6 +170,10 @@ end end +function console_listener.ondetach(conn) + sessions[conn] = nil; +end + -- Console commands -- -- These are simple commands, not valid standalone in Lua diff -r 305226a9e581 -r ec8878113907 plugins/mod_c2s.lua --- a/plugins/mod_c2s.lua Sun Aug 31 20:33:47 2014 +0200 +++ b/plugins/mod_c2s.lua Tue Sep 02 22:34:32 2014 +0200 @@ -240,9 +240,9 @@ function session.data(data) -- Parse the data, which will store stanzas in session.pending_stanzas if data then - data = filter("bytes/in", data); - if data then - local ok, err = stream:feed(data); + data = filter("bytes/in", data); + if data then + local ok, err = stream:feed(data); if not ok then log("debug", "Received invalid XML (%s) %d bytes: %s", tostring(err), #data, data:sub(1, 300):gsub("[\r\n]+", " "):gsub("[%z\1-\31]", "_")); session:close("not-well-formed"); diff -r 305226a9e581 -r ec8878113907 plugins/mod_component.lua --- a/plugins/mod_component.lua Sun Aug 31 20:33:47 2014 +0200 +++ b/plugins/mod_component.lua Tue Sep 02 22:34:32 2014 +0200 @@ -317,6 +317,10 @@ end end +function listener.ondetach(conn) + sessions[conn] = nil; +end + module:provides("net", { name = "component"; private = true; diff -r 305226a9e581 -r ec8878113907 plugins/mod_dialback.lua --- a/plugins/mod_dialback.lua Sun Aug 31 20:33:47 2014 +0200 +++ b/plugins/mod_dialback.lua Tue Sep 02 22:34:32 2014 +0200 @@ -82,6 +82,15 @@ local attr = stanza.attr; local to, from = nameprep(attr.to), nameprep(attr.from); + if not hosts[to] then + -- Not a host that we serve + origin.log("warn", "%s tried to connect to %s, which we don't serve", from, to); + origin:close("host-unknown"); + return true; + elseif not from then + origin:close("improper-addressing"); + end + if dwd and origin.secure then if check_cert_status(origin, from) == false then return @@ -92,15 +101,6 @@ end end - if not hosts[to] then - -- Not a host that we serve - origin.log("warn", "%s tried to connect to %s, which we don't serve", from, to); - origin:close("host-unknown"); - return true; - elseif not from then - origin:close("improper-addressing"); - end - origin.hosts[from] = { dialback_key = stanza[1] }; dialback_requests[from.."/"..origin.streamid] = origin; diff -r 305226a9e581 -r ec8878113907 plugins/mod_net_multiplex.lua --- a/plugins/mod_net_multiplex.lua Sun Aug 31 20:33:47 2014 +0200 +++ b/plugins/mod_net_multiplex.lua Tue Sep 02 22:34:32 2014 +0200 @@ -34,7 +34,6 @@ 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 @@ buffers[conn] = nil; -- warn if no buffer? end +listener.ondetach = listener.ondisconnect; + module:provides("net", { name = "multiplex"; config_prefix = ""; diff -r 305226a9e581 -r ec8878113907 plugins/mod_s2s/mod_s2s.lua --- a/plugins/mod_s2s/mod_s2s.lua Sun Aug 31 20:33:47 2014 +0200 +++ b/plugins/mod_s2s/mod_s2s.lua Tue Sep 02 22:34:32 2014 +0200 @@ -350,8 +350,11 @@ 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 @@ -617,6 +620,10 @@ 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; diff -r 305226a9e581 -r ec8878113907 plugins/mod_s2s_auth_certs.lua --- a/plugins/mod_s2s_auth_certs.lua Sun Aug 31 20:33:47 2014 +0200 +++ b/plugins/mod_s2s_auth_certs.lua Tue Sep 02 22:34:32 2014 +0200 @@ -7,39 +7,42 @@ module:hook("s2s-check-certificate", function(event) local session, host, cert = event.session, event.host, event.cert; local conn = session.conn:socket(); + local log = session.log or log; - if cert then - local log = session.log or log; - local chain_valid, errors; - if conn.getpeerverification then - chain_valid, errors = conn:getpeerverification(); - elseif conn.getpeerchainvalid then -- COMPAT mw/luasec-hg - chain_valid, errors = conn:getpeerchainvalid(); - errors = (not chain_valid) and { { errors } } or nil; - else - chain_valid, errors = false, { { "Chain verification not supported by this version of LuaSec" } }; + if not cert then + log("warn", "No certificate provided by %s", host or "unknown host"); + return; + end + + local chain_valid, errors; + if conn.getpeerverification then + chain_valid, errors = conn:getpeerverification(); + elseif conn.getpeerchainvalid then -- COMPAT mw/luasec-hg + chain_valid, errors = conn:getpeerchainvalid(); + errors = (not chain_valid) and { { errors } } or nil; + else + chain_valid, errors = false, { { "Chain verification not supported by this version of LuaSec" } }; + end + -- Is there any interest in printing out all/the number of errors here? + if not chain_valid then + log("debug", "certificate chain validation result: invalid"); + for depth, t in pairs(errors or NULL) do + log("debug", "certificate error(s) at depth %d: %s", depth-1, table.concat(t, ", ")) end - -- Is there any interest in printing out all/the number of errors here? - if not chain_valid then - log("debug", "certificate chain validation result: invalid"); - for depth, t in pairs(errors or NULL) do - log("debug", "certificate error(s) at depth %d: %s", depth-1, table.concat(t, ", ")) - end - session.cert_chain_status = "invalid"; - else - log("debug", "certificate chain validation result: valid"); - session.cert_chain_status = "valid"; + session.cert_chain_status = "invalid"; + else + log("debug", "certificate chain validation result: valid"); + session.cert_chain_status = "valid"; - -- We'll go ahead and verify the asserted identity if the - -- connecting server specified one. - if host then - if cert_verify_identity(host, "xmpp-server", cert) then - session.cert_identity_status = "valid" - else - session.cert_identity_status = "invalid" - end - log("debug", "certificate identity validation result: %s", session.cert_identity_status); + -- We'll go ahead and verify the asserted identity if the + -- connecting server specified one. + if host then + if cert_verify_identity(host, "xmpp-server", cert) then + session.cert_identity_status = "valid" + else + session.cert_identity_status = "invalid" end + log("debug", "certificate identity validation result: %s", session.cert_identity_status); end end end, 509); diff -r 305226a9e581 -r ec8878113907 util/hex.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/util/hex.lua Tue Sep 02 22:34:32 2014 +0200 @@ -0,0 +1,19 @@ +local s_char = string.char; + +local function char_to_hex(c) + return ("%02x"):format(c:byte()) +end + +local function hex_to_char(h) + return s_char(tonumber(h, 16)); +end + +function to(s) + return s:gsub(".", char_to_hex); +end + +function from(s) + return s:gsub("..", hex_to_char); +end + +return { to = to, from = from } diff -r 305226a9e581 -r ec8878113907 util/random.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/util/random.lua Tue Sep 02 22:34:32 2014 +0200 @@ -0,0 +1,43 @@ +-- Prosody IM +-- Copyright (C) 2008-2014 Matthew Wild +-- Copyright (C) 2008-2014 Waqas Hussain +-- +-- This project is MIT/X11 licensed. Please see the +-- COPYING file in the source package for more information. +-- + +local tostring = tostring; +local os_time = os.time; +local os_clock = os.clock; +local ceil = math.ceil; +local sha1 = require "util.hashes".sha1; + +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({})); +end + +local buffer = new_random(uniq_time()); + +local function seed(x) + buffer = new_random(buffer..x); +end + +local function bytes(n) + if #buffer < n then seed(uniq_time()); end + local r = buffer:sub(0, n); + buffer = buffer:sub(n+1); + return r; +end + +return { + seed = seed; + bytes = bytes; +}; diff -r 305226a9e581 -r ec8878113907 util/uuid.lua --- a/util/uuid.lua Sun Aug 31 20:33:47 2014 +0200 +++ b/util/uuid.lua Tue Sep 02 22:34:32 2014 +0200 @@ -6,45 +6,27 @@ -- COPYING file in the source package for more information. -- - -local m_random = math.random; -local tostring = tostring; -local os_time = os.time; -local os_clock = os.clock; -local sha1 = require "util.hashes".sha1; +local random = require "util.random"; +local random_bytes = random.bytes; +local hex = require "util.hex".to; +local m_ceil = math.ceil; -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; +local function get_nibbles(n) + return hex(random_bytes(m_ceil(n/2))):sub(1, n); 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; -end local function get_twobits() return ("%x"):format(get_nibbles(1):byte() % 4 + 8); end -function generate() +local function generate() -- 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; -return _M; +return { + get_nibbles=get_nibbles; + generate = generate ; + -- COMPAT + seed = random.seed; +};