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