diff options
author | Ted Trask <ttrask01@yahoo.com> | 2009-11-19 16:26:08 +0000 |
---|---|---|
committer | Ted Trask <ttrask01@yahoo.com> | 2009-11-19 16:26:08 +0000 |
commit | 3424c10a7a9cadc4697951b259d70fc26f56b197 (patch) | |
tree | 414f27c79e0f51dc4bf0e4bffb2ff680c778f1cb | |
parent | 0b4d7742743741065201b8acf084b9248b5f186e (diff) | |
download | acf-openvpn-3424c10a7a9cadc4697951b259d70fc26f56b197.tar.bz2 acf-openvpn-3424c10a7a9cadc4697951b259d70fc26f56b197.tar.xz |
Major changes to only handle one config and add cert processing.
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | openvpn-controller.lua | 54 | ||||
l--------- | openvpn-createconfig-html.lsp | 1 | ||||
l--------- | openvpn-editconfig-html.lsp | 1 | ||||
-rw-r--r-- | openvpn-listconfigs-html.lsp | 57 | ||||
-rw-r--r-- | openvpn-model.lua | 216 | ||||
l---------[-rwxr-xr-x] | openvpn-startstop-html.lsp | 38 | ||||
-rw-r--r-- | openvpn-statusinfo-html.lsp | 6 | ||||
-rw-r--r-- | openvpn-viewconfig-html.lsp | 10 | ||||
-rw-r--r-- | openvpn.menu | 6 | ||||
-rw-r--r-- | openvpn.roles | 6 |
11 files changed, 170 insertions, 227 deletions
@@ -1,6 +1,6 @@ APP_NAME=openvpn PACKAGE=acf-$(APP_NAME) -VERSION=0.4.3 +VERSION=0.5.0 APP_DIST= \ openvpn* \ diff --git a/openvpn-controller.lua b/openvpn-controller.lua index 85deb28..a2926d6 100644 --- a/openvpn-controller.lua +++ b/openvpn-controller.lua @@ -4,46 +4,46 @@ require("controllerfunctions") default_action = "status" -status = function (self) +status = function(self) return self.model.getstatus() end -listconfigs = function (self) - return self.model.get_conflist() +startstop = function(self) + return controllerfunctions.handle_startstop(self, self.model.startstop_service, self.clientdata) end -editconfig = function (self) - return controllerfunctions.handle_form(self, function() return self.model.get_filecontent(self.clientdata.name) end, self.model.update_filecontent, self.clientdata, "Save", "Edit Config File", "Config File Saved") +expert = function(self) + return controllerfunctions.handle_form(self, self.model.get_filecontent, self.model.update_filecontent, self.clientdata, "Save", "Edit Config File", "Config File Saved") end -createconfig = function ( self ) - return controllerfunctions.handle_form(self, self.model.create_new_config, self.model.create_config, self.clientdata, "Create", "Create new config", "New config Created") +viewconfig = function(self) + return self.model.get_config() end -deleteconfig = function(self) - return self:redirect_to_referrer(self.model.delete_config(self.clientdata.name)) +statusinfo = function (self) + return self.model.getclientinfo() end -viewconfig = function(self) - return self.model.get_config(self.clientdata.name) +logfile = function (self) + return self.model.get_logfile() end -statusinfo = function (self) - return self.model.getclientinfo(self.clientdata.name) +function listcerts(self) + return self.model.list_certs() end -logfile = function (self) - return self.model.get_logfile(self.clientdata.name) -end - -function startstop(self) - local data = self.model.startstop_service(clientdata.action,clientdata.service) - data.service = clientdata.service - if (data) and (data.value) and (data.value.result) and (data.value.result.value) then - redirect(self, "listconfigs") - end - if not (clientdata.service) then - redirect(self, "listconfigs") - end - return data +function deletecert(self) + return self:redirect_to_referrer(self.model.delete_cert(self.clientdata.cert)) +end + +function uploadcert (self) + return controllerfunctions.handle_form(self, self.model.new_upload_cert, self.model.upload_cert, self.clientdata, "Upload", "Upload Certificate", "Certificate Uploaded") +end + +function viewcert(self) + return self.model.view_cert(self.clientdata.cert) +end + +function generatedhparams(self) + return self:redirect_to_referrer(self.model.generate_dh_params()) end diff --git a/openvpn-createconfig-html.lsp b/openvpn-createconfig-html.lsp deleted file mode 120000 index 4b6b762..0000000 --- a/openvpn-createconfig-html.lsp +++ /dev/null @@ -1 +0,0 @@ -../form-html.lsp
\ No newline at end of file diff --git a/openvpn-editconfig-html.lsp b/openvpn-editconfig-html.lsp deleted file mode 120000 index 15b1930..0000000 --- a/openvpn-editconfig-html.lsp +++ /dev/null @@ -1 +0,0 @@ -../filedetails-html.lsp
\ No newline at end of file diff --git a/openvpn-listconfigs-html.lsp b/openvpn-listconfigs-html.lsp deleted file mode 100644 index 358bdc3..0000000 --- a/openvpn-listconfigs-html.lsp +++ /dev/null @@ -1,57 +0,0 @@ -<% local view, viewlibrary, page_info, session = ... %> -<% require("viewfunctions") %> - -<% displaycommandresults({"editconfig", "deleteconfig"}, session) %> -<% displaycommandresults({"createconfig"}, session, true) %> - -<% if viewlibrary.dispatch_component then - viewlibrary.dispatch_component("status") -end %> - -<H2>Available configs</H2> -<TABLE> - <TR style="background:#eee;font-weight:bold;vertical-align:top;"> - <TD class="header">Actions</TD> - <TD class="header">Config</TD> - <TD class="header">Type</TD> - <TD class="header">Status</TD> - <TD class="header">Connected<BR>Clients</TD> - </TR> - -<% for i,config in ipairs(view.value) do %> - <TR > - <TD> - <%= html.link{value = page_info.script .. page_info.prefix .. page_info.controller .. "/viewconfig?name=" .. config.name, label="View " } %> - <% if session.permissions.openvpn.editconfig then %> - <%= html.link{value = page_info.script .. page_info.prefix .. page_info.controller .. "/editconfig?name=" .. config.name.."&redir="..page_info.orig_action, label="Expert " } %> - <% end %> - <% if session.permissions.openvpn.deleteconfig then %> - <%= html.link{value = page_info.script .. page_info.prefix .. page_info.controller .. "/deleteconfig?name=" .. config.name.."&redir="..page_info.orig_action, label="Delete " } %> - <% end %> - </TD> - <TD><%= html.html_escape(string.gsub(config.name, "^.*/", "")) %></TD> - <TD <% if config.errtxt then io.write('class="error"') end %>><%= html.html_escape(config.type) %></TD> - <TD><%= html.link{value = page_info.script .. page_info.prefix .. page_info.controller .. "/startstop?service=" .. string.match(html.html_escape(string.gsub(config.name, "^.*/", "")), "^(.+)\.conf") .."&redir="..page_info.orig_action, label=html.html_escape(config.status) } %></TD> - <TD><% if ( config.type == "server" ) then %> - <% if ( config.clients > 0 ) then %> - <%= html.link{value = page_info.script .. page_info.prefix .. page_info.controller .. "/statusinfo?name=" .. config.name, label = config.clients } %> - <% else %> - <%= html.html_escape(config.clients) %> - <% end %> - <% end %> </TD> - </TR> - <% if config.errtxt then %> - <TR class="error"><TD colspan=5><%= html.html_escape(config.errtxt) %></TD></TR> - <% end %> -<% end %> - -<% if (#view.value == 0) then %> - <TR> - <TD colspan=5>(No existing config-files)</TD> - </TR> -<% end %> -</TABLE> - -<% if viewlibrary.dispatch_component and session.permissions.openvpn.createconfig then - viewlibrary.dispatch_component("createconfig") -end %> diff --git a/openvpn-model.lua b/openvpn-model.lua index 7468a01..70de3c8 100644 --- a/openvpn-model.lua +++ b/openvpn-model.lua @@ -10,8 +10,11 @@ require ("date") local processname = "openvpn" local packagename = "openvpn" +local configfile = "/etc/openvpn/openvpn.conf" local baseurl = "/etc/openvpn/" +local path = "PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin " + -- ################################################################################ -- LOCAL FUNCTIONS @@ -43,22 +46,6 @@ local function config_content( f ) return config end - -local is_running = function( process, parameters ) - local retval = "Stopped" - for i,v in ipairs(processinfo.pidof(process) or {}) do - local path = string.gsub("/proc/".. v .. "/cmdline", "%s", "") - local f = io.open(path,r) - local file_resultx = f:read("*a") - local file_result = string.match(file_resultx, parameters) - f:close() - if ( file_result ) then - retval = "Running" - end - end - return retval -end - local function check_valid_config (config) config.errtxt = nil if not (config.client) or not (config.ca) or not (config.cert) or not (config.key) or not (config.dev) or not (config.proto) or not (config.remote) then @@ -92,16 +79,6 @@ local function check_valid_config (config) return config.type, config.errtxt end -local function list_conffiles() - local configfiles = {} - for file in fs.find(".*conf", baseurl) do - if fs.is_file(file) then - configfiles[#configfiles+1] = file - end - end - return configfiles -end - local function clientlist( statusfile ) local clientlist = {} local routinglist = {} @@ -176,19 +153,20 @@ end -- PUBLIC FUNCTIONS function getstatus() - local status = modelfunctions.getstatus(processname, packagename, "OpenVPN Status") - status.value.autostart = nil - status.value.status = nil - return status + return modelfunctions.getstatus(processname, packagename, "OpenVPN Status") end -function getclientinfo(f) - local config = config_content(f) +function startstop_service(action) + return modelfunctions.startstop_service(processname, action) +end + +function getclientinfo() + local config = config_content(configfile) return cfe({ type="structure", value=clientlist(config.status), label="Client info" }) end -function get_config(f) - local config = config_content(f) +function get_config() + local config = config_content(configfile) check_valid_config(config) if config.type == "server" then local clientlist, client_count, client_lastupdate, client_lastdatechangediff = clientlist(config.status) @@ -196,95 +174,149 @@ function get_config(f) config["client_lastdatechangediff"] = client_lastdatechangediff or "? min" config["client_count"] = client_count or 0 end - config["status_isrunning"] = is_running ("openvpn", basename(f)) return cfe({ type="structure", value=config, label="OpenVPN Config" }) end function get_logfile(f) - local config = config_content(f) - return cfe({ value=config.log or "", label="Config file" }) -end - -function get_conflist () - local configlist = {} - for i,file in ipairs(list_conffiles()) do - config = config_content ( file ) - local conf_type, errtxt = check_valid_config(config) - local isrunning = is_running ("openvpn", basename(file)) - local clientlist, connclients = clientlist (config.status) - table.insert ( configlist, { name = file, type = conf_type, errtxt = errtxt, status = isrunning, clients = connclients } ) - end - return cfe({ type="structure", value=configlist, label="Configuration List" }) + local config = config_content(configfile) + return cfe({ value=config.log or "", label="Log file" }) end -function get_filecontent(f) +function get_filecontent() --FIXME validate - return modelfunctions.getfiledetails(f, list_conffiles()) + return modelfunctions.getfiledetails(configfile) end function update_filecontent(filedetails) --FIXME validate - return modelfunctions.setfiledetails(filedetails, list_conffiles()) + return modelfunctions.setfiledetails(filedetails, {configfile}) end -function create_new_config() - config = { - name = cfe({ label="File Name", descr="File name should end with \".conf\"" }), - } +function list_certs() + local list = {} + for file in fs.find(".*%.pem", baseurl) do + list[#list+1] = basename(file) + end + return cfe({ type="list", value=list, label="OpenVPN Certificates" }) +end - return cfe({ type="group", value=config, label="Config" }) +function delete_cert(certname) + local list = list_certs() + local retval = cfe({ label="Delete Certificate result", errtxt="Invalid cert name" }) + for i,cert in ipairs(list.value) do + if cert == certname then + os.remove(baseurl..certname) + retval.value = "Certificate deleted" + retval.errtxt = nil + break + end + end + return retval end -function create_config(config) +function new_upload_cert() + local value = {} + value.cert = cfe({ type="raw", value=0, label="Certificate", descr='File must be a password protected ".pfx" file' }) + value.password = cfe({ label="Certificate Password" }) + value.name = cfe({ label="Certificate Local Name" }) + return cfe({ type="group", value=value }) +end + +function upload_cert(newcert) local success = true - local path = config.value.name.value - if not string.find(path, "/") then - path = baseurl .. path + -- Trying to upload a cert/key + -- The way haserl works, cert contains the temporary file name + -- First, get the cert + local cmd, f, cmdresult + if validator.is_valid_filename(newcert.value.cert.value, "/tmp/") and fs.is_file(newcert.value.cert.value) then + cmd = path .. "openssl pkcs12 -in "..format.escapespecialcharacters(newcert.value.cert.value).." -out "..format.escapespecialcharacters(newcert.value.cert.value).."cert.pem -password pass:"..format.escapespecialcharacters(newcert.value.password.value).." -nokeys -clcerts 2>&1" + f = io.popen(cmd) + cmdresult = f:read("*a") + f:close() + local filestats = posix.stat(newcert.value.cert.value.."cert.pem") + if not filestats or filestats.size == 0 then + newcert.value.cert.errtxt = "Could not open certificate\n"..cmdresult + success = false + end + else + newcert.value.cert.errtxt = "Invalid certificate" + success = false end - if not validator.is_valid_filename(path, baseurl) then - success = false - config.value.name.errtxt = "Invalid path" - elseif posix.stat(path) then + -- Now, get the key and the ca certs + if success then + cmd = path .. "openssl pkcs12 -in "..format.escapespecialcharacters(newcert.value.cert.value).." -out "..format.escapespecialcharacters(newcert.value.cert.value).."key.pem -password pass:"..format.escapespecialcharacters(newcert.value.password.value).." -nocerts -nodes 2>&1" + f = io.popen(cmd) + cmdresult = f:read("*a") + f:close() + filestats = posix.stat(newcert.value.cert.value.."key.pem") + if not filestats or filestats.size == 0 then + newcert.value.cert.errtxt = "Could not find key\n"..cmdresult + success = false + end + + cmd = path .. "openssl pkcs12 -in "..format.escapespecialcharacters(newcert.value.cert.value).." -out "..format.escapespecialcharacters(newcert.value.cert.value).."ca.pem -password pass:"..format.escapespecialcharacters(newcert.value.password.value).." -nokeys -cacerts 2>&1" + f = io.popen(cmd) + cmdresult = f:read("*a") + f:close() + filestats = posix.stat(newcert.value.cert.value.."ca.pem") + if not filestats or filestats.size == 0 then + newcert.value.cert.errtxt = "Could not find CA certs\n"..cmdresult + success = false + end + end + + if newcert.value.name.value == "" then + newcert.value.name.errtxt = "Cannot be blank" success = false - config.value.name.errtxt = "File already exists" - elseif not string.match(path,".*%.conf") then + elseif posix.stat(baseurl..newcert.value.name.value.."-cert.pem") or posix.stat(baseurl..newcert.value.name.value.."-key.pem") or posix.stat(baseurl..newcert.value.name.value.."-ca.pem") then + newcert.value.name.errtxt = "Certificate of this name already exists" success = false - config.value.name.errtxt = "Filename must end with '.conf'" end if success then - fs.create_file(path) + if not posix.stat(baseurl) then + posix.mkdir(baseurl) + end + -- copy the keys + fs.move_file(newcert.value.cert.value.."cert.pem", baseurl..newcert.value.name.value.."-cert.pem") + fs.move_file(newcert.value.cert.value.."key.pem", baseurl..newcert.value.name.value.."-key.pem") + fs.move_file(newcert.value.cert.value.."ca.pem", baseurl..newcert.value.name.value.."-ca.pem") + posix.chmod(baseurl..newcert.value.name.value.."-key.pem", "rw-------") else - config.errtxt = "Failed to create config" + newcert.errtxt = "Failed to upload certificate" end - return config -end - -function delete_config(name) - local cmdresult = cfe({ label="Delete config result", errtxt="Failed to delete config - not found" }) - - if validator.is_valid_filename(name, baseurl) and fs.is_file(name) then - os.remove(name) - cmdresult.value = "Config Deleted" - cmdresult.errtxt = nil + -- Delete the temporary files + if validator.is_valid_filename(newcert.value.cert.value, "/tmp/") and fs.is_file(newcert.value.cert.value) then + os.remove(newcert.value.cert.value.."cert.pem") + os.remove(newcert.value.cert.value.."key.pem") + os.remove(newcert.value.cert.value.."ca.pem") end - return cmdresult + return newcert end -function startstop_service(action,service) - if (service ~= "openvpn") then - if ( fs.is_file(baseurl .. service .. ".conf") ) then - service = "openvpn." .. tostring(service) - if not ( fs.is_file("/etc/init.d/" .. service ) ) then - -- Create missing symlinks - posix.link("/etc/init.d/openvpn","/etc/init.d/" .. service, true) - end - else - return nil +view_cert = function(certname) + local list = list_certs() + local cmdresult = "Invalid cert name" + for i,cert in ipairs(list.value) do + if cert == certname or certname == (baseurl .. cert) then + local cmd = path .. "openssl x509 -in "..baseurl..format.escapespecialcharacters(cert).." -noout -text" + local f = io.popen(cmd) + cmdresult = f:read("*a") + f:close() + cmdresult = cmdresult .. "Content:\n" .. (fs.read_file(baseurl..cert) or "") end end - return modelfunctions.startstop_service(service, action) + return cfe({ type="table", value={name=certname, value=cmdresult}, label="Certificate" }) +end + +generate_dh_params = function() + local cmd = path .. "openssl dhparam -out /etc/openvpn/dh1024.pem 1024 2>&1" + f = io.popen(cmd) + local cmdresult = f:read("*a") + f:close() + + return cfe({ value=cmdresult, label="Generate Diffie Hellman parameters result" }) end diff --git a/openvpn-startstop-html.lsp b/openvpn-startstop-html.lsp index be08c76..0ea2627 100755..120000 --- a/openvpn-startstop-html.lsp +++ b/openvpn-startstop-html.lsp @@ -1,37 +1 @@ -<% local data, viewlibrary, page_info = ... %> -<% ---[[ -io.write("<H1>DEBUGGING</H1><span style='color:red'><H2>DEBUG INFO: CFE</H2>") -io.write(html.cfe_unpack(data)) -io.write("</span>") ---]] -%> -<H1>Management</H1> -<% ---[[ -%> -<% if data.value.result then %> -<H2>Previous action result</H2> -<% if data.value.result.value ~= "" then %> -<P CLASS='descr'><%= string.gsub(html.html_escape(data.value.result.value), "\n", "<BR>") %></P> -<% end if data.value.result.errtxt then %> -<P CLASS='error'><%= string.gsub(html.html_escape(data.value.result.errtxt), "\n", "<BR>") %></P> -<% end end %> -<% ---]] -%> -<DL> -<DT>Managing process based on</DT> -<DD><%= data.service %>.conf</DD> -</DL> -<DL> -<form action="<%= html.html_escape(page_info.script .. page_info.prefix .. page_info.controller .. "/" .. page_info.action) %>" method="POST"> -<DT>Program control-panel</DT> -<DD> -<% for i,act in ipairs(data.value.actions.value) do %> - <input class="submit" type="submit" name="action" value="<%= act %>"> -<% end %> -<input class="hidden" type="hidden" name="service" value="<%= data.service %>"> -</DD> -</form> -</DL> +../startstop-html.lsp
\ No newline at end of file diff --git a/openvpn-statusinfo-html.lsp b/openvpn-statusinfo-html.lsp index e68ca0c..eae83fe 100644 --- a/openvpn-statusinfo-html.lsp +++ b/openvpn-statusinfo-html.lsp @@ -1,4 +1,8 @@ -<% local view = ... %> +<% local view, viewlibrary = ... %> + +<% viewlibrary.dispatch_component("status") %> + +<% viewlibrary.dispatch_component("viewconfig") %> <h1>Status</h1> <h2>Connected clients</h2> diff --git a/openvpn-viewconfig-html.lsp b/openvpn-viewconfig-html.lsp index 65240a9..b644195 100644 --- a/openvpn-viewconfig-html.lsp +++ b/openvpn-viewconfig-html.lsp @@ -2,7 +2,7 @@ <% require("format") %> <% local shortname = string.gsub(view.value.name, "^.*/", "") %> -<h1><%= html.html_escape(format.cap_begin_word(view.value.type)) %> config '<%= html.html_escape(shortname) %>'</h1> +<h1><%= html.html_escape(format.cap_begin_word(view.value.type)) %> Config</h1> <h2><%= html.html_escape(format.cap_begin_word(view.value.type)) %> settings</h2> <dl> @@ -51,22 +51,22 @@ <dl> <% if (view.value.dh) then %> <dt>DH</dt> -<dd><%= html.html_escape(view.value.dh) %><% -- html.link{value = page_info.script .. page_info.prefix .. page_info.controller .. "/pem_info?name=" .. view.value.dh , label=view.value.dh } %></dd> +<dd><%= html.link{value = page_info.script .. page_info.prefix .. page_info.controller .. "/viewcert?cert=" .. view.value.dh, label=view.value.dh } %></dd> <% end %> <% if (view.value.ca) then %> <dt>CA Certificate</dt> -<dd><%= html.html_escape(view.value.ca) %><% -- html.link{value = page_info.script .. page_info.prefix .. page_info.controller .. "/pem_info?name=" .. view.value.ca , label=view.value.ca } %></dd> +<dd><%= html.link{value = page_info.script .. page_info.prefix .. page_info.controller .. "/viewcert?cert=" .. view.value.ca, label=view.value.ca } %></dd> <% end %> <% if (view.value.cert) then %> <dt>Certificate</dt> -<dd><%= html.html_escape(view.value.cert) %><% -- html.link{value = page_info.script .. page_info.prefix .. page_info.controller .. "/pem_info?name=" .. view.value.cert , label=view.value.cert } %></dd> +<dd><%= html.link{value = page_info.script .. page_info.prefix .. page_info.controller .. "/viewcert?cert=" .. view.value.cert, label=view.value.cert } %></dd> <% end %> <% if (view.value.key) then %> <dt>Private Key</dt> -<dd><%= html.html_escape(view.value.key) %><% -- html.link{value = page_info.script .. page_info.prefix .. page_info.controller .. "/pem_info?name=" .. view.value.key , label=view.value.key } %></dd> +<dd><%= html.html_escape(view.value.key) %></dd> <% end %> <% if (view.value.tls) then %> diff --git a/openvpn.menu b/openvpn.menu index 60ee99b..c62dabb 100644 --- a/openvpn.menu +++ b/openvpn.menu @@ -1,3 +1,5 @@ #CAT GROUP/DESC TAB ACTION -Networking 65OpenVPN Status status -Networking 65OpenVPN Config listconfigs +Networking 65OpenVPN Status statusinfo +Networking 65OpenVPN Certificates listcerts +Networking 65OpenVPN Expert expert +Networking 65OpenVPN Log_File logfile diff --git a/openvpn.roles b/openvpn.roles index c6f4134..01e19a3 100644 --- a/openvpn.roles +++ b/openvpn.roles @@ -1,3 +1,3 @@ -USER=openvpn:status,openvpn:statusinfo,openvpn:logfile,openvpn:listconfigs,openvpn:viewconfig -EXPERT=openvpn:editconfig,openvpn:createconfig,openvpn:deleteconfig -ADMIN=openvpn:status,openvpn:statusinfo,openvpn:logfile,openvpn:listconfigs,openvpn:viewconfig,openvpn:editconfig,openvpn:createconfig,openvpn:deleteconfig,openvpn:startstop, +USER=openvpn:status,openvpn:statusinfo,openvpn:logfile,openvpn:viewconfig,openvpn:startstop +EXPERT=openvpn:expert,openvpn:listcerts,openvpn:deletecert,openvpn:uploadcert,openvpn:viewcert,openvpn:generatedhparams +ADMIN=openvpn:status,openvpn:statusinfo,openvpn:logfile,openvpn:viewconfig,openvpn:startstop,openvpn:expert,openvpn:listcerts,openvpn:deletecert,openvpn:uploadcert,openvpn:viewcert,openvpn:generatedhparams |