aboutsummaryrefslogtreecommitdiffstats
path: root/util
diff options
context:
space:
mode:
authorJonas Schäfer <jonas@wielicki.name>2022-04-27 17:44:14 +0200
committerJonas Schäfer <jonas@wielicki.name>2022-04-27 17:44:14 +0200
commit38346dd6f1dcd963e17722bf175445465d7683f4 (patch)
treed8585ca60e8995f5967a7467916496937050a9db /util
parent07ee0f44708425c9cfb9381b9030692550a8cf32 (diff)
downloadprosody-38346dd6f1dcd963e17722bf175445465d7683f4.tar.gz
prosody-38346dd6f1dcd963e17722bf175445465d7683f4.zip
net: isolate LuaSec-specifics
For this, various accessor functions are now provided directly on the sockets, which reach down into the LuaSec implementation to obtain the information. While this may seem of little gain at first, it hides the implementation detail of the LuaSec+LuaSocket combination that the actual socket and the TLS layer are separate objects. The net gain here is that an alternative implementation does not have to emulate that specific implementation detail and "only" has to expose LuaSec-compatible data structures on the new functions.
Diffstat (limited to 'util')
-rw-r--r--util/sslconfig.lua54
1 files changed, 53 insertions, 1 deletions
diff --git a/util/sslconfig.lua b/util/sslconfig.lua
index 6074a1fb..23fb934c 100644
--- a/util/sslconfig.lua
+++ b/util/sslconfig.lua
@@ -3,9 +3,16 @@
local type = type;
local pairs = pairs;
local rawset = rawset;
+local rawget = rawget;
+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
@@ -34,7 +41,7 @@ function handlers.options(config, field, new)
options[value] = true;
end
end
- config[field] = options;
+ rawset(config, field, options)
end
handlers.verifyext = handlers.options;
@@ -70,6 +77,20 @@ finalisers.curveslist = finalisers.ciphers;
-- TLS 1.3 ciphers
finalisers.ciphersuites = finalisers.ciphers;
+-- Path expansion
+function finalisers.key(path)
+ if type(path) == "string" then
+ return resolve_path(config_path, path);
+ else
+ return nil
+ end
+end
+finalisers.certificate = finalisers.key;
+finalisers.cafile = finalisers.key;
+finalisers.capath = finalisers.key;
+-- XXX: copied from core/certmanager.lua, but this seems odd, because it would remove a dhparam function from the config
+finalisers.dhparam = finalisers.key;
+
-- protocol = "x" should enable only that protocol
-- protocol = "x+" should enable x and later versions
@@ -89,11 +110,14 @@ end
-- Merge options from 'new' config into 'config'
local function apply(config, new)
+ -- 0 == cache
+ rawset(config, 0, nil);
if type(new) == "table" then
for field, value in pairs(new) do
(handlers[field] or rawset)(config, field, value);
end
end
+ return config
end
-- Finalize the config into the form LuaSec expects
@@ -107,17 +131,45 @@ local function final(config)
return output;
end
+local function build(config)
+ local cached = rawget(config, 0);
+ if cached then
+ return cached, nil
+ end
+
+ local ctx, err = tls_impl.new_context(config:final(), config);
+ if ctx then
+ rawset(config, 0, ctx);
+ end
+ return ctx, err
+end
+
local sslopts_mt = {
__index = {
apply = apply;
final = final;
+ build = build;
};
+ __newindex = function()
+ error("SSL config objects cannot be modified directly. Use :apply()")
+ end;
};
+
local function new()
return setmetatable({options={}}, sslopts_mt);
end
+local function clone(config)
+ local result = new();
+ for k, v in pairs(config) do
+ rawset(result, k, v);
+ end
+ return result
+end
+
+sslopts_mt.__index.clone = clone;
+
return {
apply = apply;
final = final;