160 lines
4.8 KiB
Lua
160 lines
4.8 KiB
Lua
#!/usr/bin/env lua
|
|
|
|
require 'luasql.postgres'
|
|
require 'config'
|
|
require 'base64'
|
|
local base64 = enc
|
|
|
|
function generate_token(old) -- generates a new token (the next)
|
|
local len = config.key_len / 8 * 6
|
|
local f = io.open("/dev/urandom","r")
|
|
while true do
|
|
local r = f:read(len)
|
|
new = base64(r)
|
|
if old then
|
|
if string.sub(new, 0, config.check_len) ~= string.sub(old, 0, config.check_len) then
|
|
break
|
|
end
|
|
else
|
|
break
|
|
end
|
|
end
|
|
return new
|
|
end
|
|
|
|
function add_token(con, token, gpg_id) -- add token to the database
|
|
local now = os.time()
|
|
math.randomseed(now)
|
|
local prefix = token:sub(1, config.prefix_len)
|
|
if not gpg_id then
|
|
gpg_id = con:execute("select trim(gpg_id) from tokens where prefix='"..prefix.."';"):fetch()
|
|
if not gpg_id then
|
|
gpg_id = ""
|
|
end
|
|
end
|
|
|
|
local ttl = now + config.ttl + math.floor(math.random() * config.ruttl)
|
|
local update = "delete from tokens where prefix='"..prefix.."';"
|
|
local insert = "insert into tokens (prefix, token, ttl, gpg_id) values ('"..prefix.."', '"..token.."', "..ttl..", '"..gpg_id.."');"
|
|
local gravedigger = "insert into graveyard (prefix, token, ttrd, gpg_id) select prefix, token, ttl+"..config.ttrd..",gpg_id from tokens where ttl<"..now..";"
|
|
local clean = "delete from tokens where ttl<"..now..";"
|
|
local dig = "delete from graveyard where ttrd<"..now..";"
|
|
-- con:execute(gravedigger .. clean .. dig .. update .. insert .. update .. insert)
|
|
con:execute(gravedigger .. clean .. dig .. update .. insert)
|
|
end
|
|
|
|
function check_token(con, token) -- checks if the token is valid
|
|
if not is_base64(token) then return false end
|
|
local result = true
|
|
local ttl = con:execute("select ttl from tokens where token='"..token.."';"):fetch()
|
|
if ttl == nil then result = false end
|
|
if type(ttl) == "number" then if tonumber(ttl) < os.time() then result = false end end
|
|
return result
|
|
end
|
|
|
|
function set_prefix(old, new) -- sets the prefix from the old token to the new token
|
|
local prefix = old:sub(1, config.prefix_len)
|
|
return prefix .. new:sub(config.prefix_len+1)
|
|
end
|
|
|
|
function get_pgp_key(prefix)
|
|
local pgp_id = con:execute("select gpg_id from tokens where prefix='"..prefix.."';"):fetch()
|
|
return pgp_id
|
|
end
|
|
|
|
function encrypt_key(prefix)
|
|
if prefix:len() ~= config.prefix_len then
|
|
return false
|
|
end
|
|
local token, pgp_id = con:execute("select token, gpg_id from tokens where prefix='"..prefix.."';"):fetch()
|
|
|
|
if not pgp_id or not token then
|
|
return false, "No pgp key"
|
|
end
|
|
|
|
local out = ""
|
|
local fp = io.popen("echo -n "..token.." | gpg --batch --logger-file /dev/null -a -e --recipient "..pgp_id.."", "r")
|
|
while true do
|
|
msg = fp:read()
|
|
if not msg then
|
|
break
|
|
end
|
|
out = out.."\n"..msg
|
|
end
|
|
if out == "" then
|
|
return false, "Could not build pgp msg"
|
|
end
|
|
return string.sub(token, 0, config.check_len).."\n"..out
|
|
end
|
|
|
|
function set_pgp(prefix, gpg_id) -- add token to the database
|
|
if not gpg_id then
|
|
gpg_id = ""
|
|
end
|
|
local update = "update tokens set gpg_id='"..gpg_id.."' where prefix='"..prefix.."';"
|
|
con:execute(update)
|
|
end
|
|
|
|
function ask_pgp(prefix, gpg_id) -- add token to the database
|
|
if prefix == "" then
|
|
return
|
|
end
|
|
|
|
local buffer = ""
|
|
while true do
|
|
if string.len(buffer) == 0 then
|
|
io.stdout:write("enter gpg id or key: [] ")
|
|
end
|
|
gpg_id = io.stdin:read()
|
|
if string.len(gpg_id) == 0 and string.len(buffer) == 0 then
|
|
return false
|
|
end
|
|
if string.len(gpg_id) == 8 then
|
|
if os.execute("gpg --batch --recv-keys "..gpg_id) == 0 then
|
|
return gpg_id
|
|
-- test if already in db
|
|
elseif os.execute("gpg --batch --list-sigs "..gpg_id) == 0 then
|
|
return gpg_id
|
|
end
|
|
else
|
|
buffer = buffer.."\n"..gpg_id
|
|
if gpg_id == "-----END PGP PUBLIC KEY BLOCK-----" then
|
|
local tmp_name = os.tmpname()
|
|
fp = io.open(tmp_name, "w")
|
|
fp:write(buffer)
|
|
io.close(fp)
|
|
local fp, err = io.popen("gpg --import "..tmp_name.." 2>&1")
|
|
local out = fp:read()
|
|
for x in string.gmatch(out, "gpg: key (%w+): ") do
|
|
print("Found key: "..x)
|
|
gpg_id = x
|
|
os.remove(tmp_name)
|
|
return gpg_id
|
|
end
|
|
os.remove(tmp_name)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function display_pgp(pgp_id)
|
|
os.execute("gpg --list-sigs "..pgp_id)
|
|
end
|
|
|
|
function trust_pgp(pgp_id)
|
|
os.execute("gpg --edit-key "..pgp_id.." trust save")
|
|
end
|
|
|
|
function edit_pgp(prefix)
|
|
new_id = ask_pgp()
|
|
if new_id then
|
|
set_pgp(prefix, new_id)
|
|
print("set to new id: "..new_id)
|
|
else
|
|
new_id = get_pgp_key(prefix)
|
|
end
|
|
display_pgp(new_id)
|
|
trust_pgp(new_id)
|
|
end
|
|
|