treewide: filter shell arguments through shellquote() where applicable
authorJo-Philipp Wich <jo@mein.io>
Thu, 5 Apr 2018 07:32:22 +0000 (09:32 +0200)
committerJo-Philipp Wich <jo@mein.io>
Thu, 5 Apr 2018 07:37:43 +0000 (09:37 +0200)
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
22 files changed:
applications/luci-app-adblock/luasrc/controller/adblock.lua
applications/luci-app-cshark/luasrc/controller/cshark.lua
applications/luci-app-ddns/luasrc/controller/ddns.lua
applications/luci-app-freifunk-diagnostics/luasrc/controller/freifunk/diag.lua
applications/luci-app-mwan3/luasrc/controller/mwan3.lua
applications/luci-app-olsr/luasrc/controller/olsr.lua
applications/luci-app-openvpn/luasrc/model/cbi/openvpn.lua
applications/luci-app-splash/luasrc/controller/splash/splash.lua
applications/luci-app-splash/root/usr/sbin/luci-splash
applications/luci-app-statistics/luasrc/statistics/rrdtool.lua
applications/luci-app-tinyproxy/luasrc/view/tinyproxy_status.htm
applications/luci-app-upnp/luasrc/controller/upnp.lua
applications/luci-app-vnstat/luasrc/view/vnstat.htm
applications/luci-app-wol/luasrc/model/cbi/wol.lua
modules/luci-base/luasrc/model/ipkg.lua
modules/luci-base/luasrc/model/uci.lua
modules/luci-base/luasrc/sys.lua
modules/luci-base/luasrc/tools/status.lua
modules/luci-mod-admin-full/luasrc/controller/admin/network.lua
modules/luci-mod-admin-full/luasrc/controller/admin/status.lua
modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/vlan.lua
modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/wifi.lua

index 700f187..763c0b4 100644 (file)
@@ -36,8 +36,8 @@ end
 function queryData(domain)
        if domain then
                luci.http.prepare_content("text/plain")
-               local cmd = "/etc/init.d/adblock query %q 2>&1"
-               local util = io.popen(cmd % domain)
+               local cmd = "/etc/init.d/adblock query %s 2>&1"
+               local util = io.popen(cmd % util.shellquote(domain))
                if util then
                        while true do
                                local line = util:read("*l")
index 4d9bbba..43410a0 100644 (file)
@@ -53,7 +53,13 @@ function cshark_iface_dump_start(ifname, value, flag, filter)
 
        luci.http.prepare_content("text/plain")
 
-       local res = os.execute("(/sbin/cshark -i " .. ifname .. " -" .. flag .. " " .. value .. " -p /tmp/cshark-luci.pid " .. filter .. " > /tmp/cshark-luci.out 2>&1) &")
+       local res = os.execute("(/sbin/cshark -i %s -%s %s -p /tmp/cshark-luci.pid %s > /tmp/cshark-luci.out 2>&1) &" %{
+               luci.util.shellquote(ifname),
+               luci.util.shellquote(flag),
+               luci.util.shellquote(value),
+               luci.util.shellquote(filter)
+       })
+
        luci.http.write(tostring(res))
 end
 
index 3d31e4e..5f4a511 100755 (executable)
@@ -301,7 +301,7 @@ function startstop(section, enabled)
        uci:unload("ddns")
 
        -- start ddns-updater for section
-       local command = luci_helper .. [[ -S ]] .. section .. [[ -- start]]
+       local command = "%s -S %s -- start" %{ luci_helper, UTIL.shellquote(section) }
        os.execute(command)
        NX.nanosleep(3) -- 3 seconds "show time"
 
index 7bb4761..92b3afc 100644 (file)
@@ -33,7 +33,7 @@ function diag_command(cmd, addr)
        if addr and addr:match("^[a-zA-Z0-9%-%.:_]+$") then
                luci.http.prepare_content("text/plain")
 
-               local util = io.popen(cmd % addr)
+               local util = io.popen(cmd % luci.util.shellquote(addr))
                if util then
                        while true do
                                local ln = util:read("*l")
@@ -52,21 +52,21 @@ function diag_command(cmd, addr)
 end
 
 function diag_ping(addr)
-       diag_command("ping -c 5 -W 1 %q 2>&1", addr)
+       diag_command("ping -c 5 -W 1 %s 2>&1", addr)
 end
 
 function diag_traceroute(addr)
-       diag_command("traceroute -q 1 -w 1 -n %q 2>&1", addr)
+       diag_command("traceroute -q 1 -w 1 -n %s 2>&1", addr)
 end
 
 function diag_nslookup(addr)
-       diag_command("nslookup %q 2>&1", addr)
+       diag_command("nslookup %s 2>&1", addr)
 end
 
 function diag_ping6(addr)
-       diag_command("ping6 -c 5 %q 2>&1", addr)
+       diag_command("ping6 -c 5 %s 2>&1", addr)
 end
 
 function diag_traceroute6(addr)
-       diag_command("traceroute6 -q 1 -w 2 -n %q 2>&1", addr)
+       diag_command("traceroute6 -q 1 -w 2 -n %s 2>&1", addr)
 end
index 64ee9f5..27dc984 100644 (file)
@@ -98,7 +98,7 @@ function diagnosticsData(interface, task)
 
        function diag_command(cmd, addr)
                if addr and addr:match("^[a-zA-Z0-9%-%.:_]+$") then
-                       local util = io.popen(cmd % addr)
+                       local util = io.popen(cmd % ut.shellquote(addr))
                        if util then
                                while true do
                                        local ln = util:read("*l")
@@ -138,7 +138,7 @@ function diagnosticsData(interface, task)
                if task == "ping_gateway" then
                        local gateway = get_gateway(interface)
                        if gateway ~= nil then
-                               diag_command("ping -c 5 -W 1 %q 2>&1", gateway)
+                               diag_command("ping -c 5 -W 1 %s 2>&1", gateway)
                        else
                                luci.http.prepare_content("text/plain")
                                luci.http.write(string.format("No gateway for interface %s found.", interface))
@@ -147,7 +147,7 @@ function diagnosticsData(interface, task)
                        local trackips = uci:get("mwan3", interface, "track_ip")
                        if #trackips > 0 then
                                for i in pairs(trackips) do
-                                       diag_command("ping -c 5 -W 1 %q 2>&1", trackips[i])
+                                       diag_command("ping -c 5 -W 1 %s 2>&1", trackips[i])
                                end
                        else
                                luci.http.write(string.format("No tracking Hosts for interface %s defined.", interface))
@@ -185,10 +185,10 @@ function diagnosticsData(interface, task)
                                luci.http.write(string.format("Routing table %s for interface %s not found", number, interface))
                        end
                elseif task == "hotplug_ifup" then
-                       os.execute(string.format("/usr/sbin/mwan3 ifup %s", interface))
+                       os.execute(string.format("/usr/sbin/mwan3 ifup %s", ut.shellquote(interface)))
                        luci.http.write(string.format("Hotplug ifup sent to interface %s", interface))
                elseif task == "hotplug_ifdown" then
-                       os.execute(string.format("/usr/sbin/mwan3 ifdown %s", interface))
+                       os.execute(string.format("/usr/sbin/mwan3 ifdown %s", ut.shellquote(interface)))
                        luci.http.write(string.format("Hotplug ifdown sent to interface %s", interface))
                else
                        luci.http.write("Unknown task")
index 229f3d6..c5fb2b2 100644 (file)
@@ -84,11 +84,11 @@ function action_json()
        local jsonreq4
        local jsonreq6
 
-       local v4_port = uci:get("olsrd", "olsrd_jsoninfo", "port") or 9090
-       local v6_port = uci:get("olsrd6", "olsrd_jsoninfo", "port") or 9090
+       local v4_port = tonumber(uci:get("olsrd", "olsrd_jsoninfo", "port") or "") or 9090
+       local v6_port = tonumber(uci:get("olsrd6", "olsrd_jsoninfo", "port") or "") or 9090
 
-       jsonreq4 = utl.exec("(echo /status | nc 127.0.0.1 " .. v4_port .. " | sed -n '/^[}{ ]/p') 2>/dev/null" )
-       jsonreq6 = utl.exec("(echo /status | nc ::1 " .. v6_port .. " | sed -n '/^[}{ ]/p') 2>/dev/null")
+       jsonreq4 = utl.exec("(echo /status | nc 127.0.0.1 %d | sed -n '/^[}{ ]/p') 2>/dev/null" % v4_port)
+       jsonreq6 = utl.exec("(echo /status | nc ::1 %d | sed -n '/^[}{ ]/p') 2>/dev/null" % v6_port)
        http.prepare_content("application/json")
        if not jsonreq4 or jsonreq4 == "" then
                jsonreq4 = "{}"
@@ -150,7 +150,7 @@ function action_neigh(json)
        for _, dev in ipairs(devices) do
                for _, net in ipairs(dev:get_wifinets()) do
                        local radio = net:get_device()
-                       assoclist[#assoclist+1] = {} 
+                       assoclist[#assoclist+1] = {}
                        assoclist[#assoclist]['ifname'] = net:ifname()
                        assoclist[#assoclist]['network'] = net:network()[1]
                        assoclist[#assoclist]['device'] = radio and radio:name() or nil
@@ -165,7 +165,7 @@ function action_neigh(json)
                local mac = ""
                local ip
                local neihgt = {}
-               
+
                if resolve == "1" then
                        hostname = nixio.getnameinfo(v.remoteIP, nil, 100)
                        if hostname then
@@ -350,11 +350,11 @@ function fetch_jsoninfo(otable)
        local IpVersion = uci:get_first("olsrd", "olsrd","IpVersion")
        local jsonreq4 = ""
        local jsonreq6 = ""
-       local v4_port = uci:get("olsrd", "olsrd_jsoninfo", "port") or 9090
-       local v6_port = uci:get("olsrd6", "olsrd_jsoninfo", "port") or 9090
+       local v4_port = tonumber(uci:get("olsrd", "olsrd_jsoninfo", "port") or "") or 9090
+       local v6_port = tonumber(uci:get("olsrd6", "olsrd_jsoninfo", "port") or "") or 9090
 
-       jsonreq4 = utl.exec("(echo /" .. otable .. " | nc 127.0.0.1 " .. v4_port .. " | sed -n '/^[}{ ]/p') 2>/dev/null")
-       jsonreq6 = utl.exec("(echo /" .. otable .. " | nc ::1 " .. v6_port .. " | sed -n '/^[}{ ]/p') 2>/dev/null")
+       jsonreq4 = utl.exec("(echo /%s | nc 127.0.0.1 %d | sed -n '/^[}{ ]/p') 2>/dev/null" %{ otable, v4_port })
+       jsonreq6 = utl.exec("(echo /%s | nc ::1 %d | sed -n '/^[}{ ]/p') 2>/dev/null" %{ otable, v6_port })
        local jsondata4 = {}
        local jsondata6 = {}
        local data4 = {}
index 719145b..ccad531 100644 (file)
@@ -26,9 +26,9 @@ uci:foreach( "openvpn_recipes", "openvpn_recipe",
 )
 
 function s.getPID(section) -- Universal function which returns valid pid # or nil
-       local pid = sys.exec("%s | grep -w %s | grep openvpn | grep -v grep | awk '{print $1}'" % { psstring,section} )
-       if pid and #pid > 0 and tonumber(pid) ~= nil then
-               return tonumber(pid)
+       local pid = sys.exec("%s | grep -w [o]penvpn(%s)" % { psstring, section })
+       if pid and #pid > 0 then
+               return tonumber(pid:match("^%d+"))
        else
                return nil
        end
index b4fdbd5..af7a3a3 100644 (file)
@@ -9,7 +9,7 @@ function index()
        entry({"admin", "services", "splash", "splashtext" }, form("splash/splashtext"), _("Splashtext"), 10)
 
        local e
-       
+
        e = node("splash")
        e.target = call("action_dispatch")
 
@@ -82,7 +82,7 @@ function action_activate()
                        end
                end)
 
-               if blacklisted then     
+               if blacklisted then
                        luci.http.redirect(luci.dispatcher.build_url("splash" ,"blocked"))
                else
                        local id = tostring(mac):gsub(':', ''):lower()
@@ -106,7 +106,7 @@ function action_status_admin()
        local uci = luci.model.uci.cursor_state()
        local macs = luci.http.formvaluetable("save")
 
-       local changes = { 
+       local changes = {
                whitelist = { },
                blacklist = { },
                lease     = { },
@@ -129,22 +129,22 @@ function action_status_admin()
 
        if #changes.whitelist > 0 then
                os.execute("luci-splash whitelist %s >/dev/null"
-                       % table.concat(changes.whitelist))
+                       % util.shellquote(table.concat(changes.whitelist)))
        end
 
        if #changes.blacklist > 0 then
                os.execute("luci-splash blacklist %s >/dev/null"
-                       % table.concat(changes.blacklist))
+                       % util.shellquote(table.concat(changes.blacklist)))
        end
 
        if #changes.lease > 0 then
                os.execute("luci-splash lease %s >/dev/null"
-                       % table.concat(changes.lease))
+                       % util.shellquote(table.concat(changes.lease)))
        end
 
        if #changes.remove > 0 then
                os.execute("luci-splash remove %s >/dev/null"
-                       % table.concat(changes.remove))
+                       % util.shellquote(table.concat(changes.remove)))
        end
 
        luci.template.render("admin_status/splash", { is_admin = true })
index 2870dbe..9ec9f3a 100755 (executable)
@@ -36,6 +36,10 @@ function call(cmd)
        os.execute(cmd)
 end
 
+function esc(str)
+       return utl.shellquote(str)
+end
+
 
 function lock()
        call("lock /var/run/luci_splash.lock")
@@ -84,14 +88,14 @@ end
 
 function get_physdev(interface)
        local dev
-       dev = utl.trim(sys.exec(". /lib/functions/network.sh; network_get_device IFNAME '" ..  interface .. "'; echo $IFNAME"))
+       dev = utl.trim(sys.exec(". /lib/functions/network.sh; network_get_device IFNAME %s; echo $IFNAME" % esc(interface)))
        return dev
 end
 
 
 
 function get_filter_handle(parent, direction, device, mac)
-       local input = utl.split(sys.exec('/usr/sbin/tc filter show dev ' .. device .. ' parent ' .. parent) or {})
+       local input = utl.split(sys.exec('/usr/sbin/tc filter show dev %s parent %s' %{ esc(device), esc(parent) }) or {})
        local tbl = {}
        local handle
        for k, v in pairs(input) do
@@ -264,7 +268,7 @@ function main(argv)
                                elseif whitelist_macs[mac] then
                                        print("Removing %s from whitelist" % mac)
                                        remove_whitelist(mac)
-                                       whitelist_macs[mac] = nil                                       
+                                       whitelist_macs[mac] = nil
                                elseif blacklist_macs[mac] then
                                        print("Removing %s from blacklist" % mac)
                                        remove_blacklist(mac)
@@ -295,7 +299,7 @@ function main(argv)
                print("\n  luci-splash remove <MAC-or-IP>\n    Remove given address from the lease-, black- or whitelist")
                print("")
 
-               os.exit(1)      
+               os.exit(1)
        end
 end
 
@@ -338,8 +342,8 @@ function ipt_delete_all(args, comp, off)
                        off[r.table] = off[r.table] or { }
                        off[r.table][r.chain] = off[r.table][r.chain] or 0
 
-                       exec("iptables -t %q -D %q %d 2>/dev/null"
-                               %{ r.table, r.chain, r.index - off[r.table][r.chain] })
+                       exec("iptables -t %s -D %s %d 2>/dev/null"
+                               %{ esc(r.table), esc(r.chain), r.index - off[r.table][r.chain] })
 
                        off[r.table][r.chain] = off[r.table][r.chain] + 1
                end
@@ -353,8 +357,8 @@ function ipt6_delete_all(args, comp, off)
                        off[r.table] = off[r.table] or { }
                        off[r.table][r.chain] = off[r.table][r.chain] or 0
 
-                       exec("ip6tables -t %q -D %q %d 2>/dev/null"
-                               %{ r.table, r.chain, r.index - off[r.table][r.chain] })
+                       exec("ip6tables -t %s -D %s %d 2>/dev/null"
+                               %{ esc(r.table), esc(r.chain), r.index - off[r.table][r.chain] })
 
                        off[r.table][r.chain] = off[r.table][r.chain] + 1
                end
@@ -460,13 +464,13 @@ function remove_whitelist_tc(mac)
                        end
                        local handle = get_filter_handle('ffff:', 'src', device, mac)
                        if handle then
-                               exec('tc filter del dev "%s" parent ffff: protocol ip prio 1 handle %s u32' % { device, handle })
+                               exec('tc filter del dev %s parent ffff: protocol ip prio 1 handle %s u32' % { esc(device), esc(handle) })
                        else
                                print('Warning! Could not get a handle for %s parent :ffff on interface %s' % { mac, device })
                        end
                        local handle = get_filter_handle('1:', 'dest', device, mac)
                        if handle then
-                               exec('tc filter del dev "%s" parent 1:0 protocol ip prio 1 handle %s u32' % { device, handle })
+                               exec('tc filter del dev %s parent 1:0 protocol ip prio 1 handle %s u32' % { esc(device), esc(handle) })
                        else
                                print('Warning! Could not get a handle for %s parent 1:0 on interface %s' % { mac, device })
                        end
@@ -492,37 +496,37 @@ function add_lease_rule(mac, ipaddr, device)
                id = get_id(ipaddr)
        end
 
-       exec("iptables -t mangle -I luci_splash_mark_out -m mac --mac-source %q -j RETURN" % mac)
+       exec("iptables -t mangle -I luci_splash_mark_out -m mac --mac-source %s -j RETURN" % esc(mac))
 
        -- Mark incoming packets to a splashed host
        -- for ipv4 - by iptables and destination
        if id and device then
-               exec("iptables -t mangle -I luci_splash_mark_in -d %q -j MARK --set-mark 0x1%s -m comment --comment %s" % {ipaddr, id, mac:upper()})
+               exec("iptables -t mangle -I luci_splash_mark_in -d %s -j MARK --set-mark 0x1%s -m comment --comment %s" % { esc(ipaddr), esc(id), esc(mac:upper())})
        end
 
        --for ipv6: need to use the mac here
 
        if has_ipv6 then
-               exec("ip6tables -t mangle -I luci_splash_mark_out -m mac --mac-source %q -j MARK --set-mark 79" % mac)
+               exec("ip6tables -t mangle -I luci_splash_mark_out -m mac --mac-source %s -j MARK --set-mark 79" % esc(mac))
                if id and device and tonumber(limit_down) then
-                       exec("tc filter add dev %s parent 1:0 protocol ipv6 prio 1 u32 match ether dst %s classid 1:%s" % {device, mac:lower(), id})
+                       exec("tc filter add dev %s parent 1:0 protocol ipv6 prio 1 u32 match ether dst %s classid 1:%s" % { esc(device), esc(mac:lower()), esc(id) })
                end
        end
 
 
        if device and tonumber(limit_up) > 0 then
-               exec('tc filter add dev "%s" parent ffff: protocol all prio 2 u32 match ether src %s police rate %skbit mtu 6k burst 6k drop' % {device, mac, limit_up})
+               exec('tc filter add dev %s parent ffff: protocol all prio 2 u32 match ether src %s police rate %skbit mtu 6k burst 6k drop' % { esc(device), esc(mac), esc(limit_up) })
        end
 
        if id and device and tonumber(limit_down) > 0 then
-               exec("tc class add dev %s parent 1: classid 1:0x%s htb rate %skbit" % { device, id, limit_down })
-               exec("tc qdisc add dev %s parent 1:%s sfq perturb 10" % { device, id })
+               exec("tc class add dev %s parent 1: classid 1:0x%s htb rate %skbit" % { esc(device), esc(id), esc(limit_down) })
+               exec("tc qdisc add dev %s parent 1:%s sfq perturb 10" % { esc(device), esc(id) })
        end
 
-       exec("iptables -t filter -I luci_splash_filter -m mac --mac-source %q -j RETURN" % mac)
-       exec("iptables -t nat    -I luci_splash_leases -m mac --mac-source %q -j RETURN" % mac)
+       exec("iptables -t filter -I luci_splash_filter -m mac --mac-source %s -j RETURN" % esc(mac))
+       exec("iptables -t nat    -I luci_splash_leases -m mac --mac-source %s -j RETURN" % esc(mac))
        if has_ipv6 then
-               exec("ip6tables -t filter -I luci_splash_filter -m mac --mac-source %q -j RETURN" % mac)
+               exec("ip6tables -t filter -I luci_splash_filter -m mac --mac-source %s -j RETURN" % esc(mac))
        end
 end
 
@@ -548,32 +552,32 @@ function remove_lease_rule(mac, ipaddr, device, limit_up, limit_down)
        if device and tonumber(limit_up) > 0 then
                local handle = get_filter_handle('ffff:', 'src', device, mac)
                if handle then
-                       exec('tc filter del dev "%s" parent ffff: protocol all prio 2 handle %s u32 police rate %skbit mtu 6k burst 6k drop' % {device, handle, limit_up})
+                       exec('tc filter del dev %s parent ffff: protocol all prio 2 handle %s u32 police rate %skbit mtu 6k burst 6k drop' % { esc(device), esc(handle), esc(limit_up) })
                else
                        print('Warning! Could not get a handle for %s parent :ffff on interface %s' % { mac, device })
                end
        end
        -- remove clients class
        if device and id then
-               exec('tc class del dev "%s" classid 1:%s' % {device, id})
-               exec('tc filter del dev "%s" parent 1:0 prio 1' % device) -- ipv6 rule
-               --exec('tc qdisc del dev "%s" parent 1:%s sfq perturb 10' % { device, id })
+               exec('tc class del dev %s classid 1:%s' % { esc(device), esc(id) })
+               exec('tc filter del dev %s parent 1:0 prio 1' % esc(device)) -- ipv6 rule
+               --exec('tc qdisc del dev %s parent 1:%s sfq perturb 10' % { esc(device), esc(id) })
        end
 end
 
 
 -- Add whitelist rules
 function add_whitelist_rule(mac)
-       exec("iptables -t filter -I luci_splash_filter -m mac --mac-source %q -j RETURN" % mac)
-       exec("iptables -t nat    -I luci_splash_leases -m mac --mac-source %q -j RETURN" % mac)
+       exec("iptables -t filter -I luci_splash_filter -m mac --mac-source %s -j RETURN" % esc(mac))
+       exec("iptables -t nat    -I luci_splash_leases -m mac --mac-source %s -j RETURN" % esc(mac))
        if has_ipv6 then
-               exec("ip6tables -t filter -I luci_splash_filter -m mac --mac-source %q -j RETURN" % mac)
+               exec("ip6tables -t filter -I luci_splash_filter -m mac --mac-source %s -j RETURN" % esc(mac))
        end
         uci:foreach("luci_splash", "iface", function(s)
                local device = get_physdev(s['.name'])
                if device and device ~= "" then
-                       exec('tc filter add dev "%s" parent ffff: protocol ip prio 1 u32 match ether src %s police pass' % { device, mac })
-                       exec('tc filter add dev "%s" parent 1:0 protocol ip prio 1 u32 match ether dst %s classid 1:1' % { device, mac })
+                       exec('tc filter add dev %s parent ffff: protocol ip prio 1 u32 match ether src %s police pass' % { esc(device), esc(mac) })
+                       exec('tc filter add dev %s parent 1:0 protocol ip prio 1 u32 match ether dst %s classid 1:1' % { esc(device), esc(mac) })
                end
         end)
 end
@@ -581,9 +585,9 @@ end
 
 -- Add blacklist rules
 function add_blacklist_rule(mac)
-       exec("iptables -t filter -I luci_splash_filter -m mac --mac-source %q -j DROP" % mac)
+       exec("iptables -t filter -I luci_splash_filter -m mac --mac-source %s -j DROP" % esc(mac))
        if has_ipv6 then
-               exec("ip6tables -t filter -I luci_splash_filter -m mac --mac-source %q -j DROP" % mac)
+               exec("ip6tables -t filter -I luci_splash_filter -m mac --mac-source %s -j DROP" % esc(mac))
        end
 end
 
@@ -596,15 +600,15 @@ function sync()
 
        -- Current leases in state files
        local leases = uci:get_all("luci_splash_leases")
-       
+
        -- Convert leasetime to seconds
        local leasetime = tonumber(uci:get("luci_splash", "general", "leasetime")) * 3600
-       
+
        -- Clean state file
        uci:load("luci_splash_leases")
        uci:revert("luci_splash_leases")
 
-        
+
        local blackwhitelist = uci:get_all("luci_splash")
        local whitelist_total = 0
        local whitelist_online = 0
@@ -628,7 +632,7 @@ function sync()
                                 end
 
                                -- Rewrite state
-                               uci:section("luci_splash_leases", "lease", convert_mac_to_secname(v.mac), {             
+                               uci:section("luci_splash_leases", "lease", convert_mac_to_secname(v.mac), {
                                        mac    = v.mac,
                                        ipaddr = v.ipaddr,
                                        device = v.device,
@@ -639,7 +643,7 @@ function sync()
                        end
                end
        end
-       
+
        -- Whitelist, Blacklist
        for _, s in utl.spairs(blackwhitelist,
                function(a,b) return blackwhitelist[a][".type"] > blackwhitelist[b][".type"] end
@@ -666,7 +670,7 @@ function sync()
 
        -- ToDo:
         -- include a new field "leases_online" in stats to differ between active clients and leases:
-        -- update_stats(leasecount, leases_online, whitelist_online, whitelist_total, blacklist_online, blacklist_total) later: 
+        -- update_stats(leasecount, leases_online, whitelist_online, whitelist_total, blacklist_online, blacklist_total) later:
         update_stats(leases_online, whitelist_online, whitelist_total, blacklist_online, blacklist_total)
 
        uci:save("luci_splash_leases")
index e29a2e1..47e1696 100644 (file)
@@ -87,7 +87,7 @@ function Graph._rrdtool( self, def, rrd )
        fs.mkdirr( dir )
 
        -- construct commandline
-       local cmdline = "rrdtool graph"
+       local cmdline = { "rrdtool", "graph" }
 
        -- copy default arguments to def stack
        for i, opt in ipairs(self.args) do
@@ -102,15 +102,11 @@ function Graph._rrdtool( self, def, rrd )
                        opt = opt:gsub( "{file}", rrd )
                end
 
-               if opt:match("[^%w]") then
-                       cmdline = cmdline .. " '" .. opt .. "'"
-               else
-                       cmdline = cmdline .. " " .. opt
-               end
+               cmdline[#cmdline+1] = luci.util.shellquote(opt)
        end
 
        -- execute rrdtool
-       local rrdtool = io.popen( cmdline )
+       local rrdtool = io.popen(table.concat(cmdline, " "))
        rrdtool:close()
 end
 
index d43a887..2ba9ddd 100644 (file)
@@ -13,7 +13,11 @@ if luci.http.formvalue("frame") == "1" then
                end)
 
        local data = false
-       local wget = io.popen("wget -qO- http://%s:%s" % { addr, port })
+       local wget = io.popen("wget -qO- http://%s:%s" %{
+               luci.util.shellquote(addr),
+               luci.util.shellquote(port)
+       })
+
        if wget then
                while true do
                        local l = wget:read("*l")
@@ -30,7 +34,10 @@ if luci.http.formvalue("frame") == "1" then
 
        if not data then
                luci.http.write(translate("Failed to retrieve statistics from url:"))
-               luci.http.write(" http://%s:%s" % { addr, port })
+               luci.http.write(" http://%s:%s" %{
+                       luci.util.pcdata(addr),
+                       luci.util.pcdata(port)
+               })
        end
 
        return
@@ -43,7 +50,7 @@ end
 <div class="cbi-map">
        <h2 name="content"><%:Tinyproxy Status%></h2>
        <div class="cbi-section">
-               <iframe src="<%=REQUESTURL%>?frame=1" style="width:100%; height:350px; border:none"></iframe>
+               <iframe src="<%=REQUEST_URI%>?frame=1" style="width:100%; height:350px; border:none"></iframe>
        </div>
 </div>
 
index e485708..95a0ef4 100644 (file)
@@ -21,7 +21,7 @@ end
 function act_status()
        local uci = luci.model.uci.cursor()
        local lease_file = uci:get("upnpd", "config", "upnp_lease_file")
-       
+
        local ipt = io.popen("iptables --line-numbers -t nat -xnvL MINIUPNPD 2>/dev/null")
        if ipt then
                local upnpf = lease_file and io.open(lease_file, "r")
@@ -39,7 +39,7 @@ function act_status()
                                        num     = tonumber(num)
                                        extport = tonumber(extport)
                                        intport = tonumber(intport)
-                                       
+
                                        if upnpf then
                                                local uln = upnpf:read("*l")
                                                if uln then descr = uln:match(string.format("^%s:%d:%s:%d:%%d*:(.*)$", proto:upper(), extport, intaddr, intport)) end
@@ -76,7 +76,7 @@ function act_delete(num)
 
                local lease_file = uci:get("upnpd", "config", "upnp_lease_file")
                if lease_file and nixio.fs.access(lease_file) then
-                       luci.sys.call("sed -i -e '%dd' %q" %{ idx, lease_file })
+                       luci.sys.call("sed -i -e '%dd' %s" %{ idx, luci.util.shellquote(lease_file) })
                end
 
                luci.http.status(200, "OK")
index 2b8d9ff..42d7d24 100644 (file)
@@ -21,12 +21,13 @@ style = (style and #style > 0) and style or "s"
 -- render image
 --
 if iface then
-       style = style:gsub("[^%w]", "")
-       iface = iface:gsub("[^%w%.%-%_]", "")
-
        luci.http.prepare_content("image/png")
 
-       local png = io.popen("vnstati -i '%s' '-%s' -o -" % { iface, style })
+       local png = io.popen("vnstati -i %s -%s -o -" %{
+               utl.shellquote(iface),
+               utl.shellquote(style)
+       })
+
        luci.http.write(png:read("*a"))
        png:close()
 
@@ -89,7 +90,7 @@ dbdir = dbdir or "/var/lib/vnstat"
 <%
        end
      end
-   end 
+   end
 %>
 
 <% if empty then %>
index d40dde0..43b87dd 100644 (file)
@@ -1,6 +1,7 @@
 -- Copyright 2010 Jo-Philipp Wich <jow@openwrt.org>
 -- Licensed to the public under the Apache License 2.0.
 
+local utl = require "luci.util"
 local sys = require "luci.sys"
 local ipc = require "luci.ip"
 local fs  = require "nixio.fs"
@@ -69,8 +70,8 @@ function host.write(self, s, val)
                if util == "/usr/bin/etherwake" then
                        local iface = luci.http.formvalue("cbid.wol.1.iface")
                        local broadcast = luci.http.formvalue("cbid.wol.1.broadcast")
-                       cmd = "%s -D%s %s %q" %{
-                               util, (iface ~= "" and " -i %q" % iface or ""),
+                       cmd = "%s -D%s %s %q 2>&1" %{
+                               util, (iface ~= "" and " -i %s" % utl.shellquote(iface) or ""),
                                (broadcast == "1" and " -b" or ""), mac
                        }
                else
@@ -78,7 +79,7 @@ function host.write(self, s, val)
                end
 
                local msg = "<p><strong>%s</strong><br /><br /><code>%s<br /><br />" %{
-                       translate("Starting WoL utility:"), cmd
+                       translate("Starting WoL utility:"), utl.pcdata(cmd)
                }
 
                local p = io.popen(cmd .. " 2>&1")
index e653b03..e27ea52 100644 (file)
@@ -20,12 +20,14 @@ module "luci.model.ipkg"
 
 -- Internal action function
 local function _action(cmd, ...)
-       local pkg = ""
+       local cmdline = { ipkg, cmd }
+
+       local k, v
        for k, v in pairs({...}) do
-               pkg = pkg .. " '" .. v:gsub("'", "") .. "'"
+               cmdline[#cmdline+1] = util.shellquote(v)
        end
 
-       local c = "%s %s %s >/tmp/opkg.stdout 2>/tmp/opkg.stderr" %{ ipkg, cmd, pkg }
+       local c = "%s >/tmp/opkg.stdout 2>/tmp/opkg.stderr" % table.concat(cmdline, " ")
        local r = os.execute(c)
        local e = fs.readfile("/tmp/opkg.stderr")
        local o = fs.readfile("/tmp/opkg.stdout")
@@ -74,17 +76,17 @@ local function _parselist(rawdata)
 end
 
 -- Internal lookup function
-local function _lookup(act, pkg)
-       local cmd = ipkg .. " " .. act
+local function _lookup(cmd, pkg)
+       local cmdline = { ipkg, cmd }
        if pkg then
-               cmd = cmd .. " '" .. pkg:gsub("'", "") .. "'"
+               cmdline[#cmdline+1] = util.shellquote(pkg)
        end
 
        -- OPKG sometimes kills the whole machine because it sucks
        -- Therefore we have to use a sucky approach too and use
        -- tmpfiles instead of directly reading the output
        local tmpfile = os.tmpname()
-       os.execute(cmd .. (" >%s 2>/dev/null" % tmpfile))
+       os.execute("%s >%s 2>/dev/null" %{ table.concat(cmdline, " "), tmpfile })
 
        local data = _parselist(io.lines(tmpfile))
        os.remove(tmpfile)
@@ -123,9 +125,12 @@ end
 
 -- List helper
 local function _list(action, pat, cb)
-       local fd = io.popen(ipkg .. " " .. action ..
-               (pat and (" '%s'" % pat:gsub("'", "")) or ""))
+       local cmdline = { ipkg, action }
+       if pat then
+               cmdline[#cmdline+1] = util.shellquote(pat)
+       end
 
+       local fd = io.popen(table.concat(cmdline, " "))
        if fd then
                local name, version, sz, desc
                while true do
index 3208f3b..bbd9b4c 100644 (file)
@@ -407,7 +407,7 @@ function apply(self, configlist, command)
                return { "/sbin/luci-reload", unpack(configlist) }
        else
                return os.execute("/sbin/luci-reload %s >/dev/null 2>&1"
-                       % table.concat(configlist, " "))
+                       % util.shellquote(table.concat(configlist, " ")))
        end
 end
 
index 12b20e4..823e207 100644 (file)
@@ -87,10 +87,10 @@ end
 function httpget(url, stream, target)
        if not target then
                local source = stream and io.popen or luci.util.exec
-               return source("wget -qO- '"..url:gsub("'", "").."'")
+               return source("wget -qO- %s" % luci.util.shellquote(url))
        else
-               return os.execute("wget -qO '%s' '%s'" %
-                       {target:gsub("'", ""), url:gsub("'", "")})
+               return os.execute("wget -qO %s %s" %
+                       {luci.util.shellquote(target), luci.util.shellquote(url)})
        end
 end
 
@@ -443,18 +443,11 @@ function user.checkpasswd(username, pass)
 end
 
 function user.setpasswd(username, password)
-       if password then
-               password = password:gsub("'", [['"'"']])
-       end
-
-       if username then
-               username = username:gsub("'", [['"'"']])
-       end
-
-       return os.execute(
-               "(echo '" .. password .. "'; sleep 1; echo '" .. password .. "') | " ..
-               "passwd '" .. username .. "' >/dev/null 2>&1"
-       )
+       return os.execute("(echo %s; sleep 1; echo %s) | passwd %s >/dev/null 2>&1" %{
+               luci.util.shellquote(password),
+               luci.util.shellquote(password),
+               luci.util.shellquote(username)
+       })
 end
 
 
index 1c40387..06a9ad4 100644 (file)
@@ -187,7 +187,9 @@ function switch_status(devs)
        local switches = { }
        for dev in devs:gmatch("[^%s,]+") do
                local ports = { }
-               local swc = io.popen("swconfig dev '%s' show" % dev:gsub("'", ""), "r")
+               local swc = io.popen("swconfig dev %s show"
+                       % luci.util.shellquote(dev), "r")
+
                if swc then
                        local l
                        repeat
index 33f6a67..070a9e6 100644 (file)
@@ -289,7 +289,8 @@ function iface_reconnect(iface)
        local netmd = require "luci.model.network".init()
        local net = netmd:get_network(iface)
        if net then
-               luci.sys.call("env -i /sbin/ifup %q >/dev/null 2>/dev/null" % iface)
+               luci.sys.call("env -i /sbin/ifup %s >/dev/null 2>/dev/null"
+                       % luci.util.shellquote(iface))
                luci.http.status(200, "Reconnected")
                return
        end
@@ -301,7 +302,8 @@ function iface_shutdown(iface)
        local netmd = require "luci.model.network".init()
        local net = netmd:get_network(iface)
        if net then
-               luci.sys.call("env -i /sbin/ifdown %q >/dev/null 2>/dev/null" % iface)
+               luci.sys.call("env -i /sbin/ifdown %s >/dev/null 2>/dev/null"
+                       % luci.util.shellquote(iface))
                luci.http.status(200, "Shutdown")
                return
        end
@@ -313,7 +315,8 @@ function iface_delete(iface)
        local netmd = require "luci.model.network".init()
        local net = netmd:del_network(iface)
        if net then
-               luci.sys.call("env -i /sbin/ifdown %q >/dev/null 2>/dev/null" % iface)
+               luci.sys.call("env -i /sbin/ifdown %s >/dev/null 2>/dev/null"
+                       % luci.util.shellquote(iface))
                luci.http.redirect(luci.dispatcher.build_url("admin/network/network"))
                netmd:commit("network")
                netmd:commit("wireless")
@@ -389,7 +392,7 @@ function diag_command(cmd, addr)
        if addr and addr:match("^[a-zA-Z0-9%-%.:_]+$") then
                luci.http.prepare_content("text/plain")
 
-               local util = io.popen(cmd % addr)
+               local util = io.popen(cmd % luci.util.shellquote(addr))
                if util then
                        while true do
                                local ln = util:read("*l")
@@ -408,21 +411,21 @@ function diag_command(cmd, addr)
 end
 
 function diag_ping(addr)
-       diag_command("ping -c 5 -W 1 %q 2>&1", addr)
+       diag_command("ping -c 5 -W 1 %s 2>&1", addr)
 end
 
 function diag_traceroute(addr)
-       diag_command("traceroute -q 1 -w 1 -n %q 2>&1", addr)
+       diag_command("traceroute -q 1 -w 1 -n %s 2>&1", addr)
 end
 
 function diag_nslookup(addr)
-       diag_command("nslookup %q 2>&1", addr)
+       diag_command("nslookup %s 2>&1", addr)
 end
 
 function diag_ping6(addr)
-       diag_command("ping6 -c 5 %q 2>&1", addr)
+       diag_command("ping6 -c 5 %s 2>&1", addr)
 end
 
 function diag_traceroute6(addr)
-       diag_command("traceroute6 -q 1 -w 2 -n %q 2>&1", addr)
+       diag_command("traceroute6 -q 1 -w 2 -n %s 2>&1", addr)
 end
index 4b03a18..3a1c169 100644 (file)
@@ -62,7 +62,9 @@ end
 function action_bandwidth(iface)
        luci.http.prepare_content("application/json")
 
-       local bwc = io.popen("luci-bwc -i '%s' 2>/dev/null" % iface:gsub("'", ""))
+       local bwc = io.popen("luci-bwc -i %s 2>/dev/null"
+               % luci.util.shellquote(iface))
+
        if bwc then
                luci.http.write("[")
 
@@ -80,7 +82,9 @@ end
 function action_wireless(iface)
        luci.http.prepare_content("application/json")
 
-       local bwc = io.popen("luci-bwc -r '%s' 2>/dev/null" % iface:gsub("'", ""))
+       local bwc = io.popen("luci-bwc -r %s 2>/dev/null"
+               % luci.util.shellquote(iface))
+
        if bwc then
                luci.http.write("[")
 
index 89a73a5..b52dff1 100644 (file)
@@ -5,6 +5,7 @@
 m = Map("network", translate("Switch"), translate("The network ports on this device can be combined to several <abbr title=\"Virtual Local Area Network\">VLAN</abbr>s in which computers can communicate directly with each other. <abbr title=\"Virtual Local Area Network\">VLAN</abbr>s are often used to separate different network segments. Often there is by default one Uplink port for a connection to the next greater network like the internet and other ports for a local network."))
 
 local fs = require "nixio.fs"
+local ut = require "luci.util"
 local nw = require "luci.model.network"
 local switches = { }
 
@@ -74,7 +75,7 @@ m.uci:foreach("network", "switch",
                end
 
                -- Parse some common switch properties from swconfig help output.
-               local swc = io.popen("swconfig dev %q help 2>/dev/null" % switch_name)
+               local swc = io.popen("swconfig dev %s help 2>/dev/null" % ut.shellquote(switch_name))
                if swc then
 
                        local is_port_attr = false
index c0bb380..a574d35 100644 (file)
@@ -63,7 +63,7 @@ function m.parse(map)
        Map.parse(map)
 
        if m:get(wdev:name(), "type") == "mac80211" and new_cc and new_cc ~= old_cc then
-               luci.sys.call("iw reg set %q" % new_cc)
+               luci.sys.call("iw reg set %s" % ut.shellquote(new_cc))
                luci.http.redirect(luci.dispatcher.build_url("admin/network/wireless", arg[1]))
                return
        end