diff options
Diffstat (limited to 'openssl-model.lua')
-rw-r--r-- | openssl-model.lua | 114 |
1 files changed, 65 insertions, 49 deletions
diff --git a/openssl-model.lua b/openssl-model.lua index 470d9ba..2f4120c 100644 --- a/openssl-model.lua +++ b/openssl-model.lua @@ -105,13 +105,16 @@ local create_subject_string = function(values, ignorevalues) name = name:gsub(".*%.", "") -- remove the "0." from the front if (short_names[name] or reverseshorts[name]) and value.value and value.value ~= "" then name = short_names[name] or name - outstr[#outstr + 1] = name .. "=" .. value.value:gsub("[/=]", "\\%1") -- escape characters + -- escape characters + outstr[#outstr + 1] = name .. "=" .. format.escapespecialcharacters(value.value):gsub("[=]", "\\%1") end end + -- now do the ones with no short names (and not ignored) for name,value in pairs(values.value) do name = name:gsub(".*%.", "") -- remove the "0." from the front if not reverseignore[name] and not short_names[name] and not reverseshorts[name] and value.value and value.value ~= "" then - outstr[#outstr + 1] = name .. "=" .. value.value:gsub("[/=]", "\\%1") -- escape characters + -- escape characters + outstr[#outstr + 1] = format.escapespecialcharacters(name) .. "=" .. format.escapespecialcharacters(value.value):gsub("[=]", "\\%1") end end return "/"..table.concat(outstr, "/") @@ -186,11 +189,11 @@ end local copyca = function(cacert, cakey) config = config or format.parse_ini_file(fs.read_file(configfile) or "") local certpath = getconfigentry(config.ca.default_ca, "certificate") - local cmd = "cp "..cacert.." "..certpath + local cmd = "cp "..format.escapespecialcharacters(cacert).." "..format.escapespecialcharacters(certpath) local f = io.popen(cmd) f:close() local keypath = getconfigentry(config.ca.default_ca, "private_key") - local cmd = "cp "..cakey.." "..keypath + local cmd = "cp "..format.escapespecialcharacters(cakey).." "..format.escapespecialcharacters(keypath) local f = io.popen(cmd) f:close() end @@ -273,7 +276,7 @@ getstatus = function() if not fs.is_file(cacert.value) then cacert.errtxt="File not found" else - local cmd = path .. "openssl x509 -in "..cacert.value.." -noout -text" + local cmd = path .. "openssl x509 -in "..format.escapespecialcharacters(cacert.value).." -noout -text" local f = io.popen(cmd) cacertcontents.value = f:read("*a") f:close() @@ -412,7 +415,7 @@ submitrequest = function(defaults, user) end fs.write_file(reqname..".cfg", fileval) - local cmd = path .. "openssl req -nodes -new -config "..reqname..".cfg -keyout "..reqname..".pem -out "..reqname..".csr -subj '"..subject.."' 2>&1" + local cmd = path .. "openssl req -nodes -new -config "..format.escapespecialcharacters(reqname)..".cfg -keyout "..format.escapespecialcharacters(reqname)..".pem -out "..format.escapespecialcharacters(reqname)..'.csr -subj "'..subject..'" 2>&1' local f = io.popen(cmd) local cmdresult = f:read("*a") f:close() @@ -421,11 +424,12 @@ submitrequest = function(defaults, user) local keyfilestats = posix.stat(reqname..".pem") if not certfilestats or certfilestats.size == 0 or not keyfilestats or keyfilestats.size == 0 then success = false - cmd = "rm "..reqname..".*" + cmd = "rm "..format.escapespecialcharacters(reqname)..".*" f = io.popen(cmd) f:close() else fs.write_file(reqname..".pwd", defaults.value.password.value) + fs.write_file(reqname..".sbj", subject) end end @@ -439,7 +443,7 @@ end listrequests = function(user) user = user or "*" local list={} - local fh = io.popen("find " .. requestdir .. " -name "..user..".*.csr -maxdepth 1") + local fh = io.popen("find " .. format.escapespecialcharacters(requestdir) .. " -name "..format.escapespecialcharacters(user)..".*.csr -maxdepth 1") for x in fh:lines() do local name = basename(x,".csr") local a,b,c = string.match(name, "([^%.]*)%.([^%.]*)%.([^%.]*)") @@ -450,7 +454,7 @@ end viewrequest = function(request) local reqpath = requestdir .. request - local cmd = path .. "openssl req -in "..reqpath..".csr -text -noout" + local cmd = path .. "openssl req -in "..format.escapespecialcharacters(reqpath)..".csr -text -noout" local f = io.popen(cmd) local cmdresult = f:read("*a") f:close() @@ -473,7 +477,7 @@ approverequest = function(request) local certname = certdir..request.."."..serial -- Now, sign the certificate - local cmd = path .. "openssl ca -config "..configfile.." -in "..reqpath..".csr -out "..certname..".crt -name "..certtype.." -batch 2>&1" + local cmd = path .. "openssl ca -config "..configfile.." -in "..format.escapespecialcharacters(reqpath)..".csr -out "..format.escapespecialcharacters(certname)..".crt -name "..format.escapespecialcharacters(certtype).." -batch 2>&1" local f = io.popen(cmd) cmdresult.value = f:read("*a") f:close() @@ -482,7 +486,7 @@ approverequest = function(request) local filestats = posix.stat(certname..".crt") if filestats and filestats.size > 0 then -- We're wrapping up the key, the cert, and the CA cert (and whatever came with it) - cmd = path .. "openssl pkcs12 -export -inkey "..reqpath..".pem -in "..certname..".crt -out "..certname..".pfx -passout file:"..reqpath..".pwd -certfile "..getconfigentry(certtype, "certificate").." 2>&1" + cmd = path .. "openssl pkcs12 -export -inkey "..format.escapespecialcharacters(reqpath)..".pem -in "..format.escapespecialcharacters(certname)..".crt -out "..format.escapespecialcharacters(certname)..".pfx -passout file:"..format.escapespecialcharacters(reqpath)..".pwd -certfile "..format.escapespecialcharacters(getconfigentry(certtype, "certificate")).." 2>&1" f = io.popen(cmd) local newcmdresult = f:read("*a") f:close() @@ -492,21 +496,24 @@ approverequest = function(request) -- Finally, remove the request filestats = posix.stat(certname..".pfx") if filestats and filestats.size > 0 then - cmd = "cp "..reqpath..".pwd "..certname..".pwd" + cmd = "cp "..format.escapespecialcharacters(reqpath)..".pwd "..format.escapespecialcharacters(certname)..".pwd" f = io.popen(cmd) f:close() - cmd = "cp "..reqpath..".pem "..certname..".pem" + cmd = "cp "..format.escapespecialcharacters(reqpath)..".sbj "..format.escapespecialcharacters(certname)..".sbj" f = io.popen(cmd) f:close() - cmd = "cp "..reqpath..".cfg "..certname..".cfg" + cmd = "cp "..format.escapespecialcharacters(reqpath)..".pem "..format.escapespecialcharacters(certname)..".pem" f = io.popen(cmd) f:close() - cmd = "rm "..reqpath..".*" + cmd = "cp "..format.escapespecialcharacters(reqpath)..".cfg "..format.escapespecialcharacters(certname)..".cfg" + f = io.popen(cmd) + f:close() + cmd = "rm "..format.escapespecialcharacters(reqpath)..".*" f = io.popen(cmd) f:close() else -- or failed, remove the cert - cmd = "rm "..certname..".*" + cmd = "rm "..format.escapespecialcharacters(certname)..".*" f = io.popen(cmd) f:close() end @@ -519,7 +526,7 @@ deleterequest = function(request, user) if (not fs.is_file(requestdir..request..".csr")) or (not string.find(request, "^"..user.."%.")) then return cfe({ value="Request not found", label="Delete result" }) end - cmd = "rm "..requestdir..request..".*" + cmd = "rm "..requestdir..format.escapespecialcharacters(request)..".*" f = io.popen(cmd) f:close() return cfe({ value="Request deleted", label="Delete result" }) @@ -528,11 +535,11 @@ end listcerts = function(user) user = user or "*" local list={} - local fh = io.popen("find " .. certdir .. " -name "..user..".*.pfx -maxdepth 1") + local fh = io.popen("find " .. certdir .. " -name "..format.escapespecialcharacters(user)..".*.pfx -maxdepth 1") for x in fh:lines() do local name = basename(x,".pfx") local a,b,c,d = string.match(name, "([^%.]*)%.([^%.]*)%.([^%.]*).([^%.]*)") - local cmd = path .. "openssl x509 -in "..certdir..name..".crt -noout -enddate" + local cmd = path .. "openssl x509 -in "..certdir..format.escapespecialcharacters(name)..".crt -noout -enddate" local f = io.popen(cmd) local enddate = f:read("*a") enddate = string.match(enddate, "notAfter=(.*)") @@ -553,7 +560,7 @@ listcerts = function(user) end viewcert = function(cert) - local cmd = path .. "openssl x509 -in "..certdir..cert..".crt -noout -text" + local cmd = path .. "openssl x509 -in "..certdir..format.escapespecialcharacters(cert)..".crt -noout -text" local f = io.popen(cmd) local cmdresult = f:read("*a") f:close() @@ -570,7 +577,7 @@ end revokecert = function(cert) local cmdresult = cfe({ label="Revoke result" }) - local cmd = path .. "openssl ca -config "..configfile.." -revoke "..certdir .. cert..".crt -batch 2>&1" + local cmd = path .. "openssl ca -config "..configfile.." -revoke "..certdir .. format.escapespecialcharacters(cert)..".crt -batch 2>&1" local f = io.popen(cmd) cmdresult.value = f:read("*a") f:close() @@ -579,7 +586,7 @@ 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..".*" + cmd = "rm "..certdir..format.escapespecialcharacters(cert)..".*" f = io.popen(cmd) f:close() return cfe({ value="Certificate deleted", label="Delete result" }) @@ -597,23 +604,22 @@ renewcert = function(cert, approve) if success then -- Submit the request - -- First, get the subject - local cmd = path .. "openssl x509 -in "..certdir..cert..".crt -noout -subject" - local f = io.popen(cmd) - local subject = f:read("*a") - subject = string.match(subject, "subject= ([^\n]*)") + -- First, put the subject, config file and password in place + cmd = "cp "..certdir..format.escapespecialcharacters(cert)..".pwd "..format.escapespecialcharacters(reqname)..".pwd" + f = io.popen(cmd) f:close() - - -- Next, put the key and password in place - cmd = "cp "..certdir..cert..".pwd "..reqname..".pwd" + cmd = "cp "..certdir..format.escapespecialcharacters(cert)..".sbj "..format.escapespecialcharacters(reqname)..".sbj" f = io.popen(cmd) f:close() - cmd = "cp "..certdir..cert..".cfg "..reqname..".cfg" + cmd = "cp "..certdir..format.escapespecialcharacters(cert)..".cfg "..format.escapespecialcharacters(reqname)..".cfg" f = io.popen(cmd) f:close() - -- Next, submit the request - cmd = path .. "openssl req -nodes -new -config "..reqname..".cfg -keyout "..reqname..".pem -out "..reqname..".csr -subj '"..subject.."' 2>&1" + -- Next, get the subject (removing the /n inserted by fs.write_file) + local subject = string.gsub(fs.read_file(reqname..".sbj") or "", "\n", "") + + -- Next, submit the request (new key) + cmd = path .. "openssl req -nodes -new -config "..format.escapespecialcharacters(reqname)..".cfg -keyout "..format.escapespecialcharacters(reqname)..".pem -out "..format.escapespecialcharacters(reqname)..'.csr -subj "'..subject..'" 2>&1' f = io.popen(cmd) cmdresult = f:read("*a") f:close() @@ -621,7 +627,7 @@ renewcert = function(cert, approve) if not filestats or filestats.size == 0 then cmdresult = "Failed to submit request\n"..cmdresult success = false - cmd = "rm "..reqname..".*" + cmd = "rm "..format.escapespecialcharacters(reqname)..".*" f = io.popen(cmd) f:close() else @@ -680,19 +686,25 @@ putca = function(newca) -- Trying to upload a cert/key -- The way haserl works, ca contains the temporary file name -- First, get the cert - local cmd = path .. "openssl pkcs12 -in "..newca.value.ca.value.." -out "..newca.value.ca.value.."cert.pem -password pass:"..newca.value.password.value.." -nokeys 2>&1" - local f = io.popen(cmd) - local cmdresult = f:read("*a") - f:close() - local filestats = posix.stat(newca.value.ca.value.."cert.pem") - if not filestats or filestats.size == 0 then - newca.value.ca.errtxt = "Could not open certificate\n"..cmdresult + local cmd, f, cmdresult + if validator.is_valid_filename(newca.value.ca.value, "/tmp/") and fs.is_file(newca.value.ca.value) then + cmd = path .. "openssl pkcs12 -in "..format.escapespecialcharacters(newca.value.ca.value).." -out "..format.escapespecialcharacters(newca.value.ca.value).."cert.pem -password pass:"..format.escapespecialcharacters(newca.value.password.value).." -nokeys 2>&1" + f = io.popen(cmd) + cmdresult = f:read("*a") + f:close() + local filestats = posix.stat(newca.value.ca.value.."cert.pem") + if not filestats or filestats.size == 0 then + newca.value.ca.errtxt = "Could not open certificate\n"..cmdresult + success = false + end + else + newca.value.ca.errtxt = "Invalid certificate" success = false end - -- Since -cacerts doesn't seem to work, we have to check to make sure we got a CA + -- Check to make sure we got a CA cert if success then - cmd = path .. "openssl x509 -in "..newca.value.ca.value.."cert.pem -noout -text" + cmd = path .. "openssl x509 -in "..format.escapespecialcharacters(newca.value.ca.value).."cert.pem -noout -text" f = io.popen(cmd) cmdresult = f:read("*a") f:close() @@ -704,7 +716,7 @@ putca = function(newca) -- Now, get the key if success then - cmd = path .. "openssl pkcs12 -in "..newca.value.ca.value.." -out "..newca.value.ca.value.."key.pem -password pass:"..newca.value.password.value.." -nocerts -nodes 2>&1" + cmd = path .. "openssl pkcs12 -in "..format.escapespecialcharacters(newca.value.ca.value).." -out "..format.escapespecialcharacters(newca.value.ca.value).."key.pem -password pass:"..format.escapespecialcharacters(newca.value.password.value).." -nocerts -nodes 2>&1" f = io.popen(cmd) cmdresult = f:read("*a") f:close() @@ -723,10 +735,14 @@ putca = function(newca) end -- Delete the temporary files - cmd = "rm "..newca.value.ca.value.."*" - f = io.popen(cmd) - f:close() - + if validator.is_valid_filename(newca.value.ca.value, "/tmp/") and fs.is_file(newca.value.ca.value) then + cmd = "rm "..format.escapespecialcharacters(newca.value.ca.value) + f = io.popen(cmd.."cert.pem") + f:close() + f = io.popen(cmd.."key.pem") + f:close() + end + -- Clear the values newca.value.ca.value = "" newca.value.password.value = "" @@ -752,7 +768,7 @@ generateca = function(defaults) if success then -- Submit the request local subject = create_subject_string(defaults, {"days"}) - local cmd = path .. "openssl req -x509 -nodes -new -config "..configfile.." -keyout /tmp/cakey.pem -out /tmp/cacert.pem -subj '"..subject.."' -days "..defaults.value.days.value.." 2>&1" + local cmd = path .. "openssl req -x509 -nodes -new -config "..configfile..' -keyout /tmp/cakey.pem -out /tmp/cacert.pem -subj "'..subject..'" -days '..format.escapespecialcharacters(defaults.value.days.value).." 2>&1" local f = io.popen(cmd) local cmdresult = f:read("*a") f:close() |