mirror of https://github.com/aredn/aredn.git
838 lines
25 KiB
Perl
Executable File
838 lines
25 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
=for comment
|
|
|
|
Part of AREDN -- Used for creating Amateur Radio Emergency Data Networks
|
|
Copyright (C) 2015 Conrad Lara
|
|
See Contributors file for additional contributors
|
|
|
|
Copyright (c) 2013 David Rivenburg et al. BroadBand-HamNet
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation version 3 of the License.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
Additional Terms:
|
|
|
|
Additional use restrictions exist on the AREDN(TM) trademark and logo.
|
|
See AREDNLicense.txt for more info.
|
|
|
|
Attributions to the AREDN Project must be retained in the source code.
|
|
If importing this code into a new or existing project attribution
|
|
to the AREDN project must be added to the source code.
|
|
|
|
You must not misrepresent the origin of the material contained within.
|
|
|
|
Modified versions must be modified to attribute to the original source
|
|
and be marked in reasonable ways as differentiate it from the original
|
|
version.
|
|
|
|
=cut
|
|
|
|
BEGIN {push @INC, '/www/cgi-bin'};
|
|
use perlfunc;
|
|
|
|
sub firmware_list_gen
|
|
{
|
|
@fw_images = ();
|
|
chomp($fw_version = `cat /etc/mesh-release`);
|
|
foreach(`cat /tmp/web/firmware.list 2>/dev/null`)
|
|
{
|
|
my($md5, $fw, $tag) = /^(\S+) (\S+) (.*)/;
|
|
next unless $tag;
|
|
next if $tag eq "none";
|
|
next unless ($tag eq "all") or ($tag eq "dev" and $parms{dev}) or ($fw_version =~ /$tag/);
|
|
push @fw_images, $fw;
|
|
$fw_md5{$fw} = $md5;
|
|
}
|
|
}
|
|
|
|
|
|
$debug = 0;
|
|
$| = 1;
|
|
|
|
$tunnel_active= 0;
|
|
if ( -e "/usr/sbin/vtund" && open(my $tuncfgfd, '/etc/config/vtun')) {
|
|
while ( my $line = <$tuncfgfd> ) {
|
|
if ( $line =~ /option enabled '1'/i ) {
|
|
$tunnel_active = 1;
|
|
last;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if ( $tunnel_active ) {
|
|
read_postdata({acceptfile => false});
|
|
} else {
|
|
read_postdata({acceptfile => true});
|
|
}
|
|
|
|
reboot_page("/cgi-bin/status") if $parms{button_reboot};
|
|
read_query_string();
|
|
$node = nvram_get("node");
|
|
$tmpdir = "/tmp/web/admin";
|
|
system "mkdir -p $tmpdir";
|
|
|
|
# make developer mode stick
|
|
system "touch /tmp/developer_mode" if $parms{dev};
|
|
$parms{dev} = 1 if -e "/tmp/developer_mode";
|
|
|
|
# set the wget command options
|
|
$wget = "wget -U 'node: $node'";
|
|
|
|
#
|
|
# handle firmware updates
|
|
#
|
|
|
|
$fw_install = 0;
|
|
$patch_install = 0;
|
|
@fw_output = ();
|
|
@fw_images = ();
|
|
%fw_md5 = ();
|
|
|
|
@serverpaths = ();
|
|
$uciserverpath=`uci get aredn.\@downloads[0].firmwarepath`;
|
|
chomp($uciserverpath);
|
|
push @serverpaths, $uciserverpath;
|
|
|
|
${hardwaretype} = `/usr/local/bin/get_hardwaretype`;
|
|
chomp(${hardwaretype});
|
|
|
|
${targettype} = `ubus call system board | jsonfilter -e '@["release"].target'`;
|
|
chomp(${targettype});
|
|
|
|
# handle TPLink and Mikrotik exception conditions
|
|
$mfg=`/usr/local/bin/get_hardware_mfg`;
|
|
chomp($mfg);
|
|
$mfgprefix="";
|
|
if($mfg=~ /Ubiquiti/i)
|
|
{
|
|
$mfgprefix="ubnt";
|
|
} elsif($mfg=~ /Mikrotik/i) {
|
|
$mfgprefix="mikrotik";
|
|
} elsif($mfg=~ /TP-Link/i) {
|
|
$mfgprefix="cpe";
|
|
}
|
|
|
|
if(${hardwaretype} eq "nanostation-m")
|
|
{
|
|
${hardwaretypev}="nano-m"; # Nano XM
|
|
} elsif(${hardwaretype} eq "nanostation-m-xw") {
|
|
${hardwaretypev}= "nano-m-xw" ; # Nano XW
|
|
} elsif(${hardwaretype} eq "rb-952ui-5ac2nd") {
|
|
${hardwaretypev}= "rb-nor-flash-16M-ac" ; # hAP AC Lite
|
|
} elsif(${hardwaretype} =~ /rb-911g-[25]hpnd/i or
|
|
${hardwaretype} =~ /rb-912uag-[25]hpnd/i ) {
|
|
${hardwaretypev}= "nand-large" ; # Basebox 2/5 and QRT 2/5
|
|
} elsif(${hardwaretype} =~ /rb-l[dfhg]+-[25]nd/i or
|
|
${hardwaretype} =~ /rb-lhg-[25]hpnd/i ) {
|
|
${hardwaretypev}= "rb-nor-flash-16M" ; # LHGs & LDFs
|
|
} elsif($mfgprefix eq "cpe" ) {
|
|
$hwmodel = `/usr/local/bin/get_model`;
|
|
chomp($hwmodel);
|
|
if($hwmodel =~ /CPE210 v1\.[01]/i)
|
|
{
|
|
${hardwaretypev}= "210-220-v1" ; # v1.0/v1.1
|
|
} elsif($hwmodel =~ /CPE210 v2\.0/i) {
|
|
${hardwaretypev}= "210-v2" ; # v2.0
|
|
} elsif($hwmodel =~ /CPE210 v3\.0/i) {
|
|
${hardwaretypev}= "210-v3" ; # v3.0
|
|
} elsif($hwmodel =~ /CPE220 v2\.0/i) {
|
|
${hardwaretypev}= "220-v2" ; # v3.0
|
|
} elsif($hwmodel =~ /CPE220 v3\.0/i) {
|
|
${hardwaretypev}= "220-v3" ; # v3.0
|
|
} elsif($hwmodel =~ /CPE510 v2\.0/i) {
|
|
${hardwaretypev}= "510-v2" ; # v2.0
|
|
} elsif($hwmodel =~ /CPE510 v3\.0/i) {
|
|
${hardwaretypev}= "510-v3" ; # v3.0
|
|
} elsif($hwmodel =~ /CPE510/i) {
|
|
${hardwaretypev}= "510-520-v1" ; # CPE510 V1.0/v1.1
|
|
} elsif($hwmodel =~ /CPE610 v2\.0/i) {
|
|
${hardwaretypev}= "610-v2" ; # CPE610 V2.0
|
|
} elsif($hwmodel =~ /CPE610/i) {
|
|
${hardwaretypev}= "610-v1" ; # CPE610 V1.0
|
|
} elsif($hwmodel =~ /WBS510 v2\.0/i) {
|
|
$mfgprefix="wbs";
|
|
${hardwaretypev}= "510-v2" ; # WBS510 v2.0
|
|
} elsif($hwmodel =~ /WBS210 v1\.[012]/i) {
|
|
$mfgprefix="wbs";
|
|
${hardwaretypev}= "210-v1" ; # WBS210 v1.0/v1.1
|
|
}
|
|
} else {
|
|
${hardwaretypev}=${hardwaretype};
|
|
}
|
|
|
|
# refresh fw
|
|
if($parms{button_refresh_fw})
|
|
{
|
|
if((get_default_gw() ne "none") || ($uciserverpath =~ ".local.mesh"))
|
|
{
|
|
push @fw_output, "Downloading firmware list from $uciserverpath...\n";
|
|
unlink "/tmp/web/firmware.list";
|
|
$ok = 0;
|
|
foreach $serverpath (@serverpaths)
|
|
{
|
|
system "$wget -O /tmp/web/firmware.list $serverpath/firmware.${hardwaretype}.list >/dev/null 2>>$tmpdir/wget.err";
|
|
unless($?) { $ok = 1; last }
|
|
}
|
|
if($ok) { push @fw_output, "Done.\n" }
|
|
else { push @fw_output, `cat $tmpdir/wget.err` }
|
|
unlink "$tmpdir/wget.err";
|
|
}
|
|
else
|
|
{
|
|
push @fw_output, "Error: no route to Host\n";
|
|
unlink "/tmp/web/firmware.list";
|
|
}
|
|
}
|
|
|
|
# generate data structures
|
|
# and set $fw_version
|
|
firmware_list_gen();
|
|
|
|
|
|
# upload fw
|
|
if($parms{button_ul_fw} and -f "/tmp/web/upload/file")
|
|
{
|
|
system "mv -f /tmp/web/upload/file $tmpdir/firmware";
|
|
|
|
if($parms{firmfile} =~ /sysupgrade\.bin$/) # full firmware
|
|
{
|
|
$fw_install = 1;
|
|
|
|
# drop the page cache to take pressure of tmps when checking the firmware
|
|
`echo 3 > /proc/sys/vm/drop_caches`;
|
|
|
|
# check firmware header
|
|
|
|
if(system "/usr/local/bin/firmwarecheck.sh $tmpdir/firmware")
|
|
{
|
|
push @fw_output, "Firmware CANNOT be updated\n";
|
|
push @fw_output, "firmware file is not valid\n";
|
|
$fw_install = 0;
|
|
unlink("$tmpdir/firmware");
|
|
system("/usr/local/bin/uploadctlservices","restore") and push @fw_output, "Failed to restart all services, please reboot this node.\n";
|
|
}
|
|
}
|
|
elsif($parms{firmfile} =~ /^patch\S+\.tgz$/) # firmware patch
|
|
{
|
|
$patch_install = 1;
|
|
}
|
|
else
|
|
{
|
|
push @fw_output, "Firmware CANNOT be updated\n";
|
|
push @fw_output, "the uploaded file is not recognized\n";
|
|
unlink("$tmpdir/firmware");
|
|
system("/usr/local/bin/uploadctlservices","restore") and push @fw_output, "Failed to restart all services, please reboot this node.\n";
|
|
}
|
|
}
|
|
|
|
# download fw
|
|
if($parms{button_dl_fw} and $parms{dl_fw} ne "default")
|
|
{
|
|
if((get_default_gw() ne "none") || ($uciserverpath =~ ".local.mesh"))
|
|
{
|
|
unlink "$tmpdir/firmware";
|
|
system("/usr/local/bin/uploadctlservices","upgrade");
|
|
$ok = 0;
|
|
foreach $serverpath (@serverpaths)
|
|
{
|
|
system "$wget -O $tmpdir/firmware $serverpath/$parms{dl_fw} >/dev/null 2>>$tmpdir/wget.err";
|
|
unless($?) { $ok = 1; last }
|
|
}
|
|
|
|
if($parms{dl_fw} =~ /sysupgrade\.bin$/) # full firmware
|
|
{
|
|
$fw_install = 1;
|
|
unless($ok)
|
|
{
|
|
push @fw_output, "Downloading firmware image...\n";
|
|
push @fw_output, `cat $tmpdir/wget.err`;
|
|
}
|
|
unlink "$tmpdir/wget.err";
|
|
|
|
# check md5sum
|
|
$fw = $parms{dl_fw};
|
|
chdir $tmpdir;
|
|
if(system "echo '$fw_md5{$fw} firmware' | md5sum -cs")
|
|
{
|
|
push @fw_output, "Firmware CANNOT be updated\n";
|
|
push @fw_output, "firmware file is not valid\n";
|
|
$fw_install = 0;
|
|
unlink("$tmpdir/firmware");
|
|
system("/usr/local/bin/uploadctlservices","restore") and push @fw_output, "Failed to restart all services, please reboot this node.\n";
|
|
}
|
|
}
|
|
elsif($parms{dl_fw} =~ /^patch\S+\.tgz$/) # firmware patch
|
|
{
|
|
$patch_install = 1;
|
|
unless($ok)
|
|
{
|
|
push @fw_output, "Downloading patch file...\n";
|
|
push @fw_output, `cat $tmpdir/wget.err`;
|
|
}
|
|
unlink "$tmpdir/wget.err";
|
|
|
|
# check md5sum
|
|
$fw = $parms{dl_fw};
|
|
chdir $tmpdir;
|
|
if(system "echo '$fw_md5{$fw} firmware' | md5sum -cs")
|
|
{
|
|
push @fw_output, "Firmware CANNOT be updated\n";
|
|
push @fw_output, "patch file is not valid\n";
|
|
$patch_install = 0;
|
|
unlink("$tmpdir/firmware");
|
|
system("/usr/local/bin/uploadctlservices","restore") and push @fw_output, "Failed to restart all services, please reboot this node.\n";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
push @fw_output, "Firmware CANNOT be updated\n";
|
|
push @fw_output, "the downloaded file is not recognized\n";
|
|
unlink("$tmpdir/firmware");
|
|
system("/usr/local/bin/uploadctlservices","restore") and push @fw_output, "Failed to restart all services, please reboot this node.\n";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
push @fw_output, "Error: no route to Host\n";
|
|
unlink "/tmp/web/firmware.list";
|
|
}
|
|
}
|
|
|
|
|
|
# install fw
|
|
|
|
if($fw_install and -f "$tmpdir/firmware")
|
|
{
|
|
my $junk;
|
|
http_header();
|
|
html_header("FIRMWARE UPDATE IN PROGRESS", 0);
|
|
print "<meta http-equiv='refresh' content='180;URL=http://$node.local.mesh:8080'>";
|
|
print "</head>\n";
|
|
print "<body><center>\n";
|
|
print "<h2>The firmware is being updated.</h2>\n";
|
|
print "<h1>DO NOT REMOVE POWER UNTIL UPDATE IS FINISHED</h1>\n";
|
|
print "</center><br>\n";
|
|
unless($debug)
|
|
{
|
|
# drop the page cache to take pressure of tmps for the upgrade process
|
|
`echo 3 > /proc/sys/vm/drop_caches`;
|
|
`/usr/local/bin/upgrade_kill_prep`;
|
|
|
|
if ( $parms{checkbox_keep_settings} )
|
|
{
|
|
print "
|
|
<center><h2>Firmware will be written in the background.</h2>
|
|
<h3>If your computer is connected to the LAN of this node you may need to acquire<br>
|
|
a new IP address and reset any name service caches you may be using.</h3>
|
|
<h3>The node will reboot twice while the configuration is applied<br>
|
|
When the node has finished booting you should ensure your computer has<br>
|
|
received a new IP address and reconnect with<br>
|
|
<a href='http://$node.local.mesh:8080/'>http://$node.local.mesh:8080/</a><br>
|
|
(This page will automatically reload in 3 minutes)</h3>
|
|
</center></body></html>
|
|
";
|
|
open (my $SYSUPGRADECONF, "/etc/arednsysupgrade.conf") or die "Failed to open arednsysupgrade.conf";
|
|
open (my $TMPSYSUPGRADECONF, '>', "/tmp/sysupgradefilelist") or die "Failed to open TMPSYSUPGRADECONF";
|
|
while (<$SYSUPGRADECONF>){
|
|
chomp;
|
|
next if /^\#/ ;
|
|
if ( -e "$_" ) {
|
|
print $TMPSYSUPGRADECONF "$_\n";
|
|
}
|
|
}
|
|
close $SYSUPGRADECONF;
|
|
close $TMPSYSUPGRADECONF;
|
|
nvram_set("nodeupgraded","1");
|
|
|
|
system("tar -czf /tmp/arednsysupgradebackup.tgz -T /tmp/sysupgradefilelist");
|
|
if ($? != 0) {
|
|
print "
|
|
<center><h2>ERROR: Could not backup filesystem.</h2>
|
|
<h3>An error occured trying to backup the file system. Node will now reboot.
|
|
</center>
|
|
";
|
|
page_footer();
|
|
print "</body></html>";
|
|
nvram_set("nodeupgraded","0");
|
|
system "/sbin/reboot";
|
|
exit 1;
|
|
}
|
|
|
|
system("rm -f /tmp/sysupgradefilelist");
|
|
`/usr/local/bin/spawn_sysupgrade $tmpdir/firmware 2>&1 &`;
|
|
}
|
|
else
|
|
{
|
|
print "
|
|
<center><h2>Firmware will be written in the background.</h2>
|
|
<h3>If your computer is connected to the LAN of this node you may need to acquire<br>
|
|
a new IP address and reset any name service caches you may be using.</h3>
|
|
<h3>The node will reboot after the firmware has been written to flash memory<br>
|
|
When the node has finished booting you should ensure your computer has<br>
|
|
received a new IP address and reconnect with<br>
|
|
<a href='http://localnode.local.mesh:8080/'>http://192.168.1.1:8080/</a><br>
|
|
and continue setup of the node in firstboot state.<br>
|
|
(This page will automatically reload in 3 minutes)</h3>
|
|
</center></body></html>
|
|
";
|
|
`/sbin/sysupgrade -n $tmpdir/firmware 2>&1 &`;
|
|
}
|
|
`killall uhttpd &`;
|
|
exit;
|
|
}
|
|
}
|
|
|
|
# install patch
|
|
if($patch_install and -f "$tmpdir/firmware")
|
|
{
|
|
@fw_output = ();
|
|
|
|
for($fail = 1; ; )
|
|
{
|
|
# check available space
|
|
chomp ($size = `gunzip -c $tmpdir/firmware | wc -c`);
|
|
$size = int(($size + 1023) / 1024);
|
|
|
|
if(get_free_space("/tmp") - $size < 100)
|
|
{
|
|
push @fw_output, "Firmware CANNOT be patched\n";
|
|
push @fw_output, "insufficient /tmp space\n";
|
|
push @fw_output, "try again after a reboot\n";
|
|
last;
|
|
}
|
|
elsif(get_free_space("/overlay") - $size < 100)
|
|
{
|
|
push @fw_output, "Firmware CANNOT be patched\n";
|
|
push @fw_output, "insufficient flash space\n";
|
|
push @fw_output, "a full firmware install is required\n";
|
|
last;
|
|
}
|
|
|
|
# make it so
|
|
unlink "$tmpdir/patch.err";
|
|
unlink "$tmpdir/patch.out";
|
|
last if system "mkdir -p $tmpdir/patch 2>>$tmpdir/patch.err";
|
|
last if not chdir "$tmpdir/patch";
|
|
last if system "tar xzf $tmpdir/firmware 2>>$tmpdir/patch.err";
|
|
|
|
unless(-f "files.tar")
|
|
{
|
|
push @fw_output, "Firmware CANNOT be updated\n";
|
|
push @fw_output, "patch file is not valid\n";
|
|
last;
|
|
}
|
|
|
|
last if -x "pre-install" and system "./pre-install >>$tmpdir/patch.out 2>>$tmpdir/patch.err";
|
|
last if system "tar xvf files.tar -C / >>$tmpdir/patch.out 2>>$tmpdir/patch.err";
|
|
last if -x "post-install" and system "./post-install >>$tmpdir/patch.out 2>>$tmpdir/patch.err";
|
|
reboot_page("/cgi-bin/status") if -f "reboot";
|
|
firmware_list_gen(); # mesh-release has changed so regenerate the firmware list
|
|
$fail = 0;
|
|
last;
|
|
}
|
|
|
|
if($fail)
|
|
{
|
|
unless(@fw_output)
|
|
{
|
|
push @fw_output, "Firmware patch failed. This is very bad.\n";
|
|
push @fw_output, "You should probably reinstall the full firmware.\n";
|
|
push @fw_output, `cat $tmpdir/patch.err 2>/dev/null`;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
push @fw_output, "Installing patch...\n";
|
|
push(@fw_output, `cat $tmpdir/patch.out`) if $parms{dev};
|
|
push @fw_output, "Done.\n";
|
|
}
|
|
|
|
unlink("$tmpdir/firmware");
|
|
system("/usr/local/bin/uploadctlservices","restore") and push @fw_output, "Failed to restart all services, please reboot this node.\n";
|
|
|
|
}
|
|
|
|
|
|
#
|
|
# handle package actions
|
|
#
|
|
|
|
@pkg_output = ();
|
|
|
|
# load permanent package list
|
|
foreach(`cat /etc/permpkg 2>/dev/null`)
|
|
{
|
|
next if /^#/;
|
|
chomp;
|
|
$permpkg{$_} = 1;
|
|
}
|
|
|
|
# upload package
|
|
if($parms{button_ul_pkg} and -f "/tmp/web/upload/file")
|
|
{
|
|
system "mv -f /tmp/web/upload/file /tmp/web/upload/newpkg.ipk";
|
|
push @pkg_output, `opkg -force-overwrite install /tmp/web/upload/newpkg.ipk 2>&1`;
|
|
system "rm -rf /tmp/opkg-*";
|
|
unlink("/tmp/web/upload/newpkg.ipk");
|
|
system("/usr/local/bin/uploadctlservices","restore") and push @pkg_output, "Failed to restart all services, please reboot this node.\n";
|
|
}
|
|
|
|
# download package
|
|
$meshpkgs = system('grep -q ".local.mesh" /etc/opkg/distfeeds.conf');
|
|
if($parms{button_dl_pkg} and $parms{dl_pkg} ne "default")
|
|
{
|
|
if((get_default_gw() ne "none") || (!$meshpkgs))
|
|
{
|
|
system("/usr/local/bin/uploadctlservices","opkginstall");
|
|
push @pkg_output, `opkg -force-overwrite install $parms{dl_pkg} 2>&1`;
|
|
system("/usr/local/bin/uploadctlservices","restore") and push @pkg_output, "Failed to restart all services, please reboot this node.\n";
|
|
}
|
|
else
|
|
{
|
|
push @pkg_output, "Error: no route to Host\n";
|
|
}
|
|
}
|
|
|
|
# refresh package list
|
|
if($parms{button_refresh_pkg})
|
|
{
|
|
if((get_default_gw() ne "none") || (!$meshpkgs))
|
|
{
|
|
@pkg_output = `opkg update 2>&1`;
|
|
system "opkg list | grep -v '^ ' | cut -f1,3 -d' ' | gzip -c > /etc/opkg.list.gz";
|
|
}
|
|
else
|
|
{
|
|
push @pkg_output, "Error: no route to Host\n";
|
|
}
|
|
}
|
|
|
|
# remove package
|
|
if($parms{button_rm_pkg} and $parms{rm_pkg} ne "default" and not $permpkg{$parms{rm_pkg}})
|
|
{
|
|
@pkg_output = `opkg remove $parms{rm_pkg} 2>&1`;
|
|
if (! $?) {
|
|
push @pkg_output, "Package removed succssfully";
|
|
}
|
|
}
|
|
|
|
# generate data structures
|
|
|
|
@pkgs = ();
|
|
%pkgver = ();
|
|
foreach(`opkg list_installed | cut -f1,3 -d' '`)
|
|
{
|
|
($pkg, $ver) = split /\s/, $_;
|
|
next unless $ver;
|
|
push @pkgs, $pkg;
|
|
$pkgver{$pkg} = $ver;
|
|
}
|
|
|
|
@dl_pkgs = ();
|
|
%dlpkgver = ();
|
|
foreach(`zcat /etc/opkg.list.gz 2>/dev/null`)
|
|
{
|
|
($pkg, $ver) = split /\s/, $_;
|
|
next unless $ver;
|
|
next if $pkgver{$pkg} and $pkgver{$pkg} eq $ver;
|
|
push @dl_pkgs, $pkg;
|
|
$dlpkgver{$pkg} = $ver;
|
|
}
|
|
|
|
#
|
|
# handle ssh key actions
|
|
#
|
|
|
|
@key_output = ();
|
|
$keyfile = "/etc/dropbear/authorized_keys";
|
|
|
|
# upload key
|
|
if($parms{button_ul_key} and -f "/tmp/web/upload/file")
|
|
{
|
|
$count = `wc -l $keyfile 2>/dev/null`;
|
|
system "grep ^ssh- /tmp/web/upload/file >> $keyfile";
|
|
if($count eq `wc -l $keyfile`)
|
|
{
|
|
push @key_output, "Error: file does not appear to be an ssh key file\n";
|
|
push @key_output, "Authorized keys not changed.\n";
|
|
}
|
|
else
|
|
{
|
|
push @key_output, "Key installed.\n";
|
|
}
|
|
unlink("/tmp/web/upload/file");
|
|
system("/usr/local/bin/uploadctlservices","restore") and push @key_output, "Failed to restart all services, please reboot this node.\n";
|
|
}
|
|
|
|
# remove key
|
|
if($parms{button_rm_key} and $parms{rm_key} ne "default" and -f $keyfile)
|
|
{
|
|
$count = `wc -l $keyfile`;
|
|
system "grep -v '$parms{rm_key}' $keyfile > $tmpdir/keys";
|
|
system "mv -f $tmpdir/keys $keyfile";
|
|
if($count eq `wc -l $keyfile`)
|
|
{
|
|
push @key_output, "Error: authorized keys were not changed.\n";
|
|
}
|
|
else
|
|
{
|
|
push @key_output, "Key $parms{rm_key} removed.\n";
|
|
}
|
|
}
|
|
|
|
# generate data structures
|
|
@keys = ();
|
|
open(FILE, ">$tmpdir/newkeys");
|
|
foreach(`cat $keyfile 2>/dev/null`)
|
|
{
|
|
($type, $key, $who, $extra) = split /\s+/, $_;
|
|
next if $extra;
|
|
next unless $who =~ /.\@./;
|
|
next unless $type =~ /^ssh-/;
|
|
push @keys, $who;
|
|
print FILE "$type $key $who\n";
|
|
}
|
|
close(FILE);
|
|
|
|
# sanitize the key file
|
|
if(-f $keyfile and system "diff $keyfile $tmpdir/newkeys >/dev/null 2>&1")
|
|
{
|
|
system "mv -f $tmpdir/newkeys $keyfile";
|
|
push @key_output, "Info: key file sanitized.\n";
|
|
}
|
|
|
|
|
|
# clean up
|
|
system "rm -rf /tmp/web/upload $tmpdir" unless $debug;
|
|
|
|
|
|
#
|
|
# generate the page
|
|
#
|
|
|
|
http_header();
|
|
html_header("$node administration", 0);
|
|
print <<EOF;
|
|
<script>
|
|
function validateFirmwareFilename(elem){
|
|
var hwmfg = "$mfgprefix";
|
|
var hwtype = "${hardwaretypev}";
|
|
var searchstring = "";
|
|
var efn = "";
|
|
if(hwmfg != "cpe"){
|
|
if ($mfgprefix == "wbs") {
|
|
searchstring= ".*wbs" + hwtype + "-sysupgrade.bin$\";
|
|
efn = "aredn-$fw_version-$mfgprefix${hardwaretypev}-sysupgrade.$
|
|
} else {
|
|
searchstring= ".*-" + hwtype + "-sysupgrade.bin$\";
|
|
efn = "aredn-$fw_version-$mfgprefix-${hardwaretypev}-sysupgrade.bin";
|
|
} else {
|
|
searchstring= ".*cpe" + hwtype + "-sysupgrade.bin$\";
|
|
efn = "aredn-$fw_version-$mfgprefix${hardwaretypev}-sysupgrade.bin";
|
|
}
|
|
var re = new RegExp(searchstring,"g");
|
|
if(elem.value.match(re)){
|
|
return true;
|
|
}else{
|
|
if (confirm('This filename is NOT appropriate for this device!\\n\\nThis device expects a file such as: ' + efn + ' \\n\\n\\nClick OK to continue if you are CERTAIN that the file is correct.')) {
|
|
return true;
|
|
} else {
|
|
elem.value="";
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
EOF
|
|
print "</head>";
|
|
print "<body><center>\n";
|
|
alert_banner();
|
|
print "<form method=post action=admin enctype='multipart/form-data'>\n";
|
|
print "<table width=790>\n";
|
|
print "<tr><td>\n";
|
|
navbar("admin");
|
|
print "</td></tr>\n";
|
|
|
|
print "<tr><td align=center><a href='/help.html#admin' target='_blank'>Help</a> ";
|
|
print "<input type=submit name=button_reboot value=Reboot style='font-weight:bold' title='Immediately reboot this node'>";
|
|
print "</td></tr>\n";
|
|
print "<tr><td align=center>\n";
|
|
print "<table cellspacing=10>\n";
|
|
|
|
#
|
|
# firmware
|
|
#
|
|
|
|
print "<tr><td align=center>\n";
|
|
print "<table cellspacing=10>\n";
|
|
print "<tr><th colspan=3>Firmware Update</th></tr>\n";
|
|
|
|
if(@fw_output)
|
|
{
|
|
print "<tr><td colspan=3 align=center><table><tr><td><b><pre>\n";
|
|
print word_wrap(80, @fw_output);
|
|
print "</pre></b></td></tr></table></td></tr>\n";
|
|
}
|
|
|
|
print "<tr><td align=center colspan=3>current version: $fw_version</td></tr>\n";
|
|
print "<tr><td align=center colspan=3>hardware type: (${targettype}) $mfgprefix (${hardwaretype})</td></tr>\n";
|
|
print "<tr>\n";
|
|
print "<td>Upload Firmware</td>\n";
|
|
print "<td><input type=file name=firmfile title='choose the firmware file to install from your hard drive' accept='.bin' onchange='validateFirmwareFilename(this)'></td>\n";
|
|
print "<td align=center><input type=submit name=button_ul_fw value=Upload title='install the firmware'";
|
|
if($tunnel_active) {
|
|
print " disabled><br><small>Disabled: Tunnels enabled</small>";
|
|
} else {
|
|
print ">";
|
|
}
|
|
print "</td>\n";
|
|
print "</tr>\n";
|
|
|
|
print "<tr>\n";
|
|
print "<td>Download Firmware</td>\n";
|
|
print "<td><select name=dl_fw style='font-family:monospace'>\n";
|
|
selopt("- Select Firmware -", "default", "default");
|
|
foreach(@fw_images)
|
|
{
|
|
selopt($_, $_, "default");
|
|
}
|
|
print "</select>\n";
|
|
print "<input type=submit name=button_refresh_fw value=Refresh title='download the list of available firmware versions'>\n";
|
|
print "<td align=center><input type=submit name=button_dl_fw value=Download title='install the firmware'></td>\n";
|
|
print "<td align=right><input type=checkbox name=checkbox_keep_settings checked>Keep Settings</td>\n";
|
|
print "</tr>\n";
|
|
|
|
print "</table></td></tr>\n";
|
|
print "<tr><td colspan=3><hr></td></tr>\n";
|
|
|
|
#
|
|
# packages
|
|
#
|
|
|
|
print "<tr><td align=center>\n";
|
|
print "<table cellspacing=10>\n";
|
|
print "<tr><th colspan=3>Package Management</th></tr>\n";
|
|
|
|
if(@pkg_output)
|
|
{
|
|
# opkg can produce duplicate first lines, remove them here
|
|
while(defined $pkg_output[1] and $pkg_output[0] eq $pkg_output[1])
|
|
{
|
|
shift @pkg_output;
|
|
}
|
|
|
|
print "<tr><td colspan=3 align=center><table><tr><td><b><pre>\n";
|
|
print word_wrap(80, @pkg_output);
|
|
print "</pre></b></td></tr></table></td></tr>\n";
|
|
}
|
|
|
|
print "<tr>\n";
|
|
print "<td>Upload Package</td>\n";
|
|
print "<td><input type=file name=ul_pkg title='choose the .ipk file to install from your hard drive'> </td>\n";
|
|
print "<td align=center><input type=submit name=button_ul_pkg value=Upload title='install the package'";
|
|
if($tunnel_active) {
|
|
print " disabled><br><small>Disabled: Tunnels enabled</small>";
|
|
} else {
|
|
print ">";
|
|
}
|
|
print "</td>\n";
|
|
print "</tr>\n";
|
|
|
|
print "<tr>\n";
|
|
print "<td>Download Package</td>\n";
|
|
print "<td><select name=dl_pkg style='font-family:monospace'>\n";
|
|
selopt("- Select Package -", "default", "default");
|
|
foreach $pkg (@dl_pkgs)
|
|
{
|
|
selopt("$pkg $dlpkgver{$pkg}", $pkg, "default");
|
|
}
|
|
print "</select>\n";
|
|
print "<input type=submit name=button_refresh_pkg value=Refresh title='download the list of available packages (warning: this takes a lot of space)'>\n";
|
|
print "<td align=center><input type=submit name=button_dl_pkg value=Download title='install the package'></td>\n";
|
|
print "</tr>\n";
|
|
|
|
print "<tr>\n";
|
|
print "<td>Remove Package</td>\n";
|
|
print "<td><select name=rm_pkg style='font-family:monospace'>\n";
|
|
selopt("- Select Package -", "default", "default");
|
|
foreach $pkg (@pkgs)
|
|
{
|
|
$opt = $permpkg{$pkg} ? "disabled" : "";
|
|
selopt("$pkg $pkgver{$pkg}", $pkg, "default", $opt);
|
|
}
|
|
print "</select></td>\n";
|
|
print "<td align=center><input type=submit name=button_rm_pkg value=Remove title='remove the selected package'></td>\n";
|
|
print "</tr>\n";
|
|
|
|
print "</table></td></tr>\n";
|
|
|
|
print "<tr><td colspan=3><hr></td></tr>\n";
|
|
|
|
#
|
|
# ssh keys
|
|
#
|
|
|
|
print "<tr><td align=center>\n";
|
|
print "<table cellspacing=10>\n";
|
|
print "<tr><th colspan=3>Authorized SSH Keys</th></tr>\n";
|
|
|
|
if(@key_output)
|
|
{
|
|
print "<tr><td colspan=3 align=center><table><tr><td><b><pre>\n";
|
|
print word_wrap(80, @key_output);
|
|
print "</pre></b></td></tr></table></td></tr>\n";
|
|
}
|
|
|
|
print "<tr>\n";
|
|
print "<td>Upload Key</td>\n";
|
|
print "<td><input type=file name=sshkey title='choose the id_rsa.pub file to install from your hard drive'></td>\n";
|
|
print "<td align=center><input type=submit name=button_ul_key value=Upload title='install the key'";
|
|
print "></td>\n";
|
|
print "</tr>\n";
|
|
|
|
print "<tr>\n";
|
|
print "<td>Remove Key</td>\n";
|
|
print "<td><select name=rm_key style='font-family:monospace'>\n";
|
|
selopt("- Select Key -", "default", "default");
|
|
foreach(@keys)
|
|
{
|
|
selopt($_, $_, "default");
|
|
}
|
|
print "</select>\n";
|
|
print "<td align=center><input type=submit name=button_rm_key value=Remove title='remove the selected key'></td>\n";
|
|
print "</tr>\n";
|
|
|
|
print "</table></td></tr>\n";
|
|
|
|
print "<tr><td colspan=3><hr></td></tr>\n";
|
|
|
|
print "<tr><th colspan=3>Support Data</th></tr>\n";
|
|
print "<tr><td colspan=3 align=center><a href=/cgi-bin/supporttool>Download Support Data</a></td></tr>\n";
|
|
|
|
print "<tr><td colspan=3><hr></td></tr>\n";
|
|
|
|
print "</table>\n";
|
|
print "</td></tr>\n";
|
|
print "</table>\n";
|
|
|
|
print "<input type=hidden name=dev value=1>\n" if $parms{dev};
|
|
print "</form>\n";
|
|
print "</center>\n";
|
|
|
|
show_debug_info();
|
|
show_parse_errors();
|
|
|
|
page_footer();
|
|
print "</body>\n";
|
|
print "</html>\n";
|