Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package prosody for openSUSE:Factory checked in at 2022-06-10 15:57:33 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/prosody (Old) and /work/SRC/openSUSE:Factory/.prosody.new.1548 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "prosody" Fri Jun 10 15:57:33 2022 rev:31 rq:981547 version:0.12.1 Changes: -------- --- /work/SRC/openSUSE:Factory/prosody/prosody.changes 2022-03-18 16:42:32.053198420 +0100 +++ /work/SRC/openSUSE:Factory/.prosody.new.1548/prosody.changes 2022-06-10 15:57:53.732846857 +0200 @@ -1,0 +2,44 @@ +Thu Jun 9 16:19:46 UTC 2022 - Michael Vetter <mvet...@suse.com> + +- Update to 0.12.1: + Fixes and improvements: + * mod_http (and dependent modules): Make CORS opt-in by default (#1731) + * mod_http: Reintroduce support for disabling or limiting CORS (#1730) + * net.unbound: Disable use of hosts file by default (fixes #1737) + * MUC: Allow kicking users with the same affiliation as the kicker (fixes #1724 and improves Jitsi Meet compatibility) + * mod_tombstones: Add caching to improve performance on busy servers (fixes #1728: mod_tombstone: inefficient I/O with internal storage) + Minor changes: + * prosodyctl check config: Report paths of loaded configuration files (#1729) + * prosodyctl about: Report version of lua-readline + * prosodyctl: check config: Skip bare JID components in orphan check + * prosodyctl: check turn: Fail with error if our own address is supplied for the ping test + * prosodyctl: check turn: warn about external port mismatches behind NAT + * mod_turn_external: Update status and friendlier handling of missing secret option (#1727) + * prosodyctl: Pass server when listing (outdated) plugins (fix #1738: prosodyctl list --outdated does not handle multiple versions of a module) + * util.prosodyctl: check turn: ensure a result is always returned from a check (thanks eTaurus) + * util.prosodyctl: check turn: Report lack of TURN services as a problem #1749 + * util.random: Ensure that native random number generator works before using it, falling back to /dev/urandom (#1734) + * mod_storage_xep0227: Fix mapping of nodes without explicit configuration + * mod_admin_shell: Fix error in ???module:info()??? when statistics is not enabled (#1754) + * mod_admin_socket: Compat for luasocket prior to unix datagram support + * mod_admin_socket: Improve error reporting when socket can???t be created (#1719) + * mod_cron: Record last time a task runs to ensure correct intervals (#1751) + * core.moduleapi, core.modulemanager: Fix internal flag affecting logging in in some global modules, like mod_http (#1736, #1748) + * core.certmanager: Expand debug messages about cert lookups in index + * configmanager: Clearer errors when providing unexpected values after VirtualHost (#1735) + * mod_storage_xep0227: Support basic listing of PEP nodes in absence of pubsub#admin data + * mod_storage_xep0227: Handle missing {pubsub#owner}pubsub element (fixes #1740: mod_storage_xep0227 tracebacks reading non-existent PEP store) + * mod_storage_xep0227: Fix conversion of SCRAM into internal format (#1741) + * mod_external_services: Move error message to correct place (fix #1725: mod_external_services: Misplaced textual error message) + * mod_smacks: Fix handling of unhandled stanzas on disconnect (#1759) + * mod_smacks: Fix counting of handled stanzas + * mod_smacks: Fix bounce of stanzas directed to full JID on unclean disconnect + * mod_pubsub: Don???t attempt to use server actor as publisher (#1723) + * mod_s2s: Improve robustness of outgoing s2s certificate verification + * mod_invites_adhoc: Fall back to generic allow_user_invites for role-less users + * mod_invites_register: Push invitee contact entry to inviter + * util.startup: Show error for unrecognized command-line arguments passed to ???prosody??? (#1722) + * util.jsonpointer: Add tests, compat improvements and minor fixes + * util.jsonschema: Lua version compat improvements + +------------------------------------------------------------------- Old: ---- prosody-0.12.0.tar.gz prosody-0.12.0.tar.gz.asc New: ---- prosody-0.12.1.tar.gz prosody-0.12.1.tar.gz.asc ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ prosody.spec ++++++ --- /var/tmp/diff_new_pack.RxG2RO/_old 2022-06-10 15:57:54.340847594 +0200 +++ /var/tmp/diff_new_pack.RxG2RO/_new 2022-06-10 15:57:54.344847599 +0200 @@ -18,7 +18,7 @@ %define _piddir /run Name: prosody -Version: 0.12.0 +Version: 0.12.1 Release: 0 Summary: Communications server for Jabber/XMPP License: MIT ++++++ prosody-0.12.0.tar.gz -> prosody-0.12.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/.hg_archival.txt new/prosody-0.12.1/.hg_archival.txt --- old/prosody-0.12.0/.hg_archival.txt 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/.hg_archival.txt 2022-06-09 13:44:01.673100438 +0200 @@ -1,4 +1,4 @@ repo: 3e3171b59028ee70122cfec6ecf98f518f946b59 -node: 50fcd387948263335ca98dc98de2a3087b543f8b -branch: default -tag: 0.12.0 +node: 252ed01896dd815700593b86834c776d0fef828d +branch: 0.12 +tag: 0.12.1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/CHANGES new/prosody-0.12.1/CHANGES --- old/prosody-0.12.0/CHANGES 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/CHANGES 2022-06-09 13:44:01.673100438 +0200 @@ -1,5 +1,7 @@ -TRUNK -===== +0.12.0 +====== + +**2022-03-14** ## New diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/core/certmanager.lua new/prosody-0.12.1/core/certmanager.lua --- old/prosody-0.12.0/core/certmanager.lua 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/core/certmanager.lua 2022-06-09 13:44:01.673100438 +0200 @@ -159,7 +159,7 @@ if certs then local cert_filename, services = next(certs); if services["*"] then - log("debug", "Using cert %q from index", cert_filename); + log("debug", "Using cert %q from index for host %q", cert_filename, host); return { certificate = cert_filename, key = find_matching_key(cert_filename), @@ -185,7 +185,7 @@ for _, certs in pairs(cert_index) do for cert_filename, services in pairs(certs) do if services[service] or services["*"] then - log("debug", "Using cert %q from index", cert_filename); + log("debug", "Using cert %q from index for service %s port %d", cert_filename, service, port); return { certificate = cert_filename, key = find_matching_key(cert_filename), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/core/configmanager.lua new/prosody-0.12.1/core/configmanager.lua --- old/prosody-0.12.0/core/configmanager.lua 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/core/configmanager.lua 2022-06-09 13:44:01.673100438 +0200 @@ -31,6 +31,7 @@ local config_mt = { __index = function (t, _) return rawget(t, "*"); end}; local config = setmetatable({ ["*"] = { } }, config_mt); +local files = {}; -- When host not found, use global local host_mt = { __index = function(_, k) return config["*"][k] end } @@ -98,6 +99,10 @@ end end +function _M.files() + return files; +end + -- Built-in Lua parser do local pcall = _G.pcall; @@ -155,6 +160,11 @@ set(config_table, name or "*", "defined", true); return function (config_options) rawset(env, "__currenthost", "*"); -- Return to global scope + if type(config_options) == "string" then + error(format("VirtualHost entries do not accept a module name (module '%s' provided for host '%s')", config_options, name), 2); + elseif type(config_options) ~= "table" then + error("Invalid syntax following VirtualHost, expected options but received a "..type(config_options), 2); + end for option_name, option_value in pairs(config_options) do set(config_table, name or "*", option_name, option_value); end @@ -253,6 +263,8 @@ return nil, err; end + t_insert(files, config_file); + return true, warnings; end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/core/moduleapi.lua new/prosody-0.12.1/core/moduleapi.lua --- old/prosody-0.12.0/core/moduleapi.lua 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/core/moduleapi.lua 2022-06-09 13:44:01.673100438 +0200 @@ -307,7 +307,7 @@ function api:context(host) - return setmetatable({host=host or "*"}, {__index=self,__newindex=self}); + return setmetatable({ host = host or "*", global = "*" == host }, { __index = self, __newindex = self }); end function api:add_item(key, value) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/core/modulemanager.lua new/prosody-0.12.1/core/modulemanager.lua --- old/prosody-0.12.0/core/modulemanager.lua 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/core/modulemanager.lua 2022-06-09 13:44:01.673100438 +0200 @@ -189,6 +189,7 @@ if module_has_method(mod, "add_host") then local _log = logger.init(host..":"..module_name); local host_module_api = setmetatable({ + global = false, host = host, event_handlers = new_multitable(), items = {}; _log = _log, log = function (self, ...) return _log(...); end; --luacheck: ignore 212/self },{ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/net/unbound.lua new/prosody-0.12.1/net/unbound.lua --- old/prosody-0.12.0/net/unbound.lua 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/net/unbound.lua 2022-06-09 13:44:01.673100438 +0200 @@ -25,13 +25,22 @@ local classes, types, errors = dns_utils.classes, dns_utils.types, dns_utils.errors; local parsers = dns_utils.parsers; +local builtin_defaults = { hoststxt = false } + local function add_defaults(conf) if conf then + for option, default in pairs(builtin_defaults) do + if conf[option] == nil then + conf[option] = default; + end + end for option, default in pairs(libunbound.config) do if conf[option] == nil then conf[option] = default; end end + else + return builtin_defaults; end return conf; end @@ -133,7 +142,7 @@ if ret then waiting_queries[ret] = callback; else - log_query("warn", "Resolver error: %s", err); + log_query("error", "Resolver error: %s", err); end return ret, err; end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/plugins/mod_admin_shell.lua new/prosody-0.12.1/plugins/mod_admin_shell.lua --- old/prosody-0.12.0/plugins/mod_admin_shell.lua 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/plugins/mod_admin_shell.lua 2022-06-09 13:44:01.673100438 +0200 @@ -49,12 +49,12 @@ end local function pre(prefix, str, alt) - if (str or "") == "" then return alt or ""; end + if type(str) ~= "string" or str == "" then return alt or ""; end return prefix .. str; end local function suf(str, suffix, alt) - if (str or "") == "" then return alt or ""; end + if type(str) ~= "string" or str == "" then return alt or ""; end return str .. suffix; end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/plugins/mod_admin_socket.lua new/prosody-0.12.1/plugins/mod_admin_socket.lua --- old/prosody-0.12.0/plugins/mod_admin_socket.lua 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/plugins/mod_admin_socket.lua 2022-06-09 13:44:01.673100438 +0200 @@ -2,6 +2,15 @@ local have_unix, unix = pcall(require, "socket.unix"); +if have_unix and type(unix) == "function" then + -- COMPAT #1717 + -- Before the introduction of datagram support, only the stream socket + -- constructor was exported instead of a module table. Due to the lack of a + -- proper release of LuaSocket, distros have settled on shipping either the + -- last RC tag or some commit since then. + -- Here we accomodate both variants. + unix = { stream = unix }; +end if not have_unix or type(unix) ~= "table" then module:log_status("error", "LuaSocket unix socket support not available or incompatible, ensure it is up to date"); return; @@ -53,8 +62,16 @@ sock = unix.stream(); sock:settimeout(0); os.remove(socket_path); - assert(sock:bind(socket_path)); - assert(sock:listen()); + local ok, err = sock:bind(socket_path); + if not ok then + module:log_status("error", "Unable to bind admin socket %s: %s", socket_path, err); + return; + end + local ok, err = sock:listen(); + if not ok then + module:log_status("error", "Unable to listen on admin socket %s: %s", socket_path, err); + return; + end if server.wrapserver then conn = server.wrapserver(sock, socket_path, 0, listeners); else diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/plugins/mod_bosh.lua new/prosody-0.12.1/plugins/mod_bosh.lua --- old/prosody-0.12.0/plugins/mod_bosh.lua 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/plugins/mod_bosh.lua 2022-06-09 13:44:01.673100438 +0200 @@ -547,6 +547,9 @@ module:depends("http"); module:provides("http", { default_path = "/http-bind"; + cors = { + enabled = true; + }; route = { ["GET"] = GET_response; ["GET /"] = GET_response; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/plugins/mod_cron.lua new/prosody-0.12.1/plugins/mod_cron.lua --- old/prosody-0.12.0/plugins/mod_cron.lua 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/plugins/mod_cron.lua 2022-06-09 13:44:01.673100438 +0200 @@ -45,6 +45,7 @@ local function run_task(task) local started_at = os.time(); task:run(started_at); + task.last = started_at; task:save(started_at); end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/plugins/mod_external_services.lua new/prosody-0.12.1/plugins/mod_external_services.lua --- old/prosody-0.12.0/plugins/mod_external_services.lua 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/plugins/mod_external_services.lua 2022-06-09 13:44:01.673100438 +0200 @@ -192,7 +192,7 @@ local action = stanza.tags[1]; if origin.type ~= "c2s" then - origin.send(st.error_reply(stanza, "auth", "forbidden", "The 'port' and 'type' attributes are required.")); + origin.send(st.error_reply(stanza, "auth", "forbidden")); return true; end @@ -204,7 +204,7 @@ local requested_credentials = set.new(); for service in action:childtags("service") do if not service.attr.type or not service.attr.host then - origin.send(st.error_reply(stanza, "modify", "bad-request")); + origin.send(st.error_reply(stanza, "modify", "bad-request", "The 'port' and 'type' attributes are required.")); return true; end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/plugins/mod_http.lua new/prosody-0.12.1/plugins/mod_http.lua --- old/prosody-0.12.0/plugins/mod_http.lua 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/plugins/mod_http.lua 2022-06-09 13:44:01.673100438 +0200 @@ -31,8 +31,10 @@ server.set_option("buffer_size_limit", module:get_option_number("http_max_buffer_size")); -- CORS settings +local cors_overrides = module:get_option("http_cors_override", {}); local opt_methods = module:get_option_set("access_control_allow_methods", { "GET", "OPTIONS" }); local opt_headers = module:get_option_set("access_control_allow_headers", { "Content-Type" }); +local opt_origins = module:get_option_set("access_control_allow_origins"); local opt_credentials = module:get_option_boolean("access_control_allow_credentials", false); local opt_max_age = module:get_option_number("access_control_max_age", 2 * 60 * 60); @@ -109,7 +111,10 @@ return "http://disabled.invalid/"; end -local function apply_cors_headers(response, methods, headers, max_age, allow_credentials, origin) +local function apply_cors_headers(response, methods, headers, max_age, allow_credentials, allowed_origins, origin) + if allowed_origins and not allowed_origins[origin] then + return; + end response.headers.access_control_allow_methods = tostring(methods); response.headers.access_control_allow_headers = tostring(headers); response.headers.access_control_max_age = tostring(max_age) @@ -141,10 +146,14 @@ local app_methods = opt_methods; local app_headers = opt_headers; local app_credentials = opt_credentials; + local app_origins; + if opt_origins and not (opt_origins:empty() or opt_origins:contains("*")) then + opt_origins = opt_origins._items; + end local function cors_handler(event_data) local request, response = event_data.request, event_data.response; - apply_cors_headers(response, app_methods, app_headers, opt_max_age, app_credentials, request.headers.origin); + apply_cors_headers(response, app_methods, app_headers, opt_max_age, app_credentials, app_origins, request.headers.origin); end local function options_handler(event_data) @@ -152,17 +161,26 @@ return ""; end - if event.item.cors then - local cors = event.item.cors; - if cors.credentials ~= nil then - app_credentials = cors.credentials; - end - if cors.headers then - for header, enable in pairs(cors.headers) do - if enable and not app_headers:contains(header) then - app_headers = app_headers + set.new { header }; - elseif not enable and app_headers:contains(header) then - app_headers = app_headers - set.new { header }; + local cors = cors_overrides[app_name] or event.item.cors; + if cors then + if cors.enabled == true then + if cors.credentials ~= nil then + app_credentials = cors.credentials; + end + if cors.headers then + for header, enable in pairs(cors.headers) do + if enable and not app_headers:contains(header) then + app_headers = app_headers + set.new { header }; + elseif not enable and app_headers:contains(header) then + app_headers = app_headers - set.new { header }; + end + end + end + if cors.origins then + if cors.origins == "*" or cors.origins[1] == "*" then + app_origins = nil; + else + app_origins = set.new(cors.origins)._items; end end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/plugins/mod_http_file_share.lua new/prosody-0.12.1/plugins/mod_http_file_share.lua --- old/prosody-0.12.0/plugins/mod_http_file_share.lua 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/plugins/mod_http_file_share.lua 2022-06-09 13:44:01.673100438 +0200 @@ -578,6 +578,7 @@ module:provides("http", { streaming_uploads = true; cors = { + enabled = true; credentials = true; headers = { Authorization = true; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/plugins/mod_invites_adhoc.lua new/prosody-0.12.1/plugins/mod_invites_adhoc.lua --- old/prosody-0.12.0/plugins/mod_invites_adhoc.lua 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/plugins/mod_invites_adhoc.lua 2022-06-09 13:44:01.673100438 +0200 @@ -45,7 +45,11 @@ local function may_invite_new_users(jid) if usermanager.get_roles then local user_roles = usermanager.get_roles(jid, module.host); - if not user_roles then return; end + if not user_roles then + -- User has no roles we can check, just return default + return allow_user_invites; + end + if user_roles["prosody:admin"] then return true; end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/plugins/mod_invites_register.lua new/prosody-0.12.1/plugins/mod_invites_register.lua --- old/prosody-0.12.0/plugins/mod_invites_register.lua 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/plugins/mod_invites_register.lua 2022-06-09 13:44:01.673100438 +0200 @@ -141,6 +141,7 @@ if inviter_username then module:log("debug", "Creating mutual subscription between %s and %s", inviter_username, contact_username); subscribe_both(module.host, inviter_username, contact_username); + rostermanager.roster_push(inviter_username, module.host, contact_username.."@"..module.host); end if validated_invite.additional_data then diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/plugins/mod_pubsub/mod_pubsub.lua new/prosody-0.12.1/plugins/mod_pubsub/mod_pubsub.lua --- old/prosody-0.12.0/plugins/mod_pubsub/mod_pubsub.lua 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/plugins/mod_pubsub/mod_pubsub.lua 2022-06-09 13:44:01.673100438 +0200 @@ -84,7 +84,7 @@ end if not expose_publisher then item.attr.publisher = nil; - elseif not item.attr.publisher then + elseif not item.attr.publisher and actor ~= true then item.attr.publisher = service.config.normalize_jid(actor); end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/plugins/mod_s2s.lua new/prosody-0.12.1/plugins/mod_s2s.lua --- old/prosody-0.12.0/plugins/mod_s2s.lua 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/plugins/mod_s2s.lua 2022-06-09 13:44:01.673100438 +0200 @@ -349,6 +349,15 @@ }, nil, "Could not establish encrypted connection to remote server"); end end + + if session.type == "s2sout_unauthed" and not session.authenticated_remote and secure_auth and not insecure_domains[host] then + session:close({ + condition = "policy-violation"; + text = "Failed to verify certificate (internal error)"; + }); + return; + end + if hosts[host] then session:close({ condition = "undefined-condition", text = "Attempt to authenticate as a host we serve" }); end @@ -531,6 +540,8 @@ if session.secure and not session.cert_chain_status then if check_cert_status(session) == false then return; + else + session.authenticated_remote = true; end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/plugins/mod_smacks.lua new/prosody-0.12.1/plugins/mod_smacks.lua --- old/prosody-0.12.0/plugins/mod_smacks.lua 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/plugins/mod_smacks.lua 2022-06-09 13:44:01.673100438 +0200 @@ -55,7 +55,6 @@ local it = require"util.iterators"; local sessionmanager = require "core.sessionmanager"; -local core_process_stanza = prosody.core_process_stanza; local xmlns_errors = "urn:ietf:params:xml:ns:xmpp-stanzas"; local xmlns_delay = "urn:xmpp:delay"; @@ -143,7 +142,7 @@ if session.awaiting_ack then return end -- already waiting if force then return force end local queue = session.outgoing_stanza_queue; - local expected_h = session.last_acknowledged_stanza + queue:count_unacked(); + local expected_h = queue:count_acked() + queue:count_unacked(); local max_unacked = max_unacked_stanzas; if session.state == "inactive" then max_unacked = max_inactive_unacked_stanzas; @@ -161,7 +160,7 @@ if session.destroyed then return end -- sending something can trigger destruction session.awaiting_ack = true; -- expected_h could be lower than this expression e.g. more stanzas added to the queue meanwhile) - session.last_requested_h = session.last_acknowledged_stanza + queue:count_unacked(); + session.last_requested_h = queue:count_acked() + queue:count_unacked(); session.log("debug", "Sending <r> (inside timer, after send) from %s - #queue=%d", reason, queue:count_unacked()); if not session.delayed_ack_timer then session.delayed_ack_timer = timer.add_task(delayed_ack_timeout, function() @@ -223,7 +222,6 @@ local function wrap_session_out(session, resume) if not resume then session.outgoing_stanza_queue = smqueue.new(queue_size); - session.last_acknowledged_stanza = 0; end add_filter(session, "stanzas/out", outgoing_stanza_filter, -999); @@ -419,9 +417,9 @@ session.outgoing_stanza_queue = nil; for stanza in queue._queue:consume() do if not module:fire_event("delivery/failure", { session = session, stanza = stanza }) then - if stanza.attr.type ~= "error" and stanza.attr.to ~= session.full_jid then + if stanza.attr.type ~= "error" and stanza.attr.from ~= session.full_jid then local reply = st.error_reply(stanza, "cancel", "recipient-unavailable"); - core_process_stanza(session, reply); + module:send(reply); end end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/plugins/mod_storage_xep0227.lua new/prosody-0.12.1/plugins/mod_storage_xep0227.lua --- old/prosody-0.12.0/plugins/mod_storage_xep0227.lua 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/plugins/mod_storage_xep0227.lua 2022-06-09 13:44:01.673100438 +0200 @@ -59,7 +59,7 @@ end end end - module:log("warn", "Unable to find user element"); + module:log("warn", "Unable to find user element in %s", xml and xml:top_tag() or "nothing"); end local function createOuterXml(user, host) return st.stanza("server-data", {xmlns='urn:xmpp:pie:0'}) @@ -72,7 +72,7 @@ end local function base64_to_hex(s) - return base64.encode(hex.decode(s)); + return hex.encode(base64.decode(s)); end local handlers = {}; @@ -279,6 +279,7 @@ }; -- PEP node configuration/etc. (not items) +local xmlns_pubsub = "http://jabber.org/protocol/pubsub"; local xmlns_pubsub_owner = "http://jabber.org/protocol/pubsub#owner"; local lib_pubsub = module:require "pubsub"; handlers.pep = { @@ -299,6 +300,16 @@ ]] }; local owner_el = user_el:get_child("pubsub", xmlns_pubsub_owner); + if not owner_el then + local pubsub_el = user_el:get_child("pubsub", xmlns_pubsub); + if not pubsub_el then + return nil; + end + for node_el in pubsub_el:childtags("items") do + nodes[node_el.attr.node] = true; -- relies on COMPAT behavior in mod_pep + end + return nodes; + end for node_el in owner_el:childtags() do local node_name = node_el.attr.node; local node = nodes[node_name]; @@ -393,7 +404,6 @@ }; -- PEP items -local xmlns_pubsub = "http://jabber.org/protocol/pubsub"; handlers.pep_ = { _stores = function (self, xml) --luacheck: ignore 212/self local store_names = set.new(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/plugins/mod_tombstones.lua new/prosody-0.12.1/plugins/mod_tombstones.lua --- old/prosody-0.12.0/plugins/mod_tombstones.lua 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/plugins/mod_tombstones.lua 2022-06-09 13:44:01.673100438 +0200 @@ -2,12 +2,13 @@ -- e.g. via telnet or other admin interface local datetime = require "util.datetime"; local errors = require "util.error"; -local jid_split = require"util.jid".split; +local jid_node = require"util.jid".node; local st = require "util.stanza"; -- Using a map store as key-value store so that removal of all user data -- does not also remove the tombstone, which would defeat the point local graveyard = module:open_store(nil, "map"); +local graveyard_cache = require "util.cache".new(module:get_option_number("tombstone_cache_size", 1024)); local ttl = module:get_option_number("user_tombstone_expiry", nil); -- Keep tombstones forever by default @@ -29,15 +30,40 @@ -- Public API function has_tombstone(username) - local tombstone, err = graveyard:get(nil, username); + local tombstone; - if err or not tombstone then return tombstone, err; end + -- Check cache + local cached_result = graveyard_cache:get(username); + if cached_result == false then + -- We cached that there is no tombstone for this user + return false; + elseif cached_result then + tombstone = cached_result; + else + local stored_result, err = graveyard:get(nil, username); + if not stored_result and not err then + -- Cache that there is no tombstone for this user + graveyard_cache:set(username, false); + return false; + elseif err then + -- Failed to check tombstone status + return nil, err; + end + -- We have a tombstone stored, so let's continue with that + tombstone = stored_result; + end + -- Check expiry if ttl and tombstone + ttl < os.time() then module:log("debug", "Tombstone for %s created at %s has expired", username, datetime.datetime(tombstone)); graveyard:set(nil, username, nil); + graveyard_cache:set(username, nil); -- clear cache entry (if any) return nil; end + + -- Cache for the future + graveyard_cache:set(username, tombstone); + return tombstone; end @@ -59,6 +85,8 @@ module:hook("presence/bare", function(event) local origin, presence = event.origin, event.stanza; + local local_username = jid_node(presence.attr.to); + if not local_username then return; end -- We want to undo any left-over presence subscriptions and notify the former -- contact that they're gone. @@ -66,14 +94,17 @@ -- FIXME This leaks that the user once existed. Hard to avoid without keeping -- the contact list in some form, which we don't want to do for privacy -- reasons. Bloom filter perhaps? - if has_tombstone(jid_split(presence.attr.to)) then - if presence.attr.type == "probe" then - origin.send(st.error_reply(presence, "cancel", "gone", "User deleted")); - origin.send(st.presence({ type = "unsubscribed"; to = presence.attr.from; from = presence.attr.to })); - elseif presence.attr.type == nil or presence.attr.type == "unavailable" then - origin.send(st.error_reply(presence, "cancel", "gone", "User deleted")); - origin.send(st.presence({ type = "unsubscribe"; to = presence.attr.from; from = presence.attr.to })); - end + + local pres_type = presence.attr.type; + local is_probe = pres_type == "probe"; + local is_normal = pres_type == nil or pres_type == "unavailable"; + if is_probe and has_tombstone(local_username) then + origin.send(st.error_reply(presence, "cancel", "gone", "User deleted")); + origin.send(st.presence({ type = "unsubscribed"; to = presence.attr.from; from = presence.attr.to })); + return true; + elseif is_normal and has_tombstone(local_username) then + origin.send(st.error_reply(presence, "cancel", "gone", "User deleted")); + origin.send(st.presence({ type = "unsubscribe"; to = presence.attr.from; from = presence.attr.to })); return true; end end, 1); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/plugins/mod_turn_external.lua new/prosody-0.12.1/plugins/mod_turn_external.lua --- old/prosody-0.12.0/plugins/mod_turn_external.lua 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/plugins/mod_turn_external.lua 2022-06-09 13:44:01.673100438 +0200 @@ -8,7 +8,10 @@ local tcp = module:get_option_boolean("turn_external_tcp", false); local tls_port = module:get_option_number("turn_external_tls_port"); -if not secret then error("mod_" .. module.name .. " requires that 'turn_external_secret' be set") end +if not secret then + module:log_status("error", "Failed to initialize: the 'turn_external_secret' option is not set in your configuration"); + return; +end local services = set.new({ "stun-udp"; "turn-udp" }); if tcp then diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/plugins/mod_websocket.lua new/prosody-0.12.1/plugins/mod_websocket.lua --- old/prosody-0.12.0/plugins/mod_websocket.lua 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/plugins/mod_websocket.lua 2022-06-09 13:44:01.673100438 +0200 @@ -355,6 +355,9 @@ module:provides("http", { name = "websocket"; default_path = "xmpp-websocket"; + cors = { + enabled = true; + }; route = { ["GET"] = handle_request; ["GET /"] = handle_request; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/plugins/muc/muc.lib.lua new/prosody-0.12.1/plugins/muc/muc.lib.lua --- old/prosody-0.12.0/plugins/muc/muc.lib.lua 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/plugins/muc/muc.lib.lua 2022-06-09 13:44:01.673100438 +0200 @@ -1583,15 +1583,16 @@ return event.allowed, event.error, event.condition; end - -- Can't do anything to other owners or admins - local occupant_affiliation = self:get_affiliation(occupant.bare_jid); - if occupant_affiliation == "owner" or occupant_affiliation == "admin" then + local actor_affiliation = self:get_affiliation(actor) or "none"; + local occupant_affiliation = self:get_affiliation(occupant.bare_jid) or "none"; + + -- Can't do anything to someone with higher affiliation + if valid_affiliations[actor_affiliation] < valid_affiliations[occupant_affiliation] then return nil, "cancel", "not-allowed"; end -- If you are trying to give or take moderator role you need to be an owner or admin if occupant.role == "moderator" or role == "moderator" then - local actor_affiliation = self:get_affiliation(actor); if actor_affiliation ~= "owner" and actor_affiliation ~= "admin" then return nil, "cancel", "not-allowed"; end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/prosody.release new/prosody-0.12.1/prosody.release --- old/prosody-0.12.0/prosody.release 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/prosody.release 2022-06-09 13:44:01.673100438 +0200 @@ -1 +1 @@ -0.12.0 +0.12.1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/prosodyctl new/prosody-0.12.1/prosodyctl --- old/prosody-0.12.0/prosodyctl 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/prosodyctl 2022-06-09 13:44:01.673100438 +0200 @@ -115,11 +115,17 @@ show_usage([[list]], [[Shows installed rocks]]); return 0; end + local server = opts.server or configmanager.get("*", "plugin_server"); if opts.outdated then -- put this back for luarocks arg[1] = "--outdated"; + + if not server then + show_warning("There is no 'plugin_server' option in the configuration file, but this is needed for 'list --outdated' to work."); + return 1; + end end - local ret = call_luarocks("list", arg[1]); + local ret = call_luarocks("list", arg[1], server); return ret; end @@ -484,6 +490,7 @@ local library_versions = {}; dependencies.softreq"ssl"; dependencies.softreq"DBI"; + dependencies.softreq"readline"; local friendly_names = { DBI = "LuaDBI"; lfs = "LuaFileSystem"; @@ -492,17 +499,22 @@ socket = "LuaSocket"; ssl = "LuaSec"; }; + local alternate_version_fields = { + -- These diverge from the module._VERSION convention + readline = "Version"; + } local lunbound = dependencies.softreq"lunbound"; local lxp = dependencies.softreq"lxp"; local hashes = dependencies.softreq"util.hashes"; for name, module in pairs(package.loaded) do - if type(module) == "table" and rawget(module, "_VERSION") + local version_field = alternate_version_fields[name] or "_VERSION"; + if type(module) == "table" and rawget(module, version_field) and name ~= "_G" and not name:match("%.") then name = friendly_names[name] or name; if #name > longest_name then longest_name = #name; end - local mod_version = module._VERSION; + local mod_version = module[version_field]; if tostring(mod_version):sub(1, #name+1) == name .. " " then mod_version = mod_version:sub(#name+2); end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/spec/util_argparse_spec.lua new/prosody-0.12.1/spec/util_argparse_spec.lua --- old/prosody-0.12.0/spec/util_argparse_spec.lua 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/spec/util_argparse_spec.lua 2022-06-09 13:44:01.673100438 +0200 @@ -20,7 +20,7 @@ local arg = { "--foo"; "bar"; "--baz" }; local opts, err = parse(arg); assert.falsy(err); - assert.same({ foo = true }, opts); + assert.same({ foo = true, "bar", "--baz" }, opts); assert.same({ "bar"; "--baz" }, arg); end); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/spec/util_jsonpointer_spec.lua new/prosody-0.12.1/spec/util_jsonpointer_spec.lua --- old/prosody-0.12.0/spec/util_jsonpointer_spec.lua 1970-01-01 01:00:00.000000000 +0100 +++ new/prosody-0.12.1/spec/util_jsonpointer_spec.lua 2022-06-09 13:44:01.673100438 +0200 @@ -0,0 +1,38 @@ +describe("util.jsonpointer", function() + local json, jp; + setup(function() + json = require "util.json"; + jp = require "util.jsonpointer"; + end) + describe("resolve()", function() + local example; + setup(function() + example = json.decode([[{ + "foo": ["bar", "baz"], + "": 0, + "a/b": 1, + "c%d": 2, + "e^f": 3, + "g|h": 4, + "i\\j": 5, + "k\"l": 6, + " ": 7, + "m~n": 8 + }]]) + end) + it("works", function() + assert.same(example, jp.resolve(example, "")); + assert.same({ "bar", "baz" }, jp.resolve(example, "/foo")); + assert.same("bar", jp.resolve(example, "/foo/0")); + assert.same(0, jp.resolve(example, "/")); + assert.same(1, jp.resolve(example, "/a~1b")); + assert.same(2, jp.resolve(example, "/c%d")); + assert.same(3, jp.resolve(example, "/e^f")); + assert.same(4, jp.resolve(example, "/g|h")); + assert.same(5, jp.resolve(example, "/i\\j")); + assert.same(6, jp.resolve(example, "/k\"l")); + assert.same(7, jp.resolve(example, "/ ")); + assert.same(8, jp.resolve(example, "/m~0n")); + end) + end) +end) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/teal-src/plugins/mod_cron.tl new/prosody-0.12.1/teal-src/plugins/mod_cron.tl --- old/prosody-0.12.0/teal-src/plugins/mod_cron.tl 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/teal-src/plugins/mod_cron.tl 2022-06-09 13:44:01.673100438 +0200 @@ -84,6 +84,7 @@ local function run_task(task : task_spec) local started_at = os.time(); task:run(started_at); + task.last = started_at; task:save(started_at); end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/teal-src/util/jsonpointer.tl new/prosody-0.12.1/teal-src/util/jsonpointer.tl --- old/prosody-0.12.0/teal-src/util/jsonpointer.tl 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/teal-src/util/jsonpointer.tl 2022-06-09 13:44:01.673100438 +0200 @@ -24,7 +24,7 @@ elseif idx is integer then local i = tonumber(token) if token == "-" then i = #ref + 1 end - new_ref = ref[i] + new_ref = ref[i+1] else return nil, "invalid-table" end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/util/adminstream.lua new/prosody-0.12.1/util/adminstream.lua --- old/prosody-0.12.0/util/adminstream.lua 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/util/adminstream.lua 2022-06-09 13:44:01.673100438 +0200 @@ -139,6 +139,15 @@ local function new_connection(socket_path, listeners) local have_unix, unix = pcall(require, "socket.unix"); + if have_unix and type(unix) == "function" then + -- COMPAT #1717 + -- Before the introduction of datagram support, only the stream socket + -- constructor was exported instead of a module table. Due to the lack of a + -- proper release of LuaSocket, distros have settled on shipping either the + -- last RC tag or some commit since then. + -- Here we accomodate both variants. + unix = { stream = unix }; + end if type(unix) ~= "table" then have_unix = false; end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/util/argparse.lua new/prosody-0.12.1/util/argparse.lua --- old/prosody-0.12.0/util/argparse.lua 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/util/argparse.lua 2022-06-09 13:44:01.673100438 +0200 @@ -47,6 +47,9 @@ end parsed_opts[param_k] = param_v; end + for i = 1, #arg do + parsed_opts[i] = arg[i]; + end return parsed_opts; end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/util/jsonpointer.lua new/prosody-0.12.1/util/jsonpointer.lua --- old/prosody-0.12.0/util/jsonpointer.lua 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/util/jsonpointer.lua 2022-06-09 13:44:01.673100438 +0200 @@ -1,3 +1,7 @@ +local m_type = math.type or function (n) + return n % 1 == 0 and n <= 9007199254740992 and n >= -9007199254740992 and "integer" or "float"; +end; + local function unescape_token(escaped_token) local unescaped = escaped_token:gsub("~1", "/"):gsub("~0", "~") return unescaped @@ -15,12 +19,12 @@ if type(idx) == "string" then new_ref = ref[token] - elseif math.type(idx) == "integer" then + elseif m_type(idx) == "integer" then local i = tonumber(token) if token == "-" then i = #ref + 1 end - new_ref = ref[i] + new_ref = ref[i + 1] else return nil, "invalid-table" end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/util/jsonschema.lua new/prosody-0.12.1/util/jsonschema.lua --- old/prosody-0.12.0/util/jsonschema.lua 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/util/jsonschema.lua 2022-06-09 13:44:01.673100438 +0200 @@ -1,3 +1,6 @@ +local m_type = math.type or function (n) + return n % 1 == 0 and n <= 9007199254740992 and n >= -9007199254740992 and "integer" or "float"; +end; local json = require("util.json") local null = json.null; @@ -17,7 +20,7 @@ elseif schema == "array" and type(data) == "table" then return type(data) == "table" and (next(data) == nil or type((next(data, nil))) == "number") elseif schema == "integer" then - return math.type(data) == schema + return m_type(data) == schema elseif schema == "null" then return data == null else diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/util/prosodyctl/check.lua new/prosody-0.12.1/util/prosodyctl/check.lua --- old/prosody-0.12.0/util/prosodyctl/check.lua 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/util/prosodyctl/check.lua 2022-06-09 13:44:01.673100438 +0200 @@ -62,9 +62,7 @@ end local function check_turn_service(turn_service, ping_service) - local array = require "util.array"; local ip = require "util.ip"; - local set = require "util.set"; local stun = require "net.stun"; -- Create UDP socket for communication with the server @@ -155,7 +153,7 @@ local alloc_response, err = receive_packet(); if not alloc_response then result.error = "TURN server did not response to allocation request: "..err; - return; + return result; elseif alloc_response:is_err_resp() then result.error = ("TURN allocation failed: %d (%s)"):format(alloc_response:get_error()); return result; @@ -182,6 +180,12 @@ -- Only a hostname specified, use default STUN port ping_host, ping_port = ping_service, 3478; end + + if ping_host == turn_service.host then + result.error = ("Unable to perform ping test: please supply an external STUN server address. See https://prosody.im/doc/turn#prosodyctl-check"); + return result; + end + local ping_service_ip, err = socket.dns.toip(ping_host); if not ping_service_ip then result.error = "Unable to resolve ping service hostname: "..err; @@ -241,7 +245,7 @@ local pong_data = ping_response:get_attribute("data"); if not pong_data then result.error = "No data relayed from remote server"; - return; + return result; end local pong = stun.new_packet():deserialize(pong_data); @@ -251,9 +255,17 @@ return result; end - local relayed_address_set = set.new(array.pluck(result.relayed_addresses, "address")); - if not relayed_address_set:contains(result.external_ip_pong.address) then + local relay_address_found, relay_port_matches; + for _, relayed_address in ipairs(result.relayed_addresses) do + if relayed_address.address == result.external_ip_pong.address then + relay_address_found = true; + relay_port_matches = result.external_ip_pong.port == relayed_address.port; + end + end + if not relay_address_found then table.insert(result.warnings, "TURN external IP vs relay address mismatch! Is the TURN server behind a NAT and misconfigured?"); + elseif not relay_port_matches then + table.insert(result.warnings, "External port does not match reported relay port! This is probably caused by a NAT in front of the TURN server."); end -- @@ -320,6 +332,13 @@ end if not what or what == "config" then print("Checking config..."); + + if what == "config" then + local files = configmanager.files(); + print(" The following configuration files have been loaded:"); + print(" - "..table.concat(files, "\n - ")); + end + local obsolete = set.new({ --> remove "archive_cleanup_interval", "cross_domain_bosh", @@ -661,7 +680,7 @@ end end end - for host, host_config in enabled_hosts() do + for host, host_config in it.filter(skip_bare_jid_hosts, enabled_hosts()) do local is_component = not not host_config.component_module; if is_component then local parent_domain = host:match("^[^.]+%.(.+)$"); @@ -690,10 +709,6 @@ local dns = require "net.dns"; pcall(function () local unbound = require"net.unbound"; - local unbound_config = configmanager.get("*", "unbound") or {}; - unbound_config.hoststxt = false; -- don't look at /etc/hosts - configmanager.set("*", "unbound", unbound_config); - unbound.dns.purge(); -- ensure the above config is used dns = unbound.dns; end) local idna = require "util.encodings".idna; @@ -1258,6 +1273,7 @@ local count = it.count(pairs(turn_services)); if count == 0 then print("Error: Unable to find any TURN services configured. Enable mod_turn_external!"); + ok = false; else print("Identified "..tostring(count).." TURN services."); print(""); @@ -1284,7 +1300,7 @@ end end if result.external_ip_pong then - print(("TURN external IP: %s"):format(result.external_ip_pong.address)); + print(("TURN external address: %s:%d"):format(result.external_ip_pong.address, result.external_ip_pong.port)); end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/util/random.lua new/prosody-0.12.1/util/random.lua --- old/prosody-0.12.0/util/random.lua 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/util/random.lua 2022-06-09 13:44:01.673100438 +0200 @@ -7,7 +7,7 @@ -- local ok, crand = pcall(require, "util.crand"); -if ok then return crand; end +if ok and pcall(crand.bytes, 1) then return crand; end local urandom, urandom_err = io.open("/dev/urandom", "r"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-0.12.0/util/startup.lua new/prosody-0.12.1/util/startup.lua --- old/prosody-0.12.0/util/startup.lua 2022-03-08 13:34:39.594708341 +0100 +++ new/prosody-0.12.1/util/startup.lua 2022-06-09 13:44:01.673100438 +0200 @@ -46,12 +46,19 @@ end os.exit(1); end - if opts.help and prosody.process_type == "prosody" then - print("prosody [ -D | -F ] [ --config /path/to/prosody.cfg.lua ]"); - print(" -D, --daemonize Run in the background") - print(" -F, --no-daemonize Run in the foreground") - print(" --config FILE Specify config file") - os.exit(0); + if prosody.process_type == "prosody" then + if #arg > 0 then + print("Unrecognized option: "..arg[1]); + print("(Did you mean 'prosodyctl "..arg[1].."'?)"); + print(""); + end + if opts.help or #arg > 0 then + print("prosody [ -D | -F ] [ --config /path/to/prosody.cfg.lua ]"); + print(" -D, --daemonize Run in the background") + print(" -F, --no-daemonize Run in the foreground") + print(" --config FILE Specify config file") + os.exit(0); + end end prosody.opts = opts; end