Software /
code /
prosody
Comparison
util/openssl.lua @ 4823:a61e78b4a2b3
util.openssl: Add wrapper for the openssl cli tool and move certificate config logic from util.x509 into it.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Wed, 09 May 2012 00:12:53 +0200 |
child | 5290:befb1923527d |
comparison
equal
deleted
inserted
replaced
4821:deec69fc33e5 | 4823:a61e78b4a2b3 |
---|---|
1 local type, tostring, pairs, ipairs = type, tostring, pairs, ipairs; | |
2 local t_insert, t_concat = table.insert, table.concat; | |
3 local s_format = string.format; | |
4 | |
5 local oid_xmppaddr = "1.3.6.1.5.5.7.8.5"; -- [XMPP-CORE] | |
6 local oid_dnssrv = "1.3.6.1.5.5.7.8.7"; -- [SRV-ID] | |
7 | |
8 local idna_to_ascii = require "util.encodings".idna.to_ascii; | |
9 | |
10 local _M = {}; | |
11 local config = {}; | |
12 _M.config = config; | |
13 | |
14 local ssl_config = {}; | |
15 local ssl_config_mt = {__index=ssl_config}; | |
16 | |
17 function config.new() | |
18 return setmetatable({ | |
19 req = { | |
20 distinguished_name = "distinguished_name", | |
21 req_extensions = "v3_extensions", | |
22 x509_extensions = "v3_extensions", | |
23 prompt = "no", | |
24 }, | |
25 distinguished_name = { | |
26 commonName = "example.com", | |
27 countryName = "GB", | |
28 localityName = "The Internet", | |
29 organizationName = "Your Organisation", | |
30 organizationalUnitName = "XMPP Department", | |
31 emailAddress = "xmpp@example.com", | |
32 }, | |
33 v3_extensions = { | |
34 basicConstraints = "CA:FALSE", | |
35 keyUsage = "digitalSignature,keyEncipherment", | |
36 extendedKeyUsage = "serverAuth,clientAuth", | |
37 subjectAltName = "@subject_alternative_name", | |
38 }, | |
39 subject_alternative_name = { | |
40 DNS = {}, | |
41 otherName = {}, | |
42 }, | |
43 }, ssl_config_mt); | |
44 end | |
45 | |
46 function ssl_config:serialize() | |
47 local s = ""; | |
48 for k, t in pairs(self) do | |
49 s = s .. ("[%s]\n"):format(k); | |
50 if k == "subject_alternative_name" then | |
51 for san, n in pairs(t) do | |
52 for i = 1,#n do | |
53 s = s .. s_format("%s.%d = %s\n", san, i -1, n[i]); | |
54 end | |
55 end | |
56 else | |
57 for k, v in pairs(t) do | |
58 s = s .. ("%s = %s\n"):format(k, v); | |
59 end | |
60 end | |
61 s = s .. "\n"; | |
62 end | |
63 return s; | |
64 end | |
65 | |
66 local function utf8string(s) | |
67 -- This is how we tell openssl not to encode UTF-8 strings as fake Latin1 | |
68 return s_format("FORMAT:UTF8,UTF8:%s", s); | |
69 end | |
70 | |
71 local function ia5string(s) | |
72 return s_format("IA5STRING:%s", s); | |
73 end | |
74 | |
75 local util = {}; | |
76 _M.util = { | |
77 utf8string = utf8string, | |
78 ia5string = ia5string, | |
79 }; | |
80 | |
81 local function xmppAddr(t, host) | |
82 end | |
83 | |
84 function ssl_config:add_dNSName(host) | |
85 t_insert(self.subject_alternative_name.DNS, idna_to_ascii(host)); | |
86 end | |
87 | |
88 function ssl_config:add_sRVName(host, service) | |
89 t_insert(self.subject_alternative_name.otherName, | |
90 s_format("%s;%s", oid_dnssrv, ia5string("_" .. service .."." .. idna_to_ascii(host)))); | |
91 end | |
92 | |
93 function ssl_config:add_xmppAddr(host) | |
94 t_insert(self.subject_alternative_name.otherName, | |
95 s_format("%s;%s", oid_xmppaddr, utf8string(host))); | |
96 end | |
97 | |
98 function ssl_config:from_prosody(hosts, config, certhosts, raw) | |
99 -- TODO Decide if this should go elsewhere | |
100 local found_matching_hosts = false; | |
101 for i = 1,#certhosts do | |
102 local certhost = certhosts[i]; | |
103 for name, host in pairs(hosts) do | |
104 if name == certhost or name:sub(-1-#certhost) == "."..certhost then | |
105 found_matching_hosts = true; | |
106 self:add_dNSName(name); | |
107 --print(name .. "#component_module: " .. (config.get(name, "core", "component_module") or "nil")); | |
108 if config.get(name, "core", "component_module") == nil then | |
109 self:add_sRVName(name, "xmpp-client"); | |
110 end | |
111 --print(name .. "#anonymous_login: " .. tostring(config.get(name, "core", "anonymous_login"))); | |
112 if not (config.get(name, "core", "anonymous_login") or | |
113 config.get(name, "core", "authentication") == "anonymous") then | |
114 self:add_sRVName(name, "xmpp-server"); | |
115 end | |
116 self:add_xmppAddr(name); | |
117 end | |
118 end | |
119 end | |
120 if not found_matching_hosts then | |
121 return nil, "no-matching-hosts"; | |
122 end | |
123 end | |
124 | |
125 do -- Lua to shell calls. | |
126 local function shell_escape(s) | |
127 return s:gsub("'",[['\'']]); | |
128 end | |
129 | |
130 local function serialize(f,o) | |
131 local r = {"openssl", f}; | |
132 for k,v in pairs(o) do | |
133 if type(k) == "string" then | |
134 t_insert(r, ("-%s"):format(k)); | |
135 if v ~= true then | |
136 t_insert(r, ("'%s'"):format(shell_escape(tostring(v)))); | |
137 end | |
138 end | |
139 end | |
140 for k,v in ipairs(o) do | |
141 t_insert(r, ("'%s'"):format(shell_escape(tostring(v)))); | |
142 end | |
143 return t_concat(r, " "); | |
144 end | |
145 | |
146 local os_execute = os.execute; | |
147 setmetatable(_M, { | |
148 __index=function(self,f) | |
149 return function(opts) | |
150 return 0 == os_execute(serialize(f, type(opts) == "table" and opts or {})); | |
151 end; | |
152 end; | |
153 }); | |
154 end | |
155 | |
156 return _M; |