summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTed Trask <ttrask01@yahoo.com>2008-05-21 20:45:26 +0000
committerTed Trask <ttrask01@yahoo.com>2008-05-21 20:45:26 +0000
commitdfdb1b0cab11d31c4f9c6be83be6e179387b36ff (patch)
treed71151952b3a2dd1d60f9f96190e2cdc1db15a9d
parentf67066bd64784cb5182d6ded1847bcdd09a77d32 (diff)
downloadacf-openssl-dfdb1b0cab11d31c4f9c6be83be6e179387b36ff.tar.bz2
acf-openssl-dfdb1b0cab11d31c4f9c6be83be6e179387b36ff.tar.xz
Further progress on openssl. Added template_stream to core for downloading files.
git-svn-id: svn://svn.alpinelinux.org/acf/openssl/trunk@1171 ab2d0c66-481e-0410-8bed-d214d4d58bed
-rw-r--r--openssl-controller.lua51
-rw-r--r--openssl-html.lsp64
-rw-r--r--openssl-model.lua110
-rw-r--r--openssl.roles4
4 files changed, 206 insertions, 23 deletions
diff --git a/openssl-controller.lua b/openssl-controller.lua
index c359b51..78cbe2b 100644
--- a/openssl-controller.lua
+++ b/openssl-controller.lua
@@ -7,20 +7,24 @@ default_action = "read"
-- View all pending and approved requests and revoked certificates
readall = function(self)
+ local cmdresult = self.sessiondata.cmdresult
+ self.sessiondata.cmdresult = nil
local pending = self.model.listrequests()
- local approved = nil
+ local approved = self.model.listcerts()
local revoked = nil
- local result = cfe({ type="list", value={pending=pending, approved=approved, revoked=revoked} })
+ local result = cfe({ type="list", value={cmdresult=cmdresult, pending=pending, approved=approved, revoked=revoked} })
return result
end
-- Return all certificates (pending, approved, and revoked) for this user
read = function(self)
+ local cmdresult = self.sessiondata.cmdresult
+ self.sessiondata.cmdresult = nil
local user = cfe({ value=self.sessiondata.userinfo.userid, label="User Name" })
local pending = self.model.listrequests(self.sessiondata.userinfo.userid)
- local approved = nil
+ local approved = self.model.listcerts(self.sessiondata.userinfo.userid)
local revoked = nil
- local result = cfe({ type="list", value={user=user, pending=pending, approved=approved, revoked=revoked} })
+ local result = cfe({ type="list", value={cmdresult=cmdresult, user=user, pending=pending, approved=approved, revoked=revoked} })
return result
end
@@ -31,8 +35,10 @@ request = function(self)
-- Try to submit the request
request = self.model.submitrequest(self.clientdata, self.sessiondata.userinfo.userid)
if not request.errtxt then
- request.descr = "Submitted request"
- --redirect(self)
+ cmdresult = cfe({ value="Request submitted", label="Request result" })
+ self.sessiondata.cmdresult = cmdresult
+ --request.descr = "Submitted request"
+ redirect(self, "readall")
end
else
request = self.model.getnewrequest()
@@ -64,16 +70,45 @@ editdefaults = function(self)
return defaults
end
+-- View request details
+viewrequest = function(self)
+ return self.model.viewrequest(self.clientdata.request)
+end
+
-- Approve the specified request
approve = function(self)
+ local cmdresult = self.model.approverequest(self.clientdata.request)
+ self.sessiondata.cmdresult = cmdresult
+ redirect_to_referrer(self)
end
--- Revoke the specified cert
-revoke = function(self)
+-- Delete the specified request
+deleterequest = function(self)
+ local cmdresult = self.model.deleterequest(self.clientdata.request)
+ self.sessiondata.cmdresult = cmdresult
+ redirect_to_referrer(self)
+end
+
+-- View certificate details
+viewcert = function(self)
+ return self.model.viewcert(self.clientdata.cert)
end
-- Get the specified cert
getcert = function(self)
+ self.conf.viewtype="stream"
+ return self.model.getcert(self.clientdata.cert)
+end
+
+-- Revoke the specified cert
+revoke = function(self)
+end
+
+-- Delete the specified certificate
+deletecert = function(self)
+ local cmdresult = self.model.deletecert(self.clientdata.cert)
+ self.sessiondata.cmdresult = cmdresult
+ redirect_to_referrer(self)
end
-- Get the revoked list
diff --git a/openssl-html.lsp b/openssl-html.lsp
index 54b4f57..192f7ce 100644
--- a/openssl-html.lsp
+++ b/openssl-html.lsp
@@ -4,23 +4,36 @@
io.write(html.cfe_unpack(view))
--]] ?>
+<? if view.value.cmdresult then ?>
+<H1>Command Result</H1>
+<DL>
+<?= view.value.cmdresult.value ?>
+</DL>
+<? end ?>
+
<H1>Pending certificate requests<? if view.value.user then?> for <?= view.value.user.value ?><? end ?></H1>
<? if not view.value.pending or #view.value.pending.value == 0 then ?>
No certificates pending
<? else ?>
<TABLE>
<TR style="background:#eee;font-weight:bold;">
- <? if session.permissions.openssl.approve then ?>
- <TD style="padding-right:20px;white-space:nowrap;" class="header">Approve</TD>
- <? end ?>
+ <TD style="padding-right:20px;white-space:nowrap;" class="header">Action</TD>
<TD style="padding-right:20px;white-space:nowrap;" class="header">User</TD>
<TD style="padding-right:20px;white-space:nowrap;" class="header">Cert Type</TD>
<TD style="white-space:nowrap;" class="header">Common Name</TD>
<? for i,request in ipairs(view.value.pending.value) do ?>
<TR>
- <? if session.permissions.openssl.approve then ?>
- <TD><?= html.link{value="approve?request="..request.name, label="Approve"} ?></TD>
- <? end ?>
+ <TD>
+ <? if session.permissions.openssl.viewrequest then
+ io.write(html.link{value="viewrequest?request="..request.name, label="View "})
+ end ?>
+ <? if session.permissions.openssl.approve then
+ io.write(html.link{value="approve?request="..request.name, label="Approve "})
+ end ?>
+ <? if session.permissions.openssl.deleterequest then
+ io.write(html.link{value="deleterequest?request="..request.name, label="Delete "})
+ end ?>
+ </TD>
<TD><?= request.user ?></TD>
<TD><?= request.certtype ?></TD>
<TD><?= request.commonName ?></TD>
@@ -28,15 +41,42 @@ io.write(html.cfe_unpack(view))
<? end ?>
</TABLE>
<? end ?>
-
+
<H1>Approved certificate requests<? if view.value.user then?> for <?= view.value.user.value ?><? end ?></H1>
<? if not view.value.approved or #view.value.approved.value == 0 then ?>
No certificates approved
-<? else
- for i,name in ipairs(view.value.approved.value) do
- io.write(name..'<br>')
- end
-end ?>
+<? else ?>
+<TABLE>
+ <TR style="background:#eee;font-weight:bold;">
+ <TD style="padding-right:20px;white-space:nowrap;" class="header">Action</TD>
+ <TD style="padding-right:20px;white-space:nowrap;" class="header">User</TD>
+ <TD style="padding-right:20px;white-space:nowrap;" class="header">Cert Type</TD>
+ <TD style="padding-right:20px;white-space:nowrap;" class="header">Common Name</TD>
+ <TD style="white-space:nowrap;" class="header">Serial Num</TD>
+ <? for i,cert in ipairs(view.value.approved.value) do ?>
+ <TR>
+ <TD>
+ <? if session.permissions.openssl.viewcert then ?>
+ <?= html.link{value="viewcert?cert="..cert.name, label="View "} ?>
+ <? end ?>
+ <? if session.permissions.openssl.getcert then ?>
+ <?= html.link{value="getcert?cert="..cert.name, label="Download "} ?>
+ <? end ?>
+ <? if session.permissions.openssl.revoke then ?>
+ <?= html.link{value="revoke?cert="..cert.name, label="Revoke "} ?>
+ <? end ?>
+ <? if session.permissions.openssl.deletecert then ?>
+ <?= html.link{value="deletecert?cert="..cert.name, label="Delete "} ?>
+ <? end ?>
+ </TD>
+ <TD><?= cert.user ?></TD>
+ <TD><?= cert.certtype ?></TD>
+ <TD><?= cert.commonName ?></TD>
+ <TD><?= cert.serial ?></TD>
+ </TR>
+ <? end ?>
+</TABLE>
+<? end ?>
<H1>Revoked certificates<? if view.value.user then?> for <?= view.value.user.value ?><? end ?></H1>
<? if not view.value.revoked or #view.value.revoked.value == 0 then ?>
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
diff --git a/openssl.roles b/openssl.roles
index 3b4f668..ec8ba3e 100644
--- a/openssl.roles
+++ b/openssl.roles
@@ -1,2 +1,2 @@
-READ=openssl:read,openssl:request,openssl:getcert,openssl:getrevoked
-UPDATE=openssl:editdefaults,openssl:readall,openssl:approve,openssl:revoke,openssl:putcacert
+READ=openssl:read,openssl:request,openssl:viewrequest,openssl:viewcert,openssl:getcert,openssl:getrevoked
+UPDATE=openssl:editdefaults,openssl:readall,openssl:approve,openssl:deleterequest,openssl:revoke,openssl:deletecert,openssl:putcacert