Merge 0.9->0.10
[prosody.git] / util / sslconfig.lua
1 local type = type;
2 local pairs = pairs;
3 local rawset = rawset;
4 local t_concat = table.concat;
5 local t_insert = table.insert;
6 local setmetatable = setmetatable;
7
8 local _ENV = nil;
9
10 local handlers = { };
11 local finalisers = { };
12 local id = function (v) return v end
13
14 function handlers.options(a, k, b)
15         local o = a[k] or { };
16         if type(b) ~= "table" then b = { b } end
17         for key, value in pairs(b) do
18                 if value == true or value == false then
19                         o[key] = value;
20                 else
21                         o[value] = true;
22                 end
23         end
24         a[k] = o;
25 end
26
27 handlers.verify = handlers.options;
28 handlers.verifyext = handlers.options;
29
30 function finalisers.options(a)
31         local o = {};
32         for opt, enable in pairs(a) do
33                 if enable then
34                         o[#o+1] = opt;
35                 end
36         end
37         return o;
38 end
39
40 finalisers.verify = finalisers.options;
41 finalisers.verifyext = finalisers.options;
42
43 function finalisers.ciphers(a)
44         if type(a) == "table" then
45                 return t_concat(a, ":");
46         end
47         return a;
48 end
49
50 local protocols = { "sslv2", "sslv3", "tlsv1", "tlsv1_1", "tlsv1_2" };
51 for i = 1, #protocols do protocols[protocols[i] .. "+"] = i - 1; end
52
53 local function protocol(a)
54         local min_protocol = protocols[a.protocol];
55         if min_protocol then
56                 a.protocol = "sslv23";
57                 for i = 1, min_protocol do
58                         t_insert(a.options, "no_"..protocols[i]);
59                 end
60         end
61 end
62
63 local function apply(a, b)
64         if type(b) == "table" then
65                 for k,v in pairs(b) do
66                         (handlers[k] or rawset)(a, k, v);
67                 end
68         end
69 end
70
71 local function final(a)
72         local f = { };
73         for k,v in pairs(a) do
74                 f[k] = (finalisers[k] or id)(v);
75         end
76         protocol(f);
77         return f;
78 end
79
80 local sslopts_mt = {
81         __index = {
82                 apply = apply;
83                 final = final;
84         };
85 };
86
87 local function new()
88         return setmetatable({options={}}, sslopts_mt);
89 end
90
91 return {
92         apply = apply;
93         final = final;
94         new = new;
95 };