comparison core/portmanager.lua @ 13792:4ea7bd7325be 13.0

core.portmanager: Restore use of per-host 'ssl' for SNI hosts. Fixes #1915. This was an unintentional regression, as per-host 'ssl' options became valid in 0.12 when SNI support was added for direct TLS ports. While we encourage most people to use the simpler automatic certificate selection (and it seems most do, given the overlooking of this bug), there are likely always going to be use cases for manually-configured certificates. The issue was introduced in commit 7e9ebdc75ce4 which inadvertently removed the per-host option checking for SNI.
author Kim Alvefur <zash@zash.se>
date Sat, 29 Mar 2025 22:25:19 +0100
parents 140f7926946b
children 21c58b1d5b47
comparison
equal deleted inserted replaced
13790:24252947a8ca 13792:4ea7bd7325be
243 local function add_sni_host(host, service) 243 local function add_sni_host(host, service)
244 log("debug", "Gathering certificates for SNI for host %s, %s service", host, service or "default"); 244 log("debug", "Gathering certificates for SNI for host %s, %s service", host, service or "default");
245 for name, interface, port, n, active_service --luacheck: ignore 213 245 for name, interface, port, n, active_service --luacheck: ignore 213
246 in active_services:iter(service, nil, nil, nil) do 246 in active_services:iter(service, nil, nil, nil) do
247 if active_service.server and active_service.tls_cfg then 247 if active_service.server and active_service.tls_cfg then
248 local config_prefix = (active_service.config_prefix or name).."_";
249 if config_prefix == "_" then config_prefix = ""; end
250 local prefix_ssl_config = config.get(host, config_prefix.."ssl");
248 local alternate_host = name and config.get(host, name.."_host"); 251 local alternate_host = name and config.get(host, name.."_host");
249 if not alternate_host and name == "https" then 252 if not alternate_host and name == "https" then
250 -- TODO should this be some generic thing? e.g. in the service definition 253 -- TODO should this be some generic thing? e.g. in the service definition
251 alternate_host = config.get(host, "http_host"); 254 alternate_host = config.get(host, "http_host");
252 end 255 end
253 local autocert = certmanager.find_host_cert(alternate_host or host); 256 local ssl, err, cfg = certmanager.create_context(alternate_host or host, "server", prefix_ssl_config, active_service.tls_cfg);
254 local manualcert = active_service.tls_cfg; 257 if not ssl then
255 local certificate = (autocert and autocert.certificate) or manualcert.certificate;
256 local key = (autocert and autocert.key) or manualcert.key;
257 local ok, err = active_service.server:sslctx():set_sni_host(
258 host,
259 certificate,
260 key
261 );
262 if not ok then
263 log("error", "Error creating TLS context for SNI host %s: %s", host, err); 258 log("error", "Error creating TLS context for SNI host %s: %s", host, err);
259 else
260 local ok, err = active_service.server:sslctx():set_sni_host(
261 host,
262 cfg.certificate,
263 cfg.key
264 );
265 if not ok then
266 log("error", "Error creating TLS context for SNI host %s: %s", host, err);
267 end
264 end 268 end
265 end 269 end
266 end 270 end
267 end 271 end
268 prosody.events.add_handler("item-added/net-provider", function (event) 272 prosody.events.add_handler("item-added/net-provider", function (event)