X-Git-Url: https://git.enpas.org/?a=blobdiff_plain;f=prosodyctl;h=e4ef45ad2a1f7f00d88488ddcb75d31689e248d5;hb=0a5a6c318e189d8c067ba91b2271e368da170ce5;hp=bfb118c3039949ce2c737ecc40fd8121e21a52e2;hpb=7fac02237b6fdc0dad24fa63df3e1e8bdcce096d;p=prosody.git diff --git a/prosodyctl b/prosodyctl index bfb118c3..e4ef45ad 100755 --- a/prosodyctl +++ b/prosodyctl @@ -244,13 +244,14 @@ end local modulemanager = require "core.modulemanager" local prosodyctl = require "util.prosodyctl" -require "socket" +local socket = require "socket" ----------------------- -- FIXME: Duplicate code waiting for util.startup function read_version() -- Try to determine version local version_file = io.open((CFG_SOURCEDIR or ".").."/prosody.version"); + prosody.version = "unknown"; if version_file then prosody.version = version_file:read("*a"):gsub("%s*$", ""); version_file:close(); @@ -258,7 +259,9 @@ function read_version() prosody.version = "hg:"..prosody.version; end else - prosody.version = "unknown"; + local hg = require"util.mercurial"; + local hgid = hg.check_id(CFG_SOURCEDIR or "."); + if hgid then prosody.version = "hg:" .. hgid; end end end @@ -528,16 +531,32 @@ function commands.about(arg) return 1; end + local pwd = "."; + local lfs = require "lfs"; local array = require "util.array"; local keys = require "util.iterators".keys; + local hg = require"util.mercurial"; + local relpath = config.resolve_relative_path; print("Prosody "..(prosody.version or "(unknown version)")); print(""); print("# Prosody directories"); - print("Data directory: ", CFG_DATADIR or "./"); - print("Plugin directory:", CFG_PLUGINDIR or "./"); - print("Config directory:", CFG_CONFIGDIR or "./"); - print("Source directory:", CFG_SOURCEDIR or "./"); + print("Data directory: "..relpath(pwd, data_path)); + print("Config directory: "..relpath(pwd, CFG_CONFIGDIR or ".")); + print("Source directory: "..relpath(pwd, CFG_SOURCEDIR or ".")); + print("Plugin directories:") + print(" "..(prosody.paths.plugins:gsub("([^;]+);?", function(path) + local opath = path; + path = config.resolve_relative_path(pwd, path); + local hgid, hgrepo = hg.check_id(path); + if not hgid and hgrepo then + return path.." - "..hgrepo .."!\n "; + end + -- 010452cfaf53 is the first commit in the prosody-modules repository + hgrepo = hgrepo == "010452cfaf53" and "prosody-modules"; + return path..(hgid and " - "..(hgrepo or "HG").." rev: "..hgid or "") + .."\n "; + end))); print(""); print("# Lua environment"); print("Lua version: ", _G._VERSION); @@ -559,6 +578,8 @@ function commands.about(arg) print(""); print("# Lua module versions"); local module_versions, longest_name = {}, 8; + local luaevent =dependencies.softreq"luaevent"; + local ssl = dependencies.softreq"ssl"; for name, module in pairs(package.loaded) do if type(module) == "table" and rawget(module, "_VERSION") and name ~= "_G" and not name:match("%.") then @@ -654,14 +675,26 @@ local lfs; local cert_commands = {}; -local function ask_overwrite(filename) - return lfs.attributes(filename) and not show_yesno("Overwrite "..filename .. "?"); +-- If a file already exists, ask if the user wants to use it or replace it +-- Backups the old file if replaced +local function use_existing(filename) + local attrs = lfs.attributes(filename); + if attrs then + if show_yesno(filename .. " exists, do you want to replace it? [y/n]") then + local backup = filename..".bkp~"..os.date("%FT%T", attrs.change); + os.rename(filename, backup); + show_message(filename.." backed up to "..backup); + else + -- Use the existing file + return true; + end + end end function cert_commands.config(arg) if #arg >= 1 and arg[1] ~= "--help" then local conf_filename = (CFG_DATADIR or "./certs") .. "/" .. arg[1] .. ".cnf"; - if ask_overwrite(conf_filename) then + if use_existing(conf_filename) then return nil, conf_filename; end local conf = openssl.config.new(); @@ -709,7 +742,7 @@ end function cert_commands.key(arg) if #arg >= 1 and arg[1] ~= "--help" then local key_filename = (CFG_DATADIR or "./certs") .. "/" .. arg[1] .. ".key"; - if ask_overwrite(key_filename) then + if use_existing(key_filename) then return nil, key_filename; end os.remove(key_filename); -- This file, if it exists is unlikely to have write permissions @@ -731,7 +764,7 @@ end function cert_commands.request(arg) if #arg >= 1 and arg[1] ~= "--help" then local req_filename = (CFG_DATADIR or "./certs") .. "/" .. arg[1] .. ".req"; - if ask_overwrite(req_filename) then + if use_existing(req_filename) then return nil, req_filename; end local _, key_filename = cert_commands.key({arg[1]}); @@ -749,7 +782,7 @@ end function cert_commands.generate(arg) if #arg >= 1 and arg[1] ~= "--help" then local cert_filename = (CFG_DATADIR or "./certs") .. "/" .. arg[1] .. ".crt"; - if ask_overwrite(cert_filename) then + if use_existing(cert_filename) then return nil, cert_filename; end local _, key_filename = cert_commands.key({arg[1]}); @@ -820,7 +853,8 @@ function commands.check(arg) }); local known_global_options = set.new({ "pidfile", "log", "plugin_paths", "prosody_user", "prosody_group", "daemonize", - "umask", "prosodyctl_timeout", "use_ipv6", "use_libevent", "network_settings" + "umask", "prosodyctl_timeout", "use_ipv6", "use_libevent", "network_settings", + "network_backend", "http_default_host", }); local config = config.getconfig(); -- Check that we have any global options (caused by putting a host at the top) @@ -856,7 +890,7 @@ function commands.check(arg) for name in pairs(options) do if name:match("^interfaces?") or name:match("_ports?$") or name:match("_interfaces?$") - or name:match("_ssl$") then + or (name:match("_ssl$") and not name:match("^[cs]2s_ssl$")) then misplaced_options:add(name); end end @@ -879,6 +913,66 @@ function commands.check(arg) print(" For more information see: http://prosody.im/doc/dns"); end end + local all_modules = set.new(config["*"].modules_enabled); + local all_options = set.new(it.to_array(it.keys(config["*"]))); + for host in enabled_hosts() do + all_options:include(set.new(it.to_array(it.keys(config[host])))); + all_modules:include(set.new(config[host].modules_enabled)); + end + for mod in all_modules do + if mod:match("^mod_") then + print(""); + print(" Modules in modules_enabled should not have the 'mod_' prefix included."); + print(" Change '"..mod.."' to '"..mod:match("^mod_(.*)").."'."); + elseif mod:match("^auth_") then + print(""); + print(" Authentication modules should not be added to modules_enabled,"); + print(" but be specified in the 'authentication' option."); + print(" Remove '"..mod.."' from modules_enabled and instead add"); + print(" authentication = '"..mod:match("^auth_(.*)").."'"); + print(" For more information see https://prosody.im/doc/authentication"); + elseif mod:match("^storage_") then + print(""); + print(" storage modules should not be added to modules_enabled,"); + print(" but be specified in the 'storage' option."); + print(" Remove '"..mod.."' from modules_enabled and instead add"); + print(" storage = '"..mod:match("^storage_(.*)").."'"); + print(" For more information see https://prosody.im/doc/storage"); + end + end + local ssl = dependencies.softreq"ssl"; + if not ssl then + if not set.intersection(all_options, set.new({"require_encryption", "c2s_require_encryption", "s2s_require_encryption"})):empty() then + print(""); + print(" You require encryption but LuaSec is not available."); + print(" Connections will fail."); + ok = false; + end + elseif not ssl.loadcertificate then + if all_options:contains("s2s_secure_auth") then + print(""); + print(" You have set s2s_secure_auth but your version of LuaSec does "); + print(" not support certificate validation, so all s2s connections will"); + print(" fail."); + ok = false; + elseif all_options:contains("s2s_secure_domains") then + local secure_domains = set.new(); + for host in enabled_hosts() do + if config[host].s2s_secure_auth == true then + secure_domains:add("*"); + else + secure_domains:include(set.new(config[host].s2s_secure_domains)); + end + end + if not secure_domains:empty() then + print(""); + print(" You have set s2s_secure_domains but your version of LuaSec does "); + print(" not support certificate validation, so s2s connections to/from "); + print(" these domains will fail."); + ok = false; + end + end + end print("Done.\n"); end @@ -1075,7 +1169,7 @@ function commands.check(arg) local x509_verify_identity = require"util.x509".verify_identity; local ssl = dependencies.softreq"ssl"; -- local datetime_parse = require"util.datetime".parse_x509; - local load_cert = ssl and ssl.x509 and ssl.x509.load; + local load_cert = ssl and ssl.loadcertificate; -- or ssl.cert_from_pem if not ssl then print("LuaSec not available, can't perform certificate checks") @@ -1127,7 +1221,7 @@ function commands.check(arg) end if (not (config.get(host, "anonymous_login") or config.get(host, "authentication") == "anonymous")) - and not x509_verify_identity(host, "_xmpp-client", cert) then + and not x509_verify_identity(host, "_xmpp-server", cert) then print(" Not vaild for server-to-server connections to "..host..".") cert_ok = false end