Software /
code /
prosody
Comparison
prosodyctl @ 8671:a4899174a894
prosodyctl: Large number of changes to satisfy [luacheck], includes bug fixes
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Thu, 22 Mar 2018 22:33:42 +0000 |
parent | 8668:31c5abd49dfe |
child | 8701:b7a22baaf55f |
comparison
equal
deleted
inserted
replaced
8670:800c648827e3 | 8671:a4899174a894 |
---|---|
43 end | 43 end |
44 end | 44 end |
45 | 45 |
46 ----------- | 46 ----------- |
47 | 47 |
48 require "util.startup".prosodyctl(); | 48 local startup = require "util.startup"; |
49 startup.prosodyctl(); | |
49 | 50 |
50 ----------- | 51 ----------- |
51 | 52 |
52 local error_messages = setmetatable({ | 53 local error_messages = setmetatable({ |
53 ["invalid-username"] = "The given username is invalid in a Jabber ID"; | 54 ["invalid-username"] = "The given username is invalid in a Jabber ID"; |
59 ["no-pidfile"] = "There is no 'pidfile' option in the configuration file, see https://prosody.im/doc/prosodyctl#pidfile for help"; | 60 ["no-pidfile"] = "There is no 'pidfile' option in the configuration file, see https://prosody.im/doc/prosodyctl#pidfile for help"; |
60 ["invalid-pidfile"] = "The 'pidfile' option in the configuration file is not a string, see https://prosody.im/doc/prosodyctl#pidfile for help"; | 61 ["invalid-pidfile"] = "The 'pidfile' option in the configuration file is not a string, see https://prosody.im/doc/prosodyctl#pidfile for help"; |
61 ["no-posix"] = "The mod_posix module is not enabled in the Prosody config file, see https://prosody.im/doc/prosodyctl for more info"; | 62 ["no-posix"] = "The mod_posix module is not enabled in the Prosody config file, see https://prosody.im/doc/prosodyctl for more info"; |
62 ["no-such-method"] = "This module has no commands"; | 63 ["no-such-method"] = "This module has no commands"; |
63 ["not-running"] = "Prosody is not running"; | 64 ["not-running"] = "Prosody is not running"; |
64 }, { __index = function (t,k) return "Error: "..(tostring(k):gsub("%-", " "):gsub("^.", string.upper)); end }); | 65 }, { __index = function (_,k) return "Error: "..(tostring(k):gsub("%-", " "):gsub("^.", string.upper)); end }); |
65 | 66 |
66 local config = require "core.configmanager"; | 67 local configmanager = require "core.configmanager"; |
67 local modulemanager = require "core.modulemanager" | 68 local modulemanager = require "core.modulemanager" |
68 local prosodyctl = require "util.prosodyctl" | 69 local prosodyctl = require "util.prosodyctl" |
69 local socket = require "socket" | 70 local socket = require "socket" |
70 local dependencies = require "util.dependencies"; | 71 local dependencies = require "util.dependencies"; |
71 | 72 |
77 local show_prompt = prosodyctl.show_prompt; | 78 local show_prompt = prosodyctl.show_prompt; |
78 local read_password = prosodyctl.read_password; | 79 local read_password = prosodyctl.read_password; |
79 | 80 |
80 local jid_split = require "util.jid".prepped_split; | 81 local jid_split = require "util.jid".prepped_split; |
81 | 82 |
82 local prosodyctl_timeout = (config.get("*", "prosodyctl_timeout") or 5) * 2; | 83 local prosodyctl_timeout = (configmanager.get("*", "prosodyctl_timeout") or 5) * 2; |
83 ----------------------- | 84 ----------------------- |
84 local commands = {}; | 85 local commands = {}; |
85 local command = arg[1]; | 86 local command = arg[1]; |
86 | 87 |
87 function commands.adduser(arg) | 88 function commands.adduser(arg) |
102 end | 103 end |
103 | 104 |
104 if not hosts[host] then | 105 if not hosts[host] then |
105 show_warning("The host '%s' is not listed in the configuration file (or is not enabled).", host) | 106 show_warning("The host '%s' is not listed in the configuration file (or is not enabled).", host) |
106 show_warning("The user will not be able to log in until this is changed."); | 107 show_warning("The user will not be able to log in until this is changed."); |
107 hosts[host] = make_host(host); | 108 hosts[host] = startup.make_host(host); --luacheck: ignore 122/hosts |
108 end | 109 end |
109 | 110 |
110 if prosodyctl.user_exists{ user = user, host = host } then | 111 if prosodyctl.user_exists{ user = user, host = host } then |
111 show_message [[That user already exists]]; | 112 show_message [[That user already exists]]; |
112 return 1; | 113 return 1; |
141 end | 142 end |
142 | 143 |
143 if not hosts[host] then | 144 if not hosts[host] then |
144 show_warning("The host '%s' is not listed in the configuration file (or is not enabled).", host) | 145 show_warning("The host '%s' is not listed in the configuration file (or is not enabled).", host) |
145 show_warning("The user will not be able to log in until this is changed."); | 146 show_warning("The user will not be able to log in until this is changed."); |
146 hosts[host] = make_host(host); | 147 hosts[host] = startup.make_host(host); --luacheck: ignore 122/hosts |
147 end | 148 end |
148 | 149 |
149 if not prosodyctl.user_exists { user = user, host = host } then | 150 if not prosodyctl.user_exists { user = user, host = host } then |
150 show_message [[That user does not exist, use prosodyctl adduser to create a new user]] | 151 show_message [[That user does not exist, use prosodyctl adduser to create a new user]] |
151 return 1; | 152 return 1; |
179 return 1; | 180 return 1; |
180 end | 181 end |
181 | 182 |
182 if not hosts[host] then | 183 if not hosts[host] then |
183 show_warning("The host '%s' is not listed in the configuration file (or is not enabled).", host) | 184 show_warning("The host '%s' is not listed in the configuration file (or is not enabled).", host) |
184 hosts[host] = make_host(host); | 185 hosts[host] = startup.make_host(host); --luacheck: ignore 122/hosts |
185 end | 186 end |
186 | 187 |
187 if not prosodyctl.user_exists { user = user, host = host } then | 188 if not prosodyctl.user_exists { user = user, host = host } then |
188 show_message [[That user does not exist on this server]] | 189 show_message [[That user does not exist on this server]] |
189 return 1; | 190 return 1; |
207 show_message(error_messages[ret]); | 208 show_message(error_messages[ret]); |
208 return 1; | 209 return 1; |
209 end | 210 end |
210 | 211 |
211 if ret then | 212 if ret then |
213 --luacheck: ignore 421/ret | |
212 local ok, ret = prosodyctl.getpid(); | 214 local ok, ret = prosodyctl.getpid(); |
213 if not ok then | 215 if not ok then |
214 show_message("Couldn't get running Prosody's PID"); | 216 show_message("Couldn't get running Prosody's PID"); |
215 show_message(error_messages[ret]); | 217 show_message(error_messages[ret]); |
216 return 1; | 218 return 1; |
217 end | 219 end |
218 show_message("Prosody is already running with PID %s", ret or "(unknown)"); | 220 show_message("Prosody is already running with PID %s", ret or "(unknown)"); |
219 return 1; | 221 return 1; |
220 end | 222 end |
221 | 223 |
224 --luacheck: ignore 411/ret | |
222 local ok, ret = prosodyctl.start(prosody.paths.source); | 225 local ok, ret = prosodyctl.start(prosody.paths.source); |
223 if ok then | 226 if ok then |
224 local daemonize = config.get("*", "daemonize"); | 227 local daemonize = configmanager.get("*", "daemonize"); |
225 if daemonize == nil then | 228 if daemonize == nil then |
226 daemonize = prosody.installed; | 229 daemonize = prosody.installed; |
227 end | 230 end |
228 if daemonize then | 231 if daemonize then |
229 local i=1; | 232 local i=1; |
261 show_message(error_messages[ret]); | 264 show_message(error_messages[ret]); |
262 return 1; | 265 return 1; |
263 end | 266 end |
264 | 267 |
265 if ret then | 268 if ret then |
269 --luacheck: ignore 421/ret | |
266 local ok, ret = prosodyctl.getpid(); | 270 local ok, ret = prosodyctl.getpid(); |
267 if not ok then | 271 if not ok then |
268 show_message("Couldn't get running Prosody's PID"); | 272 show_message("Couldn't get running Prosody's PID"); |
269 show_message(error_messages[ret]); | 273 show_message(error_messages[ret]); |
270 return 1; | 274 return 1; |
271 end | 275 end |
272 show_message("Prosody is running with PID %s", ret or "(unknown)"); | 276 show_message("Prosody is running with PID %s", ret or "(unknown)"); |
273 return 0; | 277 return 0; |
274 else | 278 else |
275 show_message("Prosody is not running"); | 279 show_message("Prosody is not running"); |
276 if not switched_user and current_uid ~= 0 then | 280 if not prosody.switched_user and prosody.current_uid ~= 0 then |
277 print("\nNote:") | 281 print("\nNote:") |
278 print(" You will also see this if prosodyctl is not running under"); | 282 print(" You will also see this if prosodyctl is not running under"); |
279 print(" the same user account as Prosody. Try running as root (e.g. "); | 283 print(" the same user account as Prosody. Try running as root (e.g. "); |
280 print(" with 'sudo' in front) to gain access to Prosody's real status."); | 284 print(" with 'sudo' in front) to gain access to Prosody's real status."); |
281 end | 285 end |
282 return 2 | 286 return 2 |
283 end | 287 end |
284 return 1; | |
285 end | 288 end |
286 | 289 |
287 function commands.stop(arg) | 290 function commands.stop(arg) |
288 if arg[1] == "--help" then | 291 if arg[1] == "--help" then |
289 show_usage([[stop]], [[Stop a running Prosody server]]); | 292 show_usage([[stop]], [[Stop a running Prosody server]]); |
334 show_usage([[about]], [[Show information about this Prosody installation]]); | 337 show_usage([[about]], [[Show information about this Prosody installation]]); |
335 return 1; | 338 return 1; |
336 end | 339 end |
337 | 340 |
338 local pwd = "."; | 341 local pwd = "."; |
339 local lfs = require "lfs"; | |
340 local array = require "util.array"; | 342 local array = require "util.array"; |
341 local keys = require "util.iterators".keys; | 343 local keys = require "util.iterators".keys; |
342 local hg = require"util.mercurial"; | 344 local hg = require"util.mercurial"; |
343 local relpath = config.resolve_relative_path; | 345 local relpath = configmanager.resolve_relative_path; |
344 | 346 |
345 print("Prosody "..(prosody.version or "(unknown version)")); | 347 print("Prosody "..(prosody.version or "(unknown version)")); |
346 print(""); | 348 print(""); |
347 print("# Prosody directories"); | 349 print("# Prosody directories"); |
348 print("Data directory: "..relpath(pwd, prosody.paths.data)); | 350 print("Data directory: "..relpath(pwd, prosody.paths.data)); |
349 print("Config directory: "..relpath(pwd, prosody.paths.config or ".")); | 351 print("Config directory: "..relpath(pwd, prosody.paths.config or ".")); |
350 print("Source directory: "..relpath(pwd, prosody.paths.source or ".")); | 352 print("Source directory: "..relpath(pwd, prosody.paths.source or ".")); |
351 print("Plugin directories:") | 353 print("Plugin directories:") |
352 print(" "..(prosody.paths.plugins:gsub("([^;]+);?", function(path) | 354 print(" "..(prosody.paths.plugins:gsub("([^;]+);?", function(path) |
353 path = config.resolve_relative_path(pwd, path); | 355 path = configmanager.resolve_relative_path(pwd, path); |
354 local hgid, hgrepo = hg.check_id(path); | 356 local hgid, hgrepo = hg.check_id(path); |
355 if not hgid and hgrepo then | 357 if not hgid and hgrepo then |
356 return path.." - "..hgrepo .."!\n "; | 358 return path.." - "..hgrepo .."!\n "; |
357 end | 359 end |
358 -- 010452cfaf53 is the first commit in the prosody-modules repository | 360 -- 010452cfaf53 is the first commit in the prosody-modules repository |
380 print("LuaRocks: ", luarocks_status); | 382 print("LuaRocks: ", luarocks_status); |
381 print(""); | 383 print(""); |
382 print("# Lua module versions"); | 384 print("# Lua module versions"); |
383 local module_versions, longest_name = {}, 8; | 385 local module_versions, longest_name = {}, 8; |
384 local luaevent =dependencies.softreq"luaevent"; | 386 local luaevent =dependencies.softreq"luaevent"; |
385 local ssl = dependencies.softreq"ssl"; | 387 dependencies.softreq"ssl"; |
386 for name, module in pairs(package.loaded) do | 388 for name, module in pairs(package.loaded) do |
387 if type(module) == "table" and rawget(module, "_VERSION") | 389 if type(module) == "table" and rawget(module, "_VERSION") |
388 and name ~= "_G" and not name:match("%.") then | 390 and name ~= "_G" and not name:match("%.") then |
389 if #name > longest_name then | 391 if #name > longest_name then |
390 longest_name = #name; | 392 longest_name = #name; |
501 | 503 |
502 local have_pposix, pposix = pcall(require, "util.pposix"); | 504 local have_pposix, pposix = pcall(require, "util.pposix"); |
503 local cert_basedir = prosody.paths.data == "." and "./certs" or prosody.paths.data; | 505 local cert_basedir = prosody.paths.data == "." and "./certs" or prosody.paths.data; |
504 if have_pposix and pposix.getuid() == 0 then | 506 if have_pposix and pposix.getuid() == 0 then |
505 -- FIXME should be enough to check if this directory is writable | 507 -- FIXME should be enough to check if this directory is writable |
506 local cert_dir = config.get("*", "certificates") or "certs"; | 508 local cert_dir = configmanager.get("*", "certificates") or "certs"; |
507 cert_basedir = config.resolve_relative_path(prosody.paths.config, cert_dir); | 509 cert_basedir = configmanager.resolve_relative_path(prosody.paths.config, cert_dir); |
508 end | 510 end |
509 | 511 |
510 function cert_commands.config(arg) | 512 function cert_commands.config(arg) |
511 if #arg >= 1 and arg[1] ~= "--help" then | 513 if #arg >= 1 and arg[1] ~= "--help" then |
512 local conf_filename = cert_basedir .. "/" .. arg[1] .. ".cnf"; | 514 local conf_filename = cert_basedir .. "/" .. arg[1] .. ".cnf"; |
516 local distinguished_name; | 518 local distinguished_name; |
517 if arg[#arg]:find("^/") then | 519 if arg[#arg]:find("^/") then |
518 distinguished_name = table.remove(arg); | 520 distinguished_name = table.remove(arg); |
519 end | 521 end |
520 local conf = openssl.config.new(); | 522 local conf = openssl.config.new(); |
521 conf:from_prosody(hosts, config, arg); | 523 conf:from_prosody(hosts, configmanager, arg); |
522 if distinguished_name then | 524 if distinguished_name then |
523 local dn = {}; | 525 local dn = {}; |
524 for k, v in distinguished_name:gmatch("/([^=/]+)=([^/]+)") do | 526 for k, v in distinguished_name:gmatch("/([^=/]+)=([^/]+)") do |
525 table.insert(dn, k); | 527 table.insert(dn, k); |
526 dn[k] = v; | 528 dn[k] = v; |
530 show_message("Please provide details to include in the certificate config file."); | 532 show_message("Please provide details to include in the certificate config file."); |
531 show_message("Leave the field empty to use the default value or '.' to exclude the field.") | 533 show_message("Leave the field empty to use the default value or '.' to exclude the field.") |
532 for _, k in ipairs(openssl._DN_order) do | 534 for _, k in ipairs(openssl._DN_order) do |
533 local v = conf.distinguished_name[k]; | 535 local v = conf.distinguished_name[k]; |
534 if v then | 536 if v then |
535 local nv; | 537 local nv = nil; |
536 if k == "commonName" then | 538 if k == "commonName" then |
537 v = arg[1] | 539 v = arg[1] |
538 elseif k == "emailAddress" then | 540 elseif k == "emailAddress" then |
539 v = "xmpp@" .. arg[1]; | 541 v = "xmpp@" .. arg[1]; |
540 elseif k == "countryName" then | 542 elseif k == "countryName" then |
669 for host in domains:gmatch("%S+") do | 671 for host in domains:gmatch("%S+") do |
670 table.insert(hostnames, host); | 672 table.insert(hostnames, host); |
671 end | 673 end |
672 else | 674 else |
673 for host in pairs(prosody.hosts) do | 675 for host in pairs(prosody.hosts) do |
674 if host ~= "*" and config.get(host, "enabled") ~= false then | 676 if host ~= "*" and configmanager.get(host, "enabled") ~= false then |
675 table.insert(hostnames, host); | 677 table.insert(hostnames, host); |
676 end | 678 end |
677 end | 679 end |
678 end | 680 end |
679 end | 681 end |
682 "Copies certificates to "..cert_basedir); | 684 "Copies certificates to "..cert_basedir); |
683 return 1; | 685 return 1; |
684 end | 686 end |
685 local owner, group; | 687 local owner, group; |
686 if pposix.getuid() == 0 then -- We need root to change ownership | 688 if pposix.getuid() == 0 then -- We need root to change ownership |
687 owner = config.get("*", "prosody_user") or "prosody"; | 689 owner = configmanager.get("*", "prosody_user") or "prosody"; |
688 group = config.get("*", "prosody_group") or owner; | 690 group = configmanager.get("*", "prosody_group") or owner; |
689 end | 691 end |
690 local cm = require "core.certmanager"; | 692 local cm = require "core.certmanager"; |
691 local imported = {}; | 693 local imported = {}; |
692 for _, host in ipairs(hostnames) do | 694 for _, host in ipairs(hostnames) do |
693 for _, dir in ipairs(arg) do | 695 for _, dir in ipairs(arg) do |
764 if arg[1] == "--help" then | 766 if arg[1] == "--help" then |
765 show_usage([[check]], [[Perform basic checks on your Prosody installation]]); | 767 show_usage([[check]], [[Perform basic checks on your Prosody installation]]); |
766 return 1; | 768 return 1; |
767 end | 769 end |
768 local what = table.remove(arg, 1); | 770 local what = table.remove(arg, 1); |
769 local array, set = require "util.array", require "util.set"; | 771 local set = require "util.set"; |
770 local it = require "util.iterators"; | 772 local it = require "util.iterators"; |
771 local ok = true; | 773 local ok = true; |
772 local function disabled_hosts(host, conf) return host ~= "*" and conf.enabled ~= false; end | 774 local function disabled_hosts(host, conf) return host ~= "*" and conf.enabled ~= false; end |
773 local function enabled_hosts() return it.filter(disabled_hosts, pairs(config.getconfig())); end | 775 local function enabled_hosts() return it.filter(disabled_hosts, pairs(configmanager.getconfig())); end |
774 if not what or what == "disabled" then | 776 if not what or what == "disabled" then |
775 local disabled_hosts = set.new(); | 777 local disabled_hosts_set = set.new(); |
776 for host, host_options in it.filter("*", pairs(config.getconfig())) do | 778 for host, host_options in it.filter("*", pairs(configmanager.getconfig())) do |
777 if host_options.enabled == false then | 779 if host_options.enabled == false then |
778 disabled_hosts:add(host); | 780 disabled_hosts_set:add(host); |
779 end | 781 end |
780 end | 782 end |
781 if not disabled_hosts:empty() then | 783 if not disabled_hosts_set:empty() then |
782 local msg = "Checks will be skipped for these disabled hosts: %s"; | 784 local msg = "Checks will be skipped for these disabled hosts: %s"; |
783 if what then msg = "These hosts are disabled: %s"; end | 785 if what then msg = "These hosts are disabled: %s"; end |
784 show_warning(msg, tostring(disabled_hosts)); | 786 show_warning(msg, tostring(disabled_hosts_set)); |
785 if what then return 0; end | 787 if what then return 0; end |
786 print"" | 788 print"" |
787 end | 789 end |
788 end | 790 end |
789 if not what or what == "config" then | 791 if not what or what == "config" then |
795 local known_global_options = set.new({ | 797 local known_global_options = set.new({ |
796 "pidfile", "log", "plugin_paths", "prosody_user", "prosody_group", "daemonize", | 798 "pidfile", "log", "plugin_paths", "prosody_user", "prosody_group", "daemonize", |
797 "umask", "prosodyctl_timeout", "use_ipv6", "use_libevent", "network_settings", | 799 "umask", "prosodyctl_timeout", "use_ipv6", "use_libevent", "network_settings", |
798 "network_backend", "http_default_host", | 800 "network_backend", "http_default_host", |
799 }); | 801 }); |
800 local config = config.getconfig(); | 802 local config = configmanager.getconfig(); |
801 -- Check that we have any global options (caused by putting a host at the top) | 803 -- Check that we have any global options (caused by putting a host at the top) |
802 if it.count(it.filter("log", pairs(config["*"]))) == 0 then | 804 if it.count(it.filter("log", pairs(config["*"]))) == 0 then |
803 ok = false; | 805 ok = false; |
804 print(""); | 806 print(""); |
805 print(" No global options defined. Perhaps you have put a host definition at the top") | 807 print(" No global options defined. Perhaps you have put a host definition at the top") |
817 end | 819 end |
818 end | 820 end |
819 if not config["*"].modules_enabled then | 821 if not config["*"].modules_enabled then |
820 print(" No global modules_enabled is set?"); | 822 print(" No global modules_enabled is set?"); |
821 local suggested_global_modules; | 823 local suggested_global_modules; |
822 for host, options in enabled_hosts() do | 824 for host, options in enabled_hosts() do --luacheck: ignore 213/host |
823 if not options.component_module and options.modules_enabled then | 825 if not options.component_module and options.modules_enabled then |
824 suggested_global_modules = set.intersection(suggested_global_modules or set.new(options.modules_enabled), set.new(options.modules_enabled)); | 826 suggested_global_modules = set.intersection(suggested_global_modules or set.new(options.modules_enabled), set.new(options.modules_enabled)); |
825 end | 827 end |
826 end | 828 end |
827 if suggested_global_modules and not suggested_global_modules:empty() then | 829 if suggested_global_modules and not suggested_global_modules:empty() then |
860 print(" You need to move the following option"..(n>1 and "s" or "")..": "..table.concat(it.to_array(misplaced_options), ", ")); | 862 print(" You need to move the following option"..(n>1 and "s" or "")..": "..table.concat(it.to_array(misplaced_options), ", ")); |
861 end | 863 end |
862 local subdomain = host:match("^[^.]+"); | 864 local subdomain = host:match("^[^.]+"); |
863 if not(host_options:contains("component_module")) and (subdomain == "jabber" or subdomain == "xmpp" | 865 if not(host_options:contains("component_module")) and (subdomain == "jabber" or subdomain == "xmpp" |
864 or subdomain == "chat" or subdomain == "im") then | 866 or subdomain == "chat" or subdomain == "im") then |
865 print(""); | 867 print(""); |
866 print(" Suggestion: If "..host.. " is a new host with no real users yet, consider renaming it now to"); | 868 print(" Suggestion: If "..host.. " is a new host with no real users yet, consider renaming it now to"); |
867 print(" "..host:gsub("^[^.]+%.", "")..". You can use SRV records to redirect XMPP clients and servers to "..host.."."); | 869 print(" "..host:gsub("^[^.]+%.", "")..". You can use SRV records to redirect XMPP clients and servers to "..host.."."); |
868 print(" For more information see: https://prosody.im/doc/dns"); | 870 print(" For more information see: https://prosody.im/doc/dns"); |
869 end | 871 end |
870 end | 872 end |
871 local all_modules = set.new(config["*"].modules_enabled); | 873 local all_modules = set.new(config["*"].modules_enabled); |
872 local all_options = set.new(it.to_array(it.keys(config["*"]))); | 874 local all_options = set.new(it.to_array(it.keys(config["*"]))); |
873 for host in enabled_hosts() do | 875 for host in enabled_hosts() do |
893 print(" Remove '"..mod.."' from modules_enabled and instead add"); | 895 print(" Remove '"..mod.."' from modules_enabled and instead add"); |
894 print(" storage = '"..mod:match("^storage_(.*)").."'"); | 896 print(" storage = '"..mod:match("^storage_(.*)").."'"); |
895 print(" For more information see https://prosody.im/doc/storage"); | 897 print(" For more information see https://prosody.im/doc/storage"); |
896 end | 898 end |
897 end | 899 end |
898 for host, config in pairs(config) do | 900 for host, host_config in pairs(config) do --luacheck: ignore 213/host |
899 if type(rawget(config, "storage")) == "string" and rawget(config, "default_storage") then | 901 if type(rawget(host_config, "storage")) == "string" and rawget(host_config, "default_storage") then |
900 print(""); | 902 print(""); |
901 print(" The 'default_storage' option is not needed if 'storage' is set to a string."); | 903 print(" The 'default_storage' option is not needed if 'storage' is set to a string."); |
902 break; | 904 break; |
903 end | 905 end |
904 end | 906 end |
905 local require_encryption = set.intersection(all_options, set.new({"require_encryption", "c2s_require_encryption", "s2s_require_encryption"})):empty(); | 907 local require_encryption = set.intersection(all_options, set.new({ |
908 "require_encryption", "c2s_require_encryption", "s2s_require_encryption" | |
909 })):empty(); | |
906 local ssl = dependencies.softreq"ssl"; | 910 local ssl = dependencies.softreq"ssl"; |
907 if not ssl then | 911 if not ssl then |
908 if not require_encryption then | 912 if not require_encryption then |
909 print(""); | 913 print(""); |
910 print(" You require encryption but LuaSec is not available."); | 914 print(" You require encryption but LuaSec is not available."); |
946 end | 950 end |
947 if not what or what == "dns" then | 951 if not what or what == "dns" then |
948 local dns = require "net.dns"; | 952 local dns = require "net.dns"; |
949 local idna = require "util.encodings".idna; | 953 local idna = require "util.encodings".idna; |
950 local ip = require "util.ip"; | 954 local ip = require "util.ip"; |
951 local c2s_ports = set.new(config.get("*", "c2s_ports") or {5222}); | 955 local c2s_ports = set.new(configmanager.get("*", "c2s_ports") or {5222}); |
952 local s2s_ports = set.new(config.get("*", "s2s_ports") or {5269}); | 956 local s2s_ports = set.new(configmanager.get("*", "s2s_ports") or {5269}); |
953 | 957 |
954 local c2s_srv_required, s2s_srv_required; | 958 local c2s_srv_required, s2s_srv_required; |
955 if not c2s_ports:contains(5222) then | 959 if not c2s_ports:contains(5222) then |
956 c2s_srv_required = true; | 960 c2s_srv_required = true; |
957 end | 961 end |
963 | 967 |
964 local external_addresses, internal_addresses = set.new(), set.new(); | 968 local external_addresses, internal_addresses = set.new(), set.new(); |
965 | 969 |
966 local fqdn = socket.dns.tohostname(socket.dns.gethostname()); | 970 local fqdn = socket.dns.tohostname(socket.dns.gethostname()); |
967 if fqdn then | 971 if fqdn then |
968 local res = dns.lookup(idna.to_ascii(fqdn), "A"); | 972 do |
969 if res then | 973 local res = dns.lookup(idna.to_ascii(fqdn), "A"); |
970 for _, record in ipairs(res) do | 974 if res then |
971 external_addresses:add(record.a); | 975 for _, record in ipairs(res) do |
972 end | 976 external_addresses:add(record.a); |
973 end | 977 end |
974 local res = dns.lookup(idna.to_ascii(fqdn), "AAAA"); | 978 end |
975 if res then | 979 end |
976 for _, record in ipairs(res) do | 980 do |
977 external_addresses:add(record.aaaa); | 981 local res = dns.lookup(idna.to_ascii(fqdn), "AAAA"); |
982 if res then | |
983 for _, record in ipairs(res) do | |
984 external_addresses:add(record.aaaa); | |
985 end | |
978 end | 986 end |
979 end | 987 end |
980 end | 988 end |
981 | 989 |
982 local local_addresses = require"util.net".local_addresses() or {}; | 990 local local_addresses = require"util.net".local_addresses() or {}; |
1023 else | 1031 else |
1024 target_hosts:add(host); | 1032 target_hosts:add(host); |
1025 end | 1033 end |
1026 end | 1034 end |
1027 end | 1035 end |
1028 local res = dns.lookup("_xmpp-server._tcp."..idna.to_ascii(host)..".", "SRV"); | 1036 do |
1029 if res then | 1037 local res = dns.lookup("_xmpp-server._tcp."..idna.to_ascii(host)..".", "SRV"); |
1030 for _, record in ipairs(res) do | 1038 if res then |
1031 target_hosts:add(record.srv.target); | 1039 for _, record in ipairs(res) do |
1032 if not s2s_ports:contains(record.srv.port) then | 1040 target_hosts:add(record.srv.target); |
1033 print(" SRV target "..record.srv.target.." contains unknown server port: "..record.srv.port); | 1041 if not s2s_ports:contains(record.srv.port) then |
1042 print(" SRV target "..record.srv.target.." contains unknown server port: "..record.srv.port); | |
1043 end | |
1034 end | 1044 end |
1035 end | |
1036 else | |
1037 if s2s_srv_required then | |
1038 print(" No _xmpp-server SRV record found for "..host..", but it looks like you need one."); | |
1039 all_targets_ok = false; | |
1040 else | 1045 else |
1041 target_hosts:add(host); | 1046 if s2s_srv_required then |
1047 print(" No _xmpp-server SRV record found for "..host..", but it looks like you need one."); | |
1048 all_targets_ok = false; | |
1049 else | |
1050 target_hosts:add(host); | |
1051 end | |
1042 end | 1052 end |
1043 end | 1053 end |
1044 if target_hosts:empty() then | 1054 if target_hosts:empty() then |
1045 target_hosts:add(host); | 1055 target_hosts:add(host); |
1046 end | 1056 end |
1049 print(" Target 'localhost' cannot be accessed from other servers"); | 1059 print(" Target 'localhost' cannot be accessed from other servers"); |
1050 target_hosts:remove("localhost"); | 1060 target_hosts:remove("localhost"); |
1051 end | 1061 end |
1052 | 1062 |
1053 local modules = set.new(it.to_array(it.values(host_options.modules_enabled or {}))) | 1063 local modules = set.new(it.to_array(it.values(host_options.modules_enabled or {}))) |
1054 + set.new(it.to_array(it.values(config.get("*", "modules_enabled") or {}))) | 1064 + set.new(it.to_array(it.values(configmanager.get("*", "modules_enabled") or {}))) |
1055 + set.new({ config.get(host, "component_module") }); | 1065 + set.new({ configmanager.get(host, "component_module") }); |
1056 | 1066 |
1057 if modules:contains("proxy65") then | 1067 if modules:contains("proxy65") then |
1058 local proxy65_target = config.get(host, "proxy65_address") or host; | 1068 local proxy65_target = configmanager.get(host, "proxy65_address") or host; |
1059 local A, AAAA = dns.lookup(idna.to_ascii(proxy65_target), "A"), dns.lookup(idna.to_ascii(proxy65_target), "AAAA"); | 1069 local A, AAAA = dns.lookup(idna.to_ascii(proxy65_target), "A"), dns.lookup(idna.to_ascii(proxy65_target), "AAAA"); |
1060 local prob = {}; | 1070 local prob = {}; |
1061 if not A then | 1071 if not A then |
1062 table.insert(prob, "A"); | 1072 table.insert(prob, "A"); |
1063 end | 1073 end |
1064 if v6_supported and not AAAA then | 1074 if v6_supported and not AAAA then |
1065 table.insert(prob, "AAAA"); | 1075 table.insert(prob, "AAAA"); |
1066 end | 1076 end |
1067 if #prob > 0 then | 1077 if #prob > 0 then |
1068 print(" File transfer proxy "..proxy65_target.." has no "..table.concat(prob, "/").." record. Create one or set 'proxy65_address' to the correct host/IP."); | 1078 print(" File transfer proxy "..proxy65_target.." has no "..table.concat(prob, "/") |
1069 end | 1079 .." record. Create one or set 'proxy65_address' to the correct host/IP."); |
1070 end | 1080 end |
1071 | 1081 end |
1072 for host in target_hosts do | 1082 |
1083 for target_host in target_hosts do | |
1073 local host_ok_v4, host_ok_v6; | 1084 local host_ok_v4, host_ok_v6; |
1074 local res = dns.lookup(idna.to_ascii(host), "A"); | 1085 do |
1075 if res then | 1086 local res = dns.lookup(idna.to_ascii(target_host), "A"); |
1076 for _, record in ipairs(res) do | 1087 if res then |
1077 if external_addresses:contains(record.a) then | 1088 for _, record in ipairs(res) do |
1078 some_targets_ok = true; | 1089 if external_addresses:contains(record.a) then |
1079 host_ok_v4 = true; | 1090 some_targets_ok = true; |
1080 elseif internal_addresses:contains(record.a) then | 1091 host_ok_v4 = true; |
1081 host_ok_v4 = true; | 1092 elseif internal_addresses:contains(record.a) then |
1082 some_targets_ok = true; | 1093 host_ok_v4 = true; |
1083 print(" "..host.." A record points to internal address, external connections might fail"); | 1094 some_targets_ok = true; |
1084 else | 1095 print(" "..target_host.." A record points to internal address, external connections might fail"); |
1085 print(" "..host.." A record points to unknown address "..record.a); | 1096 else |
1086 all_targets_ok = false; | 1097 print(" "..target_host.." A record points to unknown address "..record.a); |
1098 all_targets_ok = false; | |
1099 end | |
1087 end | 1100 end |
1088 end | 1101 end |
1089 end | 1102 end |
1090 local res = dns.lookup(idna.to_ascii(host), "AAAA"); | 1103 do |
1091 if res then | 1104 local res = dns.lookup(idna.to_ascii(target_host), "AAAA"); |
1092 for _, record in ipairs(res) do | 1105 if res then |
1093 if external_addresses:contains(record.aaaa) then | 1106 for _, record in ipairs(res) do |
1094 some_targets_ok = true; | 1107 if external_addresses:contains(record.aaaa) then |
1095 host_ok_v6 = true; | 1108 some_targets_ok = true; |
1096 elseif internal_addresses:contains(record.aaaa) then | 1109 host_ok_v6 = true; |
1097 host_ok_v6 = true; | 1110 elseif internal_addresses:contains(record.aaaa) then |
1098 some_targets_ok = true; | 1111 host_ok_v6 = true; |
1099 print(" "..host.." AAAA record points to internal address, external connections might fail"); | 1112 some_targets_ok = true; |
1100 else | 1113 print(" "..target_host.." AAAA record points to internal address, external connections might fail"); |
1101 print(" "..host.." AAAA record points to unknown address "..record.aaaa); | 1114 else |
1102 all_targets_ok = false; | 1115 print(" "..target_host.." AAAA record points to unknown address "..record.aaaa); |
1116 all_targets_ok = false; | |
1117 end | |
1103 end | 1118 end |
1104 end | 1119 end |
1105 end | 1120 end |
1106 | 1121 |
1107 local bad_protos = {} | 1122 local bad_protos = {} |
1110 end | 1125 end |
1111 if not host_ok_v6 then | 1126 if not host_ok_v6 then |
1112 table.insert(bad_protos, "IPv6"); | 1127 table.insert(bad_protos, "IPv6"); |
1113 end | 1128 end |
1114 if #bad_protos > 0 then | 1129 if #bad_protos > 0 then |
1115 print(" Host "..host.." does not seem to resolve to this server ("..table.concat(bad_protos, "/")..")"); | 1130 print(" Host "..target_host.." does not seem to resolve to this server ("..table.concat(bad_protos, "/")..")"); |
1116 end | 1131 end |
1117 if host_ok_v6 and not v6_supported then | 1132 if host_ok_v6 and not v6_supported then |
1118 print(" Host "..host.." has AAAA records, but your version of LuaSocket does not support IPv6."); | 1133 print(" Host "..target_host.." has AAAA records, but your version of LuaSocket does not support IPv6."); |
1119 print(" Please see https://prosody.im/doc/ipv6 for more information."); | 1134 print(" Please see https://prosody.im/doc/ipv6 for more information."); |
1120 end | 1135 end |
1121 end | 1136 end |
1122 if not all_targets_ok then | 1137 if not all_targets_ok then |
1123 print(" "..(some_targets_ok and "Only some" or "No").." targets for "..host.." appear to resolve to this server."); | 1138 print(" "..(some_targets_ok and "Only some" or "No").." targets for "..host.." appear to resolve to this server."); |
1159 return true; | 1174 return true; |
1160 end | 1175 end |
1161 for host in it.filter(skip_bare_jid_hosts, enabled_hosts()) do | 1176 for host in it.filter(skip_bare_jid_hosts, enabled_hosts()) do |
1162 print("Checking certificate for "..host); | 1177 print("Checking certificate for "..host); |
1163 -- First, let's find out what certificate this host uses. | 1178 -- First, let's find out what certificate this host uses. |
1164 local host_ssl_config = config.rawget(host, "ssl") | 1179 local host_ssl_config = configmanager.rawget(host, "ssl") |
1165 or config.rawget(host:match("%.(.*)"), "ssl"); | 1180 or configmanager.rawget(host:match("%.(.*)"), "ssl"); |
1166 local global_ssl_config = config.rawget("*", "ssl"); | 1181 local global_ssl_config = configmanager.rawget("*", "ssl"); |
1167 local ok, err, ssl_config = create_context(host, "server", host_ssl_config, global_ssl_config); | 1182 local ok, err, ssl_config = create_context(host, "server", host_ssl_config, global_ssl_config); |
1168 if not ok then | 1183 if not ok then |
1169 print(" Error: "..err); | 1184 print(" Error: "..err); |
1170 cert_ok = false | 1185 cert_ok = false |
1171 elseif not ssl_config.certificate then | 1186 elseif not ssl_config.certificate then |
1186 if not cert_fh then | 1201 if not cert_fh then |
1187 print(" Could not open "..ssl_config.certificate..": "..err); | 1202 print(" Could not open "..ssl_config.certificate..": "..err); |
1188 cert_ok = false | 1203 cert_ok = false |
1189 else | 1204 else |
1190 print(" Certificate: "..ssl_config.certificate) | 1205 print(" Certificate: "..ssl_config.certificate) |
1191 local cert = load_cert(cert_fh:read"*a"); cert_fh = cert_fh:close(); | 1206 local cert = load_cert(cert_fh:read"*a"); cert_fh:close(); |
1192 if not cert:validat(os.time()) then | 1207 if not cert:validat(os.time()) then |
1193 print(" Certificate has expired.") | 1208 print(" Certificate has expired.") |
1194 cert_ok = false | 1209 cert_ok = false |
1195 elseif not cert:validat(os.time() + 86400) then | 1210 elseif not cert:validat(os.time() + 86400) then |
1196 print(" Certificate expires within one day.") | 1211 print(" Certificate expires within one day.") |
1198 elseif not cert:validat(os.time() + 86400*7) then | 1213 elseif not cert:validat(os.time() + 86400*7) then |
1199 print(" Certificate expires within one week.") | 1214 print(" Certificate expires within one week.") |
1200 elseif not cert:validat(os.time() + 86400*31) then | 1215 elseif not cert:validat(os.time() + 86400*31) then |
1201 print(" Certificate expires within one month.") | 1216 print(" Certificate expires within one month.") |
1202 end | 1217 end |
1203 if config.get(host, "component_module") == nil | 1218 if configmanager.get(host, "component_module") == nil |
1204 and not x509_verify_identity(host, "_xmpp-client", cert) then | 1219 and not x509_verify_identity(host, "_xmpp-client", cert) then |
1205 print(" Not valid for client connections to "..host..".") | 1220 print(" Not valid for client connections to "..host..".") |
1206 cert_ok = false | 1221 cert_ok = false |
1207 end | 1222 end |
1208 if (not (config.get(host, "anonymous_login") | 1223 if (not (configmanager.get(host, "anonymous_login") |
1209 or config.get(host, "authentication") == "anonymous")) | 1224 or configmanager.get(host, "authentication") == "anonymous")) |
1210 and not x509_verify_identity(host, "_xmpp-server", cert) then | 1225 and not x509_verify_identity(host, "_xmpp-server", cert) then |
1211 print(" Not valid for server-to-server connections to "..host..".") | 1226 print(" Not valid for server-to-server connections to "..host..".") |
1212 cert_ok = false | 1227 cert_ok = false |
1213 end | 1228 end |
1214 end | 1229 end |
1215 end | 1230 end |
1216 end | 1231 end |
1217 if cert_ok == false then | 1232 end |
1218 print("") | 1233 if cert_ok == false then |
1219 print("For more information about certificates please see https://prosody.im/doc/certificates"); | 1234 print("") |
1220 ok = false | 1235 print("For more information about certificates please see https://prosody.im/doc/certificates"); |
1221 end | 1236 ok = false |
1222 end | 1237 end |
1223 print("") | 1238 print("") |
1224 end | 1239 end |
1225 if not ok then | 1240 if not ok then |
1226 print("Problems found, see above."); | 1241 print("Problems found, see above."); |
1231 end | 1246 end |
1232 | 1247 |
1233 --------------------- | 1248 --------------------- |
1234 | 1249 |
1235 local async = require "util.async"; | 1250 local async = require "util.async"; |
1251 local server = require "net.server"; | |
1236 local watchers = { | 1252 local watchers = { |
1237 error = function (_, err) | 1253 error = function (_, err) |
1238 error(err); | 1254 error(err); |
1239 end; | 1255 end; |
1240 waiting = function () | 1256 waiting = function () |
1242 end; | 1258 end; |
1243 }; | 1259 }; |
1244 local command_runner = async.runner(function () | 1260 local command_runner = async.runner(function () |
1245 if command and command:match("^mod_") then -- Is a command in a module | 1261 if command and command:match("^mod_") then -- Is a command in a module |
1246 local module_name = command:match("^mod_(.+)"); | 1262 local module_name = command:match("^mod_(.+)"); |
1247 local ret, err = modulemanager.load("*", module_name); | 1263 do |
1248 if not ret then | 1264 local ret, err = modulemanager.load("*", module_name); |
1249 show_message("Failed to load module '"..module_name.."': "..err); | 1265 if not ret then |
1250 os.exit(1); | 1266 show_message("Failed to load module '"..module_name.."': "..err); |
1267 os.exit(1); | |
1268 end | |
1251 end | 1269 end |
1252 | 1270 |
1253 table.remove(arg, 1); | 1271 table.remove(arg, 1); |
1254 | 1272 |
1255 local module = modulemanager.get_module("*", module_name); | 1273 local module = modulemanager.get_module("*", module_name); |
1293 local commands_order = { "adduser", "passwd", "deluser", "start", "stop", "restart", "reload", "about" }; | 1311 local commands_order = { "adduser", "passwd", "deluser", "start", "stop", "restart", "reload", "about" }; |
1294 | 1312 |
1295 local done = {}; | 1313 local done = {}; |
1296 | 1314 |
1297 for _, command_name in ipairs(commands_order) do | 1315 for _, command_name in ipairs(commands_order) do |
1298 local command = commands[command_name]; | 1316 local command_func = commands[command_name]; |
1299 if command then | 1317 if command_func then |
1300 command{ "--help" }; | 1318 command_func{ "--help" }; |
1301 print"" | 1319 print"" |
1302 done[command_name] = true; | 1320 done[command_name] = true; |
1303 end | 1321 end |
1304 end | 1322 end |
1305 | 1323 |
1306 for command_name, command in pairs(commands) do | 1324 for command_name, command_func in pairs(commands) do |
1307 if not done[command_name] and not hidden_commands:contains(command_name) then | 1325 if not done[command_name] and not hidden_commands:contains(command_name) then |
1308 command{ "--help" }; | 1326 command_func{ "--help" }; |
1309 print"" | 1327 print"" |
1310 done[command_name] = true; | 1328 done[command_name] = true; |
1311 end | 1329 end |
1312 end | 1330 end |
1313 | 1331 |