Software /
code /
prosody
Comparison
util/sslconfig.lua @ 12802:4a8740e01813
Merge 0.12->trunk
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Mon, 12 Dec 2022 07:10:54 +0100 |
parent | 12481:2ee27587fec7 |
child | 12975:d10957394a3c |
comparison
equal
deleted
inserted
replaced
12801:ebd6b4d8bf04 | 12802:4a8740e01813 |
---|---|
1 -- util to easily merge multiple sets of LuaSec context options | 1 -- util to easily merge multiple sets of LuaSec context options |
2 | 2 |
3 local type = type; | 3 local type = type; |
4 local pairs = pairs; | 4 local pairs = pairs; |
5 local rawset = rawset; | 5 local rawset = rawset; |
6 local rawget = rawget; | |
7 local error = error; | |
6 local t_concat = table.concat; | 8 local t_concat = table.concat; |
7 local t_insert = table.insert; | 9 local t_insert = table.insert; |
8 local setmetatable = setmetatable; | 10 local setmetatable = setmetatable; |
11 local resolve_path = require"util.paths".resolve_relative_path; | |
9 | 12 |
10 local _ENV = nil; | 13 local _ENV = nil; |
11 -- luacheck: std none | 14 -- luacheck: std none |
12 | 15 |
13 local handlers = { }; | 16 local handlers = { }; |
32 options[key] = value; | 35 options[key] = value; |
33 else -- list item | 36 else -- list item |
34 options[value] = true; | 37 options[value] = true; |
35 end | 38 end |
36 end | 39 end |
37 config[field] = options; | 40 rawset(config, field, options) |
38 end | 41 end |
39 | 42 |
40 handlers.verifyext = handlers.options; | 43 handlers.verifyext = handlers.options; |
41 | 44 |
42 -- finalisers take something produced by handlers and return what luasec | 45 -- finalisers take something produced by handlers and return what luasec |
68 finalisers.curveslist = finalisers.ciphers; | 71 finalisers.curveslist = finalisers.ciphers; |
69 | 72 |
70 -- TLS 1.3 ciphers | 73 -- TLS 1.3 ciphers |
71 finalisers.ciphersuites = finalisers.ciphers; | 74 finalisers.ciphersuites = finalisers.ciphers; |
72 | 75 |
76 -- Path expansion | |
77 function finalisers.key(path, config) | |
78 if type(path) == "string" then | |
79 return resolve_path(config._basedir, path); | |
80 else | |
81 return nil | |
82 end | |
83 end | |
84 finalisers.certificate = finalisers.key; | |
85 finalisers.cafile = finalisers.key; | |
86 finalisers.capath = finalisers.key; | |
87 -- XXX: copied from core/certmanager.lua, but this seems odd, because it would remove a dhparam function from the config | |
88 finalisers.dhparam = finalisers.key; | |
89 | |
73 -- protocol = "x" should enable only that protocol | 90 -- protocol = "x" should enable only that protocol |
74 -- protocol = "x+" should enable x and later versions | 91 -- protocol = "x+" should enable x and later versions |
75 | 92 |
76 local protocols = { "sslv2", "sslv3", "tlsv1", "tlsv1_1", "tlsv1_2", "tlsv1_3" }; | 93 local protocols = { "sslv2", "sslv3", "tlsv1", "tlsv1_1", "tlsv1_2", "tlsv1_3" }; |
77 for i = 1, #protocols do protocols[protocols[i] .. "+"] = i - 1; end | 94 for i = 1, #protocols do protocols[protocols[i] .. "+"] = i - 1; end |
87 end | 104 end |
88 end | 105 end |
89 | 106 |
90 -- Merge options from 'new' config into 'config' | 107 -- Merge options from 'new' config into 'config' |
91 local function apply(config, new) | 108 local function apply(config, new) |
109 rawset(config, "_cache", nil); | |
92 if type(new) == "table" then | 110 if type(new) == "table" then |
93 for field, value in pairs(new) do | 111 for field, value in pairs(new) do |
94 (handlers[field] or rawset)(config, field, value); | 112 -- exclude keys which are internal to the config builder |
113 if field:sub(1, 1) ~= "_" then | |
114 (handlers[field] or rawset)(config, field, value); | |
115 end | |
95 end | 116 end |
96 end | 117 end |
118 return config | |
97 end | 119 end |
98 | 120 |
99 -- Finalize the config into the form LuaSec expects | 121 -- Finalize the config into the form LuaSec expects |
100 local function final(config) | 122 local function final(config) |
101 local output = { }; | 123 local output = { }; |
102 for field, value in pairs(config) do | 124 for field, value in pairs(config) do |
103 output[field] = (finalisers[field] or id)(value); | 125 -- exclude keys which are internal to the config builder |
126 if field:sub(1, 1) ~= "_" then | |
127 output[field] = (finalisers[field] or id)(value, config); | |
128 end | |
104 end | 129 end |
105 -- Need to handle protocols last because it adds to the options list | 130 -- Need to handle protocols last because it adds to the options list |
106 protocol(output); | 131 protocol(output); |
107 return output; | 132 return output; |
108 end | 133 end |
109 | 134 |
135 local function build(config) | |
136 local cached = rawget(config, "_cache"); | |
137 if cached then | |
138 return cached, nil | |
139 end | |
140 | |
141 local ctx, err = rawget(config, "_context_factory")(config:final(), config); | |
142 if ctx then | |
143 rawset(config, "_cache", ctx); | |
144 end | |
145 return ctx, err | |
146 end | |
147 | |
110 local sslopts_mt = { | 148 local sslopts_mt = { |
111 __index = { | 149 __index = { |
112 apply = apply; | 150 apply = apply; |
113 final = final; | 151 final = final; |
152 build = build; | |
114 }; | 153 }; |
154 __newindex = function() | |
155 error("SSL config objects cannot be modified directly. Use :apply()") | |
156 end; | |
115 }; | 157 }; |
116 | 158 |
117 local function new() | 159 |
118 return setmetatable({options={}}, sslopts_mt); | 160 -- passing basedir through everything is required to avoid sslconfig depending |
161 -- on prosody.paths.config | |
162 local function new(context_factory, basedir) | |
163 return setmetatable({ | |
164 _context_factory = context_factory, | |
165 _basedir = basedir, | |
166 options={}, | |
167 }, sslopts_mt); | |
119 end | 168 end |
169 | |
170 local function clone(config) | |
171 local result = new(); | |
172 for k, v in pairs(config) do | |
173 -- note that we *do* copy the internal keys on clone -- we have to carry | |
174 -- both the factory and the cache with us | |
175 rawset(result, k, v); | |
176 end | |
177 return result | |
178 end | |
179 | |
180 sslopts_mt.__index.clone = clone; | |
120 | 181 |
121 return { | 182 return { |
122 apply = apply; | 183 apply = apply; |
123 final = final; | 184 final = final; |
124 new = new; | 185 _new = new; |
125 }; | 186 }; |