#!/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")