1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
-- gall.util
--
-- Git Abstraction Layer for Lua -- Utility functions
--
-- Copyright 2012 Daniel Silverstone <dsilvers@digital-scurf.org>
--
--
local luxio = require 'luxio'
local sp = require 'luxio.subprocess'
local function deep_copy(t, memo)
if not memo then memo = {} end
if memo[t] then return memo[t] end
local ret = {}
memo[t] = ret
local kk, vv
for k, v in pairs(t) do
kk, vv = k, v
if type(k) == "table" then
kk = deep_copy(k, memo)
end
if type(v) == "table" then
vv = deep_copy(v, memo)
end
ret[kk] = vv
end
return ret
end
local function validate_signature(obj, keyring)
local sig_pipe = {}
luxio.pipe(sig_pipe)
local null = luxio.open("/dev/null", luxio.O_RDONLY)
local proc = sp.spawn {
"gpgv", "--keyring", keyring,
"-q", "--status-fd", "1", "/proc/self/fd/" .. tostring(sig_pipe[1]),
"-",
stdin = sp.PIPE,
stdout = sp.PIPE,
stderr = null,
close_in_child = {
sig_pipe[2], null
}
}
luxio.close(sig_pipe[1])
luxio.close(null)
-- gpgv first reads the signature file
luxio.write(sig_pipe[2], obj.signature) -- going to assume it got written
luxio.close(sig_pipe[2])
-- gpgv next reads the certificate (which is sat on its stdin pipe)
luxio.write(proc.stdin, obj.signedcert)
luxio.close(proc.stdin)
-- Finally, we read the content of the stdout pipe
local gpgv_output, l = {}
repeat
l = luxio.read(proc.stdout, 4096)
if l then gpgv_output[#gpgv_output+1] = l end
until (not l) or (l == "")
gpgv_output = table.concat(gpgv_output, "")
luxio.close(proc.stdout)
local how, why = proc:wait()
if how ~= "exit" then
return nil, ("%s: %d"):format(how, why)
end
if why ~= 0 then
return false, gpgv_output
end
-- We are looking for a line which is of the form:
-- [GNUPG:] VALIDSIG 6CCCE5B17306BCDC179CF954C30DF439F2987D74 2016-08-28 1472393046 0 3 0 1 10 00 19568523759E2A2858F4606B3CCEBABE206C3B69
local fprint = gpgv_output:match(" VALIDSIG ([0-9A-F]+) ")
if not fprint then
return false, gpgv_output
end
return fprint
end
return {
deep_copy = deep_copy,
validate_signature = validate_signature,
}
|