diff options
-rw-r--r-- | util/sslconfig.lua | 87 |
1 files changed, 56 insertions, 31 deletions
diff --git a/util/sslconfig.lua b/util/sslconfig.lua index 71f27c94..c849aa28 100644 --- a/util/sslconfig.lua +++ b/util/sslconfig.lua @@ -1,3 +1,5 @@ +-- util to easily merge multiple sets of LuaSec context options + local type = type; local pairs = pairs; local rawset = rawset; @@ -11,70 +13,93 @@ local handlers = { }; local finalisers = { }; local id = function (v) return v end -function handlers.options(a, k, b) - local o = a[k] or { }; - if type(b) ~= "table" then b = { b } end - for key, value in pairs(b) do +-- All "handlers" behave like extended rawset(table, key, value) with extra +-- processing usually merging the new value with the old in some reasonable +-- way +-- If a field does not have a defined handler then a new value simply +-- replaces the old. + + +-- Convert either a list or a set into a special type of set where each +-- item is either positive or negative in order for a later set of options +-- to be able to remove options from this set by filtering out the negative ones +function handlers.options(config, field, new) + local options = config[field] or { }; + if type(new) ~= "table" then new = { new } end + for key, value in pairs(new) do if value == true or value == false then - o[key] = value; - else - o[value] = true; + options[key] = value; + else -- list item + options[value] = true; end end - a[k] = o; + config[field] = options; end handlers.verify = handlers.options; handlers.verifyext = handlers.options; -function finalisers.options(a) - local o = {}; - for opt, enable in pairs(a) do +-- finalisers take something produced by handlers and return what luasec +-- expects it to be + +-- Produce a list of "positive" options from the set +function finalisers.options(options) + local output = {}; + for opt, enable in pairs(options) do if enable then - o[#o+1] = opt; + output[#output+1] = opt; end end - return o; + return output; end finalisers.verify = finalisers.options; finalisers.verifyext = finalisers.options; -function finalisers.ciphers(a) - if type(a) == "table" then - return t_concat(a, ":"); +-- We allow ciphers to be a list + +function finalisers.ciphers(cipherlist) + if type(cipherlist) == "table" then + return t_concat(cipherlist, ":"); end - return a; + return cipherlist; end +-- protocol = "x" should enable only that protocol +-- protocol = "x+" should enable x and later versions + local protocols = { "sslv2", "sslv3", "tlsv1", "tlsv1_1", "tlsv1_2" }; for i = 1, #protocols do protocols[protocols[i] .. "+"] = i - 1; end -local function protocol(a) - local min_protocol = protocols[a.protocol]; +-- this interacts with ssl.options as well to add no_x +local function protocol(config) + local min_protocol = protocols[config.protocol]; if min_protocol then - a.protocol = "sslv23"; + config.protocol = "sslv23"; for i = 1, min_protocol do - t_insert(a.options, "no_"..protocols[i]); + t_insert(config.options, "no_"..protocols[i]); end end end -local function apply(a, b) - if type(b) == "table" then - for k,v in pairs(b) do - (handlers[k] or rawset)(a, k, v); +-- Merge options from 'new' config into 'config' +local function apply(config, new) + if type(new) == "table" then + for field, value in pairs(new) do + (handlers[field] or rawset)(config, field, value); end end end -local function final(a) - local f = { }; - for k,v in pairs(a) do - f[k] = (finalisers[k] or id)(v); +-- Finalize the config into the form LuaSec expects +local function final(config) + local output = { }; + for field, value in pairs(config) do + output[field] = (finalisers[field] or id)(value); end - protocol(f); - return f; + -- Need to handle protocols last because it adds to the options list + protocol(output); + return output; end local sslopts_mt = { |