luci-app-openvpn: "final" changeset
authorDirk Brenken <dev@brenken.org>
Sat, 24 Nov 2018 15:33:54 +0000 (16:33 +0100)
committerDirk Brenken <dev@brenken.org>
Mon, 26 Nov 2018 12:19:52 +0000 (13:19 +0100)
* add 'auth-user-pass' edit section in file mode (see screenshot)
* add port & protocol detection in file mode (see screenshot)
* don't mix file & normal edit modes any longer
* add CC compatibility fix (for turris devices)
* fix/refine JS instance name filter
* remove needless CSS rules
* unlink ovpn/auth files on section removal
* commit changes instantly (Add/Upload/Delete)

Signed-off-by: Dirk Brenken <dev@brenken.org>
applications/luci-app-openvpn/luasrc/model/cbi/openvpn-advanced.lua
applications/luci-app-openvpn/luasrc/model/cbi/openvpn-basic.lua
applications/luci-app-openvpn/luasrc/model/cbi/openvpn-file.lua
applications/luci-app-openvpn/luasrc/model/cbi/openvpn.lua
applications/luci-app-openvpn/luasrc/view/openvpn/cbi-select-input-add.htm
applications/luci-app-openvpn/luasrc/view/openvpn/ovpn_css.htm
applications/luci-app-openvpn/luasrc/view/openvpn/pageswitch.htm

index 9a37ba80221185be4919e7c3e8afd739b29d3498..2124c3d285774615e3a296064cba410d40383556 100644 (file)
@@ -158,10 +158,6 @@ local knownParams = {
                        "script_security",
                        { 0, 1, 2, 3 },
                        translate("Policy level over usage of external programs and scripts") },
-               { Value,
-                       "config",
-                       "/etc/openvpn/ovpn-file.ovpn",
-                       translate("Local OVPN configuration file") },
        } },
 
        { "Networking", {
index 3be274dc8b0bd6aba914b046687613ba1503a7f3..3e9137baeb027cd28646bb210667b5cada2bd4ec 100644 (file)
@@ -87,10 +87,6 @@ local basicParams = {
                "key",
                "/etc/easy-rsa/keys/some-client.key",
                translate("Local private key") },
-       { Value,
-               "config",
-               "/etc/openvpn/ovpn-file.ovpn",
-               translate("Local OVPN configuration file") },
 }
 
 
index 6878275d78b0512e46ce19c3ec9363b1696237e3..9d50601b1f9df53f1beb3d81acde7158bc088999 100644 (file)
@@ -1,10 +1,11 @@
 -- Licensed to the public under the Apache License 2.0.
 
-local ip       = require("luci.ip")
-local fs       = require("nixio.fs")
-local util     = require("luci.util")
-local uci      = require("luci.model.uci").cursor()
-local cfg_file = uci:get("openvpn", arg[1], "config")
+local ip        = require("luci.ip")
+local fs        = require("nixio.fs")
+local util      = require("luci.util")
+local uci       = require("luci.model.uci").cursor()
+local cfg_file  = uci:get("openvpn", arg[1], "config")
+local auth_file = cfg_file:match("(.+)%..+").. ".auth"
 
 local m = Map("openvpn")
 
@@ -36,25 +37,45 @@ f:append(Template("openvpn/ovpn_css"))
 f.submit = translate("Save")
 f.reset = false
 
-s = f:section(SimpleSection, nil, translatef("This form allows you to modify the content of the OVPN config file (%s). ", cfg_file))
-file = s:option(TextValue, "data")
+s = f:section(SimpleSection, nil, translatef("Section to modify the OVPN config file (%s)", cfg_file))
+file = s:option(TextValue, "data1")
 file.datatype = "string"
 file.rows = 20
-file.rmempty = true
 
 function file.cfgvalue()
        return fs.readfile(cfg_file) or ""
 end
 
-function file.write(self, section, data)
-       return fs.writefile(cfg_file, "\n" .. util.trim(data:gsub("\r\n", "\n")) .. "\n")
+function file.write(self, section, data1)
+       return fs.writefile(cfg_file, "\n" .. util.trim(data1:gsub("\r\n", "\n")) .. "\n")
 end
 
 function file.remove(self, section, value)
        return fs.writefile(cfg_file, "")
 end
 
-function s.handle(self, state, data)
+function s.handle(self, state, data1)
+       return true
+end
+
+s = f:section(SimpleSection, nil, translatef("Section to add an optional 'auth-user-pass' file with your credentials (%s)", auth_file))
+file = s:option(TextValue, "data2")
+file.datatype = "string"
+file.rows = 5
+
+function file.cfgvalue()
+       return fs.readfile(auth_file) or ""
+end
+
+function file.write(self, section, data2)
+       return fs.writefile(auth_file, util.trim(data2:gsub("\r\n", "\n")) .. "\n")
+end
+
+function file.remove(self, section, value)
+       return fs.writefile(auth_file, "")
+end
+
+function s.handle(self, state, data2)
        return true
 end
 
index ad607ae6c2183341f7b07f8daf9ae03b917d69fb..41266d860e523b3c05921287e74f42c17bd5aa54 100644 (file)
@@ -69,10 +69,14 @@ function s.create(self, name)
                        local options = uci:get_all("openvpn_recipes", recipe)
                        for k, v in pairs(options) do
                                if k ~= "_role" and k ~= "_description" then
+                                       if type(v) == "boolean" then
+                                               v = v and "1" or "0"
+                                       end
                                        uci:set("openvpn", name, k, v)
                                end
                        end
                        uci:save("openvpn")
+                       uci:commit("openvpn")
                        if extedit then
                                luci.http.redirect( self.extedit:format(name) )
                        end
@@ -80,10 +84,23 @@ function s.create(self, name)
        elseif #name > 0 then
                self.invalid_cts = true
        end
-
        return 0
 end
 
+function s.remove(self, name)
+       local cfg_file  = "/etc/openvpn/" ..name.. ".ovpn"
+       local auth_file = "/etc/openvpn/" ..name.. ".auth"
+       if fs.access(cfg_file) then
+               fs.unlink(cfg_file)
+       end
+       if fs.access(auth_file) then
+               fs.unlink(auth_file)
+       end
+       uci:delete("openvpn", name)
+       uci:save("openvpn")
+       uci:commit("openvpn")
+end
+
 s:option( Flag, "enabled", translate("Enabled") )
 
 local active = s:option( DummyValue, "_active", translate("Started") )
@@ -124,12 +141,30 @@ end
 local port = s:option( DummyValue, "port", translate("Port") )
 function port.cfgvalue(self, section)
        local val = AbstractValue.cfgvalue(self, section)
+       if not val then
+               local file_cfg = self.map:get(section, "config")
+               if file_cfg  and fs.access(file_cfg) then
+                       val = sys.exec("awk '{if(match(tolower($1),/^port$/)&&match($2,/[0-9]+/)){cnt++;printf $2;exit}}END{if(cnt==0)printf \"-\"}' " ..file_cfg)
+                       if val == "-" then
+                               val = sys.exec("awk '{if(match(tolower($1),/^remote$/)&&match($3,/[0-9]+/)){cnt++;printf $3;exit}}END{if(cnt==0)printf \"-\"}' " ..file_cfg)
+                       end
+               end
+       end
        return val or "-"
 end
 
 local proto = s:option( DummyValue, "proto", translate("Protocol") )
 function proto.cfgvalue(self, section)
        local val = AbstractValue.cfgvalue(self, section)
+       if not val then
+               local file_cfg = self.map:get(section, "config")
+               if file_cfg and fs.access(file_cfg) then
+                       val = sys.exec("awk '{if(match(tolower($1),/^proto$/)&&match(tolower($2),/^udp[46]*$|^tcp[46]*-server$|^tcp[46]*-client$/)){cnt++;printf tolower($2);exit}}END{if(cnt==0)printf \"-\"}' " ..file_cfg)
+                       if val == "-" then
+                               val = sys.exec("awk '{if(match(tolower($1),/^remote$/)&&match(tolower($4),/^udp[46]*$|^tcp[46]*-server$|^tcp[46]*-client$/)){cnt++;printf $4;exit}}END{if(cnt==0)printf \"-\"}' " ..file_cfg)
+                       end
+               end
+       end
        return val or "-"
 end
 
index 09da2eb22df799f9c423e673af0c7495c3decf8a..e75bfda900bd3fcfb0fa9f42167dd34af00fcbff 100644 (file)
@@ -3,7 +3,7 @@
 //<![CDATA[
        function vpn_add()
        {
-               var vpn_name     = div_add.querySelector("#instance_name1").value.replace(/[^\x00-\x7F]|[\s!@#$%^&*()+=\[\]{};':"\\|,<>\/?]/g,'');
+               var vpn_name     = div_add.querySelector("#instance_name1").value.replace(/[^\x00-\x7F]|[\s!@#$%^&*()\-+=\[\]{};':"\\|,<>\/?]/g,'');
                var vpn_template = div_add.querySelector("#instance_template").value;
                var form         = document.getElementsByName('cbi')[0];
 
@@ -31,7 +31,7 @@
 
        function vpn_upload()
        {
-               var vpn_name = div_upload.querySelector("#instance_name2").value.replace(/[^\x00-\x7F]|[\s!@#$%^&*()+=\[\]{};':"\\|,<>\/?]/g,'');
+               var vpn_name = div_upload.querySelector("#instance_name2").value.replace(/[^\x00-\x7F]|[\s!@#$%^&*()\-+=\[\]{};':"\\|,<>\/?]/g,'');
                var vpn_file = document.getElementById("ovpn_file").value;
                var form     = document.getElementsByName('cbi')[0];
 
        <div class="table cbi-section-table">
                <h4><%:Template based configuration%></h4>
                <div class="tr cbi-section-table-row" id="div_add">
-                       <div class="td">
+                       <div class="td left">
                                <input type="text" maxlength="20" placeholder="Instance name" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.text" id="instance_name1" />
                        </div>
-                       <div class="td">
+                       <div class="td left">
                                <select id="instance_template" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.select">
                                        <option value="" selected="selected" disabled="disabled"><%:Select template ...%></option>
                                        <%- for k, v in luci.util.kspairs(self.add_select_options) do %>
                                        <% end -%>
                                </select>
                        </div>
-                       <div class="td">
+                       <div class="td left">
                                <input class="cbi-button cbi-button-add" type="submit" onclick="vpn_add(); return false;" value="<%:Add%>" title="<%:Add template based configuration%>" /><br />
                        </div>
                </div>
                <h4><%:OVPN configuration file upload%></h4>
                <div class="tr cbi-section-table-row" id="div_upload">
-                       <div class="td">
+                       <div class="td left">
                                <input type="text" maxlength="20" placeholder="Instance name" name="instance_name2" id="instance_name2" />
                        </div>
-                       <div class="td">
+                       <div class="td left">
                                <input type="file" name="ovpn_file" id="ovpn_file" accept="application/x-openvpn-profile,.ovpn" />
                        </div>
-                       <div class="td">
+                       <div class="td left">
                                <input class="cbi-button cbi-button-add" type="submit" onclick="vpn_upload(); return false;" value="<%:Upload%>" title="<%:Upload ovpn file%>" />
                        </div>
                </div>
index c7062b8d7a9a13ed3f2e25581f5aa20c83d72c06..55c0a543fc09e8ac4125404cf78613c8820c1554 100644 (file)
                border: 0px;
                text-align: left;
        }
-       .td
-       {
-               text-align: left;
-               border-top: 0px;
-               margin: 5px;
-       }
        .vpn-output
        {
                box-shadow: none;
index 17beef0d39cc80b153e392776614e4135a3e9787..c1fe05215a1c3462bc22918d9a49642bf394331f 100644 (file)
                <a href="<%=url('admin/services/openvpn')%>"><%:Overview%></a> &#187;
                <%=luci.i18n.translatef("Instance \"%s\"", self.instance)%>
        </h3>
-       <% if self.mode == "file" then %>
-               <a href="<%=url('admin/services/openvpn/basic', self.instance)%>"><%:Switch to basic configuration%> &#187;</a><p/>
-               <a href="<%=url('admin/services/openvpn/advanced', self.instance, "Service")%>"><%:Switch to advanced configuration%> &#187;</a>
-               <hr />
-       <% elseif self.mode == "basic" then %>
+       <% if self.mode == "basic" then %>
                <a href="<%=url('admin/services/openvpn/advanced', self.instance, "Service")%>"><%:Switch to advanced configuration%> &#187;</a><p/>
-               <a href="<%=url('admin/services/openvpn/file', self.instance)%>"><%:Switch to file based configuration%> &#187;</a>
                <hr />
        <% elseif self.mode == "advanced" then %>
                <a href="<%=url('admin/services/openvpn/basic', self.instance)%>"><%:Switch to basic configuration%> &#187;</a><p/>
-               <a href="<%=url('admin/services/openvpn/file', self.instance)%>"><%:Switch to file based configuration%> &#187;</a>
                <hr />
                <%:Configuration category%>:
                <% for i, c in ipairs(self.categories) do %>