aboutsummaryrefslogtreecommitdiffstats
path: root/main/ca-certificates/update-ca-certificates
diff options
context:
space:
mode:
Diffstat (limited to 'main/ca-certificates/update-ca-certificates')
-rwxr-xr-xmain/ca-certificates/update-ca-certificates84
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