diff options
Diffstat (limited to 'main/ca-certificates/update-ca-certificates')
-rwxr-xr-x | main/ca-certificates/update-ca-certificates | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/main/ca-certificates/update-ca-certificates b/main/ca-certificates/update-ca-certificates new file mode 100755 index 0000000000..cbd37779a7 --- /dev/null +++ b/main/ca-certificates/update-ca-certificates @@ -0,0 +1,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 |