Changeset

12104:29765ac7f72f

prosodyctl cert: use the indexing functions for better UX These provide (a) a way to deal with random assortments of certs and (b) avoid unnecessary error messages and warnings, according to #1669 anyway, which this fixes.
author Jonas Schäfer <jonas@wielicki.name>
date Tue, 21 Dec 2021 21:20:21 +0100
parents 12103:fc297128c33a
children 12105:47c9a76cce7d
files core/certmanager.lua util/prosodyctl/cert.lua
diffstat 2 files changed, 29 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/core/certmanager.lua	Tue Dec 21 14:23:09 2021 +0100
+++ b/core/certmanager.lua	Tue Dec 21 21:20:21 2021 +0100
@@ -167,12 +167,10 @@
 
 local cert_index;
 
-local function find_host_cert(host)
+local function find_cert_in_index(index, host)
 	if not host then return nil; end
-	if not cert_index then
-		cert_index = index_certs(resolve_path(config_path, global_certificates));
-	end
-	local certs = cert_index[host];
+	if not index then return nil; end
+	local certs = index[host];
 	if certs then
 		local cert_filename, services = next(certs);
 		if services["*"] then
@@ -183,8 +181,16 @@
 			}
 		end
 	end
+	return nil
+end
 
-	return find_cert(configmanager.get(host, "certificate"), host) or find_host_cert(host:match("%.(.+)$"));
+local function find_host_cert(host)
+	if not host then return nil; end
+	if not cert_index then
+		cert_index = index_certs(resolve_path(config_path, global_certificates));
+	end
+
+	return find_cert_in_index(cert_index, host) or find_cert(configmanager.get(host, "certificate"), host) or find_host_cert(host:match("%.(.+)$"));
 end
 
 local function find_service_cert(service, port)
@@ -439,5 +445,7 @@
 	create_context = create_context;
 	reload_ssl_config = reload_ssl_config;
 	find_cert = find_cert;
+	index_certs = index_certs;
 	find_host_cert = find_host_cert;
+	find_cert_in_index = find_cert_in_index;
 };
--- a/util/prosodyctl/cert.lua	Tue Dec 21 14:23:09 2021 +0100
+++ b/util/prosodyctl/cert.lua	Tue Dec 21 21:20:21 2021 +0100
@@ -216,22 +216,24 @@
 		group = configmanager.get("*", "prosody_group") or owner;
 	end
 	local cm = require "core.certmanager";
+	local files_by_name = {}
+	for _, dir in ipairs(arg) do
+		cm.index_certs(dir, files_by_name);
+	end
 	local imported = {};
 	for _, host in ipairs(hostnames) do
-		for _, dir in ipairs(arg) do
-			local paths = cm.find_cert(dir, host);
-			if paths then
-				copy(paths.certificate, cert_basedir .. "/" .. host .. ".crt", nil, owner, group);
-				copy(paths.key, cert_basedir .. "/" .. host .. ".key", "0377", owner, group);
-				table.insert(imported, host);
-			else
-				-- TODO Say where we looked
-				pctl.show_warning("No certificate for host "..host.." found :(");
-			end
-			-- TODO Additional checks
-			-- Certificate names matches the hostname
-			-- Private key matches public key in certificate
+		local paths = cm.find_cert_in_index(files_by_name, host);
+		if paths then
+			copy(paths.certificate, cert_basedir .. "/" .. host .. ".crt", nil, owner, group);
+			copy(paths.key, cert_basedir .. "/" .. host .. ".key", "0377", owner, group);
+			table.insert(imported, host);
+		else
+			-- TODO Say where we looked
+			pctl.show_warning("No certificate for host "..host.." found :(");
 		end
+		-- TODO Additional checks
+		-- Certificate names matches the hostname
+		-- Private key matches public key in certificate
 	end
 	if imported[1] then
 		pctl.show_message("Imported certificate and key for hosts %s", table.concat(imported, ", "));