Comparison

util/sslconfig.lua @ 7009:61f5f8435e0b

Merge
author Matthew Wild <mwild1@gmail.com>
date Wed, 16 Dec 2015 16:44:40 +0000
parent 7004:ddb03cc4ce04
child 7867:194f540e13e2
comparison
equal deleted inserted replaced
7007:e28fbe6dd424 7009:61f5f8435e0b
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;