moleflap/door/token.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