Mercurial > prosody-hg
comparison util/sslconfig.lua @ 7004:ddb03cc4ce04
util.sslconfig: More descriptive variable names and also comments
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Sun, 13 Dec 2015 21:21:09 +0100 |
| parents | 5de6b93d0190 |
| children | 194f540e13e2 |
comparison
equal
deleted
inserted
replaced
| 7002:9ab0d5e69c41 | 7004:ddb03cc4ce04 |
|---|---|
| 1 -- util to easily merge multiple sets of LuaSec context options | |
| 2 | |
| 1 local type = type; | 3 local type = type; |
| 2 local pairs = pairs; | 4 local pairs = pairs; |
| 3 local rawset = rawset; | 5 local rawset = rawset; |
| 4 local t_concat = table.concat; | 6 local t_concat = table.concat; |
| 5 local t_insert = table.insert; | 7 local t_insert = table.insert; |
| 9 | 11 |
| 10 local handlers = { }; | 12 local handlers = { }; |
| 11 local finalisers = { }; | 13 local finalisers = { }; |
| 12 local id = function (v) return v end | 14 local id = function (v) return v end |
| 13 | 15 |
| 14 function handlers.options(a, k, b) | 16 -- All "handlers" behave like extended rawset(table, key, value) with extra |
| 15 local o = a[k] or { }; | 17 -- processing usually merging the new value with the old in some reasonable |
| 16 if type(b) ~= "table" then b = { b } end | 18 -- way |
| 17 for key, value in pairs(b) do | 19 -- If a field does not have a defined handler then a new value simply |
| 20 -- replaces the old. | |
| 21 | |
| 22 | |
| 23 -- Convert either a list or a set into a special type of set where each | |
| 24 -- item is either positive or negative in order for a later set of options | |
| 25 -- to be able to remove options from this set by filtering out the negative ones | |
| 26 function handlers.options(config, field, new) | |
| 27 local options = config[field] or { }; | |
| 28 if type(new) ~= "table" then new = { new } end | |
| 29 for key, value in pairs(new) do | |
| 18 if value == true or value == false then | 30 if value == true or value == false then |
| 19 o[key] = value; | 31 options[key] = value; |
| 20 else | 32 else -- list item |
| 21 o[value] = true; | 33 options[value] = true; |
| 22 end | 34 end |
| 23 end | 35 end |
| 24 a[k] = o; | 36 config[field] = options; |
| 25 end | 37 end |
| 26 | 38 |
| 27 handlers.verify = handlers.options; | 39 handlers.verify = handlers.options; |
| 28 handlers.verifyext = handlers.options; | 40 handlers.verifyext = handlers.options; |
| 29 | 41 |
| 30 function finalisers.options(a) | 42 -- finalisers take something produced by handlers and return what luasec |
| 31 local o = {}; | 43 -- expects it to be |
| 32 for opt, enable in pairs(a) do | 44 |
| 45 -- Produce a list of "positive" options from the set | |
| 46 function finalisers.options(options) | |
| 47 local output = {}; | |
| 48 for opt, enable in pairs(options) do | |
| 33 if enable then | 49 if enable then |
| 34 o[#o+1] = opt; | 50 output[#output+1] = opt; |
| 35 end | 51 end |
| 36 end | 52 end |
| 37 return o; | 53 return output; |
| 38 end | 54 end |
| 39 | 55 |
| 40 finalisers.verify = finalisers.options; | 56 finalisers.verify = finalisers.options; |
| 41 finalisers.verifyext = finalisers.options; | 57 finalisers.verifyext = finalisers.options; |
| 42 | 58 |
| 43 function finalisers.ciphers(a) | 59 -- We allow ciphers to be a list |
| 44 if type(a) == "table" then | 60 |
| 45 return t_concat(a, ":"); | 61 function finalisers.ciphers(cipherlist) |
| 62 if type(cipherlist) == "table" then | |
| 63 return t_concat(cipherlist, ":"); | |
| 46 end | 64 end |
| 47 return a; | 65 return cipherlist; |
| 48 end | 66 end |
| 67 | |
| 68 -- protocol = "x" should enable only that protocol | |
| 69 -- protocol = "x+" should enable x and later versions | |
| 49 | 70 |
| 50 local protocols = { "sslv2", "sslv3", "tlsv1", "tlsv1_1", "tlsv1_2" }; | 71 local protocols = { "sslv2", "sslv3", "tlsv1", "tlsv1_1", "tlsv1_2" }; |
| 51 for i = 1, #protocols do protocols[protocols[i] .. "+"] = i - 1; end | 72 for i = 1, #protocols do protocols[protocols[i] .. "+"] = i - 1; end |
| 52 | 73 |
| 53 local function protocol(a) | 74 -- this interacts with ssl.options as well to add no_x |
| 54 local min_protocol = protocols[a.protocol]; | 75 local function protocol(config) |
| 76 local min_protocol = protocols[config.protocol]; | |
| 55 if min_protocol then | 77 if min_protocol then |
| 56 a.protocol = "sslv23"; | 78 config.protocol = "sslv23"; |
| 57 for i = 1, min_protocol do | 79 for i = 1, min_protocol do |
| 58 t_insert(a.options, "no_"..protocols[i]); | 80 t_insert(config.options, "no_"..protocols[i]); |
| 59 end | 81 end |
| 60 end | 82 end |
| 61 end | 83 end |
| 62 | 84 |
| 63 local function apply(a, b) | 85 -- Merge options from 'new' config into 'config' |
| 64 if type(b) == "table" then | 86 local function apply(config, new) |
| 65 for k,v in pairs(b) do | 87 if type(new) == "table" then |
| 66 (handlers[k] or rawset)(a, k, v); | 88 for field, value in pairs(new) do |
| 89 (handlers[field] or rawset)(config, field, value); | |
| 67 end | 90 end |
| 68 end | 91 end |
| 69 end | 92 end |
| 70 | 93 |
| 71 local function final(a) | 94 -- Finalize the config into the form LuaSec expects |
| 72 local f = { }; | 95 local function final(config) |
| 73 for k,v in pairs(a) do | 96 local output = { }; |
| 74 f[k] = (finalisers[k] or id)(v); | 97 for field, value in pairs(config) do |
| 98 output[field] = (finalisers[field] or id)(value); | |
| 75 end | 99 end |
| 76 protocol(f); | 100 -- Need to handle protocols last because it adds to the options list |
| 77 return f; | 101 protocol(output); |
| 102 return output; | |
| 78 end | 103 end |
| 79 | 104 |
| 80 local sslopts_mt = { | 105 local sslopts_mt = { |
| 81 __index = { | 106 __index = { |
| 82 apply = apply; | 107 apply = apply; |
