Software /
code /
prosody
Comparison
core/certmanager.lua @ 6081:19ada596aec4
Merge 0.10->trunk
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Tue, 15 Apr 2014 20:36:39 +0200 |
parent | 6080:b7d1607df87d |
child | 6087:821756a862b0 |
comparison
equal
deleted
inserted
replaced
6072:ce5428f6e3c3 | 6081:19ada596aec4 |
---|---|
13 | 13 |
14 local tostring = tostring; | 14 local tostring = tostring; |
15 local pairs = pairs; | 15 local pairs = pairs; |
16 local type = type; | 16 local type = type; |
17 local io_open = io.open; | 17 local io_open = io.open; |
18 local t_concat = table.concat; | |
18 | 19 |
19 local prosody = prosody; | 20 local prosody = prosody; |
20 local resolve_path = configmanager.resolve_relative_path; | 21 local resolve_path = configmanager.resolve_relative_path; |
21 local config_path = prosody.paths.config; | 22 local config_path = prosody.paths.config; |
22 | 23 |
31 module "certmanager" | 32 module "certmanager" |
32 | 33 |
33 -- Global SSL options if not overridden per-host | 34 -- Global SSL options if not overridden per-host |
34 local global_ssl_config = configmanager.get("*", "ssl"); | 35 local global_ssl_config = configmanager.get("*", "ssl"); |
35 | 36 |
37 -- Built-in defaults | |
36 local core_defaults = { | 38 local core_defaults = { |
37 capath = "/etc/ssl/certs"; | 39 capath = "/etc/ssl/certs"; |
38 protocol = "sslv23"; | 40 protocol = "tlsv1+"; |
39 verify = (ssl and ssl.x509 and { "peer", "client_once", }) or "none"; | 41 verify = (ssl and ssl.x509 and { "peer", "client_once", }) or "none"; |
40 options = { "no_sslv2", "no_sslv3", "cipher_server_preference", luasec_has_noticket and "no_ticket" or nil }; | 42 options = { |
43 cipher_server_preference = true; | |
44 no_ticket = luasec_has_noticket; | |
45 no_compression = luasec_has_no_compression and configmanager.get("*", "ssl_compression") ~= true; | |
46 -- Has no_compression? Then it has these too... | |
47 single_dh_use = luasec_has_no_compression; | |
48 single_ecdh_use = luasec_has_no_compression; | |
49 }; | |
41 verifyext = { "lsec_continue", "lsec_ignore_purpose" }; | 50 verifyext = { "lsec_continue", "lsec_ignore_purpose" }; |
42 curve = "secp384r1"; | 51 curve = "secp384r1"; |
43 ciphers = "HIGH+kEDH:HIGH+kEECDH:HIGH:!PSK:!SRP:!3DES:!aNULL"; | 52 ciphers = "HIGH+kEDH:HIGH+kEECDH:HIGH:!PSK:!SRP:!3DES:!aNULL"; |
44 } | 53 } |
45 local path_options = { -- These we pass through resolve_path() | 54 local path_options = { -- These we pass through resolve_path() |
46 key = true, certificate = true, cafile = true, capath = true, dhparam = true | 55 key = true, certificate = true, cafile = true, capath = true, dhparam = true |
47 } | 56 } |
57 local set_options = { | |
58 options = true, verify = true, verifyext = true | |
59 } | |
48 | 60 |
49 if ssl and not luasec_has_verifyext and ssl.x509 then | 61 if ssl and not luasec_has_verifyext and ssl.x509 then |
50 -- COMPAT mw/luasec-hg | 62 -- COMPAT mw/luasec-hg |
51 for i=1,#core_defaults.verifyext do -- Remove lsec_ prefix | 63 for i=1,#core_defaults.verifyext do -- Remove lsec_ prefix |
52 core_defaults.verify[#core_defaults.verify+1] = core_defaults.verifyext[i]:sub(6); | 64 core_defaults.verify[#core_defaults.verify+1] = core_defaults.verifyext[i]:sub(6); |
53 end | 65 end |
54 end | 66 end |
55 | 67 |
56 if luasec_has_no_compression then -- Has no_compression? Then it has these too... | 68 local function merge_set(t, o) |
57 core_defaults.options[#core_defaults.options+1] = "single_dh_use"; | 69 if type(t) ~= "table" then t = { t } end |
58 core_defaults.options[#core_defaults.options+1] = "single_ecdh_use"; | 70 for k,v in pairs(t) do |
59 if configmanager.get("*", "ssl_compression") ~= true then | 71 if v == true or v == false then |
60 core_defaults.options[#core_defaults.options+1] = "no_compression"; | 72 o[k] = v; |
61 end | 73 else |
62 end | 74 o[v] = true; |
75 end | |
76 end | |
77 return o; | |
78 end | |
79 | |
80 local protocols = { "sslv2", "sslv3", "tlsv1", "tlsv1_1", "tlsv1_2" }; | |
81 for i = 1, #protocols do protocols[protocols[i] .. "+"] = i - 1; end | |
63 | 82 |
64 function create_context(host, mode, user_ssl_config) | 83 function create_context(host, mode, user_ssl_config) |
65 user_ssl_config = user_ssl_config or {} | 84 user_ssl_config = user_ssl_config or {} |
66 user_ssl_config.mode = mode; | 85 user_ssl_config.mode = mode; |
67 | 86 |
68 if not ssl then return nil, "LuaSec (required for encryption) was not found"; end | 87 if not ssl then return nil, "LuaSec (required for encryption) was not found"; end |
69 | 88 |
70 if global_ssl_config then | 89 if global_ssl_config then |
71 for option,default_value in pairs(global_ssl_config) do | 90 for option,default_value in pairs(global_ssl_config) do |
72 if not user_ssl_config[option] then | 91 if user_ssl_config[option] == nil then |
73 user_ssl_config[option] = default_value; | 92 user_ssl_config[option] = default_value; |
74 end | 93 end |
75 end | 94 end |
76 end | 95 end |
96 | |
77 for option,default_value in pairs(core_defaults) do | 97 for option,default_value in pairs(core_defaults) do |
78 if not user_ssl_config[option] then | 98 if user_ssl_config[option] == nil then |
79 user_ssl_config[option] = default_value; | 99 user_ssl_config[option] = default_value; |
80 end | 100 end |
81 end | 101 end |
82 user_ssl_config.password = user_ssl_config.password or function() log("error", "Encrypted certificate for %s requires 'ssl' 'password' to be set in config", host); end; | 102 |
103 local min_protocol = protocols[user_ssl_config.protocol]; | |
104 if min_protocol then | |
105 user_ssl_config.protocol = "sslv23"; | |
106 for i = min_protocol, 1, -1 do | |
107 user_ssl_config.options["no_"..protocols[i]] = true; | |
108 end | |
109 end | |
110 | |
111 for option in pairs(set_options) do | |
112 local merged = {}; | |
113 merge_set(core_defaults[option], merged); | |
114 merge_set(global_ssl_config[option], merged); | |
115 merge_set(user_ssl_config[option], merged); | |
116 local final_array = {}; | |
117 for opt, enable in pairs(merged) do | |
118 if enable then | |
119 final_array[#final_array+1] = opt; | |
120 end | |
121 end | |
122 user_ssl_config[option] = final_array; | |
123 end | |
124 | |
125 -- We can't read the password interactively when daemonized | |
126 user_ssl_config.password = user_ssl_config.password or | |
127 function() log("error", "Encrypted certificate for %s requires 'ssl' 'password' to be set in config", host); end; | |
128 | |
83 for option in pairs(path_options) do | 129 for option in pairs(path_options) do |
84 if type(user_ssl_config[option]) == "string" then | 130 if type(user_ssl_config[option]) == "string" then |
85 user_ssl_config[option] = resolve_path(config_path, user_ssl_config[option]); | 131 user_ssl_config[option] = resolve_path(config_path, user_ssl_config[option]); |
86 end | 132 end |
87 end | 133 end |
88 | 134 |
89 if not user_ssl_config.key then return nil, "No key present in SSL/TLS configuration for "..host; end | 135 -- Allow the cipher list to be a table |
90 if not user_ssl_config.certificate then return nil, "No certificate present in SSL/TLS configuration for "..host; end | 136 if type(user_ssl_config.ciphers) == "table" then |
137 user_ssl_config.ciphers = t_concat(user_ssl_config.ciphers, ":") | |
138 end | |
139 | |
140 if mode == "server" then | |
141 if not user_ssl_config.key then return nil, "No key present in SSL/TLS configuration for "..host; end | |
142 if not user_ssl_config.certificate then return nil, "No certificate present in SSL/TLS configuration for "..host; end | |
143 end | |
91 | 144 |
92 -- LuaSec expects dhparam to be a callback that takes two arguments. | 145 -- LuaSec expects dhparam to be a callback that takes two arguments. |
93 -- We ignore those because it is mostly used for having a separate | 146 -- We ignore those because it is mostly used for having a separate |
94 -- set of params for EXPORT ciphers, which we don't have by default. | 147 -- set of params for EXPORT ciphers, which we don't have by default. |
95 if type(user_ssl_config.dhparam) == "string" then | 148 if type(user_ssl_config.dhparam) == "string" then |
139 return ctx, err; | 192 return ctx, err; |
140 end | 193 end |
141 | 194 |
142 function reload_ssl_config() | 195 function reload_ssl_config() |
143 global_ssl_config = configmanager.get("*", "ssl"); | 196 global_ssl_config = configmanager.get("*", "ssl"); |
197 if luasec_has_no_compression then | |
198 core_defaults.options.no_compression = configmanager.get("*", "ssl_compression") ~= true; | |
199 end | |
144 end | 200 end |
145 | 201 |
146 prosody.events.add_handler("config-reloaded", reload_ssl_config); | 202 prosody.events.add_handler("config-reloaded", reload_ssl_config); |
147 | 203 |
148 return _M; | 204 return _M; |