From 706da44cf275dc20426a55a4d01ed79026d3eb80 Mon Sep 17 00:00:00 2001 From: Steven Barth Date: Sun, 27 Apr 2008 11:04:48 +0000 Subject: [PATCH] * Reworked Luci-Splash * Created ffluci-system-addons package for Kamikaze addons --- contrib/package/ffluci-splash/Makefile | 43 +++++ contrib/package/ffluci-splash/ipkg/conffiles | 1 + .../package/ffluci-splash/src/luci-splash.lua | 173 ++++++++++++++++++ .../src/luci-splash/htdocs/cgi-bin/index.cgi | 39 ++++ .../src/luci-splash/htdocs/index.html | 10 + .../ffluci-splash/src/luci_splash.cron | 2 + .../ffluci-splash/src/luci_splash.init | 88 +++++++++ .../package/ffluci-splash/src/luci_splash.uci | 2 + .../ffluci-splash/src/luci_splash_httpd.conf | 1 + contrib/package/ffluci-system-addons/Makefile | 32 ++++ .../src}/hotplug.d-20-aliases | 0 .../ffluci-system-addons/src/root.crontab | 3 + .../ffluci-system-addons/src/run-parts | 18 ++ contrib/package/ffluci/Makefile | 3 +- core/contrib/uci/luci | 2 +- core/src/ffluci/sys.lua | 13 ++ module/admin-core/contrib/luci-splash | 2 +- 17 files changed, 428 insertions(+), 4 deletions(-) create mode 100644 contrib/package/ffluci-splash/Makefile create mode 100644 contrib/package/ffluci-splash/ipkg/conffiles create mode 100644 contrib/package/ffluci-splash/src/luci-splash.lua create mode 100644 contrib/package/ffluci-splash/src/luci-splash/htdocs/cgi-bin/index.cgi create mode 100644 contrib/package/ffluci-splash/src/luci-splash/htdocs/index.html create mode 100644 contrib/package/ffluci-splash/src/luci_splash.cron create mode 100644 contrib/package/ffluci-splash/src/luci_splash.init create mode 100644 contrib/package/ffluci-splash/src/luci_splash.uci create mode 100644 contrib/package/ffluci-splash/src/luci_splash_httpd.conf create mode 100644 contrib/package/ffluci-system-addons/Makefile rename {core/contrib => contrib/package/ffluci-system-addons/src}/hotplug.d-20-aliases (100%) create mode 100644 contrib/package/ffluci-system-addons/src/root.crontab create mode 100644 contrib/package/ffluci-system-addons/src/run-parts diff --git a/contrib/package/ffluci-splash/Makefile b/contrib/package/ffluci-splash/Makefile new file mode 100644 index 000000000..d3e98af18 --- /dev/null +++ b/contrib/package/ffluci-splash/Makefile @@ -0,0 +1,43 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=ffluci-splash +PKG_VERSION:=0.1 +PKG_RELEASE:=1 + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) +PKG_INSTALL_DIR:=$(PKG_BUILD_DIR)/ipkg-install +PKG_BUILD_DEPENDS:=lua-luci + +include $(INCLUDE_DIR)/package.mk + +define Package/ffluci-splash + SECTION:=admin + CATEGORY:=Administration + SUBMENU:=FFLuCI + DEPENDS:=+ffluci +iptables-mod-nat +lua-luci + TITLE:=FFLuCI DHCP-Splash +endef + +define Build/Compile +endef + +define Package/ffluci-splash/install + $(INSTALL_DIR) $(1)/usr/lib/luci-splash/htdocs/cgi-bin + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_DIR) $(1)/etc/cron.minutely + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_DIR) $(1)/usr/sbin + + $(CP) -a ./src/luci-splash/* $(1)/usr/lib/luci-splash/ -R + $(INSTALL_BIN) ./src/luci-splash/htdocs/cgi-bin/index.cgi $(1)/usr/lib/luci-splash/htdocs/cgi-bin + $(INSTALL_BIN) ./src/luci_splash.init $(1)/etc/init.d/luci_splash + $(INSTALL_BIN) ./src/luci-splash.lua $(1)/usr/sbin/luci-splash + + $(INSTALL_BIN) -a ./src/luci_splash.cron $(1)/etc/cron.minutely/luci_splash + $(CP) -a ./src/luci_splash.uci $(1)/etc/config/luci_splash + $(CP) -a ./src/luci_splash_httpd.conf $(1)/etc/ + + $(CP) -a ./ipkg/conffiles $(1)/CONTROL/conffiles +endef + +$(eval $(call BuildPackage,ffluci-splash)) diff --git a/contrib/package/ffluci-splash/ipkg/conffiles b/contrib/package/ffluci-splash/ipkg/conffiles new file mode 100644 index 000000000..dcbe1ad37 --- /dev/null +++ b/contrib/package/ffluci-splash/ipkg/conffiles @@ -0,0 +1 @@ +/etc/config/luci_splash \ No newline at end of file diff --git a/contrib/package/ffluci-splash/src/luci-splash.lua b/contrib/package/ffluci-splash/src/luci-splash.lua new file mode 100644 index 000000000..54c32add6 --- /dev/null +++ b/contrib/package/ffluci-splash/src/luci-splash.lua @@ -0,0 +1,173 @@ +#!/usr/bin/lua +package.path = "/usr/lib/lua/?.lua;/usr/lib/lua/?/init.lua;" .. package.path +package.cpath = "/usr/lib/lua/?.so;" .. package.cpath + +require("ffluci.http") +require("ffluci.sys") +require("ffluci.model.uci") + +-- Init state session +uci = ffluci.model.uci.Session("/var/state") + + +-- Parse stdin and do something +function main(argv) + local cmd = argv[1] + local arg = argv[2] + + if not cmd then + print("Usage: " .. argv[0] .. " [MAC]") + os.exit(1) + elseif cmd == "status" then + if not arg then + os.exit(1) + end + + if iswhitelisted(arg) then + print("whitelisted") + os.exit(0) + end + + if haslease(arg) then + print("lease") + os.exit(0) + end + + print("unknown") + os.exit(0) + elseif cmd == "add" then + if not arg then + os.exit(1) + end + + if not haslease(arg) then + add_lease(arg) + else + print("already leased!") + os.exit(2) + end + os.exit(0) + elseif cmd == "remove" then + if not cmd[2] then + os.exit(1) + end + + remove_lease(arg) + os.exit(0) + elseif cmd == "sync" then + sync() + os.exit(0) + end +end + +-- Add a lease to state and invoke add_rule +function add_lease(mac) + local key = uci:add("luci_splash", "lease") + uci:set("luci_splash", key, "mac", mac) + uci:set("luci_splash", key, "start", os.time()) + add_rule(mac) +end + + +-- Remove a lease from state and invoke remove_rule +function remove_lease(mac) + mac = mac:lower() + + for k, v in pairs(uci:show("luci_splash").luci_splash) do + if v.mac:lower() == mac then + remove_rule(mac) + uci:del("luci_splash", k) + end + end +end + + +-- Add an iptables rule +function add_rule(mac) + return os.execute("iptables -t nat -I luci_splash_leases -m mac --mac-source '"..mac.."' -j RETURN") +end + + +-- Remove an iptables rule +function remove_rule(mac) + return os.execute("iptables -t nat -D luci_splash_leases -m mac --mac-source '"..mac.."' -j RETURN") +end + + +-- Check whether a MAC-Address is listed in the lease state list +function haslease(mac) + mac = mac:lower() + + for k, v in pairs(uci:show("luci_splash").luci_splash) do + if v[".type"] == "lease" and v.mac and v.mac:lower() == mac then + return true + end + end + + return false +end + + +-- Check whether a MAC-Address is whitelisted +function iswhitelisted(mac) + mac = mac:lower() + + for k, v in pairs(uci:show("luci_splash").luci_splash) do + if v[".type"] == "whitelist" and v.mac and v.mac:lower() == mac then + return true + end + end + + return false +end + + +-- Returns a list of MAC-Addresses for which a rule is existing +function listrules() + local cmd = "iptables -t nat -L luci_splash_leases | grep RETURN |" + cmd = cmd .. "egrep -io [0-9a-f]+:[0-9a-f]+:[0-9a-f]+:[0-9a-f]+:[0-9a-f]+:[0-9a-f]+" + return ffluci.util.split(ffluci.sys.exec(cmd)) +end + + +-- Synchronise leases, remove abandoned rules +function sync() + local written = {} + local time = os.time() + + -- Current leases in state files + local leases = uci:show("luci_splash").luci_splash + + -- Convert leasetime to seconds + local leasetime = tonumber(uci:get("luci_splash", "general", "leasetime")) * 3600 + + -- Clean state file + uci:revert("luci_splash") + + + -- For all leases + for k, v in pairs(uci:show("luci_splash")) do + if v[".type"] == "lease" then + if os.difftime(time, tonumber(v.start)) > leasetime then + -- Remove expired + remove_rule(v.mac) + else + -- Rewrite state + local n = uci:add("luci_splash", "lease") + uci:set("luci_splash", n, "mac", v.mac) + uci:set("luci_splash", n, "start", v.start) + written[v.mac] = 1 + end + end + end + + + -- Delete rules without state + for i, r in ipairs(listrules()) do + if #r > 0 and not written[r] then + remove_rule(r) + end + end +end + +main(arg) \ No newline at end of file diff --git a/contrib/package/ffluci-splash/src/luci-splash/htdocs/cgi-bin/index.cgi b/contrib/package/ffluci-splash/src/luci-splash/htdocs/cgi-bin/index.cgi new file mode 100644 index 000000000..4cbddc0c5 --- /dev/null +++ b/contrib/package/ffluci-splash/src/luci-splash/htdocs/cgi-bin/index.cgi @@ -0,0 +1,39 @@ +#!/usr/bin/haserl --shell=luac +package.path = "/usr/lib/lua/?.lua;/usr/lib/lua/?/init.lua;" .. package.path +package.cpath = "/usr/lib/lua/?.so;" .. package.cpath + +require("ffluci.http") +require("ffluci.sys") +require("ffluci.model.uci") + +local srv +local ip = ffluci.http.remote_addr() +for k, v in pairs(ffluci.model.uci.show("network").network) do + if v[".type"] == "interface" and v.ipaddr then + local p = ffluci.sys.net.mask4prefix(v.netmask) + if ffluci.sys.net.belongs(ip, v.ipaddr, p) then + srv = v.ipaddr + break + end + end +end + +if not srv then + ffluci.http.textheader() + return print("Unable to detect network settings!") +end + +local action = "splash" + +local mac = ffluci.sys.net.ip4mac(ip) +if not mac then + action = "unknown" +end + +local status = ffluci.sys.exec("luci-splash status "..mac) + +if status == "whitelisted" or status == "lease" then + action = "allowed" +end + +ffluci.http.redirect("http://" .. srv .. "/cgi-bin/luci-splash/" .. action) \ No newline at end of file diff --git a/contrib/package/ffluci-splash/src/luci-splash/htdocs/index.html b/contrib/package/ffluci-splash/src/luci-splash/htdocs/index.html new file mode 100644 index 000000000..58387a5fe --- /dev/null +++ b/contrib/package/ffluci-splash/src/luci-splash/htdocs/index.html @@ -0,0 +1,10 @@ + + + + + + + +FFLuCI - Freifunk Lua Configuration Interface + + \ No newline at end of file diff --git a/contrib/package/ffluci-splash/src/luci_splash.cron b/contrib/package/ffluci-splash/src/luci_splash.cron new file mode 100644 index 000000000..eae429474 --- /dev/null +++ b/contrib/package/ffluci-splash/src/luci_splash.cron @@ -0,0 +1,2 @@ +#!/bin/sh +[ "$(date +%M | cut -c2)" == "5" ] && luci-splash sync \ No newline at end of file diff --git a/contrib/package/ffluci-splash/src/luci_splash.init b/contrib/package/ffluci-splash/src/luci_splash.init new file mode 100644 index 000000000..a7bb4abeb --- /dev/null +++ b/contrib/package/ffluci-splash/src/luci_splash.init @@ -0,0 +1,88 @@ +#!/bin/sh /etc/rc.common +START=70 + +iface_add() { + local cfg="$1" + + config_get net "$cfg" network + [ -n "$net" ] || return 0 + + config_get iface "$net" ifname + [ -n "$iface" ] || return 0 + iface="${iface%%:*}" + + config_get ipaddr "$net" ipaddr + [ -n "$ipaddr" ] || return 0 + + config_get netmask "$net" netmask + [ -n "$netmask" ] || return 0 + + eval "$(ipcalc.sh $ipaddr $netmask)" + + iptables -t nat -A luci_splash -i "$iface" -s "$IP/$PREFIX" -j luci_splash_portal + iptables -t nat -A luci_splash_portal -i "$iface" -s "$IP/$PREFIX" -d "$ipaddr" -p tcp --dport 80 -j RETURN +} + +blacklist_add() { + local cfg="$1" + + config_get mac "$cfg" mac + [ -n "$mac" ] && iptables -t nat -A luci_splash_portal -m mac --mac-source "$mac" -j DROP +} + +whitelist_add() { + local cfg="$1" + + config_get mac "$cfg" mac + [ -n "$mac" ] && iptables -t nat -A luci_splash_portal -m mac --mac-source "$mac" -j RETURN +} + +start() { + ### Read chains from config + include /lib/network + scan_interfaces + config_load luci_splash + + ### Create subchains + iptables -t nat -N luci_splash + iptables -t nat -N luci_splash_portal + iptables -t nat -N luci_splash_leases + + ### Build the main and portal rule + config_foreach blacklist_add blacklist + config_foreach whitelist_add whitelist + config_foreach iface_add iface + + ### Build the portal rule + iptables -t nat -A luci_splash_portal -p udp --dport 53 -j RETURN + iptables -t nat -A luci_splash_portal -j luci_splash_leases + + ### Build the leases rule + iptables -t nat -A luci_splash_leases -p tcp --dport 80 -j REDIRECT --to-ports 8082 + iptables -t nat -A luci_splash_leases -j DROP + + ### Start the splash httpd + httpd -c /etc/luci_splash_httpd.conf -p 8082 -h /usr/lib/luci-splash/htdocs + + ### Sync leases + /usr/lib/luci-splash/sync.lua + + ### Hook in the chain + iptables -t nat -A prerouting_rule -j luci_splash +} + +stop() { + ### Hook out the chain + iptables -t nat -D prerouting_rule -j luci_splash + + ### Clear subchains + iptables -t nat -F luci_splash_leases + iptables -t nat -F luci_splash_portal + iptables -t nat -F luci_splash + + ### Delete subchains + iptables -t nat -X luci_splash_leases + iptables -t nat -X luci_splash_portal + iptables -t nat -X luci_splash +} + diff --git a/contrib/package/ffluci-splash/src/luci_splash.uci b/contrib/package/ffluci-splash/src/luci_splash.uci new file mode 100644 index 000000000..c4cfef5dd --- /dev/null +++ b/contrib/package/ffluci-splash/src/luci_splash.uci @@ -0,0 +1,2 @@ +config core general + option leasetime 1 \ No newline at end of file diff --git a/contrib/package/ffluci-splash/src/luci_splash_httpd.conf b/contrib/package/ffluci-splash/src/luci_splash_httpd.conf new file mode 100644 index 000000000..6007e80db --- /dev/null +++ b/contrib/package/ffluci-splash/src/luci_splash_httpd.conf @@ -0,0 +1 @@ +E404:index.html \ No newline at end of file diff --git a/contrib/package/ffluci-system-addons/Makefile b/contrib/package/ffluci-system-addons/Makefile new file mode 100644 index 000000000..3d38bd36c --- /dev/null +++ b/contrib/package/ffluci-system-addons/Makefile @@ -0,0 +1,32 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=ffluci-system-addons +PKG_VERSION:=0.1 +PKG_RELEASE:=1 + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) +PKG_INSTALL_DIR:=$(PKG_BUILD_DIR)/ipkg-install + +include $(INCLUDE_DIR)/package.mk + +define Package/ffluci-splash + SECTION:=admin + CATEGORY:=Administration + SUBMENU:=FFLuCI + TITLE:=FFLuCI System Addons for Kamikaze +endef + +define Build/Compile +endef + +define Package/ffluci-system-addons/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_DIR) $(1)/etc/crontabs + $(INSTALL_DIR) $(1)/etc/hotplug.d/iface + + $(INSTALL_BIN) ./src/run-parts $(1)/usr/bin + $(CP) ./src/root.crontab $(1)/etc/crontabs/root + $(CP) ./src/hotplug.d-20-aliases $(1)/etc/hotplug.d/iface/20-aliases +endef + +$(eval $(call BuildPackage,ffluci-system-addons)) diff --git a/core/contrib/hotplug.d-20-aliases b/contrib/package/ffluci-system-addons/src/hotplug.d-20-aliases similarity index 100% rename from core/contrib/hotplug.d-20-aliases rename to contrib/package/ffluci-system-addons/src/hotplug.d-20-aliases diff --git a/contrib/package/ffluci-system-addons/src/root.crontab b/contrib/package/ffluci-system-addons/src/root.crontab new file mode 100644 index 000000000..6e2e417dc --- /dev/null +++ b/contrib/package/ffluci-system-addons/src/root.crontab @@ -0,0 +1,3 @@ +0-59/1 * * * * /usr/bin/run-parts /etc/cron.minutely +0 * * * * /usr/bin/run-parts /etc/cron.hourly +0 0 * * * /usr/bin/run-parts /etc/cron.daily diff --git a/contrib/package/ffluci-system-addons/src/run-parts b/contrib/package/ffluci-system-addons/src/run-parts new file mode 100644 index 000000000..0f0cbbdf5 --- /dev/null +++ b/contrib/package/ffluci-system-addons/src/run-parts @@ -0,0 +1,18 @@ +#!/bin/sh +set +e + +if [ $# -lt 1 ]; then + echo "Usage: run-parts " + exit 1 +fi + +if [ ! -d $1 ]; then + echo "Not a directory: $1" + exit 1 +fi + +for i in $1/*; do + [ -x $i ] && $i +done + +exit 0 \ No newline at end of file diff --git a/contrib/package/ffluci/Makefile b/contrib/package/ffluci/Makefile index aa6050dab..1c45695bb 100644 --- a/contrib/package/ffluci/Makefile +++ b/contrib/package/ffluci/Makefile @@ -26,7 +26,7 @@ define Package/ffluci CATEGORY:=Administration TITLE:=FFLuCI SUBMENU:=FFLuCI - DEPENDS:=+luaposix +haserl-lua + DEPENDS:=+luaposix +haserl-lua +ffluci-system-addons MAINTAINER:=Steven Barth endef @@ -50,7 +50,6 @@ define Package/ffluci/install $(CP) $(PKG_BUILD_DIR)/core/dist/* $(1)/usr/lib/lua/ -R $(CP) $(PKG_BUILD_DIR)/core/contrib/uci/* $(1)/etc/config/ - $(CP) $(PKG_BUILD_DIR)/core/contrib/hotplug.d-20-aliases $(1)/etc/hotplug.d/iface/20-aliases -R $(INSTALL_BIN) $(PKG_BUILD_DIR)/core/contrib/ffluci $(1)/www/cgi-bin $(INSTALL_BIN) $(PKG_BUILD_DIR)/core/contrib/ffluci-upload $(1)/www/cgi-bin $(INSTALL_BIN) $(PKG_BUILD_DIR)/core/contrib/index.cgi $(1)/www/cgi-bin diff --git a/core/contrib/uci/luci b/core/contrib/uci/luci index a3603d7ff..292e8f2b2 100644 --- a/core/contrib/uci/luci +++ b/core/contrib/uci/luci @@ -17,7 +17,7 @@ config extern flash_keep config event uci_oncommit option network "/etc/init.d/network restart" option wireless "/etc/init.d/network restart" - option olsr "/etc/init.d/olsrd restart" + option olsr "reboot" option dhcp "/etc/init.d/dnsmasq restart" option luci_fw "/etc/init.d/luci_fw restart" option dropbear "/etc/init.d/dropbear restart" diff --git a/core/src/ffluci/sys.lua b/core/src/ffluci/sys.lua index cde1877de..8aa77cf13 100644 --- a/core/src/ffluci/sys.lua +++ b/core/src/ffluci/sys.lua @@ -134,6 +134,19 @@ function net.devices() return devices end +-- Returns the MAC-Address belonging to the given IP-Address +function net.ip4mac(ip) + local mac = nil + + for i, l in ipairs(net.arptable()) do + if l["IP address"] == ip then + mac = l["HW address"] + end + end + + return mac +end + -- Returns the prefix to a given netmask function net.mask4prefix(mask) local bin = net.ip4bin(mask) diff --git a/module/admin-core/contrib/luci-splash b/module/admin-core/contrib/luci-splash index 57fa4b609..188ad7aa0 100644 --- a/module/admin-core/contrib/luci-splash +++ b/module/admin-core/contrib/luci-splash @@ -1,4 +1,4 @@ #!/bin/sh echo "Status: 302 Found" -echo "Location: ffluci/public/splash$PATH_INFO" +echo "Location: /cgi-bin/ffluci/splash/splash$PATH_INFO" echo \ No newline at end of file -- 2.25.1