Software / code / prosody
Comparison
util/prosodyctl/check.lua @ 10871:e5dee71d0ebb
prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Tue, 02 Jun 2020 08:01:21 +0100 |
| child | 10932:ea4a7619058f |
comparison
equal
deleted
inserted
replaced
| 10870:3f1889608f3e | 10871:e5dee71d0ebb |
|---|---|
| 1 local configmanager = require "core.configmanager"; | |
| 2 local show_usage = require "util.prosodyctl".show_usage; | |
| 3 local show_warning = require "util.prosodyctl".show_warning; | |
| 4 local dependencies = require "util.dependencies"; | |
| 5 local socket = require "socket"; | |
| 6 local jid_split = require "util.jid".prepped_split; | |
| 7 local modulemanager = require "core.modulemanager"; | |
| 8 | |
| 9 local function check(arg) | |
| 10 if arg[1] == "--help" then | |
| 11 show_usage([[check]], [[Perform basic checks on your Prosody installation]]); | |
| 12 return 1; | |
| 13 end | |
| 14 local what = table.remove(arg, 1); | |
| 15 local set = require "util.set"; | |
| 16 local it = require "util.iterators"; | |
| 17 local ok = true; | |
| 18 local function disabled_hosts(host, conf) return host ~= "*" and conf.enabled ~= false; end | |
| 19 local function enabled_hosts() return it.filter(disabled_hosts, pairs(configmanager.getconfig())); end | |
| 20 if not (what == nil or what == "disabled" or what == "config" or what == "dns" or what == "certs") then | |
| 21 show_warning("Don't know how to check '%s'. Try one of 'config', 'dns', 'certs' or 'disabled'.", what); | |
| 22 return 1; | |
| 23 end | |
| 24 if not what or what == "disabled" then | |
| 25 local disabled_hosts_set = set.new(); | |
| 26 for host, host_options in it.filter("*", pairs(configmanager.getconfig())) do | |
| 27 if host_options.enabled == false then | |
| 28 disabled_hosts_set:add(host); | |
| 29 end | |
| 30 end | |
| 31 if not disabled_hosts_set:empty() then | |
| 32 local msg = "Checks will be skipped for these disabled hosts: %s"; | |
| 33 if what then msg = "These hosts are disabled: %s"; end | |
| 34 show_warning(msg, tostring(disabled_hosts_set)); | |
| 35 if what then return 0; end | |
| 36 print"" | |
| 37 end | |
| 38 end | |
| 39 if not what or what == "config" then | |
| 40 print("Checking config..."); | |
| 41 local deprecated = set.new({ | |
| 42 "bosh_ports", "disallow_s2s", "no_daemonize", "anonymous_login", "require_encryption", | |
| 43 "vcard_compatibility", "cross_domain_bosh", "cross_domain_websocket", "daemonize", | |
| 44 }); | |
| 45 local known_global_options = set.new({ | |
| 46 "pidfile", "log", "plugin_paths", "prosody_user", "prosody_group", "daemonize", | |
| 47 "umask", "prosodyctl_timeout", "use_ipv6", "use_libevent", "network_settings", | |
| 48 "network_backend", "http_default_host", | |
| 49 "statistics_interval", "statistics", "statistics_config", | |
| 50 }); | |
| 51 local config = configmanager.getconfig(); | |
| 52 -- Check that we have any global options (caused by putting a host at the top) | |
| 53 if it.count(it.filter("log", pairs(config["*"]))) == 0 then | |
| 54 ok = false; | |
| 55 print(""); | |
| 56 print(" No global options defined. Perhaps you have put a host definition at the top") | |
| 57 print(" of the config file? They should be at the bottom, see https://prosody.im/doc/configure#overview"); | |
| 58 end | |
| 59 if it.count(enabled_hosts()) == 0 then | |
| 60 ok = false; | |
| 61 print(""); | |
| 62 if it.count(it.filter("*", pairs(config))) == 0 then | |
| 63 print(" No hosts are defined, please add at least one VirtualHost section") | |
| 64 elseif config["*"]["enabled"] == false then | |
| 65 print(" No hosts are enabled. Remove enabled = false from the global section or put enabled = true under at least one VirtualHost section") | |
| 66 else | |
| 67 print(" All hosts are disabled. Remove enabled = false from at least one VirtualHost section") | |
| 68 end | |
| 69 end | |
| 70 if not config["*"].modules_enabled then | |
| 71 print(" No global modules_enabled is set?"); | |
| 72 local suggested_global_modules; | |
| 73 for host, options in enabled_hosts() do --luacheck: ignore 213/host | |
| 74 if not options.component_module and options.modules_enabled then | |
| 75 suggested_global_modules = set.intersection(suggested_global_modules or set.new(options.modules_enabled), set.new(options.modules_enabled)); | |
| 76 end | |
| 77 end | |
| 78 if suggested_global_modules and not suggested_global_modules:empty() then | |
| 79 print(" Consider moving these modules into modules_enabled in the global section:") | |
| 80 print(" "..tostring(suggested_global_modules / function (x) return ("%q"):format(x) end)); | |
| 81 end | |
| 82 print(); | |
| 83 end | |
| 84 | |
| 85 do -- Check for modules enabled both normally and as components | |
| 86 local modules = set.new(config["*"]["modules_enabled"]); | |
| 87 for host, options in enabled_hosts() do | |
| 88 local component_module = options.component_module; | |
| 89 if component_module and modules:contains(component_module) then | |
| 90 print((" mod_%s is enabled both in modules_enabled and as Component %q %q"):format(component_module, host, component_module)); | |
| 91 print(" This means the service is enabled on all VirtualHosts as well as the Component."); | |
| 92 print(" Are you sure this what you want? It may cause unexpected behaviour."); | |
| 93 end | |
| 94 end | |
| 95 end | |
| 96 | |
| 97 -- Check for global options under hosts | |
| 98 local global_options = set.new(it.to_array(it.keys(config["*"]))); | |
| 99 local deprecated_global_options = set.intersection(global_options, deprecated); | |
| 100 if not deprecated_global_options:empty() then | |
| 101 print(""); | |
| 102 print(" You have some deprecated options in the global section:"); | |
| 103 print(" "..tostring(deprecated_global_options)) | |
| 104 ok = false; | |
| 105 end | |
| 106 for host, options in it.filter(function (h) return h ~= "*" end, pairs(configmanager.getconfig())) do | |
| 107 local host_options = set.new(it.to_array(it.keys(options))); | |
| 108 local misplaced_options = set.intersection(host_options, known_global_options); | |
| 109 for name in pairs(options) do | |
| 110 if name:match("^interfaces?") | |
| 111 or name:match("_ports?$") or name:match("_interfaces?$") | |
| 112 or (name:match("_ssl$") and not name:match("^[cs]2s_ssl$")) then | |
| 113 misplaced_options:add(name); | |
| 114 end | |
| 115 end | |
| 116 if not misplaced_options:empty() then | |
| 117 ok = false; | |
| 118 print(""); | |
| 119 local n = it.count(misplaced_options); | |
| 120 print(" You have "..n.." option"..(n>1 and "s " or " ").."set under "..host.." that should be"); | |
| 121 print(" in the global section of the config file, above any VirtualHost or Component definitions,") | |
| 122 print(" see https://prosody.im/doc/configure#overview for more information.") | |
| 123 print(""); | |
| 124 print(" You need to move the following option"..(n>1 and "s" or "")..": "..table.concat(it.to_array(misplaced_options), ", ")); | |
| 125 end | |
| 126 end | |
| 127 for host, options in enabled_hosts() do | |
| 128 local host_options = set.new(it.to_array(it.keys(options))); | |
| 129 local subdomain = host:match("^[^.]+"); | |
| 130 if not(host_options:contains("component_module")) and (subdomain == "jabber" or subdomain == "xmpp" | |
| 131 or subdomain == "chat" or subdomain == "im") then | |
| 132 print(""); | |
| 133 print(" Suggestion: If "..host.. " is a new host with no real users yet, consider renaming it now to"); | |
| 134 print(" "..host:gsub("^[^.]+%.", "")..". You can use SRV records to redirect XMPP clients and servers to "..host.."."); | |
| 135 print(" For more information see: https://prosody.im/doc/dns"); | |
| 136 end | |
| 137 end | |
| 138 local all_modules = set.new(config["*"].modules_enabled); | |
| 139 local all_options = set.new(it.to_array(it.keys(config["*"]))); | |
| 140 for host in enabled_hosts() do | |
| 141 all_options:include(set.new(it.to_array(it.keys(config[host])))); | |
| 142 all_modules:include(set.new(config[host].modules_enabled)); | |
| 143 end | |
| 144 for mod in all_modules do | |
| 145 if mod:match("^mod_") then | |
| 146 print(""); | |
| 147 print(" Modules in modules_enabled should not have the 'mod_' prefix included."); | |
| 148 print(" Change '"..mod.."' to '"..mod:match("^mod_(.*)").."'."); | |
| 149 elseif mod:match("^auth_") then | |
| 150 print(""); | |
| 151 print(" Authentication modules should not be added to modules_enabled,"); | |
| 152 print(" but be specified in the 'authentication' option."); | |
| 153 print(" Remove '"..mod.."' from modules_enabled and instead add"); | |
| 154 print(" authentication = '"..mod:match("^auth_(.*)").."'"); | |
| 155 print(" For more information see https://prosody.im/doc/authentication"); | |
| 156 elseif mod:match("^storage_") then | |
| 157 print(""); | |
| 158 print(" storage modules should not be added to modules_enabled,"); | |
| 159 print(" but be specified in the 'storage' option."); | |
| 160 print(" Remove '"..mod.."' from modules_enabled and instead add"); | |
| 161 print(" storage = '"..mod:match("^storage_(.*)").."'"); | |
| 162 print(" For more information see https://prosody.im/doc/storage"); | |
| 163 end | |
| 164 end | |
| 165 if all_modules:contains("vcard") and all_modules:contains("vcard_legacy") then | |
| 166 print(""); | |
| 167 print(" Both mod_vcard_legacy and mod_vcard are enabled but they conflict"); | |
| 168 print(" with each other. Remove one."); | |
| 169 end | |
| 170 if all_modules:contains("pep") and all_modules:contains("pep_simple") then | |
| 171 print(""); | |
| 172 print(" Both mod_pep_simple and mod_pep are enabled but they conflict"); | |
| 173 print(" with each other. Remove one."); | |
| 174 end | |
| 175 for host, host_config in pairs(config) do --luacheck: ignore 213/host | |
| 176 if type(rawget(host_config, "storage")) == "string" and rawget(host_config, "default_storage") then | |
| 177 print(""); | |
| 178 print(" The 'default_storage' option is not needed if 'storage' is set to a string."); | |
| 179 break; | |
| 180 end | |
| 181 end | |
| 182 local require_encryption = set.intersection(all_options, set.new({ | |
| 183 "require_encryption", "c2s_require_encryption", "s2s_require_encryption" | |
| 184 })):empty(); | |
| 185 local ssl = dependencies.softreq"ssl"; | |
| 186 if not ssl then | |
| 187 if not require_encryption then | |
| 188 print(""); | |
| 189 print(" You require encryption but LuaSec is not available."); | |
| 190 print(" Connections will fail."); | |
| 191 ok = false; | |
| 192 end | |
| 193 elseif not ssl.loadcertificate then | |
| 194 if all_options:contains("s2s_secure_auth") then | |
| 195 print(""); | |
| 196 print(" You have set s2s_secure_auth but your version of LuaSec does "); | |
| 197 print(" not support certificate validation, so all s2s connections will"); | |
| 198 print(" fail."); | |
| 199 ok = false; | |
| 200 elseif all_options:contains("s2s_secure_domains") then | |
| 201 local secure_domains = set.new(); | |
| 202 for host in enabled_hosts() do | |
| 203 if config[host].s2s_secure_auth == true then | |
| 204 secure_domains:add("*"); | |
| 205 else | |
| 206 secure_domains:include(set.new(config[host].s2s_secure_domains)); | |
| 207 end | |
| 208 end | |
| 209 if not secure_domains:empty() then | |
| 210 print(""); | |
| 211 print(" You have set s2s_secure_domains but your version of LuaSec does "); | |
| 212 print(" not support certificate validation, so s2s connections to/from "); | |
| 213 print(" these domains will fail."); | |
| 214 ok = false; | |
| 215 end | |
| 216 end | |
| 217 elseif require_encryption and not all_modules:contains("tls") then | |
| 218 print(""); | |
| 219 print(" You require encryption but mod_tls is not enabled."); | |
| 220 print(" Connections will fail."); | |
| 221 ok = false; | |
| 222 end | |
| 223 | |
| 224 print("Done.\n"); | |
| 225 end | |
| 226 if not what or what == "dns" then | |
| 227 local dns = require "net.dns"; | |
| 228 local idna = require "util.encodings".idna; | |
| 229 local ip = require "util.ip"; | |
| 230 local c2s_ports = set.new(configmanager.get("*", "c2s_ports") or {5222}); | |
| 231 local s2s_ports = set.new(configmanager.get("*", "s2s_ports") or {5269}); | |
| 232 | |
| 233 local c2s_srv_required, s2s_srv_required; | |
| 234 if not c2s_ports:contains(5222) then | |
| 235 c2s_srv_required = true; | |
| 236 end | |
| 237 if not s2s_ports:contains(5269) then | |
| 238 s2s_srv_required = true; | |
| 239 end | |
| 240 | |
| 241 local problem_hosts = set.new(); | |
| 242 | |
| 243 local external_addresses, internal_addresses = set.new(), set.new(); | |
| 244 | |
| 245 local fqdn = socket.dns.tohostname(socket.dns.gethostname()); | |
| 246 if fqdn then | |
| 247 do | |
| 248 local res = dns.lookup(idna.to_ascii(fqdn), "A"); | |
| 249 if res then | |
| 250 for _, record in ipairs(res) do | |
| 251 external_addresses:add(record.a); | |
| 252 end | |
| 253 end | |
| 254 end | |
| 255 do | |
| 256 local res = dns.lookup(idna.to_ascii(fqdn), "AAAA"); | |
| 257 if res then | |
| 258 for _, record in ipairs(res) do | |
| 259 external_addresses:add(record.aaaa); | |
| 260 end | |
| 261 end | |
| 262 end | |
| 263 end | |
| 264 | |
| 265 local local_addresses = require"util.net".local_addresses() or {}; | |
| 266 | |
| 267 for addr in it.values(local_addresses) do | |
| 268 if not ip.new_ip(addr).private then | |
| 269 external_addresses:add(addr); | |
| 270 else | |
| 271 internal_addresses:add(addr); | |
| 272 end | |
| 273 end | |
| 274 | |
| 275 if external_addresses:empty() then | |
| 276 print(""); | |
| 277 print(" Failed to determine the external addresses of this server. Checks may be inaccurate."); | |
| 278 c2s_srv_required, s2s_srv_required = true, true; | |
| 279 end | |
| 280 | |
| 281 local v6_supported = not not socket.tcp6; | |
| 282 | |
| 283 for jid, host_options in enabled_hosts() do | |
| 284 local all_targets_ok, some_targets_ok = true, false; | |
| 285 local node, host = jid_split(jid); | |
| 286 | |
| 287 local modules, component_module = modulemanager.get_modules_for_host(host); | |
| 288 if component_module then | |
| 289 modules:add(component_module); | |
| 290 end | |
| 291 | |
| 292 local is_component = not not host_options.component_module; | |
| 293 print("Checking DNS for "..(is_component and "component" or "host").." "..jid.."..."); | |
| 294 if node then | |
| 295 print("Only the domain part ("..host..") is used in DNS.") | |
| 296 end | |
| 297 local target_hosts = set.new(); | |
| 298 if modules:contains("c2s") then | |
| 299 local res = dns.lookup("_xmpp-client._tcp."..idna.to_ascii(host)..".", "SRV"); | |
| 300 if res then | |
| 301 for _, record in ipairs(res) do | |
| 302 target_hosts:add(record.srv.target); | |
| 303 if not c2s_ports:contains(record.srv.port) then | |
| 304 print(" SRV target "..record.srv.target.." contains unknown client port: "..record.srv.port); | |
| 305 end | |
| 306 end | |
| 307 else | |
| 308 if c2s_srv_required then | |
| 309 print(" No _xmpp-client SRV record found for "..host..", but it looks like you need one."); | |
| 310 all_targets_ok = false; | |
| 311 else | |
| 312 target_hosts:add(host); | |
| 313 end | |
| 314 end | |
| 315 end | |
| 316 if modules:contains("s2s") then | |
| 317 local res = dns.lookup("_xmpp-server._tcp."..idna.to_ascii(host)..".", "SRV"); | |
| 318 if res then | |
| 319 for _, record in ipairs(res) do | |
| 320 target_hosts:add(record.srv.target); | |
| 321 if not s2s_ports:contains(record.srv.port) then | |
| 322 print(" SRV target "..record.srv.target.." contains unknown server port: "..record.srv.port); | |
| 323 end | |
| 324 end | |
| 325 else | |
| 326 if s2s_srv_required then | |
| 327 print(" No _xmpp-server SRV record found for "..host..", but it looks like you need one."); | |
| 328 all_targets_ok = false; | |
| 329 else | |
| 330 target_hosts:add(host); | |
| 331 end | |
| 332 end | |
| 333 end | |
| 334 if target_hosts:empty() then | |
| 335 target_hosts:add(host); | |
| 336 end | |
| 337 | |
| 338 if target_hosts:contains("localhost") then | |
| 339 print(" Target 'localhost' cannot be accessed from other servers"); | |
| 340 target_hosts:remove("localhost"); | |
| 341 end | |
| 342 | |
| 343 if modules:contains("proxy65") then | |
| 344 local proxy65_target = configmanager.get(host, "proxy65_address") or host; | |
| 345 if type(proxy65_target) == "string" then | |
| 346 local A, AAAA = dns.lookup(idna.to_ascii(proxy65_target), "A"), dns.lookup(idna.to_ascii(proxy65_target), "AAAA"); | |
| 347 local prob = {}; | |
| 348 if not A then | |
| 349 table.insert(prob, "A"); | |
| 350 end | |
| 351 if v6_supported and not AAAA then | |
| 352 table.insert(prob, "AAAA"); | |
| 353 end | |
| 354 if #prob > 0 then | |
| 355 print(" File transfer proxy "..proxy65_target.." has no "..table.concat(prob, "/") | |
| 356 .." record. Create one or set 'proxy65_address' to the correct host/IP."); | |
| 357 end | |
| 358 else | |
| 359 print(" proxy65_address for "..host.." should be set to a string, unable to perform DNS check"); | |
| 360 end | |
| 361 end | |
| 362 | |
| 363 for target_host in target_hosts do | |
| 364 local host_ok_v4, host_ok_v6; | |
| 365 do | |
| 366 local res = dns.lookup(idna.to_ascii(target_host), "A"); | |
| 367 if res then | |
| 368 for _, record in ipairs(res) do | |
| 369 if external_addresses:contains(record.a) then | |
| 370 some_targets_ok = true; | |
| 371 host_ok_v4 = true; | |
| 372 elseif internal_addresses:contains(record.a) then | |
| 373 host_ok_v4 = true; | |
| 374 some_targets_ok = true; | |
| 375 print(" "..target_host.." A record points to internal address, external connections might fail"); | |
| 376 else | |
| 377 print(" "..target_host.." A record points to unknown address "..record.a); | |
| 378 all_targets_ok = false; | |
| 379 end | |
| 380 end | |
| 381 end | |
| 382 end | |
| 383 do | |
| 384 local res = dns.lookup(idna.to_ascii(target_host), "AAAA"); | |
| 385 if res then | |
| 386 for _, record in ipairs(res) do | |
| 387 if external_addresses:contains(record.aaaa) then | |
| 388 some_targets_ok = true; | |
| 389 host_ok_v6 = true; | |
| 390 elseif internal_addresses:contains(record.aaaa) then | |
| 391 host_ok_v6 = true; | |
| 392 some_targets_ok = true; | |
| 393 print(" "..target_host.." AAAA record points to internal address, external connections might fail"); | |
| 394 else | |
| 395 print(" "..target_host.." AAAA record points to unknown address "..record.aaaa); | |
| 396 all_targets_ok = false; | |
| 397 end | |
| 398 end | |
| 399 end | |
| 400 end | |
| 401 | |
| 402 local bad_protos = {} | |
| 403 if not host_ok_v4 then | |
| 404 table.insert(bad_protos, "IPv4"); | |
| 405 end | |
| 406 if not host_ok_v6 then | |
| 407 table.insert(bad_protos, "IPv6"); | |
| 408 end | |
| 409 if #bad_protos > 0 then | |
| 410 print(" Host "..target_host.." does not seem to resolve to this server ("..table.concat(bad_protos, "/")..")"); | |
| 411 end | |
| 412 if host_ok_v6 and not v6_supported then | |
| 413 print(" Host "..target_host.." has AAAA records, but your version of LuaSocket does not support IPv6."); | |
| 414 print(" Please see https://prosody.im/doc/ipv6 for more information."); | |
| 415 end | |
| 416 end | |
| 417 if not all_targets_ok then | |
| 418 print(" "..(some_targets_ok and "Only some" or "No").." targets for "..host.." appear to resolve to this server."); | |
| 419 if is_component then | |
| 420 print(" DNS records are necessary if you want users on other servers to access this component."); | |
| 421 end | |
| 422 problem_hosts:add(host); | |
| 423 end | |
| 424 print(""); | |
| 425 end | |
| 426 if not problem_hosts:empty() then | |
| 427 print(""); | |
| 428 print("For more information about DNS configuration please see https://prosody.im/doc/dns"); | |
| 429 print(""); | |
| 430 ok = false; | |
| 431 end | |
| 432 end | |
| 433 if not what or what == "certs" then | |
| 434 local cert_ok; | |
| 435 print"Checking certificates..." | |
| 436 local x509_verify_identity = require"util.x509".verify_identity; | |
| 437 local create_context = require "core.certmanager".create_context; | |
| 438 local ssl = dependencies.softreq"ssl"; | |
| 439 -- local datetime_parse = require"util.datetime".parse_x509; | |
| 440 local load_cert = ssl and ssl.loadcertificate; | |
| 441 -- or ssl.cert_from_pem | |
| 442 if not ssl then | |
| 443 print("LuaSec not available, can't perform certificate checks") | |
| 444 if what == "certs" then cert_ok = false end | |
| 445 elseif not load_cert then | |
| 446 print("This version of LuaSec (" .. ssl._VERSION .. ") does not support certificate checking"); | |
| 447 cert_ok = false | |
| 448 else | |
| 449 local function skip_bare_jid_hosts(host) | |
| 450 if jid_split(host) then | |
| 451 -- See issue #779 | |
| 452 return false; | |
| 453 end | |
| 454 return true; | |
| 455 end | |
| 456 for host in it.filter(skip_bare_jid_hosts, enabled_hosts()) do | |
| 457 print("Checking certificate for "..host); | |
| 458 -- First, let's find out what certificate this host uses. | |
| 459 local host_ssl_config = configmanager.rawget(host, "ssl") | |
| 460 or configmanager.rawget(host:match("%.(.*)"), "ssl"); | |
| 461 local global_ssl_config = configmanager.rawget("*", "ssl"); | |
| 462 local ok, err, ssl_config = create_context(host, "server", host_ssl_config, global_ssl_config); | |
| 463 if not ok then | |
| 464 print(" Error: "..err); | |
| 465 cert_ok = false | |
| 466 elseif not ssl_config.certificate then | |
| 467 print(" No 'certificate' found for "..host) | |
| 468 cert_ok = false | |
| 469 elseif not ssl_config.key then | |
| 470 print(" No 'key' found for "..host) | |
| 471 cert_ok = false | |
| 472 else | |
| 473 local key, err = io.open(ssl_config.key); -- Permissions check only | |
| 474 if not key then | |
| 475 print(" Could not open "..ssl_config.key..": "..err); | |
| 476 cert_ok = false | |
| 477 else | |
| 478 key:close(); | |
| 479 end | |
| 480 local cert_fh, err = io.open(ssl_config.certificate); -- Load the file. | |
| 481 if not cert_fh then | |
| 482 print(" Could not open "..ssl_config.certificate..": "..err); | |
| 483 cert_ok = false | |
| 484 else | |
| 485 print(" Certificate: "..ssl_config.certificate) | |
| 486 local cert = load_cert(cert_fh:read"*a"); cert_fh:close(); | |
| 487 if not cert:validat(os.time()) then | |
| 488 print(" Certificate has expired.") | |
| 489 cert_ok = false | |
| 490 elseif not cert:validat(os.time() + 86400) then | |
| 491 print(" Certificate expires within one day.") | |
| 492 cert_ok = false | |
| 493 elseif not cert:validat(os.time() + 86400*7) then | |
| 494 print(" Certificate expires within one week.") | |
| 495 elseif not cert:validat(os.time() + 86400*31) then | |
| 496 print(" Certificate expires within one month.") | |
| 497 end | |
| 498 if configmanager.get(host, "component_module") == nil | |
| 499 and not x509_verify_identity(host, "_xmpp-client", cert) then | |
| 500 print(" Not valid for client connections to "..host..".") | |
| 501 cert_ok = false | |
| 502 end | |
| 503 if (not (configmanager.get(host, "anonymous_login") | |
| 504 or configmanager.get(host, "authentication") == "anonymous")) | |
| 505 and not x509_verify_identity(host, "_xmpp-server", cert) then | |
| 506 print(" Not valid for server-to-server connections to "..host..".") | |
| 507 cert_ok = false | |
| 508 end | |
| 509 end | |
| 510 end | |
| 511 end | |
| 512 end | |
| 513 if cert_ok == false then | |
| 514 print("") | |
| 515 print("For more information about certificates please see https://prosody.im/doc/certificates"); | |
| 516 ok = false | |
| 517 end | |
| 518 print("") | |
| 519 end | |
| 520 if not ok then | |
| 521 print("Problems found, see above."); | |
| 522 else | |
| 523 print("All checks passed, congratulations!"); | |
| 524 end | |
| 525 return ok and 0 or 2; | |
| 526 end | |
| 527 | |
| 528 return { | |
| 529 check = check; | |
| 530 }; |