aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonas Schäfer <jonas@wielicki.name>2022-04-02 11:15:33 +0200
committerJonas Schäfer <jonas@wielicki.name>2022-04-02 11:15:33 +0200
commit9f7c3b9ba6c2fde4431cd6f3a12072518b478d69 (patch)
tree32e0b232600b224369ead1e7c62194b19d549cc0
parent38346dd6f1dcd963e17722bf175445465d7683f4 (diff)
downloadprosody-9f7c3b9ba6c2fde4431cd6f3a12072518b478d69.tar.gz
prosody-9f7c3b9ba6c2fde4431cd6f3a12072518b478d69.zip
net: refactor sslconfig to not depend on LuaSec
This now requires that the network backend exposes a tls_builder function, which essentially wraps the former util.sslconfig.new() function, passing a factory to create the eventual SSL context. That allows a net.server backend to pick whatever it likes as SSL context factory, as long as it understands the config table passed by the SSL config builder. Heck, a backend could even mock and replace the entire SSL config builder API.
-rw-r--r--core/certmanager.lua2
-rw-r--r--net/server.lua7
-rw-r--r--net/server_epoll.lua6
-rw-r--r--net/server_event.lua6
-rw-r--r--net/server_select.lua6
-rw-r--r--util/sslconfig.lua41
6 files changed, 51 insertions, 17 deletions
diff --git a/core/certmanager.lua b/core/certmanager.lua
index 6013c633..7958e8a9 100644
--- a/core/certmanager.lua
+++ b/core/certmanager.lua
@@ -10,7 +10,7 @@ local ssl = require "ssl";
local configmanager = require "core.configmanager";
local log = require "util.logger".init("certmanager");
local ssl_newcontext = ssl.newcontext;
-local new_config = require"util.sslconfig".new;
+local new_config = require"net.server".tls_builder;
local stat = require "lfs".attributes;
local x509 = require "util.x509";
diff --git a/net/server.lua b/net/server.lua
index 0696fd52..72272bef 100644
--- a/net/server.lua
+++ b/net/server.lua
@@ -118,6 +118,13 @@ if prosody and set_config then
prosody.events.add_handler("config-reloaded", load_config);
end
+local tls_builder = server.tls_builder;
+-- resolving the basedir here avoids util.sslconfig depending on
+-- prosody.paths.config
+function server.tls_builder()
+ return tls_builder(prosody.paths.config or "")
+end
+
-- require "net.server" shall now forever return this,
-- ie. server_select or server_event as chosen above.
return server;
diff --git a/net/server_epoll.lua b/net/server_epoll.lua
index f8bab56c..8e75e072 100644
--- a/net/server_epoll.lua
+++ b/net/server_epoll.lua
@@ -27,6 +27,8 @@ local inet_pton = inet.pton;
local _SOCKETINVALID = socket._SOCKETINVALID or -1;
local new_id = require "util.id".short;
local xpcall = require "util.xpcall".xpcall;
+local sslconfig = require "util.sslconfig";
+local tls_impl = require "net.tls_luasec";
local poller = require "util.poll"
local EEXIST = poller.EEXIST;
@@ -1104,6 +1106,10 @@ return {
cfg = setmetatable(newconfig, default_config);
end;
+ tls_builder = function(basedir)
+ return sslconfig._new(tls_impl.new_context, basedir)
+ end,
+
-- libevent emulation
event = { EV_READ = "r", EV_WRITE = "w", EV_READWRITE = "rw", EV_LEAVE = -1 };
addevent = function (fd, mode, callback)
diff --git a/net/server_event.lua b/net/server_event.lua
index dfd94db4..313ba981 100644
--- a/net/server_event.lua
+++ b/net/server_event.lua
@@ -52,6 +52,8 @@ local socket = require "socket"
local levent = require "luaevent.core"
local inet = require "util.net";
local inet_pton = inet.pton;
+local sslconfig = require "util.sslconfig";
+local tls_impl = require "net.tls_luasec";
local socket_gettime = socket.gettime
@@ -944,6 +946,10 @@ return {
add_task = add_task,
watchfd = watchfd,
+ tls_builder = function(basedir)
+ return sslconfig._new(tls_impl.new_context, basedir)
+ end,
+
__NAME = SCRIPT_NAME,
__DATE = LAST_MODIFIED,
__AUTHOR = SCRIPT_AUTHOR,
diff --git a/net/server_select.lua b/net/server_select.lua
index 51439fca..80754e1a 100644
--- a/net/server_select.lua
+++ b/net/server_select.lua
@@ -52,6 +52,8 @@ local luasocket = use "socket" or require "socket"
local luasocket_gettime = luasocket.gettime
local inet = require "util.net";
local inet_pton = inet.pton;
+local sslconfig = require "util.sslconfig";
+local tls_impl = require "net.tls_luasec";
--// extern lib methods //--
@@ -1181,4 +1183,8 @@ return {
removeserver = removeserver,
get_backend = get_backend,
changesettings = changesettings,
+
+ tls_builder = function(basedir)
+ return sslconfig._new(tls_impl.new_context, basedir)
+ end,
}
diff --git a/util/sslconfig.lua b/util/sslconfig.lua
index 23fb934c..0078365b 100644
--- a/util/sslconfig.lua
+++ b/util/sslconfig.lua
@@ -8,12 +8,8 @@ local error = error;
local t_concat = table.concat;
local t_insert = table.insert;
local setmetatable = setmetatable;
-local config_path = prosody.paths.config or ".";
local resolve_path = require"util.paths".resolve_relative_path;
--- TODO: use net.server directly here
-local tls_impl = require"net.tls_luasec";
-
local _ENV = nil;
-- luacheck: std none
@@ -78,9 +74,9 @@ finalisers.curveslist = finalisers.ciphers;
finalisers.ciphersuites = finalisers.ciphers;
-- Path expansion
-function finalisers.key(path)
+function finalisers.key(path, config)
if type(path) == "string" then
- return resolve_path(config_path, path);
+ return resolve_path(config._basedir, path);
else
return nil
end
@@ -110,11 +106,13 @@ end
-- Merge options from 'new' config into 'config'
local function apply(config, new)
- -- 0 == cache
- rawset(config, 0, nil);
+ rawset(config, "_cache", nil);
if type(new) == "table" then
for field, value in pairs(new) do
- (handlers[field] or rawset)(config, field, value);
+ -- exclude keys which are internal to the config builder
+ if field:sub(1, 1) ~= "_" then
+ (handlers[field] or rawset)(config, field, value);
+ end
end
end
return config
@@ -124,7 +122,10 @@ end
local function final(config)
local output = { };
for field, value in pairs(config) do
- output[field] = (finalisers[field] or id)(value);
+ -- exclude keys which are internal to the config builder
+ if field:sub(1, 1) ~= "_" then
+ output[field] = (finalisers[field] or id)(value, config);
+ end
end
-- Need to handle protocols last because it adds to the options list
protocol(output);
@@ -132,14 +133,14 @@ local function final(config)
end
local function build(config)
- local cached = rawget(config, 0);
+ local cached = rawget(config, "_cache");
if cached then
return cached, nil
end
- local ctx, err = tls_impl.new_context(config:final(), config);
+ local ctx, err = rawget(config, "_context_factory")(config:final(), config);
if ctx then
- rawset(config, 0, ctx);
+ rawset(config, "_cache", ctx);
end
return ctx, err
end
@@ -156,13 +157,21 @@ local sslopts_mt = {
};
-local function new()
- return setmetatable({options={}}, sslopts_mt);
+-- passing basedir through everything is required to avoid sslconfig depending
+-- on prosody.paths.config
+local function new(context_factory, basedir)
+ return setmetatable({
+ _context_factory = context_factory,
+ _basedir = basedir,
+ options={},
+ }, sslopts_mt);
end
local function clone(config)
local result = new();
for k, v in pairs(config) do
+ -- note that we *do* copy the internal keys on clone -- we have to carry
+ -- both the factory and the cache with us
rawset(result, k, v);
end
return result
@@ -173,5 +182,5 @@ sslopts_mt.__index.clone = clone;
return {
apply = apply;
final = final;
- new = new;
+ _new = new;
};