Эх сурвалжийг харах

rescue fw image and POST revamping

Danja Vasiliev 10 жил өмнө
parent
commit
8c6192638c
100 өөрчлөгдсөн 3442 нэмэгдсэн , 81 устгасан
  1. 20 0
      openwrt-rescue/DIR505A1/etc/config/system
  2. 1 0
      openwrt-rescue/DIR505A1/etc/superglue_model
  3. 20 0
      openwrt-rescue/TLWR710/etc/config/system
  4. 1 0
      openwrt-rescue/TLWR710/etc/superglue_model
  5. 30 0
      openwrt-rescue/common/etc/avahi/avahi-daemon.conf
  6. 14 0
      openwrt-rescue/common/etc/banner
  7. 41 0
      openwrt-rescue/common/etc/config/dhcp
  8. 5 0
      openwrt-rescue/common/etc/config/dropbear
  9. 177 0
      openwrt-rescue/common/etc/config/firewall
  10. 39 0
      openwrt-rescue/common/etc/config/fstab
  11. 19 0
      openwrt-rescue/common/etc/config/network
  12. 0 0
      openwrt-rescue/common/etc/config/ubootenv
  13. 25 0
      openwrt-rescue/common/etc/config/wireless
  14. 1 0
      openwrt-rescue/common/etc/crontabs/root
  15. 13 0
      openwrt-rescue/common/etc/firewall.user
  16. 10 0
      openwrt-rescue/common/etc/group
  17. 40 0
      openwrt-rescue/common/etc/hotplug.d/block/99-sg-dirs
  18. 47 0
      openwrt-rescue/common/etc/lighttpd/lighttpd.conf
  19. 87 0
      openwrt-rescue/common/etc/lighttpd/mime.conf
  20. 5 0
      openwrt-rescue/common/etc/logrotate.conf
  21. 6 0
      openwrt-rescue/common/etc/opkg.conf
  22. 6 0
      openwrt-rescue/common/etc/passwd
  23. 3 0
      openwrt-rescue/common/etc/rc.local
  24. 51 0
      openwrt-rescue/common/etc/rc.local.off
  25. 6 0
      openwrt-rescue/common/etc/shadow
  26. 1 0
      openwrt-rescue/common/etc/sudoers.d/sg-suid
  27. 1 0
      openwrt-rescue/common/etc/superglue_model
  28. 1 0
      openwrt-rescue/common/etc/superglue_version
  29. 31 0
      openwrt-rescue/common/etc/sysctl.conf
  30. 1 0
      openwrt-rescue/common/etc/uci-defaults/10-fstab
  31. 5 0
      openwrt-rescue/common/etc/uci-defaults/12-fstab-enable
  32. 12 0
      openwrt-rescue/common/etc/uci-defaults/20-set-ssid
  33. 476 0
      openwrt-rescue/common/opt/lib/cgi/rescue.cgi
  34. 1 0
      openwrt-rescue/common/opt/lib/cgi/suid.sh
  35. 0 0
      openwrt-rescue/common/opt/lib/htpasswd
  36. 145 0
      openwrt-rescue/common/opt/lib/resources/admin/admin.css
  37. 34 0
      openwrt-rescue/common/opt/lib/resources/admin/admin.js
  38. 0 0
      openwrt-rescue/common/opt/lib/resources/empty.html
  39. 7 0
      openwrt-rescue/common/opt/lib/resources/failsafe.html
  40. 0 0
      openwrt-rescue/common/opt/lib/resources/fonts/Titillium_Web/TitilliumWeb-Bold.ttf
  41. 0 0
      openwrt-rescue/common/opt/lib/resources/fonts/Titillium_Web/TitilliumWeb-Regular.ttf
  42. BIN
      openwrt-rescue/common/opt/lib/resources/images/superglue-logo.png
  43. 1 0
      openwrt-rescue/common/www/htdocs/default.html
  44. 1 0
      openwrt-rescue/common/www/log
  45. 1 0
      openwrt-rescue/common/www/tmp
  46. 105 0
      openwrt-rescue/make_fw.sh
  47. 1 0
      openwrt-rescue/openwrt.revision
  48. 1 0
      openwrt-rescue/sg_0.1.revision
  49. 30 0
      openwrt/common/etc/avahi/avahi-daemon.conf
  50. 3 3
      openwrt/common/etc/banner
  51. 2 2
      openwrt/common/etc/config/dhcp
  52. 7 7
      openwrt/common/etc/config/fstab
  53. 2 4
      openwrt/common/etc/config/network
  54. 9 8
      openwrt/common/etc/config/wireless
  55. 40 0
      openwrt/common/etc/hotplug.d/block/99-sg-dirs
  56. BIN
      openwrt/common/etc/lighttpd/.lighttpd.conf.swp
  57. 13 9
      openwrt/common/etc/lighttpd/lighttpd.conf
  58. 3 2
      openwrt/common/etc/logrotate.conf
  59. 1 1
      openwrt/common/etc/opkg.conf
  60. 1 42
      openwrt/common/etc/rc.local
  61. 51 0
      openwrt/common/etc/rc.local.off
  62. 1 1
      openwrt/common/etc/sudoers.d/sg-suid
  63. 1 0
      openwrt/common/etc/uci-defaults/10-fstab
  64. 1 1
      openwrt/common/etc/uci-defaults/12-fstab-enable
  65. BIN
      openwrt/common/lib/modules/3.10.36/cfg80211.ko
  66. BIN
      openwrt/common/lib/modules/3.10.49/ath.ko
  67. BIN
      openwrt/common/lib/modules/3.10.49/cfg80211.ko
  68. BIN
      openwrt/common/opt/lib/cgi/.admin.cgi.swp
  69. BIN
      openwrt/common/opt/lib/cgi/.post.cgi.swp
  70. 537 0
      openwrt/common/opt/lib/cgi/admin-pre-rescue.cgi
  71. 518 0
      openwrt/common/opt/lib/cgi/admin.cgi
  72. 1 1
      openwrt/common/opt/lib/cgi/admin.cgi-bup201014
  73. 456 0
      openwrt/common/opt/lib/cgi/admin2.cgi
  74. 0 0
      openwrt/common/opt/lib/cgi/demo.cgi
  75. 0 0
      openwrt/common/opt/lib/cgi/post.cgi
  76. 37 0
      openwrt/common/opt/lib/cgi/suid.sh
  77. 60 0
      openwrt/common/opt/lib/cgi/upload.cgi
  78. 0 0
      openwrt/common/opt/lib/devTools/SCSystemBrowser.html
  79. 0 0
      openwrt/common/opt/lib/devTools/ace/ace.js
  80. 0 0
      openwrt/common/opt/lib/devTools/ace/ext-language_tools.js
  81. 0 0
      openwrt/common/opt/lib/devTools/ace/mode-javascript.js
  82. 0 0
      openwrt/common/opt/lib/devTools/ace/theme-monokai.js
  83. 0 0
      openwrt/common/opt/lib/devTools/ace/worker-javascript.js
  84. 0 0
      openwrt/common/opt/lib/devTools/ace/worker-javascript.js.bak
  85. 1 0
      openwrt/common/opt/lib/htpasswd
  86. 122 0
      openwrt/common/opt/lib/resources/admin/admin.css
  87. 34 0
      openwrt/common/opt/lib/resources/admin/admin.js
  88. 0 0
      openwrt/common/opt/lib/resources/css/SuperGlue.css
  89. 0 0
      openwrt/common/opt/lib/resources/demo.html
  90. 19 0
      openwrt/common/opt/lib/resources/empty.html
  91. 0 0
      openwrt/common/opt/lib/resources/failsafe.html
  92. 0 0
      openwrt/common/opt/lib/resources/fonts/Dosis/Dosis-Bold.otf
  93. 0 0
      openwrt/common/opt/lib/resources/fonts/Dosis/Dosis-Light.otf
  94. 0 0
      openwrt/common/opt/lib/resources/fonts/Dosis/Dosis-Regular.otf
  95. 0 0
      openwrt/common/opt/lib/resources/fonts/Dosis/SIL Open Font License.txt
  96. 0 0
      openwrt/common/opt/lib/resources/fonts/Montserrat/Montserrat-Bold.ttf
  97. 0 0
      openwrt/common/opt/lib/resources/fonts/Montserrat/Montserrat-Regular.ttf
  98. 0 0
      openwrt/common/opt/lib/resources/fonts/Montserrat/OFL.txt
  99. 0 0
      openwrt/common/opt/lib/resources/fonts/Titillium_Web/OFL.txt
  100. BIN
      openwrt/common/opt/lib/resources/fonts/Titillium_Web/TitilliumWeb-Bold.ttf

+ 20 - 0
openwrt-rescue/DIR505A1/etc/config/system

@@ -0,0 +1,20 @@
+config system
+  option hostname 'superglue'
+  ## Made in Berlin
+  option timezone 'CET-1CEST'
+
+config timeserver 'ntp'
+  list server '0.openwrt.pool.ntp.org'
+  list server '1.openwrt.pool.ntp.org'
+  list server '2.openwrt.pool.ntp.org'
+  list server '3.openwrt.pool.ntp.org'
+  option enable_server '0'
+
+config led 'led_lan'
+  option name 'LAN'
+  option sysfs 'd-link:green:power'
+  option trigger 'netdev'
+  option dev 'eth1'
+  option dev 'wlan0'
+  option mode 'link tx rx'
+

+ 1 - 0
openwrt-rescue/DIR505A1/etc/superglue_model

@@ -0,0 +1 @@
+D-Link DIR-505

+ 20 - 0
openwrt-rescue/TLWR710/etc/config/system

@@ -0,0 +1,20 @@
+config system
+  option hostname 'superglue'
+  ## Made in Berlin 
+  option timezone 'CET-1CEST'
+
+config timeserver 'ntp'
+	list server '0.openwrt.pool.ntp.org'
+	list server '1.openwrt.pool.ntp.org'
+	list server '2.openwrt.pool.ntp.org'
+	list server '3.openwrt.pool.ntp.org'
+	option enable_server '0'
+
+config led 'led_lan'
+	option name 'LAN'
+	option sysfs 'tp-link:blue:system'
+	option trigger 'netdev'
+	option dev 'eth1'
+	option dev 'wlan0'
+	option mode 'link tx rx'
+

+ 1 - 0
openwrt-rescue/TLWR710/etc/superglue_model

@@ -0,0 +1 @@
+TP-LINK TL-WR710N

+ 30 - 0
openwrt-rescue/common/etc/avahi/avahi-daemon.conf

@@ -0,0 +1,30 @@
+[server]
+enable-dbus=no
+allow-interfaces=br-lan
+#host-name=superglue
+#domain-name=local
+use-ipv4=yes
+use-ipv6=no
+check-response-ttl=no
+use-iff-running=no
+
+[publish]
+publish-addresses=yes
+publish-hinfo=yes
+publish-workstation=no
+publish-domain=yes
+#publish-dns-servers=192.168.1.1
+publish-resolv-conf-dns-servers=yes
+
+[reflector]
+enable-reflector=no
+reflect-ipv=no
+
+[rlimits]
+#rlimit-as=
+rlimit-core=0
+rlimit-data=524288
+rlimit-fsize=0
+rlimit-nofile=30
+rlimit-stack=524288
+rlimit-nproc=3

+ 14 - 0
openwrt-rescue/common/etc/banner

@@ -0,0 +1,14 @@
+                                _
+  ___  _ _  ___  ___  ___  ___ | | _ _  ___
+ |_ -|| | || . || -_||  _|| . || || | || -_|
+ |___||___||  _||___||_|  |_  ||_||___||___|
+           |_|   personal |___| server
+ http://superglue.it -- RESCUE - SOS -- RESCUE
+ -----------------------------------------------------
+ version %VERSION% - based on OpenWRT %REVISION%
+ -----------------------------------------------------
+ provides:
+    RESCUE lightweight firmware containing only
+    http://192.168.1.1/admin
+    Good luck!
+ -----------------------------------------------------

+ 41 - 0
openwrt-rescue/common/etc/config/dhcp

@@ -0,0 +1,41 @@
+
+config dnsmasq
+	option domainneeded '1'
+	option boguspriv '1'
+	option filterwin2k '0'
+	option localise_queries '1'
+	option rebind_protection '1'
+	option rebind_localhost '1'
+	option local '/home/'
+	option domain 'home'
+	option expandhosts '1'
+	option nonegcache '0'
+	option authoritative '1'
+	option readethers '1'
+	option leasefile '/tmp/dhcp.leases'
+	option resolvfile '/tmp/resolv.conf.auto'
+
+config dhcp 'lan'
+	option interface 'lan'
+	option start '100'
+	option limit '150'
+	option leasetime '12h'
+	option dhcpv6 'hybrid'
+	option ra 'hybrid'
+	option ndp 'hybrid'
+
+config dhcp 'wan'
+	option interface 'wan'
+	option ignore '1'
+
+config odhcpd 'odhcpd'
+	option maindhcp '0'
+	option leasefile '/tmp/hosts/odhcpd'
+	option leasetrigger '/usr/sbin/odhcpd-update'
+
+config dhcp 'wan6'
+	option dhcpv6 'hybrid'
+	option ra 'hybrid'
+	option ndp 'hybrid'
+	option master '1'
+

+ 5 - 0
openwrt-rescue/common/etc/config/dropbear

@@ -0,0 +1,5 @@
+config dropbear
+	option PasswordAuth 'on'
+	option RootPasswordAuth 'on'
+	option Port         '22'
+#	option BannerFile   '/etc/banner'

+ 177 - 0
openwrt-rescue/common/etc/config/firewall

@@ -0,0 +1,177 @@
+config defaults
+	option syn_flood	1
+	option input		ACCEPT
+	option output		ACCEPT
+	option forward		REJECT
+# Uncomment this line to disable ipv6 rules
+	option disable_ipv6	1
+
+config zone
+	option name		lan
+	list   network		'lan'
+	option input		ACCEPT
+	option output		ACCEPT
+	option forward		ACCEPT
+
+config zone
+	option name		wan
+	list   network		'wan'
+	list   network		'wan6'
+	option input		REJECT
+	option output		ACCEPT
+	option forward		REJECT
+	option masq		1
+	option mtu_fix		1
+
+config forwarding
+	option src		lan
+	option dest		wan
+
+# We need to accept udp packets on port 68,
+# see https://dev.openwrt.org/ticket/4108
+config rule
+	option name		Allow-DHCP-Renew
+	option src		wan
+	option proto		udp
+	option dest_port	68
+	option target		ACCEPT
+	option family		ipv4
+
+# Allow IPv4 ping
+config rule
+	option name		Allow-Ping
+	option src		wan
+	option proto		icmp
+	option icmp_type	echo-request
+	option family		ipv4
+	option target		ACCEPT
+
+# Allow DHCPv6 replies
+# see https://dev.openwrt.org/ticket/10381
+config rule
+	option name		Allow-DHCPv6
+	option src		wan
+	option proto		udp
+	option src_ip		fe80::/10
+	option src_port		547
+	option dest_ip		fe80::/10
+	option dest_port	546
+	option family		ipv6
+	option target		ACCEPT
+
+# Allow essential incoming IPv6 ICMP traffic
+config rule
+	option name		Allow-ICMPv6-Input
+	option src		wan
+	option proto	icmp
+	list icmp_type		echo-request
+	list icmp_type		echo-reply
+	list icmp_type		destination-unreachable
+	list icmp_type		packet-too-big
+	list icmp_type		time-exceeded
+	list icmp_type		bad-header
+	list icmp_type		unknown-header-type
+	list icmp_type		router-solicitation
+	list icmp_type		neighbour-solicitation
+	list icmp_type		router-advertisement
+	list icmp_type		neighbour-advertisement
+	option limit		1000/sec
+	option family		ipv6
+	option target		ACCEPT
+
+# Allow essential forwarded IPv6 ICMP traffic
+config rule
+	option name		Allow-ICMPv6-Forward
+	option src		wan
+	option dest		*
+	option proto		icmp
+	list icmp_type		echo-request
+	list icmp_type		echo-reply
+	list icmp_type		destination-unreachable
+	list icmp_type		packet-too-big
+	list icmp_type		time-exceeded
+	list icmp_type		bad-header
+	list icmp_type		unknown-header-type
+	option limit		1000/sec
+	option family		ipv6
+	option target		ACCEPT
+
+# include a file with users custom iptables rules
+config include
+	option path /etc/firewall.user
+
+
+### EXAMPLE CONFIG SECTIONS
+# do not allow a specific ip to access wan
+#config rule
+#	option src		lan
+#	option src_ip	192.168.45.2
+#	option dest		wan
+#	option proto	tcp
+#	option target	REJECT
+
+# block a specific mac on wan
+#config rule
+#	option dest		wan
+#	option src_mac	00:11:22:33:44:66
+#	option target	REJECT
+
+# block incoming ICMP traffic on a zone
+#config rule
+#	option src		lan
+#	option proto	ICMP
+#	option target	DROP
+
+# port redirect port coming in on wan to lan
+#config redirect
+#	option src			wan
+#	option src_dport	80
+#	option dest			lan
+#	option dest_ip		192.168.16.235
+#	option dest_port	80
+#	option proto		tcp
+
+# port redirect of remapped ssh port (22001) on wan
+#config redirect
+#	option src		wan
+#	option src_dport	22001
+#	option dest		lan
+#	option dest_port	22
+#	option proto		tcp
+
+# allow IPsec/ESP and ISAKMP passthrough
+#config rule
+#	option src		wan
+#	option dest		lan
+#	option protocol		esp
+#	option target		ACCEPT
+
+#config rule
+#	option src		wan
+#	option dest		lan
+#	option src_port		500
+#	option dest_port	500
+#	option proto		udp
+#	option target		ACCEPT
+
+### FULL CONFIG SECTIONS
+#config rule
+#	option src		lan
+#	option src_ip	192.168.45.2
+#	option src_mac	00:11:22:33:44:55
+#	option src_port	80
+#	option dest		wan
+#	option dest_ip	194.25.2.129
+#	option dest_port	120
+#	option proto	tcp
+#	option target	REJECT
+
+#config redirect
+#	option src		lan
+#	option src_ip	192.168.45.2
+#	option src_mac	00:11:22:33:44:55
+#	option src_port		1024
+#	option src_dport	80
+#	option dest_ip	194.25.2.129
+#	option dest_port	120
+#	option proto	tcp

+ 39 - 0
openwrt-rescue/common/etc/config/fstab

@@ -0,0 +1,39 @@
+config 'global' 
+  option  'anon_swap'   '1' 
+  option  'anon_mount'  '0' 
+  option  'auto_swap'   '1' 
+  option  'auto_mount'  '1' 
+  option  'delay_root'  '5' 
+  option  'check_fs'    '0' 
+
+config 'global' 'automount'
+  option  'from_fstab'  '1' 
+  option  'anon_mount'  '0' 
+
+## btrfs is not picked up here
+## sticking with ext4 for now
+config 'mount'
+  option 'label'        'Superglue'
+  option 'target'       '/www'
+  option 'enabled'      '1' 
+  option 'enabled_fsck' '0' 
+  option 'options'      'rw,sync,noatime,nodiratime'
+
+## vfat compatibility
+config 'mount'
+  option 'label'        'SUPERGLUE'
+  option 'target'       '/www'
+
+# swap file
+config 'swap'
+  option 'device'       '/mnt/system/swap'
+
+# /tmp
+config 'mount'
+  option 'target'       '/tmp'
+  option 'device'       'tmpfs'
+  option 'fstype'       'tmpfs'
+  option 'options'      'remount,rw,nosuid,nodev,noatime,size=65%'
+  option 'enabled_fsck' '0'
+  option 'enabled' '1'
+

+ 19 - 0
openwrt-rescue/common/etc/config/network

@@ -0,0 +1,19 @@
+config interface 'loopback'
+	option ifname 'lo'
+	option proto 'static'
+	option ipaddr '127.0.0.1'
+	option netmask '255.0.0.0'
+
+config globals 'globals'
+	option ula_prefix 'fd2c:90fd:3f5a::/48'
+
+config interface 'lan'
+	option ifname 'eth1'
+	option force_link '1'
+	option type 'bridge'
+	option proto 'static'
+	option ipaddr '192.168.1.1'
+	option netmask '255.255.255.0'
+
+config interface 'wan'
+	option proto 'dhcp'

+ 0 - 0
openwrt/common/www/lib/.keep → openwrt-rescue/common/etc/config/ubootenv


+ 25 - 0
openwrt-rescue/common/etc/config/wireless

@@ -0,0 +1,25 @@
+config wifi-device 'radio0'
+	option type 'mac80211'
+	option channel 'auto'
+	option hwmode '11gn'
+	option path 'platform/ar933x_wmac'
+	option noscan 1
+	option htmode 'HT20'
+	option country DE
+
+config wifi-iface
+	option device 'radio0'
+	option network 'lan'
+	option mode 'ap'
+	option encryption 'none'
+	option ssid 'superglue'
+
+config wifi-iface
+	option device 'radio0'
+	option network 'wan'
+	option disabled '1'
+	option mode 'sta'
+	option encryption 'psk2'
+	option ssid ''
+	option key ''
+

+ 1 - 0
openwrt-rescue/common/etc/crontabs/root

@@ -0,0 +1 @@
+1 6 * * *	  /sbin/logrotate /www/log/*.log; /etc/init.d/lighttpd reload

+ 13 - 0
openwrt-rescue/common/etc/firewall.user

@@ -0,0 +1,13 @@
+# This file is interpreted as shell script.
+# Put your custom iptables rules here, they will
+# be executed with each firewall (re-)start.
+
+# allow Superglue!
+iptables -A input_rule -p tcp --dport 80 -j ACCEPT
+
+# allow SSH (rescue mode)
+iptables -A input_rule -p tcp --dport 22 -j ACCEPT
+
+# Internal uci firewall chains are flushed and recreated on reload, so
+# put custom rules into the root chains e.g. INPUT or FORWARD or into the
+# special user chains, e.g. input_wan_rule or postrouting_lan_rule.

+ 10 - 0
openwrt-rescue/common/etc/group

@@ -0,0 +1,10 @@
+root:x:0:
+daemon:x:1:
+adm:x:4:
+mail:x:8:
+audio:x:29:
+www-data:x:33:
+ftp:x:55:
+users:x:100:
+network:x:101:
+nogroup:x:65534:

+ 40 - 0
openwrt-rescue/common/etc/hotplug.d/block/99-sg-dirs

@@ -0,0 +1,40 @@
+#!/bin/ash
+
+set -o xtrace
+
+## USB drive should be already mounted here
+_WWW="/www"
+
+n=0
+while ! mountpoint -q $_WWW; do [ $n -gt 30 ] && exit 1;
+  sleep 1
+  let n++
+done
+unset n
+
+## if /www is mounted, then..
+_HTDOCS="$_WWW/htdocs"
+
+## make ./htdocs if there is none
+[ -e $_HTDOCS ] || mkdir $_HTDOCS
+## if not writable chown with httpd
+[ $(stat $_HTDOCS -c %U) == 'httpd' ] || chown -R httpd $_HTDOCS
+[ ! $(stat $_HTDOCS -c %a) -lt '755' ] || chmod -R u+rwX $_HTDOCS
+
+## check if index.html is present
+[ -e $_HTDOCS/index.html ] || (
+  cp /opt/lib/resources/demo.html $_HTDOCS/default.html
+  chown httpd $_HTDOCS/default.html 
+  )
+
+## check for log directory
+[ -e $_WWW/log ] || (
+  mkdir $_WWW/log
+  chown httpd $_WWW/log
+  )
+
+## check for tmp directory
+[ -e $_WWW/tmp ] || (
+  mkdir $_WWW/tmp
+  chown httpd $_WWW/tmp
+  )

+ 47 - 0
openwrt-rescue/common/etc/lighttpd/lighttpd.conf

@@ -0,0 +1,47 @@
+server.modules = (
+ "mod_alias",
+ "mod_redirect",
+ "mod_cgi"
+)
+
+server.document-root =  "/www/htdocs"
+server.upload-dirs =  ( "/www/tmp" )
+server.errorlog =       "/www/log/error.log"
+server.pid-file =       "/var/run/lighttpd.pid"
+server.username =       "httpd"
+server.groupname =      "nogroup"
+server.port =           80
+
+index-file.names = (
+    "index.html",
+    "default.html"
+)
+
+$SERVER["socket"] == ":80" {
+    $HTTP["host"] =~ "(.*)" {
+        url.redirect = ( "^(?!/systemupdate|/resources).*$" => "http://%1/systemupdate" )
+    }
+}
+
+cgi.assign = (
+    ".sh"   =>  "/bin/bash",
+    ".cgi"  =>  "",
+)
+
+#url.access-deny = ( "~", ".inc", ".htaccess", ".htpasswd", "htpasswd", "/tmp/" )
+
+$HTTP["request-method"] == "GET" {
+  alias.url = (
+    "/resources"  =>  "/opt/lib/resources",
+    "/systemupdate"      =>  "/opt/lib/cgi/rescue.cgi",
+  )
+}
+
+$HTTP["request-method"] == "POST" {
+  alias.url = (
+    "/systemupdate"      =>  "/opt/lib/cgi/rescue.cgi",
+  )
+}
+
+## reads optional conf files
+include "/etc/lighttpd/mime.conf"

+ 87 - 0
openwrt-rescue/common/etc/lighttpd/mime.conf

@@ -0,0 +1,87 @@
+mimetype.use-xattr        = "disable"
+
+## Superglue mimetype mapping
+## Dotless files are handled as text/html via URL matching,
+## see lighttpd.conf
+
+mimetype.assign             = (
+  ".appcache"     =>      "text/cache-manifest" ,
+  ".asc"          =>      "text/plain",
+  ".asf"          =>      "video/x-ms-asf",
+  ".asx"          =>      "video/x-ms-asf",
+  ".avi"          =>      "video/x-msvideo",
+  ".bz2"          =>      "application/x-bzip",
+  ".class"        =>      "application/octet-stream",
+  ".conf"         =>      "text/plain",
+  ".cpp"          =>      "text/plain",
+  ".crx"          =>      "application/x-chrome-extension",
+  ".css"          =>      "text/css",
+  ".c"            =>      "text/plain",
+  ".dtd"          =>      "text/xml",
+  ".dvi"          =>      "application/x-dvi",
+  ".eot"          =>      "application/vnd.ms-fontobject",
+  ".gif"          =>      "image/gif",
+  ".gz"           =>      "application/x-gzip",
+  ".htc"          =>      "text/x-component",
+  ".html"         =>      "text/html",
+  ".htm"          =>      "text/html",
+  ".ico"          =>      "image/x-icon",
+  ".jar"          =>      "application/x-java-archive",
+  ".jpeg"         =>      "image/jpeg",
+  ".jpg"          =>      "image/jpeg",
+  ".json"         =>      "application/json",
+  ".js"           =>      "text/javascript",
+  ".log"          =>      "text/plain",
+  ".m3u"          =>      "audio/x-mpegurl",
+  ".manifest"     =>      "text/cache-manifest" ,
+  ".mov"          =>      "video/quicktime",
+  ".mp3"          =>      "audio/mpeg",
+  ".mp4"          =>      "video/mp4",
+  ".mpeg"         =>      "video/mpeg",
+  ".mpg"          =>      "video/mpeg",
+  ".oex"          =>      "application/x-opera-extension",
+  ".oga"          =>      "audio/ogg",
+  ".ogg"          =>      "application/ogg",
+  ".ogv"          =>      "video/ogg",
+  ".otf"          =>  	  "application/font-sfnt",
+  ".pac"          =>      "application/x-ns-proxy-autoconfig",
+  ".pdf"          =>      "application/pdf",
+  ".pem"          =>      "x-pem-file",    
+  ".png"          =>      "image/png",
+  ".ps"           =>      "application/postscript",
+  ".qt"           =>      "video/quicktime",
+  ".rpm"          =>      "application/x-rpm",
+  ".safariextz"   =>      "application/octet-stream",
+  ".sig"          =>      "application/pgp-signature",
+  ".spec"         =>      "text/plain",
+  ".spl"          =>      "application/futuresplash",
+  ".svg"          =>      "image/svg+xml",
+  ".swf"          =>      "application/x-shockwave-flash",
+  ".tar"          =>      "application/x-tar",
+  ".tar.bz2"      =>      "application/x-bzip-compressed-tar",
+  ".tar.gz"       =>      "application/x-tgz",
+  ".tbz"          =>      "application/x-bzip-compressed-tar",
+  ".text"         =>      "text/plain",
+  ".tgz"          =>      "application/x-tgz",
+  ".torrent"      =>      "application/x-bittorrent",
+  ".ttc"          =>      "application/x-font-ttf",
+  ".ttf"          =>      "application/x-font-ttf",
+  ".txt"          =>      "text/plain",
+  ".vcf"          =>      "text/x-vcard",
+  ".vtt"          =>      "text/vtt",
+  ".wav"          =>      "audio/x-wav",
+  ".wax"          =>      "audio/x-ms-wax",
+  ".webapp"       =>      "application/x-web-app-manifest+json",
+  ".webm"         =>      "video/webm; codecs='vorbis'",
+  ".webp"         =>      "image/webp",
+  ".wma"          =>      "audio/x-ms-wma",
+  ".wmv"          =>      "video/x-ms-wmv",
+  ".woff"         =>      "application/font-woff",
+  ".xbm"          =>      "image/x-xbitmap",
+  ".xml"          =>      "text/xml",
+  ".xpi"          =>      "application/x-xpinstall",
+  ".xpm"          =>      "image/x-xpixmap",
+  ".xwd"          =>      "image/x-xwindowdump",
+  ".zip"          =>      "application/zip",
+  ""              =>      "application/octet-stream"
+)

+ 5 - 0
openwrt-rescue/common/etc/logrotate.conf

@@ -0,0 +1,5 @@
+## config file for /sbin/logrotate
+## this is NOT compatible with standard GNU logrotate 
+
+## keep logs for 120 days
+ROTATE=120

+ 6 - 0
openwrt-rescue/common/etc/opkg.conf

@@ -0,0 +1,6 @@
+src/gz barrier_breaker http://dev.superglue.it/packages
+dest root /
+dest ram /tmp
+dest opt /www/opt
+lists_dir ext /var/opkg-lists
+option overlay_root /overlay

+ 6 - 0
openwrt-rescue/common/etc/passwd

@@ -0,0 +1,6 @@
+root:x:0:0:root:/root:/bin/ash
+daemon:*:1:1:daemon:/var:/bin/false
+ftp:*:55:55:ftp:/home/ftp:/bin/false
+network:*:101:101:network:/var:/bin/false
+nobody:*:65534:65534:nobody:/var:/bin/false
+httpd:*:999:999:www-data:/www:/bin/false

+ 3 - 0
openwrt-rescue/common/etc/rc.local

@@ -0,0 +1,3 @@
+## 
+
+exit 0

+ 51 - 0
openwrt-rescue/common/etc/rc.local.off

@@ -0,0 +1,51 @@
+#!/bin/bash
+
+function err {
+  printf %s": "%s"\n" "$(basename $0)" "$1"
+  exit 1
+}
+
+## some Superglue special checks
+## USB drive should be already mounted here
+_WWW="/www"
+
+## try to mount 30 times with 2 second breaks
+while ! mountpoint -q $_WWW; do [[ $n -gt 30 ]] && err 'failed to mount /www..';
+  sleep 2
+  block mount &>/dev/null
+  let n++
+done
+
+## if /www is mounted, then..
+_HTDOCS="$_WWW/htdocs"
+
+## make ./htdocs if there is none
+[[ -e $_HTDOCS ]] || { mkdir $_HTDOCS; let E++; }
+## if not writable chown with httpd
+[[ $(stat $_HTDOCS -c %U) == 'httpd' ]] || { chown -R httpd $_HTDOCS; let E++; }
+[[ ! $(stat $_HTDOCS -c %a) -lt '755' ]] || { chmod -R u+rwX $_HTDOCS; let E++; }
+
+## check if index.html is present
+[[ -e $_HTDOCS/index.html ]] || (
+  cp /opt/lib/resources/demo.html $_HTDOCS/default.html
+  chown httpd $_HTDOCS/default.html 
+  )
+
+## check for log directory
+[[ -e $_WWW/log ]] || { 
+  mkdir $_WWW/log;
+  chown httpd $_WWW/log;
+  let E++; }
+
+## check for tmp directory
+[[ -e $_WWW/tmp ]] || { 
+  mkdir $_WWW/tmp;
+  chown httpd $_WWW/tmp;
+  let E++; }
+
+## if any of the above triggered reload lighttpd
+[[ -z $E ]] || (
+  echo 'reloading lighttpd'
+  /etc/init.d/lighttpd reload
+  )
+

+ 6 - 0
openwrt-rescue/common/etc/shadow

@@ -0,0 +1,6 @@
+root:$1$rTz.JBwQ$fI.mmOlidBEi2jf4MlpxW1:16245:0:99999:7:::
+daemon:*:0:0:99999:7:::
+ftp:*:0:0:99999:7:::
+network:*:0:0:99999:7:::
+nobody:*:0:0:99999:7:::
+httpd:!:16134::::::

+ 1 - 0
openwrt-rescue/common/etc/sudoers.d/sg-suid

@@ -0,0 +1 @@
+httpd ALL=NOPASSWD: /opt/lib/cgi/suid.sh

+ 1 - 0
openwrt-rescue/common/etc/superglue_model

@@ -0,0 +1 @@
+GENERIC AR71xx

+ 1 - 0
openwrt-rescue/common/etc/superglue_version

@@ -0,0 +1 @@
+0.1-git_1

+ 31 - 0
openwrt-rescue/common/etc/sysctl.conf

@@ -0,0 +1,31 @@
+vm.swappiness = 10
+
+kernel.panic=3
+net.ipv4.conf.default.arp_ignore=1
+net.ipv4.conf.all.arp_ignore=1
+net.ipv4.ip_forward=1
+net.ipv4.icmp_echo_ignore_broadcasts=1
+net.ipv4.icmp_ignore_bogus_error_responses=1
+net.ipv4.tcp_ecn=0
+net.ipv4.tcp_fin_timeout=30
+net.ipv4.tcp_keepalive_time=120
+net.ipv4.tcp_syncookies=1
+net.ipv4.tcp_timestamps=1
+net.ipv4.tcp_sack=1
+net.ipv4.tcp_dsack=1
+
+net.ipv6.conf.default.forwarding=1
+net.ipv6.conf.all.forwarding=1
+
+net.netfilter.nf_conntrack_acct=1
+net.netfilter.nf_conntrack_checksum=0
+net.netfilter.nf_conntrack_max=16384
+net.netfilter.nf_conntrack_tcp_timeout_established=7440
+net.netfilter.nf_conntrack_udp_timeout=60
+net.netfilter.nf_conntrack_udp_timeout_stream=180
+net.netfilter.nf_conntrack_skip_filter=1
+
+# disable bridge firewalling by default
+net.bridge.bridge-nf-call-arptables=0
+net.bridge.bridge-nf-call-ip6tables=0
+net.bridge.bridge-nf-call-iptables=0

+ 1 - 0
openwrt-rescue/common/etc/uci-defaults/10-fstab

@@ -0,0 +1 @@
+[ -f /etc/config/fstab ] || ( block detect > /etc/config/fstab )

+ 5 - 0
openwrt-rescue/common/etc/uci-defaults/12-fstab-enable

@@ -0,0 +1,5 @@
+[ -e /etc/config/fstab ] && [ ! -z $(find /etc/rc.d/ -name 'S??fstab') ] && ( 
+  /etc/init.d/fstab enable
+  /etc/init.d/fstab start
+  )
+

+ 12 - 0
openwrt-rescue/common/etc/uci-defaults/20-set-ssid

@@ -0,0 +1,12 @@
+_MAC=$(iw wlan0 info | awk 'BEGIN { FS=":" } /addr/ { print $5$6 }')                 
+_MAC="Superglue-$_MAC-rescue"
+
+[ $(uci get wireless.@wifi-iface[0].ssid) != $_MAC ] && (
+  uci set wireless.@wifi-iface[0].ssid=$_MAC
+  uci commit wireless
+  wifi
+  /etc/init.d/network restart
+  /etc/init.d/dnsmasq restart
+  )
+
+exit 0

+ 476 - 0
openwrt-rescue/common/opt/lib/cgi/rescue.cgi

@@ -0,0 +1,476 @@
+#!/usr/bin/haserl --shell=/bin/bash  --upload-limit=32768 --upload-dir=/www/tmp 
+<%# upload limit: 32Mb %>
+<%
+
+_WWW='/www'
+_TMP="${_WWW}/tmp"
+_LOG="${_WWW}/systemupdate.log"  ## safe persistently
+_DEBUG=1
+
+err() {
+  _ERR="$?"
+  [[ "$_ERR" -gt 0 ]] || return 0
+  log "$1"
+  head "${2:='400'}"
+  exit "$_ERR"
+} 
+
+logThis() {
+  [[ "$_DEBUG" -gt 0 ]] || return 0
+  local _TYPE='I:'
+  [[ "$_ERR" -gt 0 ]] && _TYPE='E:'
+  local _TIME; printf -v _TIME '%(%d.%m.%Y %H:%M:%S)T' -1
+  printf '%b\n' "$_TIME  $_TYPE ${@} " >> "$_LOG"
+  [[ "$_DEBUG" -gt 1 ]] && printf '%b\n' "[verbose] $_TYPE ${1}"
+}
+
+headerPrint() {
+  case "$1" in
+ 200|'') printf '%b' 'HTTP/1.1 200 OK\r\n';;
+    301) printf '%b' "HTTP/1.1 301 Moved Permanently\r\nLocation: $HTTP_REFERER\r\n";;
+    403) printf '%b' 'HTTP/1.1 403 Forbidden\r\n';;
+    405) printf '%b' 'HTTP/1.1 405 Method Not Allowed\r\n';;
+    406) printf '%b' 'HTTP/1.1 406 Not Acceptable\r\n';;
+      *) printf '%b' 'HTTP/1.1 400 Bad Request\r\n';;
+  esac
+  printf '%b' 'Content-Type: text/html\r\n\r\n';
+}
+
+setQueryVars() {
+  env
+}
+
+runSuid() {
+  local _SID=$(/usr/bin/ps -p $$ -o sid=)  ## pass session id to the child
+  local _CMD=$@
+  sudo ./suid.sh $_CMD $_SID 2>/dev/null
+}
+
+getQueryFile() {
+  local _UPLD="${HASERL_fwupload_path##*/}"
+  logThis "'multipart': decoding stream"
+  mv "$_TMP/$_UPLD" "$_TMP/fwupload.bin" 2>/dev/null || _ERR=$?
+  if [[ $_ERR -gt 0 ]]; then
+    showMesg 'Firmware upload has failed' 'Reboot your Superglue server and try again'
+  fi
+}
+
+validIp() {
+  local _IP=$1
+  local _RET=1
+  if [[ $_IP =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
+    OIFS=$IFS
+    IFS='.'
+    _IP=($_IP)
+    IFS=$OIFS
+    [[ ${_IP[0]} -le 255 && ${_IP[1]} -le 255 && ${_IP[2]} -le 255 && ${_IP[3]} -le 255 ]]
+    _RET=$?
+  fi
+  return $_RET
+}
+
+pwdChange() {
+  if [[ ! -z "${_pwd##$_pwdd}" ]]; then 
+    _ERR=1
+    showMesg 'Passwords did not match'
+  fi
+
+  if [[ ${#_pwd} -lt 6 ]]; then
+    _ERR=1
+    showMesg 'Password must be at least 6 characters long'
+  fi
+
+  runSuid "echo -e \"$_pwd\n$_pwd\" | passwd root"
+  runSuid "echo $(htDigest $_pwd) > $_PWDFILE"
+  _ERR=$?
+  if [[ $_ERR -gt 0 ]]; then
+    showMesg 'Password change failed'
+  else
+    showMesg 'Password is changed'
+  fi
+}
+
+lanAddr() {
+  logThis "new LAN addr is: $_laddr"
+  validIp $_laddr || showMesg 'Not valid network address'
+  doUci set laddr $_laddr
+  _ERR=$?
+  if [[ $_ERR -gt 0 ]]; then
+    showMesg 'Setting network address failed'
+  else
+    (sleep 1; doUci commit network; doUci commit wireless;)&
+    showMesg 'New network address is set' "Your server is now accessible under <a href='http://superglue.local/admin'>http://superglue.local/admin</a>"
+  fi 
+}
+
+wanSet() {
+  if [[ ! -z $_wanifname ]]; then
+    ## eth and wlan wan cases are different!
+    ## eth wan requires:
+    ##   config interface 'wan'
+    ##     option ifname 'eth0'
+    ##
+    ##   config wifi-iface
+    ##     option device 'radio0'
+    ##     option network 'wan'     
+    ##     option disabled '1' (or no 'config wifi-iface' section at all)
+    ##
+    ## wlan wan requires:
+    ##   config interface 'wan'
+    ##     option proto 'dhcp'
+    ##     (without 'option ifname' specified!)
+    ##
+    ##    config wifi-iface 
+    ##      option device 'radio0'
+    ##      option network 'wan'
+    logThis "wan.ifname=$_wanifname"
+    if [[ $_wanifname == 'eth0' ]]; then
+      doUci set wanifname $_wanifname
+      doUci set wanwifacedis '1'
+    elif [[ $_wanifname == 'wlan1' ]]; then
+      doUci set wanifname ''
+      doUci set wanwifacedis ''
+    fi
+    if [[ $_wanproto == 'dhcp' ]]; then
+      doUci set wanproto dhcp
+    elif [[ $_wanproto == 'static' ]]; then
+      logThis "wan.ipaddr=$_wanipaddr"
+      doUci set wanproto static
+      doUci set wanipaddr $_wanipaddr
+      doUci set wannetmask $_wannetmask
+    fi
+    if [[ $_wanifname == 'wlan1' ]]; then
+      ssidChange || showMesg 'Wireless changes failed'
+    fi
+    ## background the following
+    doUci commit network &&
+    showMesg 'Internet connection is configured' 'Waiting for device to get ready' ||
+    showMesg 'Configuring Internet connection failed'
+  fi
+  logThis "new WAN iface is: $_wanifname"
+}
+
+ssidChange() {
+  ## check for iface
+  [[ ! $_iface =~ ^('wan'|'lan')$ ]] && showMesg 'Error changing wireless settings' 'unknown/unconfigured interface'
+  logThis "$_iface is being set"
+
+  _p=$_iface
+
+  ## default enc for now
+  local _enc='psk2'
+  if [[ $_iface == 'wan' ]]; then
+    local _mode='sta'
+    local _ssid="${_wanssid}"
+    local _key="${_wankey}"
+  else 
+    local _mode='ap'
+    local _ssid="${_lanssid}"
+    local _key="${_lankey}"
+  fi
+
+  logThis "ssid: $_ssid [$_mode], key: $_key [$_enc]"
+  logThis $_wanssid
+
+  if [[ ${#_ssid} -lt 4 ]]; then
+   _ERR=1
+   showMesg 'SSID must be at least 4 characters long'
+  fi
+  doUci set $_p'ssid' "${_ssid}"
+  _ERR=$?
+  [[ $_ERR -gt 0 ]] && showMesg 'New SSID is not set'
+
+  if [[ -z $_key ]]; then
+    ## if key is empty set encryption to none and remove key
+    doUci set $_p'key' && doUci set $_p'enc' 'none'
+    _ERR=$?
+  else
+    if [[ ${#_key} -lt 8 ]]; then
+     _ERR=1
+      showMesg 'Passphrase must be at least 8 characters long'
+    fi
+    doUci set $_p'key' "${_key}" && doUci set $_p'enc' "${_enc}"
+    _ERR=$?
+    [[ $_ERR -gt 0 ]] && showMesg 'Passphrase is not set'
+  fi
+  [[ $_ERR -gt 0 ]] && return $_ERR  ##showMesg 'Wireless changes failed'
+  doUci commit wireless ##&& showMesg 'Wireless changes applied'
+}
+
+#showError() {
+#  headerPrint 406
+#  logThis "$@"
+#  echo "ERROR: $@"
+#  exit 1
+#}
+
+showMesg() {
+  logThis "$@"
+  local _MSG=$1
+  local _SUBMSG=$2
+  _MSG=${_MSG:='Not defined'}
+  _SUBMSG=${_SUBMSG:='back to control panel in a second..'}
+  if [[ $_ERR -gt 0 ]]; then
+    local _TYPE='ERROR: '
+    headerPrint 406
+  else
+    local _TYPE='OK: '
+    headerPrint 200
+  fi
+  htmlHead "<meta http-equiv='refresh' content='3;url=${HTTP_REFERER}'>"
+  echo "<body>
+<h1>Superglue system update</h1>
+<hr>
+<h2 style='display:inline'>$_TYPE $_MSG</h2>
+<span style='display:inline; margin-left: 50px;'>$_SUBMSG</span>
+<hr>
+</body></html>"
+  exit 0
+}
+
+updateFw() {
+  logThis "updating fw"
+  _FWFILE="${_TMP}/fwupload.bin"
+  logThis "fwfile is: $(ls -lad $_FWFILE)"
+  _OUT="$(/sbin/sysupgrade -T $_FWFILE 2>&1)"
+  _ERR=$?
+  [[ $_ERR -gt 0 ]] && showMesg "$_OUT"
+  _OUT="$(runSuid /sbin/mtd -e firmware -q write $_FWFILE firmware)"
+  _ERR=$?
+  [[ $_ERR -gt 0 ]] && showMesg "update failed, $_OUT"
+  _OUT="$(/sbin/mtd verify $_FWFILE firmware_2>&1)"
+  _ERR=$?
+  [[ $_ERR -gt 0 ]] && showMesg "update check failed, $_OUT"
+  runSuid reboot
+  showMesg 'Firmware update is completed, rebooting..' 'this might take up to 60 seconds'
+}
+
+rebootNow() {
+  logThis "reboot: now!"
+  runSuid reboot
+  showMesg 'Rebooting..' 'this might take up to 60 seconds'
+}
+
+doUci() {
+  local _CMD=''
+  local _ARG=''
+  case $1 in
+    get|set|commit) _CMD=$1;;
+          *) logThis 'bad UCI command'; headerPrint 405; echo 'bad UCI command'; exit 1 ;;
+  esac
+
+  case $2 in
+    lanssid) _ARG='wireless.@wifi-iface[0].ssid';;
+    lanenc) _ARG='wireless.@wifi-iface[0].encryption';;
+    lankey) _ARG='wireless.@wifi-iface[0].key';;
+    lanipaddr) _ARG='network.lan.ipaddr';;
+    wanifname) _ARG='network.wan.ifname';;
+    wanproto) _ARG='network.wan.proto';;
+    wanipaddr) _ARG='network.wan.ipaddr';;
+    wannetmask) _ARG='network.wan.netmask';;
+    wanwifacedis) _ARG='wireless.@wifi-iface[1].disabled';;
+    wanssid) _ARG='wireless.@wifi-iface[1].ssid';;
+    wanenc) _ARG='wireless.@wifi-iface[1].encryption';;
+    wankey) _ARG='wireless.@wifi-iface[1].key';;
+    *) if [[ $_CMD == 'commit' ]]; then
+        _ARG=$2
+       else 
+        logThis "bad UCI entry: $2"
+        _ERR=1
+        showMesg 'bad UCI entry'
+       fi ;;
+  esac
+
+  if [[ $_CMD == 'get' ]]; then
+    if [ ! -z $_ARG ]; then
+      /sbin/uci -q get $_ARG || return $?
+    fi
+  fi
+
+  if [[ $_CMD == 'set' ]]; then
+    local _VAL=$3
+    if [ -z $_VAL ]; then
+      logThis "empty $_ARG value, removing record"
+      runSuid /sbin/uci delete $_ARG || ( echo "uci delete $_ARG: error"; exit 1; )
+    fi
+
+    if [ ! -z $_ARG ]; then
+      logThis "setting $_ARG value"
+      runSuid /sbin/uci set $_ARG=$_VAL || ( echo "uci set $_ARG: error"; exit 1; )
+    fi
+  fi
+
+  if [[ $_CMD == 'commit' ]]; then
+    runSuid /sbin/uci commit $_ARG|| echo "uci commit $_ARG: error"
+    if [[ "$_ARG" == 'wireless' ]]; then
+      runSuid /sbin/wifi || echo 'wifi: error'
+    fi
+    if [[ "$_ARG" == 'network' ]]; then
+      runSuid /etc/init.d/dnsmasq restart && runSuid /etc/init.d/network restart || echo 'network: error'
+    fi
+  fi
+}
+
+getStat() {
+  . /usr/share/libubox/jshn.sh
+  local _IFACE=$1
+  local _IFSTAT=$(runSuid ubus call network.interface.wan status 2>/dev/null)
+  logThis "$_IFSTAT"
+  json_get_type _IFSTAT ipv4_address
+  if json_get_type _IFSTAT ipv4_address && [[ "$_IFSTAT" == 'array' ]]; then
+    json_select ipv4_address
+    json_get_type _IFSTAT 1
+    if [[ "$_IFSTAT" == 'object' ]]; then
+      json_select 1
+      json_get_var IP4 address
+      json_get_var Subnet4 mask
+      [[ "$IP4" != '' ]] && [[ "$Subnet4" != '' ]] && IP4="$IP4/$Subnet4"
+    fi
+  fi
+  logThis $IP4
+}
+
+htmlHead() {
+echo "<!-- obnoxious code below, keep your ports tight -->
+<!doctype html>
+<html>
+<head><title>SuperGlue | System update</title>
+$@
+<link rel='stylesheet' type='text/css' href='http://${HTTP_HOST}/resources/admin/admin.css'>
+</head>"
+}
+
+if [[ "${REQUEST_METHOD^^}" == "POST" ]]; then
+  [[ $CONTENT_LENGTH -gt 0 ]] || err 'content length is zero, 301 back to referer' '301'
+  case "${CONTENT_TYPE^^}" in 
+    APPLICATION/X-WWW-FORM-URLENCODED*) setQueryVars;;
+                  MULTIPART/FORM-DATA*) getQueryFile;;
+                                     *) _ERR=1; _OUT='this is not a post';;
+  esac
+
+  case $REQUEST_URI in
+                *pwdchange) pwdChange;;
+               *ssidchange) ssidChange;;
+                  *lanaddr) lanAddr;;
+                 *updatefw) updateFw;;
+                *rebootnow) rebootNow;;
+                      *wan) wanSet;;
+                         *) logThis 'bad action'; headerPrint 405; 
+                            echo 'no such thing'; exit 1;;
+  esac
+fi
+
+headerPrint 200
+
+## html head
+htmlHead
+
+sgver=$(cat /etc/superglue_version)
+devmod=$(cat /etc/superglue_model)
+openwrt=$(cat /etc/openwrt_version)
+wanifname=$(doUci get wanifname || echo 'wlan0') ## TODO fix this
+wanproto=$(doUci get wanproto)
+wanipaddr=$(doUci get wanipaddr) 
+wannetmask=$(doUci get wannetmask)
+wanssid=$(doUci get wanssid)
+wankey=$(doUci get wankey)
+
+echo "<body>
+<img src='/resources/images/superglue-logo.png' id='sg-logo'>
+<h2 style='display:inline'>Superglue system update</h2>
+<span style='display:block;'>System version: $sgver | Device: $devmod</span>
+<span style='display:block;'>$(uptime)</span>
+<hr>
+
+<span class='title2'>Firmware update:</span>
+<p>The main purpose of Superglue <b>system update mode</b> is to ensure smooth and simple upgrades to the latest versions of Superglue firmware (OS) during the period of active project development. These updates help us get rid of the bugs and introduce new features (and sometimes, the other way around)</p>
+<p>Before you begin, please make sure to obtain the latest firmware by visiting our <a href='http://discourse.superglue.it/category/superglue/l/latest' target='_blank'>online users comminuty</a> or directly via the <a href='http://dev.superglue.it/firmware/latest' target='_blank'>Superglue firmware repository</a>.</p>
+<p>Once you are ready, upload the firmware update file using the form below:</p> 
+
+<form method='post' action='/systemupdate/updatefw' enctype='multipart/form-data' name='fwupdate'>
+<div id='uploadbox'>
+<input id='uploadfile' placeholder='Choose file' disabled='disabled' style='width:400px'>
+<input id='uploadbtn' name='fwupload' type='file'>
+</div>
+<input type='submit' value='Upload'>
+</form>
+<p>Configuration options below are optional.<br>Unless you upgrade the current firmware any changes done to the setting will not be saved.</p>
+<hr>
+<br><br>
+Internet connection:
+<form method='post' action='/systemupdate/wan' name='wan' onchange='formChange();'>
+  <div style='display:inline-flex'>
+  <div style='display:inline-block;'>
+  <select name='wanifname' id='wanifname' style='display:block'>
+  <option value='eth0' id='eth' $([[ $wanifname =~ ('eth') ]] && echo 'selected')>Wired (WAN port)</option>
+  <option value='wlan1' id='wlan' $([[ $wanifname =~ ('wlan') ]] && echo 'selected')>Wireless (Wi-Fi)</option>
+  </select>
+  <fieldset id='wanwifi' class='hide'>
+  <input type='text' name='wanssid' value='$wanssid'>
+  <input type='password' name='wankey' value='$wankey'>
+  </fieldset>
+  </div>
+
+  <div style='display:inline-block;'>
+  <select name='wanproto' id='wanproto' style='display:block'>
+  <option value='dhcp' name='dhcp' id='dhcp' $([[ $wanproto == 'dhcp' ]] && echo 'selected')>Automatic (DHCP)</option>
+  <option value='stat' name='dhcp' id='stat' $([[ $wanproto == 'static' ]] && echo 'selected')>Manual (Static IP)</option>
+  </select>
+  <fieldset id='wanaddr' class='hide' >
+  <input type='text' name='wanipaddr' id='wanipaddr' value='$wanipaddr'>
+  <input type='text' name='wangw' id='wannetmask' value='$wannetmask'>
+  </fieldset>
+  </div>
+  </div>
+  <input type='hidden' name='iface' value='wan' class='inline'>
+  <input type='submit' value='Apply'>
+
+</form>
+<hr>
+
+Local wireless network:
+<form method='post' action='/systemupdate/ssidchange'>
+  <div style='display:inline-flex'>
+  <div style='display:inline-block;'>
+    <input type='text' name='lanssid' value='$(doUci get lanssid)'>
+    <input type='password' name='lankey' value='$(doUci get lankey)'>
+  </div>
+  <div style='display:inline-block;'>
+    <input type='text' name='lanipaddr' value='$(doUci get lanipaddr)'>
+    <input type='hidden' name='iface' value='lan' class='inline'>
+  </div>
+  </div>
+  <input type='submit' value='Apply'>
+  
+</form>
+
+<hr>
+
+<form action='/systemupdate/rebootnow' method='post' class='inline'>
+<input type='hidden' name='reboot' value='now' class='inline'>
+<input type='submit' value='Reboot' class='inline'>
+</form>
+
+<form action='http://logout@${HTTP_HOST}/systemupdate' method='get' class='inline'>
+<input type='submit' value='Logout' class='inline'>
+</form>
+
+<hr>
+Memory:
+<pre>$(free)</pre>
+<hr>
+Storage:
+<pre>$(df -h)</pre>
+<hr>
+Environment:
+<pre>$(env)</pre>
+<hr>
+
+</body>
+<script type='text/javascript' src='http://${HTTP_HOST}/resources/admin/admin.js'></script>
+
+</html>"
+
+%>
+
+

+ 1 - 0
openwrt/common/www/lib/cgi/suid.sh → openwrt-rescue/common/opt/lib/cgi/suid.sh

@@ -27,6 +27,7 @@ _PSID=${@: -1}
 
 ## check if we belong to group/session of lighty and admin.sh
 #if [ $_LSID != $_PSID -o $_SID != $_LSID ]; then echo 'bad session'; exit 1; fi
+#if [[ $_LSID != $_PSID ]]; then echo 'bad session'; exit 1; fi
 
 ## remove _PSID from the arguments
 _ARGS=${@//$_PSID}

+ 0 - 0
openwrt/common/www/lib/htpasswd → openwrt-rescue/common/opt/lib/htpasswd


+ 145 - 0
openwrt-rescue/common/opt/lib/resources/admin/admin.css

@@ -0,0 +1,145 @@
+html {
+  width: 1000px;
+} 
+body { 
+  background:#ccc;
+  color:#0c0c0c;
+  margin: 20px 0 0 200px;
+  font-family: TitilliumWeb;
+  font-size: 100%;
+}
+
+a:link, a:visited {
+  color: #0c0c0c;
+}
+
+img#sg-logo {
+  height: 100px;
+  position: relative;
+  margin-right: 0;
+  top: -5px;
+  float: right;
+}
+
+span.title2 {
+  font-size:20px;
+  font-weight: bold;
+}
+
+input, select {
+  font-family: sans-serif;
+  font-size: 100%; 
+  color: #555;
+  display: block;
+  font-family: sans-serif;
+  font-size: 100%; 
+  width: 200px;
+  padding: 5px;
+  margin: 5px 5px 0 0;
+  border: 1px solid #666;
+  -moz-box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box; 
+  background: #fcfcfc;
+}
+
+form[name='fwupdate'] input, 
+form[name='fwupdate'] select {
+  color: #111;
+  width: auto;
+}
+
+input {
+  text-indent: 4px;
+  background: #fcfcfc;
+}
+
+input[type='submit'] {
+  padding-right: 8px;
+  width: inherit;
+  font-size: 100%;
+  cursor: pointer;
+}
+
+input[type='button'],
+input[type='submit'],
+input[type='reset'],
+input[type='file']::-webkit-file-upload-button,
+button {
+  cursor: pointer;
+}
+
+div#uploadbox {
+  position: relative;
+  height: 38px;
+}
+
+input#uploadbtn,
+input#uploadfile {
+  position: absolute;
+  top: 0;
+  left: 0;
+  height: 33px;
+  cursor: pointer;
+  width: auto;
+}
+
+input#uploadbtn {
+  opacity: 0;
+}
+
+/*
+input[type='file'] {
+  padding-right: 8px;
+  width: 400px;
+  font-size: 100%;
+  position: absolute;
+  top: 0;
+  right: 0;
+  margin: 0;
+  padding: 0;
+  cursor: pointer;
+  opacity: 0;
+  filter: alpha(opacity=0);
+} */
+
+
+img.logo {
+  position: absolute;
+  left:50px;
+  top: 20px;
+}
+hr {
+  border: 0;
+  height: 1px;
+  background: #aaa 
+}
+pre {
+  white-space: pre-wrap;
+}
+fieldset {
+  border: 0;
+  margin: 0;
+  padding: 0; 
+}
+.inline {
+  display: inline;
+}
+.hide {
+  visibility: hidden;
+  display: none;
+}
+.show {
+  visibility: visible;
+  display: inline-block;
+}
+
+@font-face {
+  font-family: TitilliumWeb;
+  src: url('/resources/fonts/Titillium_Web/TitilliumWeb-Regular.ttf') format('truetype');
+}
+@font-face { 
+  font-family: TitilliumWeb; 
+  font-weight: bold;
+  src: url('/resources/fonts/Titillium_Web/TitilliumWeb-Bold.ttf') format('truetype'); }
+

+ 34 - 0
openwrt-rescue/common/opt/lib/resources/admin/admin.js

@@ -0,0 +1,34 @@
+(function() {
+  document.getElementById('uploadbtn').onchange = function () {
+    document.getElementById('uploadfile').value = this.value.replace(/^.*\\/, "");
+    var len = document.getElementById('uploadfile').value.length - 7;
+    document.getElementById('uploadfile').setAttribute('size', len);
+    var len = document.getElementById('uploadfile').offsetWidth;
+    document.getElementById('uploadbtn').style.width = len + "px";
+  };
+})();
+
+function formChange() {
+  if (document.activeElement.tagName.toLowerCase() !=  'select') {
+    console.log('not select');
+    return false;
+  }
+  aElem = document.activeElement;
+  aParent = aElem.parentElement;
+  sOpt = aElem[aElem.selectedIndex];
+  console.log(aElem.id + sOpt.id);
+  if (aElem.id + sOpt.id == 'wanprotostat') {
+    document.getElementById('wanaddr').setAttribute('class','show');
+  }
+  if (aElem.id + sOpt.id == 'wanprotodhcp') {
+    document.getElementById('wanaddr').setAttribute('class','hide');
+  }
+  if (aElem.id + sOpt.id == 'wanifnamewlan') {
+    document.getElementById('wanwifi').setAttribute('class','show');
+  }
+  if (aElem.id + sOpt.id == 'wanifnameeth') {
+    document.getElementById('wanwifi').setAttribute('class','hide');
+  }
+};
+
+

+ 0 - 0
openwrt/common/www/lib/resources/empty.html → openwrt-rescue/common/opt/lib/resources/empty.html


+ 7 - 0
openwrt-rescue/common/opt/lib/resources/failsafe.html

@@ -0,0 +1,7 @@
+<html>
+<head><title>Superglue RESQUE MODE</title></head>
+<body>
+<h1>RESCUE MODE</h1>
+<h3>Please visit <a href='http://192.168.1.1/admin'>http://192.168.1.1/admin</a> and upload a functional Superglue firmware</h3>
+</body>
+</html>

+ 0 - 0
openwrt/common/www/lib/resources/fonts/Titillium_Web/TitilliumWeb-Bold.ttf → openwrt-rescue/common/opt/lib/resources/fonts/Titillium_Web/TitilliumWeb-Bold.ttf


+ 0 - 0
openwrt/common/www/lib/resources/fonts/Titillium_Web/TitilliumWeb-Regular.ttf → openwrt-rescue/common/opt/lib/resources/fonts/Titillium_Web/TitilliumWeb-Regular.ttf


BIN
openwrt-rescue/common/opt/lib/resources/images/superglue-logo.png


+ 1 - 0
openwrt-rescue/common/www/htdocs/default.html

@@ -0,0 +1 @@
+../../opt/lib/resources/failsafe.html

+ 1 - 0
openwrt-rescue/common/www/log

@@ -0,0 +1 @@
+/tmp

+ 1 - 0
openwrt-rescue/common/www/tmp

@@ -0,0 +1 @@
+/tmp

+ 105 - 0
openwrt-rescue/make_fw.sh

@@ -0,0 +1,105 @@
+#!/bin/bash
+
+## !! RESCUE FIRMWARE !! Not functional otherwise !!
+
+## Firmware image building script
+## http://superglue.it | Danja Vasiliev, 2014
+##
+## Needs:
+## - OpenWRT ImageBuilder blob:
+##    http://downloads.openwrt.org/barrier_breaker/14.07-rc3/ar71xx/generic 
+##    or http://downloads.openwrt.org/snapshots/trunk/ar71xx
+## - Superglue serverfiles local repo (which this script is part of):
+##    http://git.superglue.it/superglue/serverfiles/tree/master
+
+_PWD=$(pwd)
+_IMAGEBUILDER="$_PWD/../../../openwrt/OpenWrt-ImageBuilder-ar71xx_generic-for-linux-x86_64"
+_BUILDS="$_PWD/../../../sg-builds/rescue"
+
+[[ -e $_IMAGEBUILDER ]] || (echo 'ImageBuilder is missing'; exit 1;)
+[[ -e $_BUILDS ]] || (echo 'Builds directory is missing'; exit 1;)
+
+## dirs with platform specific files
+#_TARGETS='DIR505A1 TLWR710 WRT160NL'
+_TARGETS='TLWR710'
+
+## dir with common files
+_COMMON='common'
+
+_MAJOR='0.1'  ## bump that on major changes
+#_SUFFIX='git'  ## could be 'beta', 'rc', etc
+_SUFFIX='rescue'  ## could be 'beta', 'rc', etc
+
+## read build serial, incremented on every successful build
+if [[ -e sg_$_MAJOR.revision ]]; then
+  read _MINOR < sg_$_MAJOR.revision
+  let _MINOR++
+else _MINOR=0
+fi
+
+## get OpenWRT revision number
+_OPENWRT=$(fgrep -m1 'REVISION:=' $_IMAGEBUILDER/include/version.mk || echo 'r00000')
+_OPENWRT=${_OPENWRT/REVISION:=/}
+echo $_OPENWRT > openwrt.revision
+
+_VERSION="$_MAJOR"."$_MINOR"-"$_SUFFIX"
+
+echo "About to start building version: $_VERSION"
+echo -e "Targets for this build: $_TARGETS\n"
+
+echo 'Removing temporary dirs (if any)'
+find -maxdepth 1 -name *.tmp -exec rm -Rf {} \;
+
+for _TARGET in $_TARGETS; do
+  [[ -e $_TARGET.tmp ]] && rm -Rf $_TARGET.tmp 
+  cp -Ra $_COMMON $_TARGET.tmp
+  cp -Ra $_TARGET/* $_TARGET.tmp/
+
+  sed -e "s/%REVISION%/$_OPENWRT/g" -e "s/%VERSION%/$_VERSION/g" $_COMMON/etc/banner > $_TARGET.tmp/etc/banner
+
+  echo $_VERSION > $_TARGET.tmp/etc/superglue_version
+  cd $_IMAGEBUILDER && make clean
+
+  make image PROFILE=$_TARGET PACKAGES="bash sudo procps-ps haserl lighttpd lighttpd-mod-cgi lighttpd-mod-alias lighttpd-mod-redirect blkid kmod-fs-ext4 block-mount kmod-usb-storage kmod-scsi-generic mount-utils kmod-fs-vfat swap-utils coreutils-stat openssh-sftp-server avahi-daemon -gawk -kmod-ipv6 -kmod-ip6tables -odhcp6c -ip6tables" FILES=$_PWD/$_TARGET.tmp BIN_DIR=$_BUILDS/$_VERSION/$_TARGET/openwrt && 
+
+  ln -s $_BUILDS/$_VERSION/$_TARGET/openwrt/openwrt-*-factory.bin $_BUILDS/$_VERSION/$_TARGET/superglue-firmware-$_VERSION-$(echo $_TARGET | tr [:upper:] [:lower:])-factory.bin
+  ln -s $_BUILDS/$_VERSION/$_TARGET/openwrt/openwrt-*-sysupgrade.bin $_BUILDS/$_VERSION/$_TARGET/superglue-firmware-$_VERSION-$(echo $_TARGET | tr [:upper:] [:lower:])-sysupgrade.bin
+  cd $_BUILDS/$_VERSION/$_TARGET
+  md5sum *.bin > md5sums
+  cd -
+
+  _ERR=$?
+
+  if [[ $_ERR -eq 0 ]]; then 
+    echo -e "\n$_TARGET build completed\n"
+  else
+    rm -Rf $_BUILDS/$_VERSION/$_TARGET
+  fi
+
+  echo 'Cleaning up..'
+  make clean
+  cd $_PWD 
+  rm -Rf $_TARGET.tmp
+  
+done
+
+if [[ $_ERR -eq 0 ]]; then
+  ## if build succeeded bump revision
+  echo $_MINOR > sg_$_MAJOR.revision
+  echo -e "\nBuilding SUCCEEDED! :)\n"
+
+  ## create symlinks to latest
+  [[ -e $_BUILDS/latest ]] && touch $_BUILDS/latest || mkdir $_BUILDS/latest 
+  for _TARGET in $_TARGETS; do
+    [[ -e $_BUILDS/latest/$_TARGET ]] && rm -f $_BUILDS/latest/$_TARGET/* || mkdir $_BUILDS/latest/$_TARGET
+    set -o xtrace
+    ln -sf $_BUILDS/$_VERSION/$_TARGET/superglue-firmware-*-factory.bin $_BUILDS/latest/$_TARGET/superglue-firmware-latest-$(echo $_TARGET | tr [:upper:] [:lower:])-factory.bin
+    ln -sf $_BUILDS/$_VERSION/$_TARGET/superglue-firmware-*-sysupgrade.bin $_BUILDS/latest/$_TARGET/superglue-firmware-latest-$(echo $_TARGET | tr [:upper:] [:lower:])-sysupgrade.bin
+    set +o xtrace
+  done
+
+else
+  echo -e "\nBuilding FAILED.. :/\n"
+fi
+
+exit $_ERR

+ 1 - 0
openwrt-rescue/openwrt.revision

@@ -0,0 +1 @@
+r42056

+ 1 - 0
openwrt-rescue/sg_0.1.revision

@@ -0,0 +1 @@
+8

+ 30 - 0
openwrt/common/etc/avahi/avahi-daemon.conf

@@ -0,0 +1,30 @@
+[server]
+enable-dbus=no
+allow-interfaces=br-lan
+#host-name=superglue
+#domain-name=local
+use-ipv4=yes
+use-ipv6=no
+check-response-ttl=no
+use-iff-running=no
+
+[publish]
+publish-addresses=yes
+publish-hinfo=yes
+publish-workstation=no
+publish-domain=yes
+#publish-dns-servers=192.168.1.1
+publish-resolv-conf-dns-servers=yes
+
+[reflector]
+enable-reflector=no
+reflect-ipv=no
+
+[rlimits]
+#rlimit-as=
+rlimit-core=0
+rlimit-data=524288
+rlimit-fsize=0
+rlimit-nofile=30
+rlimit-stack=524288
+rlimit-nproc=3

+ 3 - 3
openwrt/common/etc/banner

@@ -8,7 +8,7 @@
  version %VERSION% - based on OpenWRT %REVISION%
  -----------------------------------------------------
  provides now:            will provide:
-   * HTTP (lighttpd)        * SMTP      
-   * Bash CGI               * IMAP
-                            * Lua CGI
+   * Lighttpd               * Btrfs
+   * Bash CGI               * Lua CGI
+   * SSH tunnels            * OpenVPN      
  -----------------------------------------------------

+ 2 - 2
openwrt/common/etc/config/dhcp

@@ -6,8 +6,8 @@ config dnsmasq
 	option localise_queries '1'
 	option rebind_protection '1'
 	option rebind_localhost '1'
-	option local '/local/'
-	option domain 'local'
+	option local '/home/'
+	option domain 'home'
 	option expandhosts '1'
 	option nonegcache '0'
 	option authoritative '1'

+ 7 - 7
openwrt/common/etc/config/fstab

@@ -13,15 +13,15 @@ config 'global' 'automount'
 ## btrfs is not picked up here
 config 'mount'
   option 'label'        'sg'
-  option 'target'       '/mnt/sg'
+  option 'target'       '/www'
   option 'enabled'      '1' 
   option 'enabled_fsck' '0' 
-#  option 'options'      'rw,noatime,nodiratime'
+  option 'options'      'rw,noatime,nodiratime'
 
 ## compatibility
-config 'mount'
-  option 'label'       'SUPERGLUE'
-  option 'target'       '/mnt/sg'
-  option 'enabled'      '1' 
-  option 'enabled_fsck' '0' 
+#config 'mount'
+#  option 'label'       'SUPERGLUE'
+#  option 'target'       '/mnt/sg'
+#  option 'enabled'      '1' 
+#  option 'enabled_fsck' '0' 
 #  option 'options'      'rw,noatime,nodiratime'

+ 2 - 4
openwrt/common/etc/config/network

@@ -14,8 +14,6 @@ config interface 'lan'
 	option proto 'static'
 	option ipaddr '192.168.1.1'
 	option netmask '255.255.255.0'
-	option ip6assign '60'
 
-#config interface 'wan'
-#  option ifname 'wlan0'
-#  option proto 'dhcp'
+config interface 'wan'
+	option proto 'dhcp'

+ 9 - 8
openwrt/common/etc/config/wireless

@@ -12,13 +12,14 @@ config wifi-iface
 	option network 'lan'
 	option mode 'ap'
 	option encryption 'none'
-  option ssid 'superglue'
+	option ssid 'superglue'
 
-#config wifi-iface
-#  option device 'radio0'
-#  option network 'wan'
-#  option mode 'sta'
-#  option ssid '<bssid>'
-#  option encryption 'psk2'
-#  option key '<passphrase>'
+config wifi-iface
+	option device 'radio0'
+	option network 'wan'
+	option disabled '1'
+	option mode 'sta'
+	option encryption 'psk2'
+	option ssid ''
+	option key ''
 

+ 40 - 0
openwrt/common/etc/hotplug.d/block/99-sg-dirs

@@ -0,0 +1,40 @@
+#!/bin/ash
+
+set -o xtrace
+
+## USB drive should be already mounted here
+_WWW="/www"
+
+n=0
+while ! mountpoint -q $_WWW; do [ $n -gt 30 ] && exit 1;
+  sleep 1
+  let n++
+done
+unset n
+
+## if /www is mounted, then..
+_HTDOCS="$_WWW/htdocs"
+
+## make ./htdocs if there is none
+[ -e $_HTDOCS ] || mkdir $_HTDOCS
+## if not writable chown with httpd
+[ $(stat $_HTDOCS -c %U) == 'httpd' ] || chown -R httpd $_HTDOCS
+[ ! $(stat $_HTDOCS -c %a) -lt '755' ] || chmod -R u+rwX $_HTDOCS
+
+## check if index.html is present
+[ -e $_HTDOCS/index.html ] || (
+  cp /opt/lib/resources/demo.html $_HTDOCS/default.html
+  chown httpd $_HTDOCS/default.html 
+  )
+
+## check for log directory
+[ -e $_WWW/log ] || (
+  mkdir $_WWW/log
+  chown httpd $_WWW/log
+  )
+
+## check for tmp directory
+[ -e $_WWW/tmp ] || (
+  mkdir $_WWW/tmp
+  chown httpd $_WWW/tmp
+  )

BIN
openwrt/common/etc/lighttpd/.lighttpd.conf.swp


+ 13 - 9
openwrt/common/etc/lighttpd/lighttpd.conf

@@ -45,7 +45,7 @@ cgi.assign = (
 url.access-deny = ( "~", ".inc", ".htaccess", ".htpasswd", "htpasswd", "/tmp/" )
 
 auth.backend = "htdigest"
-auth.backend.htdigest.userfile = "/www/lib/htpasswd"
+auth.backend.htdigest.userfile = "/opt/lib/htpasswd"
 auth.require = (
   "/admin"  => (
     "method"  =>  "digest",
@@ -71,11 +71,11 @@ $HTTP["request-method"] == "GET" {
     "^/templates/(.*)$" =>  "templates/$1",
   ),
   alias.url = (
-    "/resources"  =>  "/www/lib/resources",
-    "/devTools"   =>  "/www/lib/devTools",
-    "/extension"  =>  "/www/lib/extension",
-    "/templates"  =>  "/www/lib/templates",
-    "/admin"      =>  "/www/lib/cgi/admin.cgi"
+    "/resources"  =>  "/opt/lib/resources",
+    "/devTools"   =>  "/opt/lib/devTools",
+    "/extension"  =>  "/opt/lib/extension",
+    "/templates"  =>  "/opt/lib/templates",
+    "/admin"      =>  "/opt/lib/cgi/admin.cgi"
   )
   ## override content and mime type for dotless files to text/html
   $HTTP["url"] !~ "(\.)" {
@@ -88,8 +88,8 @@ $HTTP["request-method"] == "GET" {
 
 $HTTP["request-method"] == "POST" {
   alias.url = (
-    "/admin"    =>  "/www/lib/cgi/admin.cgi",
-    ""          =>  "/www/lib/cgi/post.cgi"
+    "/admin"    =>  "/opt/lib/cgi/admin.cgi",
+    ""          =>  "/opt/lib/cgi/post.cgi"
   )
   auth.require = (
     "" => (
@@ -100,8 +100,12 @@ $HTTP["request-method"] == "POST" {
   )
 }
 
+## can use this? per 
+## https://dev.openwrt.org/browser/packages/net/lighttpd/files/lighttpd.conf?rev=38469
+# include_shell "cat /etc/lighttpd/conf.d/*.conf"
+
 ## reads optional conf files
-include_shell "/etc/lighttpd/opts.sh mime.conf" # compress.conf
+include_shell "/etc/lighttpd/opts.sh mime.conf compress.conf"
 ## defines var.superglueVersion from /etc/superglue_version
 include_shell "/etc/lighttpd/vars.sh"
 setenv.add-response-header = ( "X-Superglue-Version" => var.superglueVersion )

+ 3 - 2
openwrt/common/etc/logrotate.conf

@@ -1,4 +1,5 @@
 ## config file for /sbin/logrotate
-## this is NOT compatible with standard GNU logrotate 
+## this file is NOT compatible with standard GNU logrotate 
 
-ROTATE=120
+## keep logs for 120 days
+_ROTATE=120

+ 1 - 1
openwrt/common/etc/opkg.conf

@@ -1,6 +1,6 @@
 src/gz barrier_breaker http://dev.superglue.it/packages
 dest root /
 dest ram /tmp
-dest opt /opt/root
+dest opt /www/opt
 lists_dir ext /var/opkg-lists
 option overlay_root /overlay

+ 1 - 42
openwrt/common/etc/rc.local

@@ -1,44 +1,3 @@
-#!/bin/bash
-
-## tweaks
-sysctl -w vm.swappiness=10
-
-## some checks specific to Superglue
-
-## where Superglue storage is mounted 
-_SG=/mnt/sg
-## htdocs to bind to
-_HTDOCS=/www/htdocs
-
-## mount if needed
-while ! mountpoint -q $_HTDOCS; do [ $n -gt 30 ] && break;
-  mount --bind $_SG/htdocs $_HTDOCS;
-  let n++
-done
-unset n
-mountpoint -q $_HTDOCS || ( echo 'failed to mount HTDOCS..'; exit 1; )
-
-## if /www/htdocs is mounted, then..
-  
-## if not writable chown with httpd
-[ $(stat $_HTDOCS -c %U) != 'httpd' ] && chown -R httpd $_HTDOCS
-[ $(stat $_HTDOCS -c %a) -lt '755' ] && chmod -R u+rwX $_HTDOCS
-
-## check if index.html is present
-[ -e $_HTDOCS/index.html ] || (
-  cp /www/lib/resources/demo.html $_HTDOCS/default.html
-  chown httpd $_HTDOCS/default.html
-  )
-
-## check for log directory
-[ -e /www/log ] || ( mkdir /www/log
-  chown httpd /www/log
-  /etc/init.d/lighttpd reload
-  )
-
-## check for tmp directory
-[ -e /www/tmp ] || ( mkdir /www/tmp
-  chown httpd /www/tmp
-  )
+## 
 
 exit 0

+ 51 - 0
openwrt/common/etc/rc.local.off

@@ -0,0 +1,51 @@
+#!/bin/bash
+
+function err {
+  printf %s": "%s"\n" "$(basename $0)" "$1"
+  exit 1
+}
+
+## some Superglue special checks
+## USB drive should be already mounted here
+_WWW="/www"
+
+## try to mount 30 times with 2 second breaks
+while ! mountpoint -q $_WWW; do [[ $n -gt 30 ]] && err 'failed to mount /www..';
+  sleep 2
+  block mount &>/dev/null
+  let n++
+done
+
+## if /www is mounted, then..
+_HTDOCS="$_WWW/htdocs"
+
+## make ./htdocs if there is none
+[[ -e $_HTDOCS ]] || { mkdir $_HTDOCS; let E++; }
+## if not writable chown with httpd
+[[ $(stat $_HTDOCS -c %U) == 'httpd' ]] || { chown -R httpd $_HTDOCS; let E++; }
+[[ ! $(stat $_HTDOCS -c %a) -lt '755' ]] || { chmod -R u+rwX $_HTDOCS; let E++; }
+
+## check if index.html is present
+[[ -e $_HTDOCS/index.html ]] || (
+  cp /opt/lib/resources/demo.html $_HTDOCS/default.html
+  chown httpd $_HTDOCS/default.html 
+  )
+
+## check for log directory
+[[ -e $_WWW/log ]] || { 
+  mkdir $_WWW/log;
+  chown httpd $_WWW/log;
+  let E++; }
+
+## check for tmp directory
+[[ -e $_WWW/tmp ]] || { 
+  mkdir $_WWW/tmp;
+  chown httpd $_WWW/tmp;
+  let E++; }
+
+## if any of the above triggered reload lighttpd
+[[ -z $E ]] || (
+  echo 'reloading lighttpd'
+  /etc/init.d/lighttpd reload
+  )
+

+ 1 - 1
openwrt/common/etc/sudoers.d/sg-suid

@@ -1 +1 @@
-httpd ALL=NOPASSWD: /www/lib/cgi/suid.sh
+httpd ALL=NOPASSWD: /opt/lib/cgi/suid.sh

+ 1 - 0
openwrt/common/etc/uci-defaults/10-fstab

@@ -0,0 +1 @@
+[ -f /etc/config/fstab ] || ( block detect > /etc/config/fstab )

+ 1 - 1
openwrt/common/etc/uci-defaults/12-fstab-enable

@@ -1,4 +1,4 @@
-[ -e /etc/config/fstab ] && [ -z $(find /etc/rc.d/ -name 'S??fstab') ] && ( 
+[ -e /etc/config/fstab ] && [ ! -z $(find /etc/rc.d/ -name 'S??fstab') ] && ( 
   /etc/init.d/fstab enable
   /etc/init.d/fstab start
   )

BIN
openwrt/common/lib/modules/3.10.36/cfg80211.ko


BIN
openwrt/common/lib/modules/3.10.36/ath.ko → openwrt/common/lib/modules/3.10.49/ath.ko


BIN
openwrt/common/lib/modules/3.10.49/cfg80211.ko


BIN
openwrt/common/opt/lib/cgi/.admin.cgi.swp


BIN
openwrt/common/opt/lib/cgi/.post.cgi.swp


+ 537 - 0
openwrt/common/opt/lib/cgi/admin-pre-rescue.cgi

@@ -0,0 +1,537 @@
+#!/bin/bash
+
+_WWW='/www'
+_PWDFILE="/opt/lib/htpasswd"
+_TMP="${_WWW}/tmp"
+_LOG="${_WWW}/log/admin.log"
+
+_DEBUG=1
+
+## logging
+logThis() {
+  [[ $_DEBUG -gt 0 ]] || return 0
+  [[ $_ERR -gt 0 ]] && _TYPE='E:' || _TYPE='I:'  ## Info or Error indication
+  local _TIME=$(printf '%(%d.%m.%Y %H:%M:%S)T' -1)
+  printf '%b\n' "$_TIME  $_TYPE ${1} " >> $_LOG
+  [[ $_DEBUG -gt 1 ]] && printf '%b\n' "[verbose] $_TYPE ${1}"
+  return 0
+}
+
+## http response
+headerPrint() {
+  case ${1} in
+    200) printf '%b' 'HTTP/1.1 200 OK\nAccess-Control-Allow-Origin: *\n\n';;
+    301) printf '%b' "HTTP/1.1 301 Moved Permanently\nLocation: ${HTTP_REFERER}\n\n";;
+    403) printf '%b' 'HTTP/1.1 403 Forbidden\n\n';;
+    405) printf '%b' 'HTTP/1.1 405 Method Not Allowed\n\n';;
+    406) printf '%b' 'HTTP/1.1 406 Not Acceptable\n\n';;
+  esac
+  return 0
+}
+
+htDigest() {
+  _USER='admin'
+  _PWD=$1
+  _REALM='superglue'
+  _HASH=$(echo -n "$_USER:$_REALM:$_PWD" | md5sum | cut -b -32)
+  echo -n "$_USER:$_REALM:$_HASH"
+}
+
+urlDec() {
+  local value=${*//+/%20}
+  for part in ${value//%/ \\x}; do
+    printf "%b%s" "${part:0:4}" "${part:4}"
+  done
+}
+
+setQueryVars() {
+  local _POST=$(cat)
+  local vars=${_POST//\*/%2A}
+  for var in ${vars//&/ }; do
+    local value=$(urlDec "${var#*=}")
+    value=${value//\\/\\\\}
+    eval "_${var%=*}=\"${value//\"/\\\"}\""
+  done
+}
+
+getQueryFile() {
+  _POST_TMP=$(mktemp -p $_TMP)  ## make tmp POST file
+  cat > $_POST_TMP  ## cautiously storing entire POST in a file
+  logThis "'multipart': decoding stream"
+  local _BND=$(findPostOpt 'boundary')
+  ## bash is binary unsafe and eats away precious lines
+  ## thus using gawk
+  function cutFile() {
+    gawk -v "want=$1" -v "bnd=$_BND" '
+      BEGIN { RS="\r\n"; ORS="\r\n" }
+
+      # reset based on boundaries
+      $0 == "--"bnd""     { st=1; next; }
+      $0 == "--"bnd"--"   { st=0; next; }
+      $0 == "--"bnd"--\r" { st=0; next; }
+
+      # search for wanted file
+      st == 1 && $0 ~  "^Content-Disposition:.* name=\""want"\"" { st=2; next; }
+      st == 1 && $0 == "" { st=9; next; }
+
+      # wait for newline, then start printing
+      st == 2 && $0 == "" { st=3; next; }
+      st == 3 { print $0 }
+      ' 2>&1
+  }
+  cutFile 'fwupload' < "${_POST_TMP}" > "${_TMP}/fwupload.bin"
+}
+
+## find arbitrary option supplied in Content-Type header
+## eg: "Content-Type:application/octet-stream; verbose=1"
+findPostOpt() {
+  for i in "${CONTENT_TYPE[@]:1}"; do
+    case "${i/=*}" in 
+      "$1") printf '%b' "${i/*=}" ;;
+    esac
+  done
+  return 0
+}
+
+runSuid() {
+  local _SID=$(/usr/bin/ps -p $$ -o sid=)  ## pass session id to the child
+  local _CMD=$@
+  sudo ./suid.sh $_CMD $_SID 2>/dev/null
+}
+
+validIp() {
+  local _IP=$1
+  local _RET=1
+  if [[ $_IP =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
+    OIFS=$IFS
+    IFS='.'
+    _IP=($_IP)
+    IFS=$OIFS
+    [[ ${_IP[0]} -le 255 && ${_IP[1]} -le 255 && ${_IP[2]} -le 255 && ${_IP[3]} -le 255 ]]
+    _RET=$?
+  fi
+  return $_RET
+}
+
+pwdChange() {
+  if [[ ! -z "${_pwd##$_pwdd}" ]]; then 
+    _ERR=1
+    showMesg 'Passwords did not match'
+  fi
+
+  if [[ ${#_pwd} -lt 6 ]]; then
+    _ERR=1
+    showMesg 'Password must be at least 6 characters long'
+  fi
+
+  runSuid "echo -e \"$_pwd\n$_pwd\" | passwd root"
+  runSuid "echo $(htDigest $_pwd) > $_PWDFILE"
+  _ERR=$?
+  if [[ $_ERR -gt 0 ]]; then
+    showMesg 'Password change failed'
+  else
+    showMesg 'Password is changed'
+  fi
+}
+
+lanAddr() {
+  logThis "new LAN addr is: $_laddr"
+  validIp $_laddr || showMesg 'Not valid network address'
+  doUci set laddr $_laddr
+  _ERR=$?
+  if [[ $_ERR -gt 0 ]]; then
+    showMesg 'Setting network address failed'
+  else
+    (sleep 1; doUci commit network; doUci commit wireless;)&
+    showMesg 'New network address is set' "Your server is now accessible under <a href='http://superglue.local/admin'>http://superglue.local/admin</a>"
+  fi 
+}
+
+wanSet() {
+  if [[ ! -z $_wanifname ]]; then
+    ## eth and wlan wan cases are different!
+    ## eth wan requires:
+    ##   config interface 'wan'
+    ##     option ifname 'eth0'
+    ##
+    ##   config wifi-iface
+    ##     option device 'radio0'
+    ##     option network 'wan'     
+    ##     option disabled '1' (or no 'config wifi-iface' section at all)
+    ##
+    ## wlan wan requires:
+    ##   config interface 'wan'
+    ##     option proto 'dhcp'
+    ##     (without 'option ifname' specified!)
+    ##
+    ##    config wifi-iface 
+    ##      option device 'radio0'
+    ##      option network 'wan'
+    logThis "wan.ifname=$_wanifname"
+    if [[ $_wanifname == 'eth0' ]]; then
+      doUci set wanifname $_wanifname
+      doUci set wanwifacedis '1'
+    elif [[ $_wanifname == 'wlan1' ]]; then
+      doUci set wanifname ''
+      doUci set wanwifacedis ''
+    fi
+    if [[ $_wanproto == 'dhcp' ]]; then
+      doUci set wanproto dhcp
+    elif [[ $_wanproto == 'static' ]]; then
+      logThis "wan.ipaddr=$_wanipaddr"
+      doUci set wanproto static
+      doUci set wanipaddr $_wanipaddr
+      doUci set wannetmask $_wannetmask
+    fi
+    if [[ $_wanifname == 'wlan1' ]]; then
+      ssidChange || showMesg 'Wireless changes failed'
+    fi
+    ## background the following
+    doUci commit network &&
+    showMesg 'Internet connection is configured' 'Waiting for device to get ready' ||
+    showMesg 'Configuring Internet connection failed'
+  fi
+  logThis "new WAN iface is: $_wanifname"
+}
+
+ssidChange() {
+  ## check for iface
+  [[ ! $_iface =~ ^('wan'|'lan')$ ]] && showMesg 'Error changing wireless settings' 'unknown/unconfigured interface'
+  logThis "$_iface is being set"
+
+  _p=$_iface
+
+  ## default enc for now
+  local _enc='psk2'
+  if [[ $_iface == 'wan' ]]; then
+    local _mode='sta'
+    local _ssid="${_wanssid}"
+    local _key="${_wankey}"
+  else 
+    local _mode='ap'
+    local _ssid="${_lanssid}"
+    local _key="${_lankey}"
+  fi
+
+  logThis "ssid: $_ssid [$_mode], key: $_key [$_enc]"
+  logThis $_wanssid
+
+  if [[ ${#_ssid} -lt 4 ]]; then
+   _ERR=1
+   showMesg 'SSID must be at least 4 characters long'
+  fi
+  doUci set $_p'ssid' "${_ssid}"
+  _ERR=$?
+  [[ $_ERR -gt 0 ]] && showMesg 'New SSID is not set'
+
+  if [[ -z $_key ]]; then
+    ## if key is empty set encryption to none and remove key
+    doUci set $_p'key' && doUci set $_p'enc' 'none'
+    _ERR=$?
+  else
+    if [[ ${#_key} -lt 8 ]]; then
+     _ERR=1
+      showMesg 'Passphrase must be at least 8 characters long'
+    fi
+    doUci set $_p'key' "${_key}" && doUci set $_p'enc' "${_enc}"
+    _ERR=$?
+    [[ $_ERR -gt 0 ]] && showMesg 'Passphrase is not set'
+  fi
+  [[ $_ERR -gt 0 ]] && return $_ERR  ##showMesg 'Wireless changes failed'
+  doUci commit wireless ##&& showMesg 'Wireless changes applied'
+}
+
+#showError() {
+#  headerPrint 406
+#  logThis "$@"
+#  echo "ERROR: $@"
+#  exit 1
+#}
+
+showMesg() {
+  logThis "$@"
+  local _MSG=$1
+  local _SUBMSG=$2
+  _MSG=${_MSG:='Not defined'}
+  _SUBMSG=${_SUBMSG:='back to control panel in a second..'}
+  if [[ $_ERR -gt 0 ]]; then
+    local _TYPE='ERROR: '
+    headerPrint 406
+  else
+    local _TYPE='OK: '
+    headerPrint 200
+  fi
+  htmlHead "<meta http-equiv='refresh' content='3;url=${HTTP_REFERER}'>"
+  echo "<body>
+<h1>SG rescue mode</h1>
+<hr>
+<h2 style='display:inline'>$_TYPE $_MSG</h2>
+<span style='display:inline; margin-left: 50px;'>$_SUBMSG</span>
+<hr>
+</body></html>"
+  exit 0
+}
+
+updateFw() {
+  logThis "updating fw"
+  _FWFILE="${_TMP}/fwupload.bin"
+  logThis "fwfile is: $(ls -lad $_FWFILE)"
+  _OUT="$(/sbin/sysupgrade -T $_FWFILE 2>&1)"
+  _ERR=$?
+  [[ $_ERR -gt 0 ]] && showMesg "$_OUT"
+  _OUT="$(runSuid /sbin/mtd -e firmware -q write $_FWFILE firmware)"
+  _ERR=$?
+  [[ $_ERR -gt 0 ]] && showMesg "mtd failed, $_OUT"
+  runSuid reboot
+  showMesg 'Firmware update is completed, rebooting..' 'this might take up to 60 seconds'
+}
+
+rebootNow() {
+  logThis "reboot: now!"
+  runSuid reboot
+  showMesg 'Rebooting..' 'this might take up to 60 seconds'
+}
+
+doUci() {
+  local _CMD=''
+  local _ARG=''
+  case $1 in
+    get|set|commit) _CMD=$1;;
+          *) logThis 'bad UCI command'; headerPrint 405; echo 'bad UCI command'; exit 1 ;;
+  esac
+
+  case $2 in
+    lanssid) _ARG='wireless.@wifi-iface[0].ssid';;
+    lanenc) _ARG='wireless.@wifi-iface[0].encryption';;
+    lankey) _ARG='wireless.@wifi-iface[0].key';;
+    lanipaddr) _ARG='network.lan.ipaddr';;
+    wanifname) _ARG='network.wan.ifname';;
+    wanproto) _ARG='network.wan.proto';;
+    wanipaddr) _ARG='network.wan.ipaddr';;
+    wannetmask) _ARG='network.wan.netmask';;
+    wanwifacedis) _ARG='wireless.@wifi-iface[1].disabled';;
+    wanssid) _ARG='wireless.@wifi-iface[1].ssid';;
+    wanenc) _ARG='wireless.@wifi-iface[1].encryption';;
+    wankey) _ARG='wireless.@wifi-iface[1].key';;
+    *) if [[ $_CMD == 'commit' ]]; then
+        _ARG=$2
+       else 
+        logThis "bad UCI entry: $2"
+        _ERR=1
+        showMesg 'bad UCI entry'
+       fi ;;
+  esac
+
+  if [[ $_CMD == 'get' ]]; then
+    if [ ! -z $_ARG ]; then
+      /sbin/uci -q get $_ARG || return $?
+    fi
+  fi
+
+  if [[ $_CMD == 'set' ]]; then
+    local _VAL=$3
+    if [ -z $_VAL ]; then
+      logThis "empty $_ARG value, removing record"
+      runSuid /sbin/uci delete $_ARG || ( echo "uci delete $_ARG: error"; exit 1; )
+    fi
+
+    if [ ! -z $_ARG ]; then
+      logThis "setting $_ARG value"
+      runSuid /sbin/uci set $_ARG=$_VAL || ( echo "uci set $_ARG: error"; exit 1; )
+    fi
+  fi
+
+  if [[ $_CMD == 'commit' ]]; then
+    runSuid /sbin/uci commit $_ARG|| echo "uci commit $_ARG: error"
+    if [[ "$_ARG" == 'wireless' ]]; then
+      runSuid /sbin/wifi || echo 'wifi: error'
+    fi
+    if [[ "$_ARG" == 'network' ]]; then
+      runSuid /etc/init.d/dnsmasq restart && runSuid /etc/init.d/network restart || echo 'network: error'
+    fi
+  fi
+}
+
+getStat() {
+  . /usr/share/libubox/jshn.sh
+  local _IFACE=$1
+  local _IFSTAT=$(runSuid ubus call network.interface.wan status 2>/dev/null)
+  logThis "$_IFSTAT"
+  json_get_type _IFSTAT ipv4_address
+  if json_get_type _IFSTAT ipv4_address && [[ "$_IFSTAT" == 'array' ]]; then
+    json_select ipv4_address
+    json_get_type _IFSTAT 1
+    if [[ "$_IFSTAT" == 'object' ]]; then
+      json_select 1
+      json_get_var IP4 address
+      json_get_var Subnet4 mask
+      [[ "$IP4" != '' ]] && [[ "$Subnet4" != '' ]] && IP4="$IP4/$Subnet4"
+    fi
+  fi
+  logThis $IP4
+}
+
+##getStat wan
+
+htmlHead() {
+echo "<!-- obnoxious code below, keep your ports tight -->
+<!doctype html>
+<html>
+<head><title>SuperGlue | Administration</title>
+$@
+<link rel='stylesheet' type='text/css' href='http://${HTTP_HOST}/resources/admin/admin.css'>
+</head>"
+}
+
+## unless auth is disabled in lighttpd
+## it should never come to this, if [[ -z $HTTP_AUTHORIZATION ]]; then
+if [[ -z $HTTP_AUTHORIZATION ]]; then
+  logThis 'no auth'
+  headerPrint 403
+  echo 'no is no'
+  exit 1
+else logThis 'auth OK'
+fi
+
+if [[ $REQUEST_METHOD == 'POST' ]]; then
+  if [[ $CONTENT_LENGTH -gt 0 ]]; then
+    CONTENT_TYPE=( ${CONTENT_TYPE} )
+    _CONTENT_TYPE="${CONTENT_TYPE[0]/;}"
+    _ENC="${HTTP_CONTENT_ENCODING}"
+    case "${_CONTENT_TYPE}" in
+      application/x-www-form-urlencoded) setQueryVars;;
+      multipart/form-data) getQueryFile;;
+      *) _ERR=1; _OUT='this is not a post' ;;
+    esac
+
+    case $REQUEST_URI in
+      /admin/pwdchange) pwdChange;;
+      /admin/ssidchange) ssidChange;;
+      /admin/lanaddr) lanAddr;;
+      /admin/updatefw) updateFw;;
+      /admin/rebootnow) rebootNow;;
+      /admin/wan) wanSet;;
+      *) logThis 'bad action'; headerPrint 405; echo 'no such thing'; exit 1;;
+    esac
+  fi
+  headerPrint 301
+fi
+
+headerPrint 200
+## html head
+htmlHead
+
+sgver=$(cat /etc/superglue_version)
+devmod=$(cat /etc/superglue_model)
+openwrt=$(cat /etc/openwrt_version)
+wanifname=$(doUci get wanifname || echo 'wlan0') ## TODO fix this
+wanproto=$(doUci get wanproto)
+wanipaddr=$(doUci get wanipaddr) 
+wannetmask=$(doUci get wannetmask)
+wanssid=$(doUci get wanssid)
+wankey=$(doUci get wankey)
+
+echo "<body>
+<h1>SG rescue mode</h1>
+<hr>
+<span style='display:block;'>System version: $sgver | Device: $devmod | OpenWRT: $openwrt</span>
+<span style='display:block;'>$(uptime)</span>
+<hr>
+
+Internet connection:
+<form method='post' action='/admin/wan' name='wan' onchange='formChange();'>
+  <div style='display:inline-flex'>
+  <div style='display:inline-block;'>
+  <select name='wanifname' id='wanifname' style='display:block'>
+  <option value='eth0' id='eth' $([[ $wanifname =~ ('eth') ]] && echo 'selected')>Wired (WAN port)</option>
+  <option value='wlan1' id='wlan' $([[ $wanifname =~ ('wlan') ]] && echo 'selected')>Wireless (Wi-Fi)</option>
+  </select>
+  <fieldset id='wanwifi' class='hide'>
+  <input type='text' name='wanssid' value='$wanssid'>
+  <input type='password' name='wankey' value='$wankey'>
+  </fieldset>
+  </div>
+
+  <div style='display:inline-block;'>
+  <select name='wanproto' id='wanproto' style='display:block'>
+  <option value='dhcp' name='dhcp' id='dhcp' $([[ $wanproto == 'dhcp' ]] && echo 'selected')>Automatic (DHCP)</option>
+  <option value='stat' name='dhcp' id='stat' $([[ $wanproto == 'static' ]] && echo 'selected')>Manual (Static IP)</option>
+  </select>
+  <fieldset id='wanaddr' class='hide' >
+  <input type='text' name='wanipaddr' id='wanipaddr' value='$wanipaddr'>
+  <input type='text' name='wangw' id='wannetmask' value='$wannetmask'>
+  </fieldset>
+  </div>
+  </div>
+  <input type='hidden' name='iface' value='wan' class='inline'>
+  <input type='submit' value='Apply'>
+
+</form>
+<hr>
+
+Local wireless network:
+<form method='post' action='/admin/ssidchange'>
+  <div style='display:inline-flex'>
+  <div style='display:inline-block;'>
+    <input type='text' name='lanssid' value='$(doUci get lanssid)'>
+    <input type='password' name='lankey' value='$(doUci get lankey)'>
+  </div>
+  <div style='display:inline-block;'>
+    <input type='text' name='lanipaddr' value='$(doUci get lanipaddr)'>
+    <input type='hidden' name='iface' value='lan' class='inline'>
+  </div>
+  </div>
+  <input type='submit' value='Apply'>
+  
+</form>
+
+
+<hr>
+Change password:
+<form method='post' action='/admin/pwdchange'>
+<input type='text' name='usr' value='admin' readonly>
+<input type='password' name='pwd'>
+<input type='password' name='pwdd'>
+<input type='submit' value='Apply'>
+</form>
+<hr>
+
+
+Update firmware:
+<form method='post' action='/admin/updatefw' enctype='multipart/form-data'>
+<div id='uploadbox'>
+<input id='uploadfile' placeholder='Choose file' disabled='disabled'>
+<input id='uploadbtn' name='fwupload' type='file'>
+</div>
+<input type='submit' value='Upload'>
+</form>
+
+<hr>
+
+<form action='/admin/rebootnow' method='post' class='inline'>
+<input type='hidden' name='reboot' value='now' class='inline'>
+<input type='submit' value='Reboot' class='inline'>
+</form>
+
+<form action='http://logout@${HTTP_HOST}/admin' method='get' class='inline'>
+<input type='submit' value='Logout' class='inline'>
+</form>
+
+<hr>
+Memory:
+<pre>$(free)</pre>
+<hr>
+Storage:
+<pre>$(df -h)</pre>
+<hr>
+Environment:
+<pre>$(env)</pre>
+<hr>
+$_POST
+
+</body>
+<script type='text/javascript' src='http://${HTTP_HOST}/resources/admin/admin.js'></script>
+
+</html>"
+
+exit 0

+ 518 - 0
openwrt/common/opt/lib/cgi/admin.cgi

@@ -0,0 +1,518 @@
+#!/bin/bash
+
+_WWW='/www'
+_PWDFILE="/opt/lib/htpasswd"
+_TMP="${_WWW}/tmp"
+_LOG="${_WWW}/log/admin.log"
+
+_DEBUG=1
+
+## logging
+logThis() {
+  [[ $_DEBUG -gt 0 ]] || return 0
+  [[ $_ERR -gt 0 ]] && _TYPE='E:' || _TYPE='I:'  ## Info or Error indication
+  local _TIME=$(printf '%(%d.%m.%Y %H:%M:%S)T' -1)
+  printf '%b\n' "$_TIME  $_TYPE ${1} " >> $_LOG
+  [[ $_DEBUG -gt 1 ]] && printf '%b\n' "[verbose] $_TYPE ${1}"
+  return 0
+}
+
+## http response
+headerPrint() {
+  case ${1} in
+    200) printf '%b' 'HTTP/1.1 200 OK\nAccess-Control-Allow-Origin: *\n\n';;
+    301) printf '%b' "HTTP/1.1 301 Moved Permanently\nLocation: ${HTTP_REFERER}\n\n";;
+    403) printf '%b' 'HTTP/1.1 403 Forbidden\n\n';;
+    405) printf '%b' 'HTTP/1.1 405 Method Not Allowed\n\n';;
+    406) printf '%b' 'HTTP/1.1 406 Not Acceptable\n\n';;
+  esac
+  return 0
+}
+
+htDigest() {
+  _USER='admin'
+  _PWD=$1
+  _REALM='superglue'
+  _HASH=$(echo -n "$_USER:$_REALM:$_PWD" | md5sum | cut -b -32)
+  echo -n "$_USER:$_REALM:$_HASH"
+}
+
+urlDec() {
+  local value=${*//+/%20}
+  for part in ${value//%/ \\x}; do
+    printf "%b%s" "${part:0:4}" "${part:4}"
+  done
+}
+
+setQueryVars() {
+  local _POST=$(cat)
+  local vars=${_POST//\*/%2A}
+  for var in ${vars//&/ }; do
+    local value=$(urlDec "${var#*=}")
+    value=${value//\\/\\\\}
+    eval "_${var%=*}=\"${value//\"/\\\"}\""
+  done
+}
+
+getQueryFile() {
+  _POST_TMP=$(mktemp -p $_TMP)  ## make tmp POST file
+  cat > $_POST_TMP  ## cautiously storing entire POST in a file
+  logThis "'multipart': decoding stream"
+  local _BND=$(findPostOpt 'boundary')
+  ## bash is binary unsafe and eats away precious lines
+  ## thus using gawk
+  function cutFile() {
+    gawk -v "want=$1" -v "bnd=$_BND" '
+      BEGIN { RS="\r\n"; ORS="\r\n" }
+
+      # reset based on boundaries
+      $0 == "--"bnd""     { st=1; next; }
+      $0 == "--"bnd"--"   { st=0; next; }
+      $0 == "--"bnd"--\r" { st=0; next; }
+
+      # search for wanted file
+      st == 1 && $0 ~  "^Content-Disposition:.* name=\""want"\"" { st=2; next; }
+      st == 1 && $0 == "" { st=9; next; }
+
+      # wait for newline, then start printing
+      st == 2 && $0 == "" { st=3; next; }
+      st == 3 { print $0 }
+      ' 2>&1
+  }
+  cutFile 'fwupload' < "${_POST_TMP}" > "${_TMP}/fwupload.bin"
+}
+
+## find arbitrary option supplied in Content-Type header
+## eg: "Content-Type:application/octet-stream; verbose=1"
+findPostOpt() {
+  for i in "${CONTENT_TYPE[@]:1}"; do
+    case "${i/=*}" in 
+      "$1") printf '%b' "${i/*=}" ;;
+    esac
+  done
+  return 0
+}
+
+runSuid() {
+  local _SID=$(/usr/bin/ps -p $$ -o sid=)  ## pass session id to the child
+  local _CMD=$@
+  sudo ./suid.sh $_CMD $_SID 2>/dev/null
+}
+
+validIp() {
+  local _IP=$1
+  local _RET=1
+  if [[ $_IP =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
+    OIFS=$IFS
+    IFS='.'
+    _IP=($_IP)
+    IFS=$OIFS
+    [[ ${_IP[0]} -le 255 && ${_IP[1]} -le 255 && ${_IP[2]} -le 255 && ${_IP[3]} -le 255 ]]
+    _RET=$?
+  fi
+  return $_RET
+}
+
+pwdChange() {
+  if [[ ! -z "${_pwd##$_pwdd}" ]]; then 
+    _ERR=1
+    showMesg 'Passwords did not match'
+  fi
+
+  if [[ ${#_pwd} -lt 6 ]]; then
+    _ERR=1
+    showMesg 'Password must be at least 6 characters long'
+  fi
+
+  runSuid "echo -e \"$_pwd\n$_pwd\" | passwd root"
+  runSuid "echo $(htDigest $_pwd) > $_PWDFILE"
+  _ERR=$?
+  if [[ $_ERR -gt 0 ]]; then
+    showMesg 'Password change failed'
+  else
+    showMesg 'Password is changed'
+  fi
+}
+
+lanAddr() {
+  logThis "new LAN addr is: $_laddr"
+  validIp $_laddr || showMesg 'Not valid network address'
+  doUci set laddr $_laddr
+  _ERR=$?
+  if [[ $_ERR -gt 0 ]]; then
+    showMesg 'Setting network address failed'
+  else
+    (sleep 1; doUci commit network; doUci commit wireless;)&
+    showMesg 'New network address is set' "Your server is now accessible under <a href='http://superglue.local/admin'>http://superglue.local/admin</a>"
+  fi 
+}
+
+wanSet() {
+  if [[ ! -z $_wanifname ]]; then
+    ## eth and wlan wan cases are different!
+    ## eth wan requires:
+    ##   config interface 'wan'
+    ##     option ifname 'eth0'
+    ##
+    ##   config wifi-iface
+    ##     option device 'radio0'
+    ##     option network 'wan'     
+    ##     option disabled '1' (or no 'config wifi-iface' section at all)
+    ##
+    ## wlan wan requires:
+    ##   config interface 'wan'
+    ##     option proto 'dhcp'
+    ##     (without 'option ifname' specified!)
+    ##
+    ##    config wifi-iface 
+    ##      option device 'radio0'
+    ##      option network 'wan'
+    logThis "wan.ifname=$_wanifname"
+    if [[ $_wanifname == 'eth0' ]]; then
+      doUci set wanifname $_wanifname
+      doUci set wanwifacedis '1'
+    elif [[ $_wanifname == 'wlan1' ]]; then
+      doUci set wanifname ''
+      doUci set wanwifacedis ''
+    fi
+    if [[ $_wanproto == 'dhcp' ]]; then
+      doUci set wanproto dhcp
+    elif [[ $_wanproto == 'static' ]]; then
+      logThis "wan.ipaddr=$_wanipaddr"
+      doUci set wanproto static
+      doUci set wanipaddr $_wanipaddr
+      doUci set wannetmask $_wannetmask
+    fi
+    if [[ $_wanifname == 'wlan1' ]]; then
+      ssidChange || showMesg 'Wireless changes failed'
+    fi
+    ## background the following
+    doUci commit network &&
+    showMesg 'Internet connection is configured' 'Waiting for device to get ready' ||
+    showMesg 'Configuring Internet connection failed'
+  fi
+  logThis "new WAN iface is: $_wanifname"
+}
+
+ssidChange() {
+  ## check for iface
+  [[ ! $_iface =~ ^('wan'|'lan')$ ]] && showMesg 'Error changing wireless settings' 'unknown/unconfigured interface'
+  logThis "$_iface is being set"
+
+  _p=$_iface
+
+  ## default enc for now
+  local _enc='psk2'
+  if [[ $_iface == 'wan' ]]; then
+    local _mode='sta'
+    local _ssid="${_wanssid}"
+    local _key="${_wankey}"
+  else 
+    local _mode='ap'
+    local _ssid="${_lanssid}"
+    local _key="${_lankey}"
+  fi
+
+  logThis "ssid: $_ssid [$_mode], key: $_key [$_enc]"
+  logThis $_wanssid
+
+  if [[ ${#_ssid} -lt 4 ]]; then
+   _ERR=1
+   showMesg 'SSID must be at least 4 characters long'
+  fi
+  doUci set $_p'ssid' "${_ssid}"
+  _ERR=$?
+  [[ $_ERR -gt 0 ]] && showMesg 'New SSID is not set'
+
+  if [[ -z $_key ]]; then
+    ## if key is empty set encryption to none and remove key
+    doUci set $_p'key' && doUci set $_p'enc' 'none'
+    _ERR=$?
+  else
+    if [[ ${#_key} -lt 8 ]]; then
+     _ERR=1
+      showMesg 'Passphrase must be at least 8 characters long'
+    fi
+    doUci set $_p'key' "${_key}" && doUci set $_p'enc' "${_enc}"
+    _ERR=$?
+    [[ $_ERR -gt 0 ]] && showMesg 'Passphrase is not set'
+  fi
+  [[ $_ERR -gt 0 ]] && return $_ERR  ##showMesg 'Wireless changes failed'
+  doUci commit wireless ##&& showMesg 'Wireless changes applied'
+}
+
+#showError() {
+#  headerPrint 406
+#  logThis "$@"
+#  echo "ERROR: $@"
+#  exit 1
+#}
+
+showMesg() {
+  logThis "$@"
+  local _MSG=$1
+  local _SUBMSG=$2
+  _MSG=${_MSG:='Not defined'}
+  _SUBMSG=${_SUBMSG:='back to control panel in a second..'}
+  if [[ $_ERR -gt 0 ]]; then
+    local _TYPE='ERROR: '
+    headerPrint 406
+  else
+    local _TYPE='OK: '
+    headerPrint 200
+  fi
+  htmlHead "<meta http-equiv='refresh' content='3;url=${HTTP_REFERER}'>"
+  echo "<body>
+<h1>SG</h1>
+<hr>
+<h2 style='display:inline'>$_TYPE $_MSG</h2>
+<span style='display:inline; margin-left: 50px;'>$_SUBMSG</span>
+<hr>
+</body></html>"
+  exit 0
+}
+
+updateFw() {
+  logThis "updating fw"
+  _FWFILE="${_TMP}/fwupload.bin"
+  logThis "fwfile is: $(ls -lad $_FWFILE)"
+  _OUT="$(/sbin/sysupgrade -T $_FWFILE 2>&1)"
+  _ERR=$?
+  [[ $_ERR -gt 0 ]] && showMesg "$_OUT"
+  _OUT="$(runSuid /sbin/mtd -e firmware -q write $_FWFILE firmware)"
+  _ERR=$?
+  [[ $_ERR -gt 0 ]] && showMesg "mtd failed, $_OUT"
+  runSuid reboot
+  showMesg 'Firmware update is completed, rebooting..' 'this might take up to 60 seconds'
+}
+
+rebootNow() {
+  logThis "reboot: now!"
+  runSuid reboot
+  showMesg 'Rebooting..' 'this might take up to 60 seconds'
+}
+
+doUci() {
+  local _CMD=''
+  local _ARG=''
+  case $1 in
+    get|set|commit) _CMD=$1;;
+          *) logThis 'bad UCI command'; headerPrint 405; echo 'bad UCI command'; exit 1 ;;
+  esac
+
+  case $2 in
+    lanssid) _ARG='wireless.@wifi-iface[0].ssid';;
+    lanenc) _ARG='wireless.@wifi-iface[0].encryption';;
+    lankey) _ARG='wireless.@wifi-iface[0].key';;
+    lanipaddr) _ARG='network.lan.ipaddr';;
+    wanifname) _ARG='network.wan.ifname';;
+    wanproto) _ARG='network.wan.proto';;
+    wanipaddr) _ARG='network.wan.ipaddr';;
+    wannetmask) _ARG='network.wan.netmask';;
+    wanwifacedis) _ARG='wireless.@wifi-iface[1].disabled';;
+    wanssid) _ARG='wireless.@wifi-iface[1].ssid';;
+    wanenc) _ARG='wireless.@wifi-iface[1].encryption';;
+    wankey) _ARG='wireless.@wifi-iface[1].key';;
+    *) if [[ $_CMD == 'commit' ]]; then
+        _ARG=$2
+       else 
+        logThis "bad UCI entry: $2"
+        _ERR=1
+        showMesg 'bad UCI entry'
+       fi ;;
+  esac
+
+  if [[ $_CMD == 'get' ]]; then
+    if [ ! -z $_ARG ]; then
+      /sbin/uci -q get $_ARG || return $?
+    fi
+  fi
+
+  if [[ $_CMD == 'set' ]]; then
+    local _VAL=$3
+    if [ -z $_VAL ]; then
+      logThis "empty $_ARG value, removing record"
+      runSuid /sbin/uci delete $_ARG || ( echo "uci delete $_ARG: error"; exit 1; )
+    fi
+
+    if [ ! -z $_ARG ]; then
+      logThis "setting $_ARG value"
+      runSuid /sbin/uci set $_ARG=$_VAL || ( echo "uci set $_ARG: error"; exit 1; )
+    fi
+  fi
+
+  if [[ $_CMD == 'commit' ]]; then
+    runSuid /sbin/uci commit $_ARG|| echo "uci commit $_ARG: error"
+    if [[ "$_ARG" == 'wireless' ]]; then
+      runSuid /sbin/wifi || echo 'wifi: error'
+    fi
+    if [[ "$_ARG" == 'network' ]]; then
+      runSuid /etc/init.d/dnsmasq restart && runSuid /etc/init.d/network restart || echo 'network: error'
+    fi
+  fi
+}
+
+getStat() {
+  . /usr/share/libubox/jshn.sh
+  local _IFACE=$1
+  local _IFSTAT=$(runSuid ubus call network.interface.wan status 2>/dev/null)
+  logThis "$_IFSTAT"
+  json_get_type _IFSTAT ipv4_address
+  if json_get_type _IFSTAT ipv4_address && [[ "$_IFSTAT" == 'array' ]]; then
+    json_select ipv4_address
+    json_get_type _IFSTAT 1
+    if [[ "$_IFSTAT" == 'object' ]]; then
+      json_select 1
+      json_get_var IP4 address
+      json_get_var Subnet4 mask
+      [[ "$IP4" != '' ]] && [[ "$Subnet4" != '' ]] && IP4="$IP4/$Subnet4"
+    fi
+  fi
+  logThis $IP4
+}
+
+##getStat wan
+
+htmlHead() {
+echo "<!-- obnoxious code below, keep your ports tight -->
+<!doctype html>
+<html>
+<head><title>SuperGlue | Administration</title>
+$@
+<link rel='stylesheet' type='text/css' href='http://${HTTP_HOST}/resources/admin/admin.css'>
+</head>"
+}
+
+if [[ $REQUEST_METHOD == 'POST' ]]; then
+  if [[ $CONTENT_LENGTH -gt 0 ]]; then
+    CONTENT_TYPE=( ${CONTENT_TYPE} )
+    _CONTENT_TYPE="${CONTENT_TYPE[0]/;}"
+    _ENC="${HTTP_CONTENT_ENCODING}"
+    case "${_CONTENT_TYPE}" in
+      application/x-www-form-urlencoded) setQueryVars;;
+      multipart/form-data) getQueryFile;;
+      *) _ERR=1; _OUT='this is not a post' ;;
+    esac
+
+    case $REQUEST_URI in
+      /admin/pwdchange) pwdChange;;
+      /admin/ssidchange) ssidChange;;
+      /admin/lanaddr) lanAddr;;
+      /admin/updatefw) updateFw;;
+      /admin/rebootnow) rebootNow;;
+      /admin/wan) wanSet;;
+      *) logThis 'bad action'; headerPrint 405; echo 'no such thing'; exit 1;;
+    esac
+  fi
+  headerPrint 301
+fi
+
+headerPrint 200
+## html head
+htmlHead
+
+sgver=$(cat /etc/superglue_version)
+devmod=$(cat /etc/superglue_model)
+openwrt=$(cat /etc/openwrt_version)
+wanifname=$(doUci get wanifname || echo 'wlan0') ## TODO fix this
+wanproto=$(doUci get wanproto)
+wanipaddr=$(doUci get wanipaddr) 
+wannetmask=$(doUci get wannetmask)
+wanssid=$(doUci get wanssid)
+wankey=$(doUci get wankey)
+
+echo "<body>
+<h1>SG</h1>
+<hr>
+<h2 style='display:inline'>Superglue server control panel</h2>
+<span style='display:block;'>System version: $sgver | Device: $devmod | OpenWRT: $openwrt</span>
+<span style='display:block;'>$(uptime)</span>
+<hr>
+
+Update firmware:
+<form method='post' action='/admin/updatefw' enctype='multipart/form-data'>
+<div id='uploadbox'>
+<input id='uploadfile' placeholder='Choose file' disabled='disabled'>
+<input id='uploadbtn' name='fwupload' type='file'>
+</div>
+<input type='submit' value='Upload'>
+</form>
+
+<hr>
+
+Internet connection:
+<form method='post' action='/admin/wan' name='wan' onchange='formChange();'>
+  <div style='display:inline-flex'>
+  <div style='display:inline-block;'>
+  <select name='wanifname' id='wanifname' style='display:block'>
+  <option value='eth0' id='eth' $([[ $wanifname =~ ('eth') ]] && echo 'selected')>Wired (WAN port)</option>
+  <option value='wlan1' id='wlan' $([[ $wanifname =~ ('wlan') ]] && echo 'selected')>Wireless (Wi-Fi)</option>
+  </select>
+  <fieldset id='wanwifi' class='hide'>
+  <input type='text' name='wanssid' value='$wanssid'>
+  <input type='password' name='wankey' value='$wankey'>
+  </fieldset>
+  </div>
+
+  <div style='display:inline-block;'>
+  <select name='wanproto' id='wanproto' style='display:block'>
+  <option value='dhcp' name='dhcp' id='dhcp' $([[ $wanproto == 'dhcp' ]] && echo 'selected')>Automatic (DHCP)</option>
+  <option value='stat' name='dhcp' id='stat' $([[ $wanproto == 'static' ]] && echo 'selected')>Manual (Static IP)</option>
+  </select>
+  <fieldset id='wanaddr' class='hide' >
+  <input type='text' name='wanipaddr' id='wanipaddr' value='$wanipaddr'>
+  <input type='text' name='wangw' id='wannetmask' value='$wannetmask'>
+  </fieldset>
+  </div>
+  </div>
+  <input type='hidden' name='iface' value='wan' class='inline'>
+  <input type='submit' value='Apply'>
+
+</form>
+<hr>
+
+Local wireless network:
+<form method='post' action='/admin/ssidchange'>
+  <div style='display:inline-flex'>
+  <div style='display:inline-block;'>
+    <input type='text' name='lanssid' value='$(doUci get lanssid)'>
+    <input type='password' name='lankey' value='$(doUci get lankey)'>
+  </div>
+  <div style='display:inline-block;'>
+    <input type='text' name='lanipaddr' value='$(doUci get lanipaddr)'>
+    <input type='hidden' name='iface' value='lan' class='inline'>
+  </div>
+  </div>
+  <input type='submit' value='Apply'>
+  
+</form>
+
+<hr>
+
+<form action='/admin/rebootnow' method='post' class='inline'>
+<input type='hidden' name='reboot' value='now' class='inline'>
+<input type='submit' value='Reboot' class='inline'>
+</form>
+
+<form action='http://logout@${HTTP_HOST}/admin' method='get' class='inline'>
+<input type='submit' value='Logout' class='inline'>
+</form>
+
+<hr>
+Memory:
+<pre>$(free)</pre>
+<hr>
+Storage:
+<pre>$(df -h)</pre>
+<hr>
+Environment:
+<pre>$(env)</pre>
+<hr>
+$_POST
+
+</body>
+<script type='text/javascript' src='http://${HTTP_HOST}/resources/admin/admin.js'></script>
+
+</html>"
+
+exit 0

+ 1 - 1
openwrt/common/www/lib/cgi/admin.cgi → openwrt/common/opt/lib/cgi/admin.cgi-bup201014

@@ -218,7 +218,7 @@ updateFw() {
   _OUT="$(/sbin/sysupgrade -T $_FWFILE 2>&1)"
   _ERR=$?
   [[ $_ERR -gt 0 ]] && showMesg "$_OUT"
-  _OUT="$(runSuid /sbin/mtd -q write $_FWFILE firmware)"
+  _OUT="$(runSuid /sbin/mtd -e firmware -q write $_FWFILE firmware)"
   _ERR=$?
   [[ $_ERR -gt 0 ]] && showMesg "mtd failed, $_OUT"
   runSuid reboot

+ 456 - 0
openwrt/common/opt/lib/cgi/admin2.cgi

@@ -0,0 +1,456 @@
+#!/usr/bin/haserl --shell=/bin/bash  --upload-limit=32768 --upload-dir=/www/tmp 
+<%# upload limit: 32Mb %>
+<%
+
+_WWW='/www'
+_PWDFILE="/opt/lib/htpasswd"
+_TMP="${_WWW}/tmp"
+_LOG="${_WWW}/log/admin.log"
+_DEBUG=1
+
+err() {
+  _ERR="$?"
+  [[ "$_ERR" -gt 0 ]] || return 0
+  log "$1"
+  head "${2:='400'}"
+  exit "$_ERR"
+} 
+
+logThis() {
+  [[ "$_DEBUG" -gt 0 ]] || return 0
+  local _TYPE='I:'
+  [[ "$_ERR" -gt 0 ]] && _TYPE='E:'
+  local _TIME; printf -v _TIME '%(%d.%m.%Y %H:%M:%S)T' -1
+  printf '%b\n' "$_TIME  $_TYPE ${@} " >> "$_LOG"
+  [[ "$_DEBUG" -gt 1 ]] && printf '%b\n' "[verbose] $_TYPE ${1}"
+}
+
+headerPrint() {
+  case "$1" in
+ 200|'') printf '%b' 'HTTP/1.1 200 OK\r\n';;
+    301) printf '%b' "HTTP/1.1 301 Moved Permanently\r\nLocation: $HTTP_REFERER\r\n";;
+    403) printf '%b' 'HTTP/1.1 403 Forbidden\r\n';;
+    405) printf '%b' 'HTTP/1.1 405 Method Not Allowed\r\n';;
+    406) printf '%b' 'HTTP/1.1 406 Not Acceptable\r\n';;
+      *) printf '%b' 'HTTP/1.1 400 Bad Request\r\n';;
+  esac
+  printf '%b' 'Content-Type: text/html\r\n\r\n';
+}
+
+htDigest() {
+  _USER='admin'
+  _PWD=$1
+  _REALM='superglue'
+  _HASH=$(echo -n "$_USER:$_REALM:$_PWD" | md5sum | cut -b -32)
+  echo -n "$_USER:$_REALM:$_HASH"
+}
+
+setQueryVars() {
+  env
+}
+
+getQueryFile() {
+  local _UPLD="${HASERL_fwupload_path##*/}"
+  logThis "'multipart': decoding stream"
+  mv "$_TMP/$_UPLD" "$_TMP/fwupload.bin" 2>/dev/null || _ERR=$?
+  if [[ $_ERR -gt 0 ]]; then
+    showMesg 'Firmware upload has failed' 'Reboot your Superglue server and try again'
+  fi
+}
+
+validIp() {
+  local _IP=$1
+  local _RET=1
+  if [[ $_IP =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
+    OIFS=$IFS
+    IFS='.'
+    _IP=($_IP)
+    IFS=$OIFS
+    [[ ${_IP[0]} -le 255 && ${_IP[1]} -le 255 && ${_IP[2]} -le 255 && ${_IP[3]} -le 255 ]]
+    _RET=$?
+  fi
+  return $_RET
+}
+
+pwdChange() {
+  if [[ ! -z "${_pwd##$_pwdd}" ]]; then 
+    _ERR=1
+    showMesg 'Passwords did not match'
+  fi
+
+  if [[ ${#_pwd} -lt 6 ]]; then
+    _ERR=1
+    showMesg 'Password must be at least 6 characters long'
+  fi
+
+  runSuid "echo -e \"$_pwd\n$_pwd\" | passwd root"
+  runSuid "echo $(htDigest $_pwd) > $_PWDFILE"
+  _ERR=$?
+  if [[ $_ERR -gt 0 ]]; then
+    showMesg 'Password change failed'
+  else
+    showMesg 'Password is changed'
+  fi
+}
+
+lanAddr() {
+  logThis "new LAN addr is: $_laddr"
+  validIp $_laddr || showMesg 'Not valid network address'
+  doUci set laddr $_laddr
+  _ERR=$?
+  if [[ $_ERR -gt 0 ]]; then
+    showMesg 'Setting network address failed'
+  else
+    (sleep 1; doUci commit network; doUci commit wireless;)&
+    showMesg 'New network address is set' "Your server is now accessible under <a href='http://superglue.local/admin'>http://superglue.local/admin</a>"
+  fi 
+}
+
+wanSet() {
+  if [[ ! -z $_wanifname ]]; then
+    ## eth and wlan wan cases are different!
+    ## eth wan requires:
+    ##   config interface 'wan'
+    ##     option ifname 'eth0'
+    ##
+    ##   config wifi-iface
+    ##     option device 'radio0'
+    ##     option network 'wan'     
+    ##     option disabled '1' (or no 'config wifi-iface' section at all)
+    ##
+    ## wlan wan requires:
+    ##   config interface 'wan'
+    ##     option proto 'dhcp'
+    ##     (without 'option ifname' specified!)
+    ##
+    ##    config wifi-iface 
+    ##      option device 'radio0'
+    ##      option network 'wan'
+    logThis "wan.ifname=$_wanifname"
+    if [[ $_wanifname == 'eth0' ]]; then
+      doUci set wanifname $_wanifname
+      doUci set wanwifacedis '1'
+    elif [[ $_wanifname == 'wlan1' ]]; then
+      doUci set wanifname ''
+      doUci set wanwifacedis ''
+    fi
+    if [[ $_wanproto == 'dhcp' ]]; then
+      doUci set wanproto dhcp
+    elif [[ $_wanproto == 'static' ]]; then
+      logThis "wan.ipaddr=$_wanipaddr"
+      doUci set wanproto static
+      doUci set wanipaddr $_wanipaddr
+      doUci set wannetmask $_wannetmask
+    fi
+    if [[ $_wanifname == 'wlan1' ]]; then
+      ssidChange || showMesg 'Wireless changes failed'
+    fi
+    ## background the following
+    doUci commit network &&
+    showMesg 'Internet connection is configured' 'Waiting for device to get ready' ||
+    showMesg 'Configuring Internet connection failed'
+  fi
+  logThis "new WAN iface is: $_wanifname"
+}
+
+ssidChange() {
+  ## check for iface
+  [[ ! $_iface =~ ^('wan'|'lan')$ ]] && showMesg 'Error changing wireless settings' 'unknown/unconfigured interface'
+  logThis "$_iface is being set"
+
+  _p=$_iface
+
+  ## default enc for now
+  local _enc='psk2'
+  if [[ $_iface == 'wan' ]]; then
+    local _mode='sta'
+    local _ssid="${_wanssid}"
+    local _key="${_wankey}"
+  else 
+    local _mode='ap'
+    local _ssid="${_lanssid}"
+    local _key="${_lankey}"
+  fi
+
+  logThis "ssid: $_ssid [$_mode], key: $_key [$_enc]"
+  logThis $_wanssid
+
+  if [[ ${#_ssid} -lt 4 ]]; then
+   _ERR=1
+   showMesg 'SSID must be at least 4 characters long'
+  fi
+  doUci set $_p'ssid' "${_ssid}"
+  _ERR=$?
+  [[ $_ERR -gt 0 ]] && showMesg 'New SSID is not set'
+
+  if [[ -z $_key ]]; then
+    ## if key is empty set encryption to none and remove key
+    doUci set $_p'key' && doUci set $_p'enc' 'none'
+    _ERR=$?
+  else
+    if [[ ${#_key} -lt 8 ]]; then
+     _ERR=1
+      showMesg 'Passphrase must be at least 8 characters long'
+    fi
+    doUci set $_p'key' "${_key}" && doUci set $_p'enc' "${_enc}"
+    _ERR=$?
+    [[ $_ERR -gt 0 ]] && showMesg 'Passphrase is not set'
+  fi
+  [[ $_ERR -gt 0 ]] && return $_ERR  ##showMesg 'Wireless changes failed'
+  doUci commit wireless ##&& showMesg 'Wireless changes applied'
+}
+
+#showError() {
+#  headerPrint 406
+#  logThis "$@"
+#  echo "ERROR: $@"
+#  exit 1
+#}
+
+showMesg() {
+  logThis "$@"
+  local _MSG=$1
+  local _SUBMSG=$2
+  _MSG=${_MSG:='Not defined'}
+  _SUBMSG=${_SUBMSG:='back to control panel in a second..'}
+  if [[ $_ERR -gt 0 ]]; then
+    local _TYPE='ERROR: '
+    headerPrint 406
+  else
+    local _TYPE='OK: '
+    headerPrint 200
+  fi
+  htmlHead "<meta http-equiv='refresh' content='3;url=${HTTP_REFERER}'>"
+  echo "<body>
+<h1>SG</h1>
+<hr>
+<h2 style='display:inline'>$_TYPE $_MSG</h2>
+<span style='display:inline; margin-left: 50px;'>$_SUBMSG</span>
+<hr>
+</body></html>"
+  exit 0
+}
+
+updateFw() {
+  logThis "updating fw"
+  _FWFILE="${_TMP}/fwupload.bin"
+  logThis "fwfile is: $(ls -lad $_FWFILE)"
+  _OUT="$(/sbin/sysupgrade -T $_FWFILE 2>&1)"
+  _ERR=$?
+  [[ $_ERR -gt 0 ]] && showMesg "$_OUT"
+#  _OUT="$(runSuid /sbin/mtd -e firmware -q write $_FWFILE firmware)"
+  _ERR=$?
+  [[ $_ERR -gt 0 ]] && showMesg "mtd failed, $_OUT"
+#  runSuid reboot
+  showMesg 'Firmware update is completed, rebooting..' 'this might take up to 60 seconds'
+}
+
+rebootNow() {
+  logThis "reboot: now!"
+  runSuid reboot
+  showMesg 'Rebooting..' 'this might take up to 60 seconds'
+}
+
+doUci() {
+  local _CMD=''
+  local _ARG=''
+  case $1 in
+    get|set|commit) _CMD=$1;;
+          *) logThis 'bad UCI command'; headerPrint 405; echo 'bad UCI command'; exit 1 ;;
+  esac
+
+  case $2 in
+    lanssid) _ARG='wireless.@wifi-iface[0].ssid';;
+    lanenc) _ARG='wireless.@wifi-iface[0].encryption';;
+    lankey) _ARG='wireless.@wifi-iface[0].key';;
+    lanipaddr) _ARG='network.lan.ipaddr';;
+    wanifname) _ARG='network.wan.ifname';;
+    wanproto) _ARG='network.wan.proto';;
+    wanipaddr) _ARG='network.wan.ipaddr';;
+    wannetmask) _ARG='network.wan.netmask';;
+    wanwifacedis) _ARG='wireless.@wifi-iface[1].disabled';;
+    wanssid) _ARG='wireless.@wifi-iface[1].ssid';;
+    wanenc) _ARG='wireless.@wifi-iface[1].encryption';;
+    wankey) _ARG='wireless.@wifi-iface[1].key';;
+    *) if [[ $_CMD == 'commit' ]]; then
+        _ARG=$2
+       else 
+        logThis "bad UCI entry: $2"
+        _ERR=1
+        showMesg 'bad UCI entry'
+       fi ;;
+  esac
+
+  if [[ $_CMD == 'get' ]]; then
+    if [ ! -z $_ARG ]; then
+      /sbin/uci -q get $_ARG || return $?
+    fi
+  fi
+
+  if [[ $_CMD == 'set' ]]; then
+    local _VAL=$3
+    if [ -z $_VAL ]; then
+      logThis "empty $_ARG value, removing record"
+      runSuid /sbin/uci delete $_ARG || ( echo "uci delete $_ARG: error"; exit 1; )
+    fi
+
+    if [ ! -z $_ARG ]; then
+      logThis "setting $_ARG value"
+      runSuid /sbin/uci set $_ARG=$_VAL || ( echo "uci set $_ARG: error"; exit 1; )
+    fi
+  fi
+
+  if [[ $_CMD == 'commit' ]]; then
+    runSuid /sbin/uci commit $_ARG|| echo "uci commit $_ARG: error"
+    if [[ "$_ARG" == 'wireless' ]]; then
+      runSuid /sbin/wifi || echo 'wifi: error'
+    fi
+    if [[ "$_ARG" == 'network' ]]; then
+      runSuid /etc/init.d/dnsmasq restart && runSuid /etc/init.d/network restart || echo 'network: error'
+    fi
+  fi
+}
+
+getStat() {
+  . /usr/share/libubox/jshn.sh
+  local _IFACE=$1
+  local _IFSTAT=$(runSuid ubus call network.interface.wan status 2>/dev/null)
+  logThis "$_IFSTAT"
+  json_get_type _IFSTAT ipv4_address
+  if json_get_type _IFSTAT ipv4_address && [[ "$_IFSTAT" == 'array' ]]; then
+    json_select ipv4_address
+    json_get_type _IFSTAT 1
+    if [[ "$_IFSTAT" == 'object' ]]; then
+      json_select 1
+      json_get_var IP4 address
+      json_get_var Subnet4 mask
+      [[ "$IP4" != '' ]] && [[ "$Subnet4" != '' ]] && IP4="$IP4/$Subnet4"
+    fi
+  fi
+  logThis $IP4
+}
+
+htmlHead() {
+echo "<!-- obnoxious code below, keep your ports tight -->
+<!doctype html>
+<html>
+<head><title>SuperGlue | Administration</title>
+$@
+<link rel='stylesheet' type='text/css' href='http://${HTTP_HOST}/resources/admin/admin.css'>
+</head>"
+}
+%>
+
+<% headerPrint '200' %>
+
+<%
+## html head
+htmlHead
+
+sgver=$(cat /etc/superglue_version)
+devmod=$(cat /etc/superglue_model)
+openwrt=$(cat /etc/openwrt_version)
+wanifname=$(doUci get wanifname || echo 'wlan0') ## TODO fix this
+wanproto=$(doUci get wanproto)
+wanipaddr=$(doUci get wanipaddr) 
+wannetmask=$(doUci get wannetmask)
+wanssid=$(doUci get wanssid)
+wankey=$(doUci get wankey)
+
+echo "<body>
+<h1>SG</h1>
+<hr>
+<h2 style='display:inline'>Superglue server control panel</h2>
+<span style='display:block;'>System version: $sgver | Device: $devmod | OpenWRT: $openwrt</span>
+<span style='display:block;'>$(uptime)</span>
+<hr>
+
+Update firmware:
+<form method='post' action='/admin/updatefw' enctype='multipart/form-data'>
+<div id='uploadbox'>
+<input id='uploadfile' placeholder='Choose file' disabled='disabled'>
+<input id='uploadbtn' name='fwupload' type='file'>
+</div>
+<input type='submit' value='Upload'>
+</form>
+
+<hr>
+
+Internet connection:
+<form method='post' action='/admin/wan' name='wan' onchange='formChange();'>
+  <div style='display:inline-flex'>
+  <div style='display:inline-block;'>
+  <select name='wanifname' id='wanifname' style='display:block'>
+  <option value='eth0' id='eth' $([[ $wanifname =~ ('eth') ]] && echo 'selected')>Wired (WAN port)</option>
+  <option value='wlan1' id='wlan' $([[ $wanifname =~ ('wlan') ]] && echo 'selected')>Wireless (Wi-Fi)</option>
+  </select>
+  <fieldset id='wanwifi' class='hide'>
+  <input type='text' name='wanssid' value='$wanssid'>
+  <input type='password' name='wankey' value='$wankey'>
+  </fieldset>
+  </div>
+
+  <div style='display:inline-block;'>
+  <select name='wanproto' id='wanproto' style='display:block'>
+  <option value='dhcp' name='dhcp' id='dhcp' $([[ $wanproto == 'dhcp' ]] && echo 'selected')>Automatic (DHCP)</option>
+  <option value='stat' name='dhcp' id='stat' $([[ $wanproto == 'static' ]] && echo 'selected')>Manual (Static IP)</option>
+  </select>
+  <fieldset id='wanaddr' class='hide' >
+  <input type='text' name='wanipaddr' id='wanipaddr' value='$wanipaddr'>
+  <input type='text' name='wangw' id='wannetmask' value='$wannetmask'>
+  </fieldset>
+  </div>
+  </div>
+  <input type='hidden' name='iface' value='wan' class='inline'>
+  <input type='submit' value='Apply'>
+
+</form>
+<hr>
+
+Local wireless network:
+<form method='post' action='/admin/ssidchange'>
+  <div style='display:inline-flex'>
+  <div style='display:inline-block;'>
+    <input type='text' name='lanssid' value='$(doUci get lanssid)'>
+    <input type='password' name='lankey' value='$(doUci get lankey)'>
+  </div>
+  <div style='display:inline-block;'>
+    <input type='text' name='lanipaddr' value='$(doUci get lanipaddr)'>
+    <input type='hidden' name='iface' value='lan' class='inline'>
+  </div>
+  </div>
+  <input type='submit' value='Apply'>
+  
+</form>
+
+<hr>
+
+<form action='/admin/rebootnow' method='post' class='inline'>
+<input type='hidden' name='reboot' value='now' class='inline'>
+<input type='submit' value='Reboot' class='inline'>
+</form>
+
+<form action='http://logout@${HTTP_HOST}/admin' method='get' class='inline'>
+<input type='submit' value='Logout' class='inline'>
+</form>
+
+<hr>
+Memory:
+<pre>$(free)</pre>
+<hr>
+Storage:
+<pre>$(df -h)</pre>
+<hr>
+Environment:
+<pre>$(env)</pre>
+<hr>
+
+</body>
+<script type='text/javascript' src='http://${HTTP_HOST}/resources/admin/admin.js'></script>
+
+</html>"
+
+
+%>
+
+

+ 0 - 0
openwrt/common/www/lib/cgi/demo.cgi → openwrt/common/opt/lib/cgi/demo.cgi


+ 0 - 0
openwrt/common/www/lib/cgi/post.cgi → openwrt/common/opt/lib/cgi/post.cgi


+ 37 - 0
openwrt/common/opt/lib/cgi/suid.sh

@@ -0,0 +1,37 @@
+#!/bin/bash
+
+SHELL=/bin/bash
+
+if [[ $EUID -ne 0 ]]; then echo 'root only'; exit 1; fi
+
+## parent process id
+#_PPID=$PPID
+
+## grandparent process id (process that called sudo that called us)
+#_GPPID=$(ps -p$PPID -o ppid=)
+
+## grandparent command
+#_GPCMD=$(ps -f -p$_GPPID)
+
+## check if called by admin.sh
+#if [[ ! $_GPCMD =~ 'admin/admin.sh' ]]; then echo 'bad granny'; exit 1; fi
+
+## get lighttpd session id
+#_LSID=$(ps -C lighttpd -o sid=)
+
+## parent session id
+_PSID=${@: -1}
+
+## our session id
+#_SID=$(ps -p$$ -o sid=)
+
+## check if we belong to group/session of lighty and admin.sh
+#if [ $_LSID != $_PSID -o $_SID != $_LSID ]; then echo 'bad session'; exit 1; fi
+#if [[ $_LSID != $_PSID ]]; then echo 'bad session'; exit 1; fi
+
+## remove _PSID from the arguments
+_ARGS=${@//$_PSID}
+
+eval $_ARGS
+
+exit $?

+ 60 - 0
openwrt/common/opt/lib/cgi/upload.cgi

@@ -0,0 +1,60 @@
+#!/usr/bin/haserl --shell=/bin/bash --upload-limit=32768 --upload-dir=/tmp
+<%# upload limit: 32Mb %>
+<%
+
+#some path variables
+_WWW='/www'
+_TMP="${_WWW}/tmp"
+_LOG="${_WWW}/log/upload.log"
+_DEBUG=1
+
+err() {
+  _ERR="$?"
+  [[ "$_ERR" -gt 0 ]] || return 0
+  log "$1"
+  head "${2:='400'}"
+  exit "$_ERR"
+} 
+
+log() {
+  [[ "$_DEBUG" -gt 0 ]] || return 0
+  local _TYPE='I:'
+  [[ "$_ERR" -gt 0 ]] && _TYPE='E:'
+  local _TIME; printf -v _TIME '%(%d.%m.%Y %H:%M:%S)T' -1
+  printf '%b\n' "$_TIME  $_TYPE ${@} " >> "$_LOG"
+  [[ "$_DEBUG" -gt 1 ]] && printf '%b\n' "[verbose] $_TYPE ${1}"
+  return 0
+}
+
+head() {
+  case "$1" in
+ 200|'') printf '%b' 'HTTP/1.1 200 OK\nAccess-Control-Allow-Origin: *\n\n';;
+    405) printf '%b' 'HTTP/1.1 405 Method Not Allowed\n\n';;
+    406) printf '%b' 'HTTP/1.1 406 Not Acceptable\n\n';;
+      *) printf '%b' 'HTTP/1.1 400 Bad Request\n\n';;
+  esac
+}
+
+#_REF="$HTTP_REFERER"
+#_SESS="$SESSIONID"
+#log $_REF $_SESS
+
+
+## checks and sanitation
+[[ ${CONTENT_TYPE^^} == MULTIPART/FORM-DATA* ]] || err 'wrong content type' '406' 
+[[ "${REQUEST_METHOD^^}" == "POST" ]] || err 'wrong method, not a post' '405'
+_UPLD="${HASERL_fwupload_path##*/}"
+mv "$_TMP/$_UPLD" "$_TMP/fwupload.bin" 2>/dev/null || err 'error renaming upload'
+
+log 'upload OK'
+head '200'
+
+#UPLD="${HASERL_fwupload_path##*/}"
+#UPLD="${_UPLD//[^a-zA-Z0-9_.-]/}"
+#[ -n "$_UPLD" ] || err 'empty filename value, sanitation failed?'
+#[ -f "$_TMP/$_UPLD" ] || err 'can not access uploaded file, sanitation failed?'
+#log "$_UPLD"
+
+%>
+
+

+ 0 - 0
openwrt/common/www/lib/devTools/SCSystemBrowser.html → openwrt/common/opt/lib/devTools/SCSystemBrowser.html


+ 0 - 0
openwrt/common/www/lib/devTools/ace/ace.js → openwrt/common/opt/lib/devTools/ace/ace.js


+ 0 - 0
openwrt/common/www/lib/devTools/ace/ext-language_tools.js → openwrt/common/opt/lib/devTools/ace/ext-language_tools.js


+ 0 - 0
openwrt/common/www/lib/devTools/ace/mode-javascript.js → openwrt/common/opt/lib/devTools/ace/mode-javascript.js


+ 0 - 0
openwrt/common/www/lib/devTools/ace/theme-monokai.js → openwrt/common/opt/lib/devTools/ace/theme-monokai.js


+ 0 - 0
openwrt/common/www/lib/devTools/ace/worker-javascript.js → openwrt/common/opt/lib/devTools/ace/worker-javascript.js


+ 0 - 0
openwrt/common/www/lib/devTools/ace/worker-javascript.js.bak → openwrt/common/opt/lib/devTools/ace/worker-javascript.js.bak


+ 1 - 0
openwrt/common/opt/lib/htpasswd

@@ -0,0 +1 @@
+admin:superglue:dbeca8aa1272a6b13c2575ac5b234690

+ 122 - 0
openwrt/common/opt/lib/resources/admin/admin.css

@@ -0,0 +1,122 @@
+html {
+  width: 1000px;
+} 
+body { 
+  background:#ccc;
+  color:#0c0c0c;
+  margin: 20px 0 0 200px;
+  font-family: TitilliumWeb;
+  font-size: 100%;
+}
+
+input, select {
+  font-family: sans-serif;
+  font-size: 100%; 
+  color: #111;
+  display: block;
+  font-family: sans-serif;
+  font-size: 100%; 
+  width: 200px;
+  padding: 5px;
+  margin: 5px 5px 0 0;
+  border: 1px solid #666;
+  -moz-box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box; 
+  background: #fcfcfc;
+}
+
+input {
+  text-indent: 4px;
+  background: #fcfcfc;
+}
+
+input[type='submit'] {
+  padding-right: 8px;
+  width: inherit;
+  font-size: 100%;
+  cursor: pointer;
+}
+
+input[type='button'],
+input[type='submit'],
+input[type='reset'],
+input[type='file']::-webkit-file-upload-button,
+button {
+  cursor: pointer;
+}
+
+div#uploadbox {
+  position: relative;
+  height: 38px;
+}
+
+input#uploadbtn,
+input#uploadfile {
+  position: absolute;
+  top: 0;
+  left: 0;
+  height: 33px;
+  cursor: pointer;
+  width: auto;
+}
+
+input#uploadbtn {
+  opacity: 0;
+}
+
+/*
+input[type='file'] {
+  padding-right: 8px;
+  width: 400px;
+  font-size: 100%;
+  position: absolute;
+  top: 0;
+  right: 0;
+  margin: 0;
+  padding: 0;
+  cursor: pointer;
+  opacity: 0;
+  filter: alpha(opacity=0);
+} */
+
+
+img.logo {
+  position: absolute;
+  left:50px;
+  top: 20px;
+}
+hr {
+  border: 0;
+  height: 1px;
+  background: #aaa 
+}
+pre {
+  white-space: pre-wrap;
+}
+fieldset {
+  border: 0;
+  margin: 0;
+  padding: 0; 
+}
+.inline {
+  display: inline;
+}
+.hide {
+  visibility: hidden;
+  display: none;
+}
+.show {
+  visibility: visible;
+  display: inline-block;
+}
+
+@font-face {
+  font-family: TitilliumWeb;
+  src: url('/resources/fonts/Titillium_Web/TitilliumWeb-Regular.ttf') format('truetype');
+}
+@font-face { 
+  font-family: TitilliumWeb; 
+  font-weight: bold;
+  src: url('/resources/fonts/Titillium_Web/TitilliumWeb-Bold.ttf') format('truetype'); }
+

+ 34 - 0
openwrt/common/opt/lib/resources/admin/admin.js

@@ -0,0 +1,34 @@
+(function() {
+  document.getElementById('uploadbtn').onchange = function () {
+    document.getElementById('uploadfile').value = this.value.replace(/^.*\\/, "");
+    var len = document.getElementById('uploadfile').value.length - 7;
+    document.getElementById('uploadfile').setAttribute('size', len);
+    var len = document.getElementById('uploadfile').offsetWidth;
+    document.getElementById('uploadbtn').style.width = len + "px";
+  };
+})();
+
+function formChange() {
+  if (document.activeElement.tagName.toLowerCase() !=  'select') {
+    console.log('not select');
+    return false;
+  }
+  aElem = document.activeElement;
+  aParent = aElem.parentElement;
+  sOpt = aElem[aElem.selectedIndex];
+  console.log(aElem.id + sOpt.id);
+  if (aElem.id + sOpt.id == 'wanprotostat') {
+    document.getElementById('wanaddr').setAttribute('class','show');
+  }
+  if (aElem.id + sOpt.id == 'wanprotodhcp') {
+    document.getElementById('wanaddr').setAttribute('class','hide');
+  }
+  if (aElem.id + sOpt.id == 'wanifnamewlan') {
+    document.getElementById('wanwifi').setAttribute('class','show');
+  }
+  if (aElem.id + sOpt.id == 'wanifnameeth') {
+    document.getElementById('wanwifi').setAttribute('class','hide');
+  }
+};
+
+

+ 0 - 0
openwrt/common/www/lib/resources/css/SuperGlue.css → openwrt/common/opt/lib/resources/css/SuperGlue.css


+ 0 - 0
openwrt/common/www/lib/resources/demo.html → openwrt/common/opt/lib/resources/demo.html


+ 19 - 0
openwrt/common/opt/lib/resources/empty.html

@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+		<meta name="generator" content="SuperGlue" data-superglue-version="1.0" data-superglue-settings="">
+		<title>New Page</title>
+		<style type="text/css" data-superglue="default-css">
+			body { margin: 0px; padding: 0px; }
+			#sg-page { position: relative; top: 0px; }
+			#sg-page.sg-page-centered { margin: 0px auto; }
+			.sg-element { position: absolute; overflow: hidden; }
+		</style>
+		<link rel="stylesheet" href="/resources/css/SuperGlue.css" data-superglue="text-css">
+	</head>
+	<body style="">
+		<div id="sg-page" data-superglue-grid="off/0px">
+		</div>
+	</body>
+</html>

+ 0 - 0
openwrt/common/www/lib/resources/failsafe.html → openwrt/common/opt/lib/resources/failsafe.html


+ 0 - 0
openwrt/common/www/lib/resources/fonts/Dosis/Dosis-Bold.otf → openwrt/common/opt/lib/resources/fonts/Dosis/Dosis-Bold.otf


+ 0 - 0
openwrt/common/www/lib/resources/fonts/Dosis/Dosis-Light.otf → openwrt/common/opt/lib/resources/fonts/Dosis/Dosis-Light.otf


+ 0 - 0
openwrt/common/www/lib/resources/fonts/Dosis/Dosis-Regular.otf → openwrt/common/opt/lib/resources/fonts/Dosis/Dosis-Regular.otf


+ 0 - 0
openwrt/common/www/lib/resources/fonts/Dosis/SIL Open Font License.txt → openwrt/common/opt/lib/resources/fonts/Dosis/SIL Open Font License.txt


+ 0 - 0
openwrt/common/www/lib/resources/fonts/Montserrat/Montserrat-Bold.ttf → openwrt/common/opt/lib/resources/fonts/Montserrat/Montserrat-Bold.ttf


+ 0 - 0
openwrt/common/www/lib/resources/fonts/Montserrat/Montserrat-Regular.ttf → openwrt/common/opt/lib/resources/fonts/Montserrat/Montserrat-Regular.ttf


+ 0 - 0
openwrt/common/www/lib/resources/fonts/Montserrat/OFL.txt → openwrt/common/opt/lib/resources/fonts/Montserrat/OFL.txt


+ 0 - 0
openwrt/common/www/lib/resources/fonts/Titillium_Web/OFL.txt → openwrt/common/opt/lib/resources/fonts/Titillium_Web/OFL.txt


BIN
openwrt/common/opt/lib/resources/fonts/Titillium_Web/TitilliumWeb-Bold.ttf


Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно