Browse Source

[Project] Improve keys creation in rspamadm vault

tags/1.9.3
Vsevolod Stakhov 5 years ago
parent
commit
4d95a0327b
1 changed files with 88 additions and 46 deletions
  1. 88
    46
      lualib/rspamadm/vault.lua

+ 88
- 46
lualib/rspamadm/vault.lua View File

@@ -121,20 +121,28 @@ local function is_http_error(err, data)
return err or (math.floor(data.code / 100) ~= 2)
end

local function parse_vault_reply(data)
local p = ucl.parser()
local res,parser_err = p:parse_string(data)

if not res then
return nil,parser_err
else
return p:get_object(),nil
end
end

local function maybe_print_vault_data(opts, data, func)
if data then
local p = ucl.parser()
local res,parser_err = p:parse_string(data)
local res,parser_err = parse_vault_reply(data)

if not res then
printf('vault reply for cannot be parsed: %s', parser_err)
else
local obj = p:get_object()

if func then
printf(ucl.to_format(func(obj), opts.output))
printf(ucl.to_format(func(res), opts.output))
else
printf(ucl.to_format(obj, opts.output))
printf(ucl.to_format(res, opts.output))
end
end
else
@@ -149,7 +157,7 @@ local function print_dkim_txt_record(b64, selector, alg)
if #b64 < 255 then
labels = {'"' .. b64 .. '"'}
else
for sl=1,#b64,255 do
for sl=1,#b64,256 do
table.insert(labels, '"' .. b64:sub(sl, sl + 255) .. '"')
end
end
@@ -234,6 +242,60 @@ local function genkey(opts)
return cr.gen_dkim_keypair(opts.algorithm, opts.bits)
end

local function create_and_push_key(opts, domain, existing)
local uri = vault_url(opts, domain)
local sk,pk = genkey(opts)

local res = {
selectors = {
[1] = {
selector = opts.selector,
domain = domain,
key = tostring(sk),
alg = opts.algorithm,
}
}
}

for _,sel in ipairs(existing) do
res.selectors[#res.selectors + 1] = sel
end

if opts.expire then
res.selectors[1].valid_end = os.time() + opts.expire * 3600 * 24
end

local err,data = rspamd_http.request{
config = rspamd_config,
ev_base = rspamadm_ev_base,
session = rspamadm_session,
resolver = rspamadm_dns_resolver,
url = uri,
method = 'put',
headers = {
['X-Vault-Token'] = opts.token
},
body = {
ucl.to_format(res, 'json-compact')
},
}

if is_http_error(err, data) then
printf('cannot get request to the vault (%s), HTTP error code %s', uri, data.code)
maybe_print_vault_data(opts, data.content)
os.exit(1)
else
maybe_printf(opts,'stored key for: %s, selector: %s', domain, opts.selector)
maybe_printf(opts, 'please place the corresponding public key as following:')

if opts.silent then
printf('%s', pk)
else
print_dkim_txt_record(tostring(pk), opts.selector, opts.algorithm)
end
end
end

local function newkey_handler(opts, domain)
local uri = vault_url(opts, domain)

@@ -254,51 +316,31 @@ local function newkey_handler(opts, domain)
}
}

if is_http_error(err, data) or not data.content.data then
local sk,pk = genkey(opts)

local res = {
selectors = {
[1] = {
selector = opts.selector,
domain = domain,
key = tostring(sk),
alg = opts.algorithm,
}
}
}
if is_http_error(err, data) or not data.content then
create_and_push_key(opts, domain,{})
else
-- Key exists
local rep = parse_vault_reply(data.content)

if opts.expire then
res.selectors[1].valid_end = os.time() + opts.expire * 3600 * 24
if not rep or not rep.data then
printf('cannot parse reply for %s: %s', uri, data.content)
os.exit(1)
end

err,data = rspamd_http.request{
config = rspamd_config,
ev_base = rspamadm_ev_base,
session = rspamadm_session,
resolver = rspamadm_dns_resolver,
url = uri,
method = 'put',
headers = {
['X-Vault-Token'] = opts.token
},
body = {
ucl.to_format(res, 'json-compact')
},
}
local elts = rep.data.selectors

if is_http_error(err, data) then
printf('cannot get request to the vault (%s), HTTP error code %s', uri, data.code)
maybe_print_vault_data(opts, data.content)
os.exit(1)
else
maybe_printf(opts,'stored key for: %s, selector: %s', domain, opts.selector)
maybe_printf(opts, 'please place the corresponding public key as following:')
if not elts then
create_and_push_key(opts, domain,{})
os.exit(0)
end

if opts.silent then
printf('%s', pk)
for _,sel in ipairs(elts) do
if sel.alg == opts.algorithm then
printf('key with the specific algorithm %s is already presented at %s selector for %s domain',
opts.algorithm, sel.selector, domain)
os.exit(1)
else
print_dkim_txt_record(tostring(pk), opts.selector, opts.algorithm)
create_and_push_key(opts, domain, elts)
end
end
end

Loading…
Cancel
Save