2015-01-16 22:38:38 +00:00
-- Copyright 2008 Steven Barth <steven@midlink.org>
2015-01-16 22:46:42 +00:00
-- Copyright 2008-2011 Jo-Philipp Wich <jow@openwrt.org>
2015-01-16 22:38:38 +00:00
-- Licensed to the public under the Apache License 2.0.
2010-11-24 13:42:20 +00:00
2008-05-25 17:00:30 +00:00
module ( " luci.controller.admin.system " , package.seeall )
2008-04-11 18:24:25 +00:00
2008-05-22 14:04:03 +00:00
function index ( )
2015-01-15 14:37:46 +00:00
local fs = require " nixio.fs "
2011-08-12 13:16:27 +00:00
entry ( { " admin " , " system " , " system " } , cbi ( " admin_system/system " ) , _ ( " System " ) , 1 )
2015-10-20 19:01:41 +00:00
entry ( { " admin " , " system " , " clock_status " } , post_on ( { set = true } , " action_clock_status " ) )
2019-03-08 12:26:19 +00:00
entry ( { " admin " , " system " , " ntp_restart " } , call ( " action_ntp_restart " ) , nil ) . leaf = true
2011-10-24 01:10:34 +00:00
2018-11-20 09:50:03 +00:00
entry ( { " admin " , " system " , " admin " } , firstchild ( ) , _ ( " Administration " ) , 2 )
entry ( { " admin " , " system " , " admin " , " password " } , template ( " admin_system/password " ) , _ ( " Router Password " ) , 1 )
entry ( { " admin " , " system " , " admin " , " password " , " json " } , post ( " action_password " ) )
if fs.access ( " /etc/config/dropbear " ) then
entry ( { " admin " , " system " , " admin " , " dropbear " } , cbi ( " admin_system/dropbear " ) , _ ( " SSH Access " ) , 2 )
entry ( { " admin " , " system " , " admin " , " sshkeys " } , template ( " admin_system/sshkeys " ) , _ ( " SSH-Keys " ) , 3 )
entry ( { " admin " , " system " , " admin " , " sshkeys " , " json " } , post_on ( { keys = true } , " action_sshkeys " ) )
end
2011-08-12 13:16:27 +00:00
entry ( { " admin " , " system " , " startup " } , form ( " admin_system/startup " ) , _ ( " Startup " ) , 45 )
2011-10-26 00:58:12 +00:00
entry ( { " admin " , " system " , " crontab " } , form ( " admin_system/crontab " ) , _ ( " Scheduled Tasks " ) , 46 )
2010-03-08 02:16:38 +00:00
2016-05-23 11:16:04 +00:00
if fs.access ( " /sbin/block " ) and fs.access ( " /etc/config/fstab " ) then
2011-08-12 13:16:27 +00:00
entry ( { " admin " , " system " , " fstab " } , cbi ( " admin_system/fstab " ) , _ ( " Mount Points " ) , 50 )
2010-11-27 04:55:38 +00:00
entry ( { " admin " , " system " , " fstab " , " mount " } , cbi ( " admin_system/fstab/mount " ) , nil ) . leaf = true
entry ( { " admin " , " system " , " fstab " , " swap " } , cbi ( " admin_system/fstab/swap " ) , nil ) . leaf = true
2010-03-08 02:16:38 +00:00
end
2008-12-19 12:12:43 +00:00
2018-05-07 13:17:42 +00:00
local nodes , number = fs.glob ( " /sys/class/leds/* " )
2017-06-04 16:49:27 +00:00
if number > 0 then
2011-08-12 13:16:27 +00:00
entry ( { " admin " , " system " , " leds " } , cbi ( " admin_system/leds " ) , _ ( " <abbr title= \" Light Emitting Diode \" >LED</abbr> Configuration " ) , 60 )
2008-12-19 12:12:43 +00:00
end
2015-10-22 06:35:34 +00:00
entry ( { " admin " , " system " , " flashops " } , call ( " action_flashops " ) , _ ( " Backup / Flash Firmware " ) , 70 )
entry ( { " admin " , " system " , " flashops " , " reset " } , post ( " action_reset " ) )
entry ( { " admin " , " system " , " flashops " , " backup " } , post ( " action_backup " ) )
2018-09-08 07:07:01 +00:00
entry ( { " admin " , " system " , " flashops " , " backupmtdblock " } , post ( " action_backupmtdblock " ) )
2011-10-24 01:10:34 +00:00
entry ( { " admin " , " system " , " flashops " , " backupfiles " } , form ( " admin_system/backupfiles " ) )
2015-10-22 06:35:34 +00:00
-- call() instead of post() due to upload handling!
entry ( { " admin " , " system " , " flashops " , " restore " } , call ( " action_restore " ) )
entry ( { " admin " , " system " , " flashops " , " sysupgrade " } , call ( " action_sysupgrade " ) )
2015-10-06 23:54:56 +00:00
entry ( { " admin " , " system " , " reboot " } , template ( " admin_system/reboot " ) , _ ( " Reboot " ) , 90 )
entry ( { " admin " , " system " , " reboot " , " call " } , post ( " action_reboot " ) )
2008-05-22 14:04:03 +00:00
end
2011-10-24 01:10:34 +00:00
function action_clock_status ( )
local set = tonumber ( luci.http . formvalue ( " set " ) )
if set ~= nil and set > 0 then
local date = os.date ( " *t " , set )
if date then
luci.sys . call ( " date -s '%04d-%02d-%02d %02d:%02d:%02d' " % {
date.year , date.month , date.day , date.hour , date.min , date.sec
} )
2016-11-28 14:12:11 +00:00
luci.sys . call ( " /etc/init.d/sysfixtime restart " )
2011-10-24 01:10:34 +00:00
end
end
luci.http . prepare_content ( " application/json " )
luci.http . write_json ( { timestring = os.date ( " %c " ) } )
end
2019-03-08 12:26:19 +00:00
function action_ntp_restart ( )
if nixio.fs . access ( " /etc/init.d/sysntpd " ) then
os.execute ( " /etc/init.d/sysntpd restart " )
end
luci.http . prepare_content ( " text/plain " )
luci.http . write ( " 0 " )
end
2015-10-22 06:35:34 +00:00
local function image_supported ( image )
return ( os.execute ( " sysupgrade -T %q >/dev/null " % image ) == 0 )
end
2015-10-20 19:01:41 +00:00
2015-10-22 06:35:34 +00:00
local function image_checksum ( image )
return ( luci.sys . exec ( " md5sum %q " % image ) : match ( " ^([^%s]+) " ) )
end
2010-11-24 13:42:20 +00:00
2016-08-19 07:59:52 +00:00
local function image_sha256_checksum ( image )
return ( luci.sys . exec ( " sha256sum %q " % image ) : match ( " ^([^%s]+) " ) )
end
2015-10-22 06:35:34 +00:00
local function supports_sysupgrade ( )
return nixio.fs . access ( " /lib/upgrade/platform.sh " )
end
2011-10-24 01:10:34 +00:00
2015-10-22 06:35:34 +00:00
local function supports_reset ( )
2017-11-29 15:51:08 +00:00
return ( os.execute ( [[grep -sq "^overlayfs:/overlay / overlay " /proc/mounts]] ) == 0 )
2015-10-22 06:35:34 +00:00
end
2011-10-24 01:10:34 +00:00
2015-10-22 06:35:34 +00:00
local function storage_size ( )
local size = 0
if nixio.fs . access ( " /proc/mtd " ) then
for l in io.lines ( " /proc/mtd " ) do
local d , s , e , n = l : match ( ' ^([^%s]+)%s+([^%s]+)%s+([^%s]+)%s+"([^%s]+)" ' )
if n == " linux " or n == " firmware " then
size = tonumber ( s , 16 )
break
end
end
elseif nixio.fs . access ( " /proc/partitions " ) then
for l in io.lines ( " /proc/partitions " ) do
local x , y , b , n = l : match ( ' ^%s*(%d+)%s+(%d+)%s+([^%s]+)%s+([^%s]+) ' )
if b and n and not n : match ( ' [0-9] ' ) then
size = tonumber ( b ) * 1024
break
end
end
2011-10-24 01:10:34 +00:00
end
2015-10-22 06:35:34 +00:00
return size
end
2011-10-24 01:10:34 +00:00
2015-10-22 06:35:34 +00:00
function action_flashops ( )
--
-- Overview
--
luci.template . render ( " admin_system/flashops " , {
reset_avail = supports_reset ( ) ,
upgrade_avail = supports_sysupgrade ( )
} )
end
function action_sysupgrade ( )
local fs = require " nixio.fs "
local http = require " luci.http "
local image_tmp = " /tmp/firmware.img "
local fp
http.setfilehandler (
function ( meta , chunk , eof )
if not fp and meta and meta.name == " image " then
fp = io.open ( image_tmp , " w " )
2011-10-24 01:10:34 +00:00
end
2015-10-22 06:35:34 +00:00
if fp and chunk then
fp : write ( chunk )
end
if fp and eof then
fp : close ( )
2011-10-24 01:10:34 +00:00
end
end
2015-10-22 06:35:34 +00:00
)
if not luci.dispatcher . test_post_security ( ) then
fs.unlink ( image_tmp )
return
2011-10-24 01:10:34 +00:00
end
2015-10-20 19:01:41 +00:00
--
2015-10-22 06:35:34 +00:00
-- Cancel firmware flash
2015-10-20 19:01:41 +00:00
--
2015-10-22 06:35:34 +00:00
if http.formvalue ( " cancel " ) then
fs.unlink ( image_tmp )
http.redirect ( luci.dispatcher . build_url ( ' admin/system/flashops ' ) )
return
end
2015-10-20 19:01:41 +00:00
2015-10-22 06:35:34 +00:00
--
-- Initiate firmware flash
--
2018-08-17 10:52:36 +00:00
local step = tonumber ( http.formvalue ( " step " ) ) or 1
2015-10-22 06:35:34 +00:00
if step == 1 then
2018-08-17 10:52:36 +00:00
local force = http.formvalue ( " force " )
if image_supported ( image_tmp ) or force then
2015-10-22 06:35:34 +00:00
luci.template . render ( " admin_system/upgrade " , {
checksum = image_checksum ( image_tmp ) ,
2016-08-19 07:59:52 +00:00
sha256ch = image_sha256_checksum ( image_tmp ) ,
2015-10-22 06:35:34 +00:00
storage = storage_size ( ) ,
size = ( fs.stat ( image_tmp , " size " ) or 0 ) ,
2018-08-17 10:52:36 +00:00
keep = ( not not http.formvalue ( " keep " ) ) ,
force = ( not not http.formvalue ( " force " ) )
2015-10-22 06:35:34 +00:00
} )
else
fs.unlink ( image_tmp )
luci.template . render ( " admin_system/flashops " , {
reset_avail = supports_reset ( ) ,
upgrade_avail = supports_sysupgrade ( ) ,
image_invalid = true
} )
end
2018-08-17 10:52:36 +00:00
2015-10-22 06:35:34 +00:00
--
-- Start sysupgrade flash
--
elseif step == 2 then
local keep = ( http.formvalue ( " keep " ) == " 1 " ) and " " or " -n "
2018-08-20 19:36:11 +00:00
local force = ( http.formvalue ( " force " ) == " 1 " ) and " -F " or " "
2015-10-22 06:35:34 +00:00
luci.template . render ( " admin_system/applyreboot " , {
title = luci.i18n . translate ( " Flashing... " ) ,
msg = luci.i18n . translate ( " The system is flashing now.<br /> DO NOT POWER OFF THE DEVICE!<br /> Wait a few minutes before you try to reconnect. It might be necessary to renew the address of your computer to reach the device again, depending on your settings. " ) ,
2018-08-17 10:52:36 +00:00
addr = ( # keep > 0 ) and ( # force > 0 ) and " 192.168.1.1 " or nil
2015-10-22 06:35:34 +00:00
} )
2018-11-14 12:48:59 +00:00
luci.sys . process.exec ( { " /bin/sh " , " -c " , " sleep 1; killall dropbear uhttpd; sleep 1; /sbin/sysupgrade %s %s %q " % { keep , force , image_tmp } } , nil , nil , true )
2015-10-22 06:35:34 +00:00
end
end
function action_backup ( )
2018-11-14 12:48:59 +00:00
luci.http . header ( ' Content-Disposition ' , ' attachment; filename="backup-%s-%s.tar.gz" '
% { luci.sys . hostname ( ) , os.date ( " %Y-%m-%d " ) } )
2015-10-22 06:35:34 +00:00
luci.http . prepare_content ( " application/x-targz " )
2018-11-14 12:48:59 +00:00
luci.sys . process.exec ( { " /sbin/sysupgrade " , " --create-backup " , " - " } , luci.http . write )
2015-10-22 06:35:34 +00:00
end
2018-09-08 07:07:01 +00:00
function action_backupmtdblock ( )
2018-11-14 12:37:51 +00:00
local mv = luci.http . formvalue ( " mtdblockname " ) or " "
local m , n = mv : match ( ' ^([^%s%./"]+)/%d+/(%d+)$ ' )
if not m and n then
luci.http . status ( 400 , " Bad Request " )
return
end
2018-09-08 07:07:01 +00:00
2018-11-14 12:48:59 +00:00
luci.http . header ( ' Content-Disposition ' , ' attachment; filename="backup-%s-%s-%s.bin" '
% { luci.sys . hostname ( ) , m , os.date ( " %Y-%m-%d " ) } )
2018-09-08 07:07:01 +00:00
luci.http . prepare_content ( " application/octet-stream " )
2018-11-14 12:48:59 +00:00
luci.sys . process.exec ( { " /bin/dd " , " if=/dev/mtd%s " % n , " conv=fsync,notrunc " } , luci.http . write )
2018-09-08 07:07:01 +00:00
end
2015-10-22 06:35:34 +00:00
function action_restore ( )
local fs = require " nixio.fs "
local http = require " luci.http "
local archive_tmp = " /tmp/restore.tar.gz "
local fp
http.setfilehandler (
function ( meta , chunk , eof )
if not fp and meta and meta.name == " archive " then
fp = io.open ( archive_tmp , " w " )
2008-08-03 15:01:36 +00:00
end
2015-10-22 06:35:34 +00:00
if fp and chunk then
fp : write ( chunk )
2008-08-03 15:01:36 +00:00
end
2015-10-22 06:35:34 +00:00
if fp and eof then
fp : close ( )
2011-10-24 01:10:34 +00:00
end
end
2015-10-22 06:35:34 +00:00
)
if not luci.dispatcher . test_post_security ( ) then
fs.unlink ( archive_tmp )
return
2008-08-03 15:01:36 +00:00
end
2015-10-20 19:01:41 +00:00
2015-10-22 06:35:34 +00:00
local upload = http.formvalue ( " archive " )
if upload and # upload > 0 then
2018-05-15 09:35:40 +00:00
if os.execute ( " gunzip -t %q >/dev/null 2>&1 " % archive_tmp ) == 0 then
luci.template . render ( " admin_system/applyreboot " )
os.execute ( " tar -C / -xzf %q >/dev/null 2>&1 " % archive_tmp )
luci.sys . reboot ( )
else
luci.template . render ( " admin_system/flashops " , {
reset_avail = supports_reset ( ) ,
upgrade_avail = supports_sysupgrade ( ) ,
backup_invalid = true
} )
end
2015-10-22 06:35:34 +00:00
return
end
http.redirect ( luci.dispatcher . build_url ( ' admin/system/flashops ' ) )
end
function action_reset ( )
if supports_reset ( ) then
luci.template . render ( " admin_system/applyreboot " , {
title = luci.i18n . translate ( " Erasing... " ) ,
msg = luci.i18n . translate ( " The system is erasing the configuration partition now and will reboot itself when finished. " ) ,
addr = " 192.168.1.1 "
} )
2018-11-14 12:48:59 +00:00
luci.sys . process.exec ( { " /bin/sh " , " -c " , " sleep 1; killall dropbear uhttpd; sleep 1; jffs2reset -y && reboot " } , nil , nil , true )
2015-10-22 06:35:34 +00:00
return
end
http.redirect ( luci.dispatcher . build_url ( ' admin/system/flashops ' ) )
2008-08-03 15:01:36 +00:00
end
2018-11-20 09:50:03 +00:00
function action_password ( )
local password = luci.http . formvalue ( " password " )
if not password then
luci.http . status ( 400 , " Bad Request " )
return
end
2010-11-23 22:38:01 +00:00
2018-11-20 09:50:03 +00:00
luci.http . prepare_content ( " application/json " )
luci.http . write_json ( { code = luci.sys . user.setpasswd ( " root " , password ) } )
end
function action_sshkeys ( )
local keys = luci.http . formvalue ( " keys " )
if keys then
keys = luci.jsonc . parse ( keys )
if not keys or type ( keys ) ~= " table " then
luci.http . status ( 400 , " Bad Request " )
return
2008-04-11 18:24:25 +00:00
end
2018-11-20 09:50:03 +00:00
local fd , err = io.open ( " /etc/dropbear/authorized_keys " , " w " )
if not fd then
luci.http . status ( 503 , err )
return
end
local _ , k
for _ , k in ipairs ( keys ) do
if type ( k ) == " string " and k : match ( " ^%w+%- " ) then
fd : write ( k )
fd : write ( " \n " )
end
end
fd : close ( )
end
local fd , err = io.open ( " /etc/dropbear/authorized_keys " , " r " )
if not fd then
luci.http . status ( 503 , err )
return
2008-04-11 18:24:25 +00:00
end
2010-11-23 22:38:01 +00:00
2018-11-20 09:50:03 +00:00
local rv = { }
while true do
local ln = fd : read ( " *l " )
if not ln then
break
elseif ln : match ( " ^[%w%-]+%s+[A-Za-z0-9+/=]+$ " ) or
ln : match ( " ^[%w%-]+%s+[A-Za-z0-9+/=]+%s " )
then
rv [ # rv + 1 ] = ln
end
end
fd : close ( )
luci.http . prepare_content ( " application/json " )
luci.http . write_json ( rv )
2008-04-11 18:24:25 +00:00
end
function action_reboot ( )
2015-10-06 23:54:56 +00:00
luci.sys . reboot ( )
2008-04-11 18:24:25 +00:00
end