Annotate

util/prosodyctl/cert.lua @ 12945:d2c1c327a4d1

util.sasl.{scram,plain}: Pass authzid to SASL profile callback For potential future use. Used for logging into a different account than the one used for authentication.
author Kim Alvefur <zash@zash.se>
date Thu, 16 Mar 2023 13:57:30 +0100
parent 12786:5d4957c8a972
child 12975:d10957394a3c
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
10871
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
1 local lfs = require "lfs";
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
2
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
3 local pctl = require "util.prosodyctl";
11203
d10f59ac7f74 util.prosodyctl.cert: Fix for prompt functions having moved to util.human.io
Kim Alvefur <zash@zash.se>
parents: 10871
diff changeset
4 local hi = require "util.human.io";
10871
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
5 local configmanager = require "core.configmanager";
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
6
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
7 local openssl;
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
8
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
9 local cert_commands = {};
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
10
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
11 -- If a file already exists, ask if the user wants to use it or replace it
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
12 -- Backups the old file if replaced
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
13 local function use_existing(filename)
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
14 local attrs = lfs.attributes(filename);
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
15 if attrs then
11203
d10f59ac7f74 util.prosodyctl.cert: Fix for prompt functions having moved to util.human.io
Kim Alvefur <zash@zash.se>
parents: 10871
diff changeset
16 if hi.show_yesno(filename .. " exists, do you want to replace it? [y/n]") then
10871
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
17 local backup = filename..".bkp~"..os.date("%FT%T", attrs.change);
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
18 os.rename(filename, backup);
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
19 pctl.show_message("%s backed up to %s", filename, backup);
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
20 else
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
21 -- Use the existing file
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
22 return true;
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
23 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
24 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
25 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
26
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
27 local have_pposix, pposix = pcall(require, "util.pposix");
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
28 local cert_basedir = prosody.paths.data == "." and "./certs" or prosody.paths.data;
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
29 if have_pposix and pposix.getuid() == 0 then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
30 -- FIXME should be enough to check if this directory is writable
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
31 local cert_dir = configmanager.get("*", "certificates") or "certs";
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
32 cert_basedir = configmanager.resolve_relative_path(prosody.paths.config, cert_dir);
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
33 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
34
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
35 function cert_commands.config(arg)
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
36 if #arg >= 1 and arg[1] ~= "--help" then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
37 local conf_filename = cert_basedir .. "/" .. arg[1] .. ".cnf";
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
38 if use_existing(conf_filename) then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
39 return nil, conf_filename;
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
40 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
41 local distinguished_name;
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
42 if arg[#arg]:find("^/") then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
43 distinguished_name = table.remove(arg);
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
44 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
45 local conf = openssl.config.new();
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
46 conf:from_prosody(prosody.hosts, configmanager, arg);
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
47 if distinguished_name then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
48 local dn = {};
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
49 for k, v in distinguished_name:gmatch("/([^=/]+)=([^/]+)") do
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
50 table.insert(dn, k);
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
51 dn[k] = v;
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
52 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
53 conf.distinguished_name = dn;
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
54 else
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
55 pctl.show_message("Please provide details to include in the certificate config file.");
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
56 pctl.show_message("Leave the field empty to use the default value or '.' to exclude the field.")
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
57 for _, k in ipairs(openssl._DN_order) do
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
58 local v = conf.distinguished_name[k];
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
59 if v then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
60 local nv = nil;
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
61 if k == "commonName" then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
62 v = arg[1]
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
63 elseif k == "emailAddress" then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
64 v = "xmpp@" .. arg[1];
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
65 elseif k == "countryName" then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
66 local tld = arg[1]:match"%.([a-z]+)$";
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
67 if tld and #tld == 2 and tld ~= "uk" then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
68 v = tld:upper();
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
69 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
70 end
11203
d10f59ac7f74 util.prosodyctl.cert: Fix for prompt functions having moved to util.human.io
Kim Alvefur <zash@zash.se>
parents: 10871
diff changeset
71 nv = hi.show_prompt(("%s (%s):"):format(k, nv or v));
10871
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
72 nv = (not nv or nv == "") and v or nv;
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
73 if nv:find"[\192-\252][\128-\191]+" then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
74 conf.req.string_mask = "utf8only"
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
75 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
76 conf.distinguished_name[k] = nv ~= "." and nv or nil;
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
77 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
78 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
79 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
80 local conf_file, err = io.open(conf_filename, "w");
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
81 if not conf_file then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
82 pctl.show_warning("Could not open OpenSSL config file for writing");
12199
12eaa2fdd75b util.prosodyctl.cert: Pass variables via formatting instead of concatenation
Kim Alvefur <zash@zash.se>
parents: 12169
diff changeset
83 pctl.show_warning("%s", err);
10871
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
84 os.exit(1);
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
85 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
86 conf_file:write(conf:serialize());
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
87 conf_file:close();
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
88 print("");
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
89 pctl.show_message("Config written to %s", conf_filename);
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
90 return nil, conf_filename;
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
91 else
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
92 pctl.show_usage("cert config HOSTNAME [HOSTNAME+]", "Builds a certificate config file covering the supplied hostname(s)")
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
93 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
94 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
95
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
96 function cert_commands.key(arg)
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
97 if #arg >= 1 and arg[1] ~= "--help" then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
98 local key_filename = cert_basedir .. "/" .. arg[1] .. ".key";
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
99 if use_existing(key_filename) then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
100 return nil, key_filename;
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
101 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
102 os.remove(key_filename); -- This file, if it exists is unlikely to have write permissions
11203
d10f59ac7f74 util.prosodyctl.cert: Fix for prompt functions having moved to util.human.io
Kim Alvefur <zash@zash.se>
parents: 10871
diff changeset
103 local key_size = tonumber(arg[2] or hi.show_prompt("Choose key size (2048):") or 2048);
10871
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
104 local old_umask = pposix.umask("0377");
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
105 if openssl.genrsa{out=key_filename, key_size} then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
106 os.execute(("chmod 400 '%s'"):format(key_filename));
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
107 pctl.show_message("Key written to %s", key_filename);
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
108 pposix.umask(old_umask);
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
109 return nil, key_filename;
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
110 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
111 pctl.show_message("There was a problem, see OpenSSL output");
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
112 else
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
113 pctl.show_usage("cert key HOSTNAME <bits>", "Generates a RSA key named HOSTNAME.key\n "
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
114 .."Prompts for a key size if none given")
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
115 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
116 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
117
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
118 function cert_commands.request(arg)
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
119 if #arg >= 1 and arg[1] ~= "--help" then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
120 local req_filename = cert_basedir .. "/" .. arg[1] .. ".req";
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
121 if use_existing(req_filename) then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
122 return nil, req_filename;
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
123 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
124 local _, key_filename = cert_commands.key({arg[1]});
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
125 local _, conf_filename = cert_commands.config(arg);
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
126 if openssl.req{new=true, key=key_filename, utf8=true, sha256=true, config=conf_filename, out=req_filename} then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
127 pctl.show_message("Certificate request written to %s", req_filename);
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
128 else
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
129 pctl.show_message("There was a problem, see OpenSSL output");
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
130 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
131 else
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
132 pctl.show_usage("cert request HOSTNAME [HOSTNAME+]", "Generates a certificate request for the supplied hostname(s)")
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
133 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
134 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
135
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
136 function cert_commands.generate(arg)
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
137 if #arg >= 1 and arg[1] ~= "--help" then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
138 local cert_filename = cert_basedir .. "/" .. arg[1] .. ".crt";
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
139 if use_existing(cert_filename) then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
140 return nil, cert_filename;
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
141 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
142 local _, key_filename = cert_commands.key({arg[1]});
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
143 local _, conf_filename = cert_commands.config(arg);
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
144 if key_filename and conf_filename and cert_filename
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
145 and openssl.req{new=true, x509=true, nodes=true, key=key_filename,
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
146 days=365, sha256=true, utf8=true, config=conf_filename, out=cert_filename} then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
147 pctl.show_message("Certificate written to %s", cert_filename);
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
148 print();
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
149 else
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
150 pctl.show_message("There was a problem, see OpenSSL output");
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
151 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
152 else
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
153 pctl.show_usage("cert generate HOSTNAME [HOSTNAME+]", "Generates a self-signed certificate for the current hostname(s)")
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
154 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
155 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
156
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
157 local function sh_esc(s)
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
158 return "'" .. s:gsub("'", "'\\''") .. "'";
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
159 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
160
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
161 local function copy(from, to, umask, owner, group)
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
162 local old_umask = umask and pposix.umask(umask);
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
163 local attrs = lfs.attributes(to);
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
164 if attrs then -- Move old file out of the way
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
165 local backup = to..".bkp~"..os.date("%FT%T", attrs.change);
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
166 os.rename(to, backup);
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
167 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
168 -- FIXME friendlier error handling, maybe move above backup back?
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
169 local input = assert(io.open(from));
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
170 local output = assert(io.open(to, "w"));
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
171 local data = input:read(2^11);
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
172 while data and output:write(data) do
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
173 data = input:read(2^11);
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
174 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
175 assert(input:close());
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
176 assert(output:close());
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
177 if not prosody.installed then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
178 -- FIXME this is possibly specific to GNU chown
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
179 os.execute(("chown -c --reference=%s %s"):format(sh_esc(cert_basedir), sh_esc(to)));
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
180 elseif owner and group then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
181 local ok = os.execute(("chown %s:%s %s"):format(sh_esc(owner), sh_esc(group), sh_esc(to)));
12786
5d4957c8a972 util.prosodyctl.cert: Remove Lua 5.1 os.execute() return value compat
Kim Alvefur <zash@zash.se>
parents: 12387
diff changeset
182 assert(ok, "Failed to change ownership of "..to);
10871
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
183 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
184 if old_umask then pposix.umask(old_umask); end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
185 return true;
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
186 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
187
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
188 function cert_commands.import(arg)
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
189 local hostnames = {};
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
190 -- Move hostname arguments out of arg, the rest should be a list of paths
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
191 while arg[1] and prosody.hosts[ arg[1] ] do
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
192 table.insert(hostnames, table.remove(arg, 1));
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
193 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
194 if hostnames[1] == nil then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
195 local domains = os.getenv"RENEWED_DOMAINS"; -- Set if invoked via certbot
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
196 if domains then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
197 for host in domains:gmatch("%S+") do
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
198 table.insert(hostnames, host);
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
199 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
200 else
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
201 for host in pairs(prosody.hosts) do
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
202 if host ~= "*" and configmanager.get(host, "enabled") ~= false then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
203 table.insert(hostnames, host);
12219
0a44def211fa util.prosodyctl.cert: Look for certs matching 'http_host'
Kim Alvefur <zash@zash.se>
parents: 12216
diff changeset
204 local http_host = configmanager.get(host, "http_host") or host;
0a44def211fa util.prosodyctl.cert: Look for certs matching 'http_host'
Kim Alvefur <zash@zash.se>
parents: 12216
diff changeset
205 if http_host ~= host then
0a44def211fa util.prosodyctl.cert: Look for certs matching 'http_host'
Kim Alvefur <zash@zash.se>
parents: 12216
diff changeset
206 table.insert(hostnames, http_host);
0a44def211fa util.prosodyctl.cert: Look for certs matching 'http_host'
Kim Alvefur <zash@zash.se>
parents: 12216
diff changeset
207 end
10871
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
208 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
209 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
210 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
211 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
212 if not arg[1] or arg[1] == "--help" then -- Probably forgot the path
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
213 pctl.show_usage("cert import [HOSTNAME+] /path/to/certs [/other/paths/]+",
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
214 "Copies certificates to "..cert_basedir);
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
215 return 1;
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
216 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
217 local owner, group;
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
218 if pposix.getuid() == 0 then -- We need root to change ownership
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
219 owner = configmanager.get("*", "prosody_user") or "prosody";
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
220 group = configmanager.get("*", "prosody_group") or owner;
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
221 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
222 local cm = require "core.certmanager";
12104
29765ac7f72f prosodyctl cert: use the indexing functions for better UX
Jonas Schäfer <jonas@wielicki.name>
parents: 11203
diff changeset
223 local files_by_name = {}
29765ac7f72f prosodyctl cert: use the indexing functions for better UX
Jonas Schäfer <jonas@wielicki.name>
parents: 11203
diff changeset
224 for _, dir in ipairs(arg) do
29765ac7f72f prosodyctl cert: use the indexing functions for better UX
Jonas Schäfer <jonas@wielicki.name>
parents: 11203
diff changeset
225 cm.index_certs(dir, files_by_name);
29765ac7f72f prosodyctl cert: use the indexing functions for better UX
Jonas Schäfer <jonas@wielicki.name>
parents: 11203
diff changeset
226 end
10871
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
227 local imported = {};
12216
0f5d04c3092f util.prosodyctl.cert: Look for certificates in a consistent order
Kim Alvefur <zash@zash.se>
parents: 12200
diff changeset
228 table.sort(hostnames, function (a, b)
0f5d04c3092f util.prosodyctl.cert: Look for certificates in a consistent order
Kim Alvefur <zash@zash.se>
parents: 12200
diff changeset
229 -- Try to find base domain name before sub-domains, then alphabetically, so
0f5d04c3092f util.prosodyctl.cert: Look for certificates in a consistent order
Kim Alvefur <zash@zash.se>
parents: 12200
diff changeset
230 -- that the order and choice of file name is deterministic.
0f5d04c3092f util.prosodyctl.cert: Look for certificates in a consistent order
Kim Alvefur <zash@zash.se>
parents: 12200
diff changeset
231 if #a == #b then
0f5d04c3092f util.prosodyctl.cert: Look for certificates in a consistent order
Kim Alvefur <zash@zash.se>
parents: 12200
diff changeset
232 return a < b;
0f5d04c3092f util.prosodyctl.cert: Look for certificates in a consistent order
Kim Alvefur <zash@zash.se>
parents: 12200
diff changeset
233 else
0f5d04c3092f util.prosodyctl.cert: Look for certificates in a consistent order
Kim Alvefur <zash@zash.se>
parents: 12200
diff changeset
234 return #a < #b;
0f5d04c3092f util.prosodyctl.cert: Look for certificates in a consistent order
Kim Alvefur <zash@zash.se>
parents: 12200
diff changeset
235 end
0f5d04c3092f util.prosodyctl.cert: Look for certificates in a consistent order
Kim Alvefur <zash@zash.se>
parents: 12200
diff changeset
236 end);
10871
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
237 for _, host in ipairs(hostnames) do
12104
29765ac7f72f prosodyctl cert: use the indexing functions for better UX
Jonas Schäfer <jonas@wielicki.name>
parents: 11203
diff changeset
238 local paths = cm.find_cert_in_index(files_by_name, host);
12169
866d06644956 util.prosodyctl.cert: Fix boolean logic bug
Kim Alvefur <zash@zash.se>
parents: 12107
diff changeset
239 if paths and imported[paths.certificate] then
12387
05c250fa335a Spelling: Fix various spelling mistakes (thanks timeless)
Kim Alvefur <zash@zash.se>
parents: 12219
diff changeset
240 -- One certificate, many names!
12107
8a5a9c1adb90 util.prosodyctl.cert: Copy SAN/wildcard certs only once
Kim Alvefur <zash@zash.se>
parents: 12104
diff changeset
241 table.insert(imported, host);
8a5a9c1adb90 util.prosodyctl.cert: Copy SAN/wildcard certs only once
Kim Alvefur <zash@zash.se>
parents: 12104
diff changeset
242 elseif paths then
12200
2bb4ee5f42be util.prosodyctl.cert: Check success of copy operations, warn on fail
Kim Alvefur <zash@zash.se>
parents: 12199
diff changeset
243 local c = copy(paths.certificate, cert_basedir .. "/" .. host .. ".crt", nil, owner, group);
2bb4ee5f42be util.prosodyctl.cert: Check success of copy operations, warn on fail
Kim Alvefur <zash@zash.se>
parents: 12199
diff changeset
244 local k = copy(paths.key, cert_basedir .. "/" .. host .. ".key", "0377", owner, group);
2bb4ee5f42be util.prosodyctl.cert: Check success of copy operations, warn on fail
Kim Alvefur <zash@zash.se>
parents: 12199
diff changeset
245 if c and k then
2bb4ee5f42be util.prosodyctl.cert: Check success of copy operations, warn on fail
Kim Alvefur <zash@zash.se>
parents: 12199
diff changeset
246 table.insert(imported, host);
2bb4ee5f42be util.prosodyctl.cert: Check success of copy operations, warn on fail
Kim Alvefur <zash@zash.se>
parents: 12199
diff changeset
247 imported[paths.certificate] = true;
2bb4ee5f42be util.prosodyctl.cert: Check success of copy operations, warn on fail
Kim Alvefur <zash@zash.se>
parents: 12199
diff changeset
248 else
2bb4ee5f42be util.prosodyctl.cert: Check success of copy operations, warn on fail
Kim Alvefur <zash@zash.se>
parents: 12199
diff changeset
249 if not c then pctl.show_warning("Could not copy certificate '%s'", paths.certificate); end
2bb4ee5f42be util.prosodyctl.cert: Check success of copy operations, warn on fail
Kim Alvefur <zash@zash.se>
parents: 12199
diff changeset
250 if not k then pctl.show_warning("Could not copy key '%s'", paths.key); end
2bb4ee5f42be util.prosodyctl.cert: Check success of copy operations, warn on fail
Kim Alvefur <zash@zash.se>
parents: 12199
diff changeset
251 end
12104
29765ac7f72f prosodyctl cert: use the indexing functions for better UX
Jonas Schäfer <jonas@wielicki.name>
parents: 11203
diff changeset
252 else
29765ac7f72f prosodyctl cert: use the indexing functions for better UX
Jonas Schäfer <jonas@wielicki.name>
parents: 11203
diff changeset
253 -- TODO Say where we looked
12199
12eaa2fdd75b util.prosodyctl.cert: Pass variables via formatting instead of concatenation
Kim Alvefur <zash@zash.se>
parents: 12169
diff changeset
254 pctl.show_warning("No certificate for host %s found :(", host);
10871
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
255 end
12104
29765ac7f72f prosodyctl cert: use the indexing functions for better UX
Jonas Schäfer <jonas@wielicki.name>
parents: 11203
diff changeset
256 -- TODO Additional checks
29765ac7f72f prosodyctl cert: use the indexing functions for better UX
Jonas Schäfer <jonas@wielicki.name>
parents: 11203
diff changeset
257 -- Certificate names matches the hostname
29765ac7f72f prosodyctl cert: use the indexing functions for better UX
Jonas Schäfer <jonas@wielicki.name>
parents: 11203
diff changeset
258 -- Private key matches public key in certificate
10871
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
259 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
260 if imported[1] then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
261 pctl.show_message("Imported certificate and key for hosts %s", table.concat(imported, ", "));
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
262 local ok, err = pctl.reload();
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
263 if not ok and err ~= "not-running" then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
264 pctl.show_message(pctl.error_messages[err]);
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
265 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
266 else
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
267 pctl.show_warning("No certificates imported :(");
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
268 return 1;
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
269 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
270 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
271
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
272 local function cert(arg)
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
273 if #arg >= 1 and arg[1] ~= "--help" then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
274 openssl = require "util.openssl";
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
275 lfs = require "lfs";
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
276 local cert_dir_attrs = lfs.attributes(cert_basedir);
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
277 if not cert_dir_attrs then
12199
12eaa2fdd75b util.prosodyctl.cert: Pass variables via formatting instead of concatenation
Kim Alvefur <zash@zash.se>
parents: 12169
diff changeset
278 pctl.show_warning("The directory %s does not exist", cert_basedir);
10871
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
279 return 1; -- TODO Should we create it?
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
280 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
281 local uid = pposix.getuid();
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
282 if uid ~= 0 and uid ~= cert_dir_attrs.uid then
12199
12eaa2fdd75b util.prosodyctl.cert: Pass variables via formatting instead of concatenation
Kim Alvefur <zash@zash.se>
parents: 12169
diff changeset
283 pctl.show_warning("The directory %s is not owned by the current user, won't be able to write files to it", cert_basedir);
10871
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
284 return 1;
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
285 elseif not cert_dir_attrs.permissions then -- COMPAT with LuaFilesystem < 1.6.2 (hey CentOS!)
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
286 pctl.show_message("Unable to check permissions on %s (LuaFilesystem 1.6.2+ required)", cert_basedir);
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
287 pctl.show_message("Please confirm that Prosody (and only Prosody) can write to this directory)");
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
288 elseif cert_dir_attrs.permissions:match("^%.w..%-..%-.$") then
12199
12eaa2fdd75b util.prosodyctl.cert: Pass variables via formatting instead of concatenation
Kim Alvefur <zash@zash.se>
parents: 12169
diff changeset
289 pctl.show_warning("The directory %s not only writable by its owner", cert_basedir);
10871
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
290 return 1;
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
291 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
292 local subcmd = table.remove(arg, 1);
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
293 if type(cert_commands[subcmd]) == "function" then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
294 if subcmd ~= "import" then -- hostnames are optional for import
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
295 if not arg[1] then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
296 pctl.show_message"You need to supply at least one hostname"
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
297 arg = { "--help" };
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
298 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
299 if arg[1] ~= "--help" and not prosody.hosts[arg[1]] then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
300 pctl.show_message(pctl.error_messages["no-such-host"]);
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
301 return 1;
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
302 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
303 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
304 return cert_commands[subcmd](arg);
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
305 elseif subcmd == "check" then
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
306 return require "util.prosodyctl.check".check({"certs"});
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
307 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
308 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
309 pctl.show_usage("cert config|request|generate|key|import", "Helpers for generating X.509 certificates and keys.")
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
310 for _, cmd in pairs(cert_commands) do
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
311 print()
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
312 cmd{ "--help" }
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
313 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
314 end
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
315
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
316 return {
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
317 cert = cert;
e5dee71d0ebb prosodyctl+util.prosodyctl.*: Start breaking up the ever-growing prosodyctl
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
318 };