summaryrefslogtreecommitdiffstats
path: root/main/ca-certificates/update-ca-certificates
blob: 1780ce5d934722772f53b70871f17603848e5962 (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
85
86
#!/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'
function string.begins(str, prefix) return str:sub(1,#prefix)==prefix end

local function add(fn, out, links)
	-- Map fn to file in etc
	local pem = "ca-cert-"..fn:gsub('.*/', ''):gsub('.crt$',''):gsub('[, ]','_'):gsub('[()]','=')..".pem"
	links[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()
		out:write(content)
		if content:sub(-1) ~= '\n' then out:write('\n') end
	end
end

local calinks = {}
local cacerts = {}

local fd, tmpfile = posix.mkstemp(ETCCERTSDIR..'bundleXXXXXX')
if not fd then
	print("Failed to open temporary file for ca bundle")
	return 1
end
posix.close(fd)
posix.chmod(tmpfile, "rw-r--r--")
local bundle = io.open(tmpfile, "wb")

-- 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, bundle, calinks)
	end
end

-- Handle local CA certificates
local certlist = posix.glob(LOCALCERTSDIR..'*.crt')
if certlist ~= nil then
	table.sort(certlist)
	for _, fn in ipairs(certlist) do
		if posix.stat(fn, 'type') == 'regular' then
			add(fn, bundle, calinks)
		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 curtgt = posix.readlink(fn)
		local target = calinks[f]
		if target == nil then
			-- Symlink exists but is not wanted
			-- Delete it if it points to 'our' directory
			if curtgt:begins(CERTSDIR) or curtgt:begins(LOCALCERTSDIR) then
				os.remove(fn)
			end
		elseif curtgt ~= 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
for f, target in pairs(calinks) do
	posix.link(target, ETCCERTSDIR..f, true)
end

-- Update hashes and the bundle
bundle:close()
os.rename(tmpfile, ETCCERTSDIR..CERTBUNDLE)
os.execute("c_rehash "..ETCCERTSDIR.." > /dev/null")