From d5457e36492d72a959b12b466ba92b21374e7417 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 9 Apr 2013 15:50:46 +0200 Subject: prosodyctl: Bump util.pposix version for API change --- prosodyctl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'prosodyctl') diff --git a/prosodyctl b/prosodyctl index 71b99f9e..24d28157 100755 --- a/prosodyctl +++ b/prosodyctl @@ -135,7 +135,7 @@ dependencies.log_warnings(); -- Switch away from root and into the prosody user -- local switched_user, current_uid; -local want_pposix_version = "0.3.5"; +local want_pposix_version = "0.3.6"; local ok, pposix = pcall(require, "util.pposix"); if ok and pposix then -- cgit v1.2.3 From 99a110b625c997a25dded7dcadba921fad8560d4 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 17 May 2013 09:01:11 +0100 Subject: prosodyctl: Add 'check' command, which currently checks the config file for some common mistakes --- prosodyctl | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'prosodyctl') diff --git a/prosodyctl b/prosodyctl index 247b099a..262be676 100755 --- a/prosodyctl +++ b/prosodyctl @@ -776,6 +776,58 @@ function commands.cert(arg) show_usage("cert config|request|generate|key", "Helpers for generating X.509 certificates and keys.") end +function commands.check(arg) + local what = table.remove(arg, 1); + local array, set = require "util.array", require "util.set"; + local it = require "util.iterators"; + local ok = true; + if not what or what == "config" then + print("Checking config..."); + local known_global_options = set.new({ + "pidfile", "log", "plugin_paths", "prosody_user", "prosody_group", "daemonize", + "umask", "prosodyctl_timeout", "use_ipv6", "use_libevent", "network_settings" + }); + local config = config.getconfig(); + -- Check that we have any global options (caused by putting a host at the top) + if it.count(it.filter("log", pairs(config["*"]))) == 0 then + ok = false; + print(""); + print(" No global options defined. Perhaps you have put a host definition at the top") + print(" of the config file? They should be at the bottom, see http://prosody.im/doc/configure#overview"); + end + -- Check for global options under hosts + local global_options = set.new(it.to_array(it.keys(config["*"]))); + for host, options in it.filter("*", pairs(config)) do + local host_options = set.new(it.to_array(it.keys(options))); + local misplaced_options = set.intersection(host_options, known_global_options); + for name in pairs(options) do + if name:match("^interfaces?") + or name:match("_ports?$") or name:match("_interfaces?$") + or name:match("_ssl$") then + misplaced_options:add(name); + end + end + if not misplaced_options:empty() then + ok = false; + print(""); + local n = it.count(misplaced_options); + print(" You have "..n.." option"..(n>1 and "s " or " ").."set under "..host.." that should be"); + print(" in the global section of the config file, above any VirtualHost or Component definitions,") + print(" see http://prosody.im/doc/configure#overview for more information.") + print(""); + print(" You need to move the following option"..(n>1 and "s" or "")..": "..table.concat(it.to_array(misplaced_options), ", ")); + end + end + print("Done."); + end + if not ok then + print("Problems found, see above."); + else + print("All checks passed, congratulations!"); + end + return ok and 0 or 2; +end + --------------------- if command and command:match("^mod_") then -- Is a command in a module -- cgit v1.2.3 From a4bd217da1874b9e0837bbda638d7b42eeb7a0e2 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 17 May 2013 13:35:12 +0100 Subject: prosodyctl: Add 'prosodyctl check dns' to make an attempt at verifying the server's DNS records --- prosodyctl | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 142 insertions(+), 1 deletion(-) (limited to 'prosodyctl') diff --git a/prosodyctl b/prosodyctl index 262be676..d3ba8932 100755 --- a/prosodyctl +++ b/prosodyctl @@ -818,7 +818,148 @@ function commands.check(arg) print(" You need to move the following option"..(n>1 and "s" or "")..": "..table.concat(it.to_array(misplaced_options), ", ")); end end - print("Done."); + print("Done.\n"); + end + if not what or what == "dns" then + local dns = require "net.dns"; + local c2s_ports = set.new(config.get("*", "c2s_ports") or {5222}); + local s2s_ports = set.new(config.get("*", "s2s_ports") or {5269}); + + local c2s_srv_required, s2s_srv_required; + if not c2s_ports:contains(5222) then + c2s_srv_required = true; + end + if not s2s_ports:contains(5269) then + s2s_srv_required = true; + end + + local problem_hosts = set.new(); + + local external_addresses = set.new(); + + local fqdn = socket.dns.tohostname(socket.dns.gethostname()); + if fqdn then + local res = dns.lookup(fqdn, "A"); + if res then + for _, record in ipairs(res) do + external_addresses:add(record.a); + end + end + local res = dns.lookup(fqdn, "AAAA"); + if res then + for _, record in ipairs(res) do + external_addresses:add(record.aaaa); + end + end + end + + if external_addresses:empty() then + print(""); + print(" Failed to determine the external addresses of this server. Checks may be inaccurate."); + c2s_srv_required, s2s_srv_required = true, true; + end + + local v6_supported = not not socket.tcp6; + + for host, host_options in it.filter("*", pairs(config.getconfig())) do + local all_targets_ok, some_targets_ok = true, false; + + local is_component = not not host_options.component_module; + print("Checking DNS for "..(is_component and "component" or "host").." "..host.."..."); + local target_hosts = set.new(); + if not is_component then + local res = dns.lookup("_xmpp-client._tcp."..host..".", "SRV"); + if res then + for _, record in ipairs(res) do + target_hosts:add(record.srv.target); + if not c2s_ports:contains(record.srv.port) then + print(" SRV target "..record.srv.target.." contains unknown client port: "..record.srv.port); + end + end + else + if c2s_srv_required then + print(" No _xmpp-client SRV record found for "..host..", but it looks like you need one."); + else + target_hosts:add(host); + end + end + end + local res = dns.lookup("_xmpp-server._tcp."..host..".", "SRV"); + if res then + for _, record in ipairs(res) do + target_hosts:add(record.srv.target); + if not s2s_ports:contains(record.srv.port) then + print(" SRV target "..record.srv.target.." contains unknown server port: "..record.srv.port); + end + end + else + if s2s_srv_required then + print(" No _xmpp-server SRV record found for "..host..", but it looks like you need one."); + else + target_hosts:add(host); + end + end + if target_hosts:empty() then + target_hosts:add(host); + end + + if target_hosts:contains("localhost") then + print(" Target 'localhost' cannot be accessed from other servers"); + target_hosts:remove("localhost"); + end + + for host in target_hosts do + local host_ok_v4, host_ok_v6; + local res = dns.lookup(host, "A"); + if res then + for _, record in ipairs(res) do + if external_addresses:contains(record.a) then + some_targets_ok = true; + host_ok_v4 = true; + else + print(" "..host.." A record points to unknown address "..record.a); + all_targets_ok = false; + end + end + end + local res = dns.lookup(host, "AAAA"); + if res then + for _, record in ipairs(res) do + if external_addresses:contains(record.aaaa) then + some_targets_ok = true; + host_ok_v6 = true; + else + print(" "..host.." AAAA record points to unknown address "..record.aaaa); + all_targets_ok = false; + end + end + end + + if not host_ok_v4 then + print(" Host "..host.." does not seem to resolve to this server for IPv4"); + end + if not host_ok_v6 and v6_supported then + print(" Host "..host.." does not seem to resolve to this server for IPv6"); + elseif host_ok_v6 and not v6_supported then + print(" Host "..host.." has AAAA records, but your version of LuaSocket does not support IPv6."); + print(" Please see http://prosody.im/doc/ipv6 for more information."); + end + end + if not all_targets_ok then + print(" "..(some_targets_ok and "Only some" or "No").." targets for "..host.." appear to resolve to this server."); + if is_component then + print(" DNS records are necessary if you want users on other servers to access this component."); + end + print(""); + problem_hosts:add(host); + end + end + if not problem_hosts:empty() then + print(""); + print("For more information about DNS configuration please see http://prosody.im/doc/dns"); + print(""); + ok = false; + end end if not ok then print("Problems found, see above."); -- cgit v1.2.3 From 3d22661def97ba52851d798e6795fd8f2460b61e Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 17 May 2013 14:55:05 +0100 Subject: prosodyctl: check dns: Correctly mark host as failed if expected SRV records are not found --- prosodyctl | 2 ++ 1 file changed, 2 insertions(+) (limited to 'prosodyctl') diff --git a/prosodyctl b/prosodyctl index d3ba8932..11c6296b 100755 --- a/prosodyctl +++ b/prosodyctl @@ -879,6 +879,7 @@ function commands.check(arg) else if c2s_srv_required then print(" No _xmpp-client SRV record found for "..host..", but it looks like you need one."); + all_targst_ok = false; else target_hosts:add(host); end @@ -895,6 +896,7 @@ function commands.check(arg) else if s2s_srv_required then print(" No _xmpp-server SRV record found for "..host..", but it looks like you need one."); + all_targets_ok = false; else target_hosts:add(host); end -- cgit v1.2.3 From 45e58c98b5e4602efaf1d24ec6d23d07d67b006a Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 17 May 2013 14:55:57 +0100 Subject: prosodyctl: check dns: More concise output (merged separate v4/v6 warnings) --- prosodyctl | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'prosodyctl') diff --git a/prosodyctl b/prosodyctl index 11c6296b..e0114e3a 100755 --- a/prosodyctl +++ b/prosodyctl @@ -937,12 +937,17 @@ function commands.check(arg) end end + local bad_protos = {} if not host_ok_v4 then - print(" Host "..host.." does not seem to resolve to this server for IPv4"); + table.insert(bad_protos, "IPv4"); end - if not host_ok_v6 and v6_supported then - print(" Host "..host.." does not seem to resolve to this server for IPv6"); - elseif host_ok_v6 and not v6_supported then + if not host_ok_v6 then + table.insert(bad_protos, "IPv6"); + end + if #bad_protos > 0 then + print(" Host "..host.." does not seem to resolve to this server ("..table.concat(bad_protos, "/")..")"); + end + if host_ok_v6 and not v6_supported then print(" Host "..host.." has AAAA records, but your version of LuaSocket does not support IPv6."); print(" Please see http://prosody.im/doc/ipv6 for more information."); end -- cgit v1.2.3 From ad9525152440cec194c1c3f8effae68a27e719d6 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 17 May 2013 14:56:18 +0100 Subject: prosodyctl: check dns: Whitespace fix in output --- prosodyctl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'prosodyctl') diff --git a/prosodyctl b/prosodyctl index e0114e3a..f5763f92 100755 --- a/prosodyctl +++ b/prosodyctl @@ -957,9 +957,9 @@ function commands.check(arg) if is_component then print(" DNS records are necessary if you want users on other servers to access this component."); end - print(""); problem_hosts:add(host); end + print(""); end if not problem_hosts:empty() then print(""); -- cgit v1.2.3 From 87c32db77c63f9ada68a7d612a1379286cf0f8c8 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 17 May 2013 14:56:36 +0100 Subject: prosodyctl: check dns: Use socket.local_addresses() if available --- prosodyctl | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'prosodyctl') diff --git a/prosodyctl b/prosodyctl index f5763f92..41f3b8dc 100755 --- a/prosodyctl +++ b/prosodyctl @@ -822,6 +822,7 @@ function commands.check(arg) end if not what or what == "dns" then local dns = require "net.dns"; + local ip = require "util.ip"; local c2s_ports = set.new(config.get("*", "c2s_ports") or {5222}); local s2s_ports = set.new(config.get("*", "s2s_ports") or {5269}); @@ -835,7 +836,7 @@ function commands.check(arg) local problem_hosts = set.new(); - local external_addresses = set.new(); + local external_addresses, internal_addresses = set.new(), set.new(); local fqdn = socket.dns.tohostname(socket.dns.gethostname()); if fqdn then @@ -853,6 +854,16 @@ function commands.check(arg) end end + local local_addresses = socket.local_addresses and socket.local_addresses() or {}; + + for addr in it.values(local_addresses) do + if not ip.new_ip(addr).private then + external_addresses:add(addr); + else + internal_addresses:add(addr); + end + end + if external_addresses:empty() then print(""); print(" Failed to determine the external addresses of this server. Checks may be inaccurate."); @@ -918,6 +929,10 @@ function commands.check(arg) if external_addresses:contains(record.a) then some_targets_ok = true; host_ok_v4 = true; + elseif internal_addresses:contains(record.a) then + host_ok_v4 = true; + some_targets_ok = true; + print(" "..host.." A record points to internal address, external connections might fail"); else print(" "..host.." A record points to unknown address "..record.a); all_targets_ok = false; @@ -930,6 +945,10 @@ function commands.check(arg) if external_addresses:contains(record.aaaa) then some_targets_ok = true; host_ok_v6 = true; + elseif internal_addresses:contains(record.aaaa) then + host_ok_v6 = true; + some_targets_ok = true; + print(" "..host.." AAAA record points to internal address, external connections might fail"); else print(" "..host.." AAAA record points to unknown address "..record.aaaa); all_targets_ok = false; -- cgit v1.2.3 From 8c3cb3971b29f84e8831f5ded9863cc282bfcde5 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Mon, 20 May 2013 15:33:57 +0100 Subject: prosodyctl: Use jid.split() to parse parameter to adduser/deluser/passwd --- prosodyctl | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'prosodyctl') diff --git a/prosodyctl b/prosodyctl index 41f3b8dc..780821be 100755 --- a/prosodyctl +++ b/prosodyctl @@ -274,11 +274,12 @@ local commands = {}; local command = arg[1]; function commands.adduser(arg) + local jid_split = require "util.jid".split; if not arg[1] or arg[1] == "--help" then show_usage([[adduser JID]], [[Create the specified user account in Prosody]]); return 1; end - local user, host = arg[1]:match("([^@]+)@(.+)"); + local user, host = jid_split(arg[1]); if not user and host then show_message [[Failed to understand JID, please supply the JID you want to create]] show_usage [[adduser user@host]] @@ -313,11 +314,12 @@ function commands.adduser(arg) end function commands.passwd(arg) + local jid_split = require "util.jid".split; if not arg[1] or arg[1] == "--help" then show_usage([[passwd JID]], [[Set the password for the specified user account in Prosody]]); return 1; end - local user, host = arg[1]:match("([^@]+)@(.+)"); + local user, host = jid_split(arg[1]); if not user and host then show_message [[Failed to understand JID, please supply the JID you want to set the password for]] show_usage [[passwd user@host]] @@ -352,11 +354,12 @@ function commands.passwd(arg) end function commands.deluser(arg) + local jid_split = require "util.jid".split; if not arg[1] or arg[1] == "--help" then show_usage([[deluser JID]], [[Permanently remove the specified user account from Prosody]]); return 1; end - local user, host = arg[1]:match("([^@]+)@(.+)"); + local user, host = jid_split(arg[1]); if not user and host then show_message [[Failed to understand JID, please supply the JID you want to set the password for]] show_usage [[passwd user@host]] -- cgit v1.2.3 From e0476bb4f1b46631ed4f71e1614f403bb87420da Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 21 May 2013 13:18:56 +0100 Subject: prosodyctl: check config: Show a suggestion to change hosts that begin with jabber/xmpp/chat/im subdomains, and link to DNS documentation --- prosodyctl | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'prosodyctl') diff --git a/prosodyctl b/prosodyctl index 780821be..de7c09c5 100755 --- a/prosodyctl +++ b/prosodyctl @@ -820,7 +820,15 @@ function commands.check(arg) print(""); print(" You need to move the following option"..(n>1 and "s" or "")..": "..table.concat(it.to_array(misplaced_options), ", ")); end + local subdomain = host:match("^[^.]+"); + if not(is_component) and (subdomain == "jabber" or subdomain == "xmpp" + or subdomain == "chat" or subdomain == "im") then + print(" Suggestion: If "..host.. " is a new host with no real users yet, consider renaming it now to"); + print(" "..host:gsub("^[^.]+%.", "")..". You can use SRV records to redirect XMPP clients and servers to "..host.."."); + print(" For more information see: http://prosody.im/doc/dns"); + end end + print("Done.\n"); end if not what or what == "dns" then -- cgit v1.2.3 From b0c86fe0553fdd69b150ee50e6265313f8b08f01 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 21 May 2013 13:21:12 +0100 Subject: prosodyctl: check config: whitespace fix --- prosodyctl | 1 + 1 file changed, 1 insertion(+) (limited to 'prosodyctl') diff --git a/prosodyctl b/prosodyctl index de7c09c5..5441b2b3 100755 --- a/prosodyctl +++ b/prosodyctl @@ -823,6 +823,7 @@ function commands.check(arg) local subdomain = host:match("^[^.]+"); if not(is_component) and (subdomain == "jabber" or subdomain == "xmpp" or subdomain == "chat" or subdomain == "im") then + print(""); print(" Suggestion: If "..host.. " is a new host with no real users yet, consider renaming it now to"); print(" "..host:gsub("^[^.]+%.", "")..". You can use SRV records to redirect XMPP clients and servers to "..host.."."); print(" For more information see: http://prosody.im/doc/dns"); -- cgit v1.2.3 From e6533b846352a28dd37578f1e366d8d61cd11622 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Wed, 22 May 2013 13:32:38 +0100 Subject: prosodyctl: check config: Fix check for whether host is a component --- prosodyctl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'prosodyctl') diff --git a/prosodyctl b/prosodyctl index 5441b2b3..c0f5dd92 100755 --- a/prosodyctl +++ b/prosodyctl @@ -821,7 +821,7 @@ function commands.check(arg) print(" You need to move the following option"..(n>1 and "s" or "")..": "..table.concat(it.to_array(misplaced_options), ", ")); end local subdomain = host:match("^[^.]+"); - if not(is_component) and (subdomain == "jabber" or subdomain == "xmpp" + if not(host_options:contains("component_module")) and (subdomain == "jabber" or subdomain == "xmpp" or subdomain == "chat" or subdomain == "im") then print(""); print(" Suggestion: If "..host.. " is a new host with no real users yet, consider renaming it now to"); -- cgit v1.2.3 From a8da45a1b9aca9dae8e2d9ceeb491815716df340 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Wed, 22 May 2013 13:33:33 +0100 Subject: prosodyctl: check dns: Add check that proxy65 addresses resolve correctly --- prosodyctl | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'prosodyctl') diff --git a/prosodyctl b/prosodyctl index c0f5dd92..4d7f678f 100755 --- a/prosodyctl +++ b/prosodyctl @@ -933,6 +933,25 @@ function commands.check(arg) target_hosts:remove("localhost"); end + local modules = set.new(it.to_array(it.values(host_options.modules_enabled))) + + set.new(it.to_array(it.values(config.get("*", "modules_enabled")))) + + set.new({ config.get(host, "component_module") }); + + if modules:contains("proxy65") then + local proxy65_target = config.get(host, "proxy65_address") or host; + local A, AAAA = dns.lookup(proxy65_target, "A"), dns.lookup(proxy65_target, "AAAA"); + local prob = {}; + if not A then + table.insert(prob, "A"); + end + if v6_supported and not AAAA then + table.insert(prob, "AAAA"); + end + if #prob > 0 then + print(" File transfer proxy "..proxy65_target.." has no "..table.concat(prob, "/").." record. Create one or set 'proxy65_address' to the correct host/IP."); + end + end + for host in target_hosts do local host_ok_v4, host_ok_v6; local res = dns.lookup(host, "A"); -- cgit v1.2.3 From e626df2fc20257eb9e96fb9cfcfc22df10e044c9 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 7 Jun 2013 20:05:23 +0200 Subject: prosodyctl: Add 'prosodyctl check --help' --- prosodyctl | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'prosodyctl') diff --git a/prosodyctl b/prosodyctl index 4d7f678f..47273014 100755 --- a/prosodyctl +++ b/prosodyctl @@ -780,6 +780,10 @@ function commands.cert(arg) end function commands.check(arg) + if arg[1] == "--help" then + show_usage([[check]], [[Perform basic checks on your Prosody installation]]); + return 1; + end local what = table.remove(arg, 1); local array, set = require "util.array", require "util.set"; local it = require "util.iterators"; -- cgit v1.2.3 From 192d4df580039eedb58e804604874c596b2eca77 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 7 Jun 2013 20:59:43 +0200 Subject: prosodyctl: Add 'prosodyctl check certs' for validating TLS/SSL certificates --- prosodyctl | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) (limited to 'prosodyctl') diff --git a/prosodyctl b/prosodyctl index 47273014..aa6f2073 100755 --- a/prosodyctl +++ b/prosodyctl @@ -1022,6 +1022,81 @@ function commands.check(arg) ok = false; end end + if not what or what == "certs" then + local cert_ok; + print"Checking certificates..." + 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; + -- or ssl.cert_from_pem + if not ssl then + print("LuaSec not available, can't perform certificate checks") + if what == "certs" then cert_ok = false end + elseif not load_cert then + print("This version of LuaSec (" .. ssl._VERSION .. ") does not support certificate checking"); + cert_ok = false + else + for host in pairs(hosts) do + if host ~= "*" then -- Should check global certs too. + print("Checking certificate for "..host); + -- First, let's find out what certificate this host uses. + local ssl_config = config.rawget(host, "ssl"); + if not ssl_config then + local base_host = host:match("%.(.*)"); + ssl_config = config.get(base_host, "ssl"); + end + if not ssl_config then + print(" No 'ssl' option defined for "..host) + cert_ok = false + elseif not ssl_config.certificate then + print(" No 'certificate' set in ssl option for "..host) + cert_ok = false + elseif not ssl_config.key then + print(" No 'key' set in ssl option for "..host) + cert_ok = false + else + local key, err = io.open(ssl_config.key); -- Permissions check only + if not key then + print(" Could not open "..ssl_config.key..": "..err); + cert_ok = false + else + key:close(); + end + local cert_fh, err = io.open(ssl_config.certificate); -- Load the file. + if not cert_fh then + print(" Could not open "..ssl_config.certificate..": "..err); + cert_ok = false + else + print(" Certificate: "..ssl_config.certificate) + local cert = load_cert(cert_fh:read"*a"); cert_fh = cert_fh:close(); + if not cert:validat(os.time()) then + print(" Certificate has expired.") + cert_ok = false + end + if config.get(host, "component_module") == nil + and not x509_verify_identity(host, "_xmpp-client", cert) then + print(" Not vaild for client connections to "..host..".") + cert_ok = false + end + if (not (config.get(name, "anonymous_login") + or config.get(name, "authentication") == "anonymous")) + and not x509_verify_identity(host, "_xmpp-client", cert) then + print(" Not vaild for server-to-server connections to "..host..".") + cert_ok = false + end + end + end + end + end + if cert_ok == false then + print("") + print("For more information about certificates please see http://prosody.im/doc/certificates"); + ok = false + end + end + print("") + end if not ok then print("Problems found, see above."); else -- cgit v1.2.3