diff options
Diffstat (limited to 'openssl-model.lua')
-rw-r--r-- | openssl-model.lua | 110 |
1 files changed, 109 insertions, 1 deletions
diff --git a/openssl-model.lua b/openssl-model.lua index a80ade4..a572f92 100644 --- a/openssl-model.lua +++ b/openssl-model.lua @@ -10,6 +10,8 @@ require("html") local configfile = "/etc/ssl/openssl.cnf" local requestdir = "/etc/ssl/req/" +local certdir = "/etc/ssl/cert/" +local openssldir = "/etc/ssl/" -- list of request entries that can be edited local distinguished_names = { {name="countryName", label="Country Name", short="C"}, @@ -70,7 +72,6 @@ local create_subject_string = function(values) for i,name in ipairs(distinguished_names) do outstr[#outstr + 1] = (name.short or name.name) .. "=" .. values.value[name.name].value end - outstr[#outstr + 1] = "password="..values.value.password.value return "/"..table.concat(outstr, "/") end @@ -123,6 +124,15 @@ local handle_req_clientdata = function(clientdata, defaults, config) return success, defaults, config end +local getconfigpath = function(config, section, value) + result=config[section][value] or "" + while string.find(result, "%$[%w_]+") do + local sub = string.match(result, "%$[%w_]+") + result = string.gsub(result, sub, config[section][string.sub(sub,2)] or config[""][string.sub(sub,2)]) + end + return result +end + -- FIXME we need to make sure necessary files / directories / private key are there verifyopenssl = function() local retval = false @@ -218,6 +228,9 @@ submitrequest = function(clientdata, user) local cmdresult = f:read("*a") f:close() defaults.descr = cmdresult + if fs.is_file(reqname..".csr") then + fs.write_file(reqname..".pwd", defaults.value.password.value) + end end if not success then @@ -238,3 +251,98 @@ listrequests = function(user) end return cfe({ type="list", value=list, label="List of pending requests" }) end + +viewrequest = function(request) + local path = requestdir .. request + local cmd = "openssl req -in "..path..".csr -text -noout" + local f = io.popen(cmd) + local cmdresult = f:read("*a") + f:close() + local a,b,c = string.match(request, "([^%.]*)%.([^%.]*)%.([^%.]*)") + local request = cfe({ type="table", value={name=name, user=a, certtype=b, commonName=c, value=cmdresult}, label="Request" }) + return request +end + +approverequest = function(request) + local cmdresult = cfe({ value="Failed to approve request", label="Approve result" }) + local path = requestdir .. request + if fs.is_file(path..".csr") then + -- Request file exists, so try to sign + local user,certtype,commonName = string.match(request, "([^%.]*)%.([^%.]*)%.([^%.]*)") + + -- Add the serial number to the end of the cert file name + local config = getopts.getoptsfromfile(configfile) + local serialpath = getconfigpath(config, certtype, "serial") + local serialfile = fs.read_file(openssldir..serialpath) + local serial = string.match(serialfile, "%x%x") + local certname = certdir..request.."."..serial + + -- Now, sign the certificate + local cwd = posix.getcwd() + posix.chdir(openssldir) + local cmd = "PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin openssl ca -config "..configfile.." -in "..path..".csr -out "..certname..".crt -name "..certtype.." -batch 2>&1" +APP.logevent(cmd) + local f = io.popen(cmd) + cmdresult.value = f:read("*a") + f:close() + posix.chdir(cwd) + + -- If certificate created, create the wrapped up pkcs12 + if fs.is_file(certname..".crt") then + cmd = "PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin openssl pkcs12 -export -inkey "..path..".pem -in "..certname..".crt -out "..certname..".pfx -passout file:"..path..".pwd 2>&1" + f = io.popen(cmd) + local newcmdresult = f:read("*a") + f:close() + cmdresult.value = cmdresult.value .. newcmdresult + end + + -- Finally, remove the request + if fs.is_file(certname..".pfx") then + cmd = "rm "..path..".*" + f = io.popen(cmd) + f:close() + end + end + return cmdresult +end + +deleterequest = function(request) + cmd = "rm "..requestdir..request..".*" + f = io.popen(cmd) + f:close() + return cfe({ value="Request deleted", label="Delete result" }) +end + +listcerts = function(user) + user = user or "" + local list={} + local fh = io.popen('find ' .. certdir .. ' -name "'..user..'*.pfx" -maxdepth 1') + for x in fh:lines() do + local name = basename(x,".pfx") + local a,b,c,d = string.match(name, "([^%.]*)%.([^%.]*)%.([^%.]*).([^%.]*)") + list[#list + 1] = {name=name, user=a, certtype=b, commonName=c, serial=d} + end + return cfe({ type="list", value=list, label="List of approved certificates" }) +end + +viewcert = function(cert) + local cmdresult = fs.read_file(certdir..cert..".crt") + local a,b,c,d = string.match(cert, "([^%.]*)%.([^%.]*)%.([^%.]*).([^%.]*)") + return cfe({ type="table", value={name=name, user=a, certtype=b, commonName=c, serial=d, value=cmdresult}, label="Certificate" }) +end + +getcert = function(cert) + local f = fs.read_file(certdir..cert..".pfx") + return cfe({ type="raw", value=f, label=cert..".pfx" }) +end + +revokecert = function(cert) +end + +deletecert = function(cert) + -- The certificate will still be in the ca directories and index.txt, just not available for web interface + cmd = "rm "..certdir..cert..".*" + f = io.popen(cmd) + f:close() + return cfe({ value="Certificate deleted", label="Delete result" }) +end |