aboutsummaryrefslogtreecommitdiffstats
path: root/main/ca-certificates/update-ca-certificates
blob: cbd37779a73f6d132d5cdd17ec87034d8ae8b271 (plain)
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
82
83
84
#!/usr/bin/lua5.2

local CERTSDIR='/usr/share/ca-certificates/'
local LOCALCERTSDIR='/usr/local/share/ca-certificates/'
local ETCCERTSDIR='/etc/ssl/certs/'
local CERTBUNDLE='ca-certificates.crt'
local CERTSCONF='/etc/ca-certificates.conf'

local posix = require 'posix'
local calinks = {}
local cacerts = {}

function string.begins(str, prefix) return str:sub(1,#prefix)==prefix end

local function add(fn)
	-- Map fn to file in etc
	local pem = "ca-cert-"..fn:gsub('.*/', ''):gsub('.crt$',''):gsub('[, ]','_'):gsub('[()]','=')..".pem"
	calinks[pem] = fn
	-- Read the certificate for the bundle
	local f = io.open(fn, "rb")
	if f ~= nil then
		local content = f:read("*all")
		f:close()
		table.insert(cacerts, content)
		if content:sub(-1) ~= '\n' then table.insert(cacerts, '\n') end
	end
end

-- Handle global CA certs from config file
for l in io.lines(CERTSCONF) do
	local firstchar = l:sub(1,1)
	if firstchar ~= "#" and firstchar ~= "!" then
		add(CERTSDIR..l)
	end
end

-- Handle local CA certificates
local certlist = posix.glob(LOCALCERTSDIR..'*.crt')
if certlist ~= nil then
	table.sort(certlist)
	for f in pairs(certlist) do
		local fn = LOCALCERTSDIR..f
		if posix.stat(fn, 'type') == 'regular' then
			add(fn)
		end
	end
end

-- Update etc cert dir for additions and deletions
local f, target
for f in posix.files(ETCCERTSDIR) do
	local fn = ETCCERTSDIR..f
	if posix.stat(fn, 'type') == 'link' then
		local target = calinks[f]
		local curtgt = posix.readlink(fn)
		if curtgt:begins(CERTSDIR) or curtgt:begins(LOCALCERTSDIR) then
			if target == nil then
				-- Symlink exists but is unwanted
				os.remove(fn)
			elseif current_target ~= wanted_target then
				-- Symlink exists but points wrong
				posix.link(target, ETCCERTSDIR..f, true)
			else
				-- Symlink exists and is ok
				calinks[f] = nil
			end
		end
	end
end
for f, target in pairs(calinks) do
	posix.link(target, ETCCERTSDIR..f, true)
end

-- Update hashes and the bundle
os.execute("c_rehash "..ETCCERTSDIR.." > /dev/null")
local fd, tmpfile = posix.mkstemp(ETCCERTSDIR..'bundleXXXXXX')
if fd >= 0 then
	posix.close(fd)
	posix.chmod(tmpfile, "a+r")
	local file = io.open(tmpfile, "wb")
	file:write(table.concat(cacerts))
	file:close()
	os.rename(tmpfile, ETCCERTSDIR..CERTBUNDLE)
end