From 68b08ba0a7525e7571f304e4756c2e0a8f7d6e47 Mon Sep 17 00:00:00 2001 From: Ted Trask Date: Wed, 28 May 2008 17:56:17 +0000 Subject: Check to see if necessary openssl directories exist, add support to create them And enddate and daysremaining to list of certificates Add ability to renew a certificate git-svn-id: svn://svn.alpinelinux.org/acf/openssl/trunk@1188 ab2d0c66-481e-0410-8bed-d214d4d58bed --- openssl-controller.lua | 27 ++++++- openssl-editconfigfile-html.lsp | 8 ++- openssl-html.lsp | 11 ++- openssl-model.lua | 155 +++++++++++++++++++++++++++++++++++++++- openssl-status-html.lsp | 12 +++- openssl.roles | 4 +- 6 files changed, 203 insertions(+), 14 deletions(-) diff --git a/openssl-controller.lua b/openssl-controller.lua index ff9fb91..0b3cdde 100644 --- a/openssl-controller.lua +++ b/openssl-controller.lua @@ -12,7 +12,9 @@ mvc.pre_exec = function(self) sslstatus = self.model.getstatus() if (sslstatus.value.version.errtxt and self.conf.action ~= "status") or (sslstatus.value.conffile.errtxt and self.conf.action ~= "status" and self.conf.action ~= "editconfigfile") - or ((sslstatus.value.cacert.errtxt or sslstatus.value.cakey.errtxt) and self.conf.action ~= "status" and self.conf.action ~= "editconfigfile" and self.conf.action ~= "putcacert" and self.conf.action ~= "generatecacert") then + or (sslstatus.value.environment.errtxt and self.conf.action ~= "status" and self.conf.action ~= "editconfigfile" and self.conf.action ~= "checkenvironment") + or ((sslstatus.value.cacert.errtxt or sslstatus.value.cakey.errtxt) and self.conf.action ~= "status" and self.conf.action ~= "editconfigfile" and self.conf.action ~= "putcacert" and self.conf.action ~= "generatecacert" and self.conf.action ~= "checkenvironment") + then redirect(self) end end @@ -138,6 +140,20 @@ deletecert = function(self) redirect_to_referrer(self) end +-- Submit request to renew the specified certificate +requestrenewcert = function(self) + local cmdresult = self.model.renewcert(self.clientdata.cert) + self.sessiondata.cmdresult = cmdresult + redirect_to_referrer(self) +end + +-- Renew the specified certificate +renewcert = function(self) + local cmdresult = self.model.renewcert(self.clientdata.cert, true) + self.sessiondata.cmdresult = cmdresult + redirect_to_referrer(self) +end + -- Get the revoked list getrevoked = function(self) self.conf.viewtype="stream" @@ -195,3 +211,12 @@ editconfigfile = function(self) end return configfile end + +checkenvironment = function(self) + local form = cfe({ type="form", value={}, label="Check Environment", option="Configure" }) + form.value.status = self.model.checkenvironment(self.clientdata.Configure) + if self.clientdata.Configure and not form.value.status.errtxt then + redirect_to_referrer(self) + end + return form +end diff --git a/openssl-editconfigfile-html.lsp b/openssl-editconfigfile-html.lsp index be6dae0..890909c 100644 --- a/openssl-editconfigfile-html.lsp +++ b/openssl-editconfigfile-html.lsp @@ -1,4 +1,4 @@ - + -
Save/Apply above settings
+
- + diff --git a/openssl-html.lsp b/openssl-html.lsp index adac74e..f2c65e6 100644 --- a/openssl-html.lsp +++ b/openssl-html.lsp @@ -72,9 +72,10 @@ end ?> User Cert Type Common Name - Serial Num + Serial Num + End Date - + class='error'> @@ -82,6 +83,11 @@ end ?> + + + + + @@ -93,6 +99,7 @@ end ?> + diff --git a/openssl-model.lua b/openssl-model.lua index 5f4897d..575882a 100644 --- a/openssl-model.lua +++ b/openssl-model.lua @@ -171,6 +171,30 @@ local copyca = function(cacert, cakey) f:close() end +local checkdir = function(name, path) + local errtxt, cmdline + local filestats = posix.stat(path, "type") + if not filestats or filestats == "" then + errtxt = name.." does not exist" + cmdline = "mkdir -p "..path + elseif filestats ~= "directory" then + errtxt = "UNRECOVERABLE - "..name.." not a directory" + end + return errtxt, cmdline +end + +local checkfile = function(name, path, default) + local errtxt, cmdline + local filestats = posix.stat(path, "type") + if not filestats or filestats == "" then + errtxt = name.." does not exist" + cmdline = "echo "..default.." > "..path + elseif filestats ~= "regular" then + errtxt = "UNRECOVERABLE - "..name.." not a file" + end + return errtxt, cmdline +end + getstatus = function() require("processinfo") -- set the working directory once for model @@ -209,7 +233,8 @@ getstatus = function() end end end - return cfe({ type="group", value={version=version, conffile=conffile, cacert=cacert, cacertcontents=cacertcontents, cakey=cakey}, label="openssl status" }) + local environment = checkenvironment() + return cfe({ type="group", value={version=version, conffile=conffile, environment=environment, cacert=cacert, cacertcontents=cacertcontents, cakey=cakey}, label="openssl status" }) end getreqdefaults = function() @@ -274,9 +299,14 @@ submitrequest = function(clientdata, user) success = false end + local reqname = requestdir..user.."."..defaults.value.certtype.value.."."..defaults.value.commonName.value + if fs.is_file(reqname..".csr") then + defaults.errtxt = "Failed to submit request\nRequest already exists" + success = false + end + if success then -- Submit the request - local reqname = requestdir..user.."."..defaults.value.certtype.value.."."..defaults.value.commonName.value local subject = create_subject_string(defaults) local cmd = "PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin openssl req -nodes -new -config "..configfile.." -keyout "..reqname..".pem -out "..reqname..".csr -subj '"..subject.."' 2>&1" local f = io.popen(cmd) @@ -287,6 +317,9 @@ submitrequest = function(clientdata, 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..".*" + f = io.popen(cmd) + f:close() else fs.write_file(reqname..".pwd", defaults.value.password.value) end @@ -357,6 +390,9 @@ approverequest = function(request) cmd = "cp "..path..".pwd "..certname..".pwd" f = io.popen(cmd) f:close() + cmd = "cp "..path..".pem "..certname..".pem" + f = io.popen(cmd) + f:close() cmd = "rm "..path..".*" f = io.popen(cmd) f:close() @@ -388,7 +424,21 @@ listcerts = function(user) 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} + local cmd = "PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin openssl x509 -in "..certdir..name..".crt -noout -enddate" + local f = io.popen(cmd) + local enddate = f:read("*a") + enddate = string.match(enddate, "notAfter=(.*)") + f:close() + local month, day, year = string.match(enddate, "(%a+) (%d+) %S+ (%d+)") + + local reversemonth = {Jan=1,Feb=2,Mar=3,Apr=4,May=5,Jun=6,Jul=7,Aug=8,Sep=9,Oct=10,Nov=11,Dec=12} + local time = os.time({year=year, month=reversemonth[month], day=day}) + if os.time() > time then + time = 0 + else + time = (time-os.time())/86400 + end + list[#list + 1] = {name=name, user=a, certtype=b, commonName=c, serial=d, enddate=enddate, daysremaining=time} end fh:close() return cfe({ type="list", value=list, label="List of approved certificates" }) @@ -425,6 +475,58 @@ deletecert = function(cert) return cfe({ value="Certificate deleted", label="Delete result" }) end +renewcert = function(cert, approve) + local cmdresult = "" + local success = true + local user,certtype,commonName,serialnum = string.match(cert, "([^%.]*)%.([^%.]*)%.([^%.]*).([^%.]*)") + local reqname = requestdir..user.."."..certtype.."."..commonName + if fs.is_file(reqname..".csr") then + cmdresult = "Failed to submit request\nRequest already exists" + success = false + end + + if success then + -- Submit the request + -- First, get the subject + local cmd = "PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin openssl x509 -in "..certdir..cert..".crt -noout -subject" + local f = io.popen(cmd) + local subject = f:read("*a") + subject = string.match(subject, "subject= ([^\n]*)") + f:close() + + -- Next, put the key and password in place + cmd = "cp "..certdir..cert..".pwd "..reqname..".pwd" + f = io.popen(cmd) + f:close() + cmd = "cp "..certdir..cert..".pem "..reqname..".pem" + f = io.popen(cmd) + f:close() + + -- Next, submit the request + cmd = "PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin openssl req -new -config "..configfile.." -key "..reqname..".pem -out "..reqname..".csr -subj '"..subject.."' 2>&1" +APP.logevent(cmd) + f = io.popen(cmd) + cmdresult = f:read("*a") + f:close() + local filestats = posix.stat(reqname..".csr") + if not filestats or filestats.size == 0 then + cmdresult = "Failed to submit request\n"..cmdresult + success = false + cmd = "rm "..reqname..".*" + f = io.popen(cmd) + f:close() + else + cmdresult = "Submitted request" + end + end + + if success and approve then + approverequest(basename(reqname)) + end + + return cfe({ type="boolean", value=cmdresult, label="Renew result" }) +end + listrevoked = function() config = config or getopts.getoptsfromfile(configfile) local databasepath = getconfigpath(config.ca.default_ca, "database") @@ -587,7 +689,54 @@ end setconfigfile = function(file) if file and type(file)=="string" and #file>0 then fs.write_file(configfile, file) + config = nil return true end return false end + +checkenvironment = function(set) + local errtxt = {} + local cmdline = {} + config = config or getopts.getoptsfromfile(configfile) + + local path = getconfigpath(config.ca.default_ca, "new_certs_dir") + errtxt[#errtxt+1], cmdline[#cmdline+1] = checkdir("new_certs_dir", path) + + local file = getconfigpath(config.ca.default_ca, "certificate") + path = dirname(file) + errtxt[#errtxt+1], cmdline[#cmdline+1] = checkdir("certificate directory", path) + + file = getconfigpath(config.ca.default_ca, "private_key") + path = dirname(file) + errtxt[#errtxt+1], cmdline[#cmdline+1] = checkdir("private_key directory", path) + + file = getconfigpath(config.ca.default_ca, "database") + path = dirname(file) + errtxt[#errtxt+1], cmdline[#cmdline+1] = checkdir("database directory", path) + errtxt[#errtxt+1], cmdline[#cmdline+1] = checkfile("database", file, "") + + file = getconfigpath(config.ca.default_ca, "serial") + path = dirname(file) + errtxt[#errtxt+1], cmdline[#cmdline+1] = checkdir("serial directory", path) + errtxt[#errtxt+1], cmdline[#cmdline+1] = checkfile("serial", file, "01") + + if set then + -- loop through the cmdline and execute + for x,cmd in ipairs(cmdline) do + local f = io.popen(cmd) + f:close() + end + return checkenvironment() + else + errtxt = table.concat(errtxt, '\n') + local value + if errtxt == "" then + errtxt = nil + value = "Environment ready" + else + value = "Environment not ready" + end + return cfe({ value=value, errtxt=errtxt, label="Environment" }) + end +end diff --git a/openssl-status-html.lsp b/openssl-status-html.lsp index 37d45fc..7ba2b95 100644 --- a/openssl-status-html.lsp +++ b/openssl-status-html.lsp @@ -9,15 +9,20 @@ io.write(html.cfe_unpack(view))
+
- +

CA Certificate contents

- + diff --git a/openssl.roles b/openssl.roles index 1e7896a..f4500b6 100644 --- a/openssl.roles +++ b/openssl.roles @@ -1,2 +1,2 @@ -READ=openssl:status,openssl:read,openssl:request,openssl:viewrequest,openssl:deletemyrequest,openssl:viewcert,openssl:getcert,openssl:getrevoked -UPDATE=openssl:editdefaults,openssl:readall,openssl:approve,openssl:deleterequest,openssl:revoke,openssl:deletecert,openssl:putcacert,openssl:generatecacert,openssl:editconfigfile +READ=openssl:status,openssl:read,openssl:request,openssl:viewrequest,openssl:deletemyrequest,openssl:viewcert,openssl:getcert,openssl:requestrenewcert,openssl:getrevoked +UPDATE=openssl:editdefaults,openssl:readall,openssl:approve,openssl:deleterequest,openssl:revoke,openssl:deletecert,openssl:renewcert,openssl:putcacert,openssl:generatecacert,openssl:editconfigfile,openssl:checkenvironment -- cgit v1.2.3