-#!/usr/bin/perl\r
-#\r
-# IPCop CGI's - backup.cgi: manage import/export of configuration files\r
-#\r
-# This code is distributed under the terms of the GPL\r
-#\r
-# (c) The IPCop Team\r
-# 2005 Franck Bourdonnec, major rewrite\r
-#\r
-# $Id: backup.cgi,v 1.2.2.15 2006/01/29 15:31:49 eoberlander Exp $\r
-#\r
-#\r
-\r
-\r
-# to fully troubleshot your code, uncomment diagnostics, Carp and cluck lines\r
-# use diagnostics; # need to add the file /usr/lib/perl5/5.8.x/pods/perldiag.pod before to work\r
-# next look at /var/log/httpd/error_log , http://www.perl.com/pub/a/2002/05/07/mod_perl.html may help\r
-#use warnings;\r
-use strict;\r
-#use Carp ();\r
-#local $SIG{__WARN__} = \&Carp::cluck;\r
-use File::Copy;\r
-use Sys::Hostname;\r
-\r
-require 'CONFIG_ROOT/general-functions.pl';\r
-require "${General::swroot}/lang.pl";\r
-require "${General::swroot}/header.pl";\r
-\r
-my $errormessage = '';\r
-my $warnmessage = '';\r
-my $setdir = '/home/httpd/html/backup'; # location where sets are stored and imported\r
-my $datafile = hostname() . '.dat'; # file containing data backup\r
-my $datefile = $datafile . '.time'; # and creation date\r
-\r
-# ask if backup crypting key exists\r
-my $tmpkeyfile = "$setdir/key"; # import the backup key\r
-\r
-# Get GUI values\r
-my %settings = ();\r
-&Header::getcgihash(\%settings, {'wantfile' => 1, 'filevar' => 'FH'});\r
-\r
-##\r
-## Backup key management\r
-##\r
-\r
-#\r
-# Export the key. root pw is required to avoid user 'noboby' uses the helper to read it and creates\r
-# fake backup.\r
-#\r
-if ($settings{'ACTION'} eq $Lang::tr{'backup export key'}) {\r
-\r
- my $size = 0;\r
- if ($settings{'PASSWORD1'} ne '' && $settings{'PASSWORD1'} ne $settings{'PASSWORD2'} ){\r
- $errormessage = $Lang::tr{'passwords do not match'}\r
- } else {\r
- my @lines = `/usr/local/bin/ipcopbackup -keycat $settings{'PASSWORD'}`;\r
- # If previous operation succeded and the key need to be crypted, redo operation with pipe to openssl\r
- if (@lines && $settings{'PASSWORD1'}) {\r
- @lines = `/usr/local/bin/ipcopbackup -keycat $settings{'PASSWORD'}|openssl enc -a -e -aes256 -salt -pass pass:$settings{'PASSWORD1'} `;\r
- }\r
- if (@lines) {\r
- use bytes;\r
- foreach (@lines) {$size += length($_)};\r
- print "Pragma: no-cache\n";\r
- print "Cache-control: no-cache\n";\r
- print "Connection: close\n";\r
- print "Content-type: application/octet-stream\n";\r
- print "Content-Disposition: filename=backup.key\n";\r
- print "Content-Length: $size\n\n";\r
- print @lines;\r
- exit (0);\r
- } else {\r
- $errormessage = $Lang::tr{'incorrect password'};\r
- }\r
- } \r
-}\r
-#\r
-# Import the key. Fail if key exists. This avoid creating fake backup.\r
-#\r
-if ($settings{'ACTION'} eq $Lang::tr{'backup import key'}) {\r
- if (ref ($settings{'FH'}) ne 'Fh') {\r
- $errormessage = $Lang::tr{'no cfg upload'};\r
- } else {\r
- if (copy ($settings{'FH'}, $tmpkeyfile) != 1) {\r
- $errormessage = $Lang::tr{'save error'};\r
- } else {\r
- # if a password is given, decrypt the key received in $tmpkeyfile file with it.\r
- # no error is produce if the password is wrong.\r
- if ($settings{'PASSWORD1'}) {\r
- my @lines = `openssl enc -a -d -aes256 -salt -pass pass:$settings{'PASSWORD1'} -in $tmpkeyfile`;\r
- open(FILE,">$tmpkeyfile");\r
- print FILE @lines;\r
- close (FILE);\r
- }\r
- $errormessage = &get_bk_error(system ('/usr/local/bin/ipcopbackup -key import')>>8);\r
- }\r
- }\r
-}\r
-#\r
-# Import the key. Fail if key exists. Key is extracted from a non-encrypted backup (pre 1.4.10)\r
-#\r
-if ($settings{'ACTION'} eq $Lang::tr{'backup extract key'}) {\r
- if (ref ($settings{'FH'}) ne 'Fh') {\r
- $errormessage = $Lang::tr{'no cfg upload'};\r
- } else {\r
- if (copy ($settings{'FH'}, '/tmp/tmptarfile.tgz') != 1) {\r
- $errormessage = $Lang::tr{'save error'};\r
- } else {\r
- system( "tar -C /tmp -xzf /tmp/tmptarfile.tgz */backup/backup.key;\\r
- mv -f /tmp${General::swroot}/backup/backup.key $tmpkeyfile;\\r
- rm -rf /tmp${General::swroot};\\r
- rm /tmp/tmptarfile.tgz");\r
- $errormessage = &get_bk_error(system ('/usr/local/bin/ipcopbackup -key import')>>8);\r
- }\r
- }\r
-}\r
-#\r
-# Create the key. Cannot overwrite existing key to avoid difference with exported (saved) key\r
-#\r
-if ($settings{'ACTION'} eq $Lang::tr{'backup generate key'}) {\r
- $errormessage = &get_bk_error(system('/usr/local/bin/ipcopbackup -key new')>>8);\r
-}\r
-\r
-my $cryptkeymissing = system ('/usr/local/bin/ipcopbackup -key exist')>>8;\r
-\r
-&Header::showhttpheaders();\r
-if ($cryptkeymissing) { #If no key is present, force creation or import\r
- &Header::openpage($Lang::tr{'backup configuration'}, 1, '');\r
- &Header::openbigbox('100%', 'left', '', $errormessage);\r
- if ($errormessage) {\r
- &Header::openbox('100%', 'left', $Lang::tr{'error messages'});\r
- print "<font class='base'>$errormessage </font>";\r
- &Header::closebox();\r
- }\r
- &Header::openbox('100%', 'left', $Lang::tr{'backup key'});\r
- print <<END\r
- <form method = 'post' enctype = 'multipart/form-data'>\r
- <table>\r
- <tr>\r
- <td colspan='2'>\r
- $Lang::tr{'backup explain key'}:\r
- <ul>\r
- <li>$Lang::tr{'backup explain key li1'}\r
- <li>$Lang::tr{'backup explain key li2'}\r
- <li>$Lang::tr{'backup explain key li3'}\r
- </ul>\r
- </td>\r
- </tr><tr>\r
- <td width='15%'></td><td width='20%'></td><td>\r
- <input type = 'submit' name = 'ACTION' value = '$Lang::tr{'backup generate key'}' />\r
- </td>\r
- </tr><tr>\r
- <td align='right'>$Lang::tr{'backup key file'}:</td><td><input type = 'file' name = 'FH' size = '30' value='backup.key' />\r
- </td><td>\r
- <input type = 'submit' name = 'ACTION' value = '$Lang::tr{'backup import key'}' />\r
- </tr><tr>\r
- <td align='right'>$Lang::tr{'backup protect key password'}:<td><input type = 'password' name='PASSWORD1' size='10' />\r
- </td>\r
- </tr><tr>\r
- <td align='right'>$Lang::tr{'backup clear archive'}:</td><td><input type = 'file' name = 'FH' size = '30' value='your-ipcop.tar.gz' />\r
- </td><td>\r
- <input type = 'submit' name = 'ACTION' value = '$Lang::tr{'backup extract key'}' />\r
- </td>\r
- </tr>\r
- </table>\r
- $Lang::tr{'notes'}:\r
- <ul>\r
- <li>$Lang::tr{'backup explain key no1'}\r
- <li>$Lang::tr{'backup explain key no2'}\r
- </ul>\r
- </form>\r
-END\r
-;\r
- &floppybox();\r
- &Header::closebox();\r
- &Header::closebigbox();\r
- &Header::closepage();\r
- exit (0);\r
-}\r
-\r
-##\r
-## Sets management (create/delete/import/restore)\r
-##\r
-\r
-erase_files ($setdir); #clean up\r
-\r
-#\r
-# create new archive set\r
-#\r
-if ($settings{'ACTION'} eq $Lang::tr{'create'}) {\r
- $errormessage = &get_bk_error(system('/usr/local/bin/ipcopbkcfg > /dev/null')>>8);\r
- &import_set (" ".&Header::cleanhtml ($settings{'COMMENT'})) if (!$errormessage);\r
-}\r
-#\r
-# delete a backup set\r
-#\r
-if ($settings{'ACTION'} eq $Lang::tr{'remove'}) {\r
- erase_files (&Header::cleanhtml ($settings{'KEY'})); # remove files\r
- rmdir($settings{'KEY'}); # remove directory\r
-}\r
-#\r
-# import an archive set\r
-#\r
-if ($settings{'ACTION'} eq $Lang::tr{'import'}) {\r
- if (ref ($settings{'FH'}) ne 'Fh') {\r
- $errormessage = $Lang::tr{'no cfg upload'};\r
- } else {\r
- if (!copy ($settings{'FH'}, "$setdir/$datafile")) {\r
- $errormessage = $Lang::tr{'save error'};\r
- } else {\r
- &import_set (' (imported)');\r
- }\r
- }\r
-}\r
-#\r
-# restore an archive\r
-#\r
-if ($settings{'ACTION'} eq $Lang::tr{'restore'}) {\r
- if ($settings{'AreYouSure'} eq 'yes') {\r
- if (!$cryptkeymissing) { # if keyfile exists\r
- if (-e "$settings{'KEY'}/$datafile"){ # encrypted dat is required\r
- copy_files($settings{'KEY'}, $setdir); # to working dir\r
- $errormessage = get_rs_error(system("/usr/local/bin/ipcoprscfg" \r
- . ($settings{'RESTOREHW'} eq 'on' ? ' --hardware' : '') \r
- . ' >/dev/null')>>8);\r
- if (!$errormessage) {\r
- # restored ok, recommend restarting system\r
- $warnmessage = $Lang::tr{'cfg restart'};\r
- }\r
- erase_files ($setdir); #clean up\r
- } else {\r
- $errormessage = $Lang::tr{'missing dat'}."$settings{'KEY'}/$datafile";\r
- }\r
- } else { # if keyfile does not exist\r
- $errormessage = $Lang::tr{'backup missing key'};\r
- }\r
- \r
- } else { # not AreYouSure=yes\r
- &Header::openpage($Lang::tr{'backup configuration'}, 1, '');\r
- &Header::openbigbox('100%', 'left');\r
- &Header::openbox('100%', 'left', $Lang::tr{'are you sure'});\r
- print <<END\r
-<form method = 'post'>\r
- <input type = 'hidden' name = 'KEY' value ='$settings{'KEY'}' /> \r
- <input type = 'hidden' name = 'AreYouSure' value ='yes' />\r
- <table align = 'center'>\r
- <tr>\r
- <td align = 'center'>\r
- <input type = 'submit' name = 'ACTION' value = '$Lang::tr{'restore'}' />\r
- </td><td>\r
- <input type = 'submit' name = 'ACTION' value = '$Lang::tr{'cancel'}' />\r
- </td>\r
- </tr><tr>\r
- <td>\r
- $Lang::tr{'restore hardware settings'}: <input type = 'checkbox' name = 'RESTOREHW'>\r
- </td>\r
- </tr>\r
-</table>\r
-</form>\r
-END\r
-;\r
- &Header::closebox();\r
- &Header::closebigbox();\r
- &Header::closepage();\r
- exit (0);\r
- }\r
-}\r
-##\r
-## Media management\r
-##\r
-#\r
-# now build the list of removable device\r
-#\r
-\r
-# Read partitions sizes registered with the system\r
-my %partitions;\r
-foreach my $li (`/usr/local/bin/ipcopbackup -proc partitions`) { # use suid helper...\r
- # partitions{'sda1'} = 128M if /major minor blocks name/\r
- $partitions{$4} = &kmgt($3*1024,4) if ($li =~ /(\d+) +(\d+) +(\d+) +(.*)/);\r
-}\r
-\r
-# Search usb-storage scsi device\r
-my %medias;\r
- \r
-foreach (`/usr/local/bin/ipcopbackup -glob '/proc/scsi/usb-storage*/*'`) {# use suid helper...\r
- my $m;\r
- foreach ( `cat $_` ) { # list each line of information for the device:\r
-# Host scsi0: usb-storage\r
-# Vendor: SWISSBIT\r
-# Product: Black Silver\r
-# Serial Number: D0ED423A4F84A31E\r
-# Protocol: Transparent SCSI\r
-# Transport: Bulk\r
-# GUID: 13706828d0ed423a4f84a31e\r
-# Attached: Yes\r
- \r
- chomp;\r
- my ($key,$val) = split(': ',$_,2);\r
- $key =~ s/^ *//; # remove front space\r
-\r
- # convert 'scsi?' key to sda, sdb,... and use it as a %medias keyhash\r
- if ($key =~ /Host scsi(.)/) {\r
- $val = $m = 'sd' . chr(97+$1);\r
- $key = 'Host';\r
- }\r
- $medias{$m}{$key} = $val; # save data\r
- }\r
-}\r
-\r
-#\r
-# Switch mounted media\r
-#\r
-if ($settings{'ACTION'} eq $Lang::tr{'mount'})\r
-{\r
- # Find what is really mounted under backup. Can be local hard disk or any removable media\r
- my $mounted = &findmounted();\r
- #umount previous, even if same device already mouted.\r
- system ("/usr/local/bin/ipcopbackup -U $mounted") if ($mounted ne $Lang::tr{'local hard disk'});\r
- $errormessage = `/usr/local/bin/ipcopbackup -M $settings{'SELECT'}` if (grep (/$settings{'SELECT'}/,%partitions));\r
-}\r
-#\r
-# Compute a full description of device\r
-#\r
-my $mounted = &findmounted();\r
-my $media_des = $mounted; # Description\r
-if ($mounted ne $Lang::tr{'local hard disk'}) {\r
- $_ = $mounted; # sda1 => sda\r
- tr/0-9//d;\r
- $media_des = "$medias{$_}{'Product'} ($media_des, $partitions{$mounted})";\r
-}\r
-&Header::openpage($Lang::tr{'backup configuration'}, 1, '');\r
-&Header::openbigbox('100%', 'left', '', $errormessage);\r
-\r
-if ($errormessage) {\r
- &Header::openbox('100%', 'left', $Lang::tr{'error messages'});\r
- print "<font class='base'>$errormessage </font>";\r
- &Header::closebox();\r
-}\r
-\r
-$warnmessage = "<font color=${Header::colourred}><b>$Lang::tr{'capswarning'}</b></font>: $warnmessage <p>" if ($warnmessage);\r
-\r
-&Header::openbox('100%', 'left', $Lang::tr{'backup configuration'});\r
-\r
-#Divide the window in two : left and right\r
-print <<END\r
- <table width = '100%' >\r
- <tr>\r
- <th width = '50%'>$Lang::tr{'current media'}:<font color=${Header::colourred}><b>$media_des</b></font></th>\r
- <th width = '3%'></th>\r
- <th>$Lang::tr{'choose media'}</th>\r
- </tr>\r
-END\r
-;\r
-\r
-# Left part of window\r
-print <<END\r
- <tr><td>\r
- <ul>\r
- <li>$Lang::tr{'backup sets'}:\r
- <table width = '80%' border='0'>\r
- <tr>\r
- <th class = 'boldbase' align = 'center'>$Lang::tr{'name'}</th>\r
- <th class = 'boldbase' align = 'center' colspan = '3'>$Lang::tr{'action'}</th>\r
- </tr>\r
-END\r
-;\r
-\r
-# get list of available sets by globbing directories under $setdir\r
-# External device (usk key) are mounted in $setdir. -R permits finding sets in hierarchy.\r
-my $i = 0;\r
-foreach my $set (`ls -Rt1 $setdir`) {\r
- chop ($set); #remove ':' & newline from line\r
- chop ($set);\r
- if (-d $set && ($set =~ m!/.+/\d{8}_\d{6}! ) ) { # filter out things not sets !\r
- if ($i++ % 2) {\r
- print "<tr bgcolor = '$Header::table2colour'>";\r
- } else {\r
- print "<tr bgcolor = '$Header::table1colour'>";\r
- }\r
- my $settime = read_timefile( "$set/$datefile", "$set/$datafile" );\r
- my $name = substr ($set,length($setdir)+1);\r
- print<<EOF\r
-<td>\r
- $settime\r
-</td>\r
-\r
-<td align = 'center'>\r
-<form method = 'post'>\r
-<input type = 'hidden' name = 'ACTION' value ='$Lang::tr{'restore'}' />\r
-<input type = 'image' name = '$Lang::tr{'restore'}' src = '/images/reload.gif' alt = '$Lang::tr{'restore'}' title = '$Lang::tr{'restore'}' />\r
-<input type = 'hidden' name = 'KEY' value = '$set' />\r
-</form>\r
-</td>\r
-\r
-<td align = 'center'>\r
-<a href = '/backup/$name/$datafile'><img src = '/images/floppy.gif' title = '$Lang::tr{'export'}'></a>\r
-</td>\r
-\r
-<td align = 'center'>\r
-<form method = 'post'>\r
-<input type = 'hidden' name = 'ACTION' value = '$Lang::tr{'remove'}' />\r
-<input type = 'image' name = '$Lang::tr{'remove'}' src = '/images/delete.gif' alt = '$Lang::tr{'remove'}' title = '$Lang::tr{'remove'}' border = '0' />\r
-<input type = 'hidden' name = 'KEY' value = '$set' />\r
-</form>\r
-</td>\r
-</tr>\r
-EOF\r
-;\r
- }\r
-}\r
-print "</table>" . ($i ? "<br>" : "$Lang::tr{'empty'}!<hr /><br>");\r
-print <<EOF\r
-$warnmessage\r
-<form method = 'post'>\r
- <li>$Lang::tr{'backup configuration'}<br>\r
- $Lang::tr{'description'}:<input type = 'text' name = 'COMMENT' size='30' />\r
- <input type = 'submit' name = 'ACTION' value = '$Lang::tr{'create'}' />\r
-</form><p>\r
-<form method = 'post' enctype = 'multipart/form-data'>\r
- <li>$Lang::tr{'backup import dat file'}:<br>\r
- <input type = 'file' name = 'FH' size = '20' />\r
- <input type = 'submit' name = 'ACTION' value = '$Lang::tr{'import'}' />\r
-</form>\r
-</ul>\r
-EOF\r
-;\r
-\r
-print "</td><td></td><td valign='top'>"; # Start right part (devices selection)\r
-print $Lang::tr{'backup media info'};\r
-\r
-print "<form method = 'post'>";\r
-print "<table width = '100%'><tr><td>";\r
-my $nodev = 1; # nothing present\r
-foreach my $media (keys %medias) {\r
- if ( $medias{$media}{'Attached'} eq 'Yes') { # device is attached to USB bus ?\r
- $nodev = 0; # at least one device present\r
- my $checked = $medias{$media}{'Host'} eq $mounted ? "checked='checked'" : '';\r
- print "<input type='radio' name = 'SELECT' value = '$medias{$media}{'Host'}' $checked />";\r
- print "<b>$medias{$media}{'Product'}</b><br>";\r
- # list attached partitions to this media\r
- foreach my $part (sort (keys (%partitions))) {\r
- if ($part =~ /$medias{$media}{'Host'}./) {\r
- my $checked = $part eq $mounted ? "checked='checked'" : '';\r
- print " <input type='radio' name = 'SELECT' value = '$part' $checked />$part ($partitions{$part})<br>";\r
- }\r
- }\r
- }\r
-}\r
-if ($nodev) {\r
- print "<br>$Lang::tr{'insert removable device'}";\r
- print "</td><td>";\r
- print "<br><input type = 'submit' name = 'ACTION' value = '$Lang::tr{'done'}' />";\r
-} else {\r
- #Add an entry for the local disk\r
- my $checked = $Lang::tr{'local hard disk'} eq $mounted ? "checked='checked'" : '';\r
- print "<input type = 'radio' name = 'SELECT' value = '$Lang::tr{'local hard disk'}' $checked />";\r
- print "<b>$Lang::tr{'local hard disk'}</b>";\r
- print "</td><td>";\r
- print "<br><input type = 'submit' name = 'ACTION' value = '$Lang::tr{'mount'}' />";\r
-}\r
-print "</tr></table>";\r
-print "</form>";\r
-#\r
-#Backup key\r
-#\r
-print<<EOF\r
- <hr />\r
-<form method='post'>\r
- <b>$Lang::tr{'backup key'}</b><br>\r
- $Lang::tr{'backup key info'}<br>\r
- <table><tr>\r
- <td align= 'right'>$Lang::tr{'root user password'}:\r
- <td align='left'><input type = 'password' name='PASSWORD' />\r
- <input type = 'submit' name = 'ACTION' value = '$Lang::tr{'backup export key'}' />\r
- </tr><tr>\r
- <td align='right'>$Lang::tr{'backup protect key password'}:\r
- <td align='left'><input type = 'password' name='PASSWORD1' size='10' />\r
- </tr><tr>\r
- <td align='right'>$Lang::tr{'again'}\r
- <td align='left'><input type = 'password' name='PASSWORD2' size='10'/>\r
- </tr></table>\r
-</form>\r
-\r
-EOF\r
-;\r
-# End of right table\r
-print "</td></tr></table>";\r
-\r
-&floppybox();\r
-\r
-&Header::closebox();\r
-&Header::closebigbox();\r
-&Header::closepage();\r
-\r
-sub floppybox {\r
- print <<END\r
-<hr />\r
-<form method = 'post'>\r
-<table width='100%'>\r
-<tr>\r
- <td>\r
- <b>$Lang::tr{'backup to floppy'}</b>\r
- </td>\r
-</tr>\r
-<tr>\r
- <td width='50%'>\r
- $Lang::tr{'insert floppy'}\r
- </td>\r
- <td align='center'> \r
- <input type='submit' name='ACTION' value='$Lang::tr{'backup to floppy'}' />\r
- </td> \r
-</tr>\r
-</table>\r
-</form>\r
-END\r
-;\r
- print "<b>$Lang::tr{'alt information'}</b><pre>" .\r
- `/usr/local/bin/ipcopbackup -savecfg floppy` .\r
- ' </pre>' if ($settings{'ACTION'} eq $Lang::tr{'backup to floppy'} );\r
-}\r
-\r
-# Return device name of what is mounted under 'backup'\r
-sub findmounted() {\r
- my $mounted = `mount|grep ' /home/httpd/html/backup '`;\r
- if ($mounted) { # extract device name\r
- $mounted =~ m!^/dev/(.*) on!; # device on mountmoint options\r
- return $1; \r
- } else { # it's the normal subdir\r
- return $Lang::tr{'local hard disk'};\r
- }\r
-}\r
-# read and return a date/time string from a time file\r
-sub read_timefile() {\r
- my $fname = shift; # name of file to read from\r
- my $fname2 = shift; # if first file doesn't exist, get date of this file\r
-\r
- my $dt;\r
- if (defined(open(FH, "<$fname"))) {\r
- $dt = <FH>;\r
- chomp $dt;\r
- close(FH);\r
- } else {\r
- $dt = &get_fdate($fname2); # get file date/time\r
- write_timefile($fname, $dt); # write to expected time file\r
- }\r
- return $dt;\r
-}\r
-# write a date/time string to a time file\r
-sub write_timefile() {\r
- my $fname = shift; # name of file to write to\r
- my $dt = shift; # date/time string to write\r
-\r
- if (open(FH, ">$fname")) {\r
- print FH "$dt\n";\r
- close(FH);\r
- } \r
-}\r
-# move a dat file without time stamp to subdir\r
-sub import_set() {\r
- my $dt = get_fdate("$setdir/$datafile") . shift;\r
- &write_timefile("$setdir/$datefile", $dt);\r
-\r
- # create set directory\r
- my $setname = "$setdir/" . get_ddate("$setdir/$datafile");\r
- mkdir($setname);\r
-\r
- # move files to the new set directory\r
- copy_files($setdir, $setname);\r
- erase_files ($setdir);\r
-}\r
-\r
-# get date/time string from file\r
-sub get_fdate() {\r
- my $fname = shift;\r
- open(DT, "/bin/date -r $fname|");\r
- my $dt = <DT>;\r
- close(DT);\r
- chomp $dt;\r
- $dt =~ s/\s+/ /g; # remove duplicate spaces\r
- return $dt;\r
-}\r
-# get date/time string from file for use as directory name\r
-sub get_ddate() {\r
- my $fname = shift;\r
- open(DT, "/bin/date -r $fname +%Y%m%d_%H%M%S|");\r
- my $dt = <DT>;\r
- close(DT);\r
- chomp $dt;\r
- return $dt;\r
-}\r
-# copy archive files from source directory to destination directory\r
-sub copy_files() {\r
- my $src_dir = shift;\r
- my $dest_dir = shift;\r
- map (copy ("$src_dir/$_", "$dest_dir/$_"), ($datafile, $datefile) );\r
-}\r
-# erase set files\r
-sub erase_files() {\r
- my $src_dir = shift;\r
- map (unlink ("$src_dir/$_"), ($datafile, $datefile));\r
-}\r
-# get backup error text\r
-sub get_bk_error() {\r
- my $exit_code = shift || return '';\r
- if ($exit_code == 0) {\r
- return '';\r
- } elsif ($exit_code == 2) {\r
- return $Lang::tr{'err bk 2 key'};\r
- } elsif ($exit_code == 3) {\r
- return $Lang::tr{'err bk 3 tar'};\r
- } elsif ($exit_code == 4) {\r
- return $Lang::tr{'err bk 4 gz'};\r
- } elsif ($exit_code == 5) {\r
- return $Lang::tr{'err bk 5 encrypt'};\r
- } else {\r
- return $Lang::tr{'err bk 1'};\r
- }\r
-}\r
-# show any restore errors\r
-sub get_rs_error() {\r
- \r
- my $exit_code = shift || return '';\r
- if ($exit_code == 0) {\r
- return '';\r
- } elsif ($exit_code == 6) {\r
- return $Lang::tr{'err rs 6 decrypt'};\r
- } elsif ($exit_code == 7) {\r
- return $Lang::tr{'err rs 7 untartst'};\r
- } elsif ($exit_code == 8) {\r
- return $Lang::tr{'err rs 8 untar'};\r
- } elsif ($exit_code == 9) {\r
- return $Lang::tr{'missing dat'};\r
- } else {\r
- return $Lang::tr{'err rs 1'}."($exit_code)";\r
- }\r
-}\r
-sub kmgt {\r
- my ($value,$length,$opt_U) = @_;\r
- if ( $value > 10**( $length + 8 ) or $opt_U eq 'T' ) {\r
- return sprintf( "%d%s", int( ( $value / 1024**4 ) + .5 ), 'T' );\r
- } elsif ( $value > 10**( $length + 5 ) or $opt_U eq 'G' ) {\r
- return sprintf( "%d%s", int( ( $value / 1024**3 ) + .5 ), 'G' );\r
- } elsif ( $value > 10**( $length + 2 ) or $opt_U eq 'M' ) {\r
- return sprintf( "%d%s", int( ( $value / 1024**2 ) + .5 ), 'M' );\r
- } elsif ( $value > 10**($length) or $opt_U eq 'K' ) {\r
- return sprintf( "%d%s", int( ( $value / 1024 ) + .5 ), 'K' );\r
- } else {\r
- return $value;\r
- }\r
-}\r
-\r
-1;\r
+#!/usr/bin/perl
+###############################################################################
+# #
+# IPFire.org - A linux based firewall #
+# Copyright (C) 2007 Michael Tremer & Christian Schmidt #
+# #
+# 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, either version 3 of the License, or #
+# (at your option) any later version. #
+# #
+# 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/>. #
+# #
+###############################################################################
+
+use strict;
+# enable only the following on debugging purpose
+#use warnings;
+#use CGI::Carp 'fatalsToBrowser';
+use File::Copy;
+
+require '/var/ipfire/general-functions.pl';
+require "${General::swroot}/lang.pl";
+require "${General::swroot}/header.pl";
+
+my %color = ();
+my %mainsettings = ();
+my %cgiparams=();
+my %checked = ();
+my $message = "";
+my $errormessage = "";
+
+$a = new CGI;
+
+&General::readhash("${General::swroot}/main/settings", \%mainsettings);
+&General::readhash("/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", \%color);
+
+$cgiparams{'ACTION'} = '';
+$cgiparams{'FILE'} = '';
+$cgiparams{'UPLOAD'} = '';
+$cgiparams{'BACKUPLOGS'} = '';
+
+&Header::getcgihash(\%cgiparams);
+
+############################################################################################################################
+################################################ Workaround for Directories ################################################
+
+system("/usr/local/bin/backupctrl makedirs >/dev/null 2>&1 ") unless ( -e '/var/ipfire/backup/addons/backup') ;
+
+############################################################################################################################
+############################################## System calls ohne Http Header ###############################################
+
+# Replace slashes from filename
+$cgiparams{'FILE'} =~ s/\///;
+
+if ( $cgiparams{'ACTION'} eq "download" )
+{
+ open(DLFILE, "</var/ipfire/backup/$cgiparams{'FILE'}") or die "Unable to open $cgiparams{'FILE'}: $!";
+ my @fileholder = <DLFILE>;
+ print "Content-Type:application/x-download\n";
+ print "Content-Disposition:attachment;filename=$cgiparams{'FILE'}\n\n";
+ print @fileholder;
+ exit (0);
+}
+if ( $cgiparams{'ACTION'} eq "downloadiso" )
+{
+ open(DLFILE, "</var/tmp/backupiso/$cgiparams{'FILE'}") or die "Unable to open $cgiparams{'FILE'}: $!";
+ my @fileholder = <DLFILE>;
+ print "Content-Type:application/x-download\n";
+ print "Content-Disposition:attachment;filename=$cgiparams{'FILE'}\n\n";
+ print @fileholder;
+ exit (0);
+}
+if ( $cgiparams{'ACTION'} eq "downloadaddon" )
+{
+ open(DLFILE, "</var/ipfire/backup/addons/backup/$cgiparams{'FILE'}") or die "Unable to open $cgiparams{'FILE'}: $!";
+ my @fileholder = <DLFILE>;
+ print "Content-Type:application/x-download\n";
+ print "Content-Disposition:attachment;filename=$cgiparams{'FILE'}\n\n";
+ print @fileholder;
+ exit (0);
+}
+elsif ( $cgiparams{'ACTION'} eq "restore" )
+{
+ my $upload = $a->param("UPLOAD");
+ open UPLOADFILE, ">/tmp/restore.ipf";
+ binmode $upload;
+ while ( <$upload> ) {
+ print UPLOADFILE;
+ }
+ close UPLOADFILE;
+ system("/usr/local/bin/backupctrl restore >/dev/null 2>&1");
+}
+elsif ( $cgiparams{'ACTION'} eq "restoreaddon" )
+{
+ chomp($cgiparams{'UPLOAD'});
+ # we need to fix cause IE7 gives the full path and FF only the filename
+ my @temp = split(/\\/,$cgiparams{'UPLOAD'});
+ my $upload = $a->param("UPLOAD");
+ open UPLOADFILE, ">/tmp/".$temp[$#temp];
+ binmode $upload;
+ while ( <$upload> ) {
+ print UPLOADFILE;
+ }
+ close UPLOADFILE;
+ system("/usr/local/bin/backupctrl restoreaddon ".$temp[$#temp]." >/dev/null 2>&1");
+}
+
+&Header::showhttpheaders();
+
+sub refreshpage{&Header::openbox( 'Waiting', 1, "<meta http-equiv='refresh' content='1;'>" );print "<center><img src='/images/clock.gif' alt='' /><br/><font color='red'>$Lang::tr{'pagerefresh'}</font></center>";&Header::closebox();}
+
+&Header::openpage($Lang::tr{'backup'}, 1, "");
+&Header::openbigbox('100%', 'left', '', $errormessage);
+
+############################################################################################################################
+################################################### Default System calls ###################################################
+
+if ( $cgiparams{'ACTION'} eq "backup" )
+{
+ if ( $cgiparams{'BACKUPLOGS'} eq "include" ) {
+ system("/usr/local/bin/backupctrl include >/dev/null 2>&1");
+ } elsif ( $cgiparams{'BACKUPLOGS'} eq "exclude" ) {
+ system("/usr/local/bin/backupctrl exclude >/dev/null 2>&1");
+ } elsif ( $cgiparams{'BACKUPLOGS'} eq "iso" ) {
+ system("/usr/local/bin/backupctrl iso >/dev/null 2>&1");
+ }
+}
+if ( $cgiparams{'ACTION'} eq "addonbackup" )
+{
+ system("/usr/local/bin/backupctrl addonbackup $cgiparams{'ADDON'} >/dev/null 2>&1");
+}
+elsif ( $cgiparams{'ACTION'} eq "delete" )
+{
+ system("/usr/local/bin/backupctrl $cgiparams{'FILE'} >/dev/null 2>&1");
+}
+
+############################################################################################################################
+############################################ Backups des Systems erstellen #################################################
+
+if ( $message ne "" ){
+ &Header::openbox('100%','left',$Lang::tr{'error messages'});
+ print "<font color='red'>$message</font>\n";
+ &Header::closebox();
+}
+
+my @backups = `cd /var/ipfire/backup/ && ls *.ipf 2>/dev/null`;
+my @backupisos = `cd /var/tmp/backupiso/ && ls *.iso 2>/dev/null`;
+
+&Header::openbox('100%', 'center', $Lang::tr{'backup'});
+
+print <<END
+<form method='post' action='$ENV{'SCRIPT_NAME'}'>
+<table width='95%' cellspacing='0'>
+<tr>
+ <td align='left' width='40%'>$Lang::tr{'logs'}</td>
+ <td align='left'>
+ <input type='radio' name='BACKUPLOGS' value='include'/> $Lang::tr{'include logfiles'}<br/>
+ <input type='radio' name='BACKUPLOGS' value='exclude' checked='checked'/> $Lang::tr{'exclude logfiles'}<br/>
+ <input type='radio' name='BACKUPLOGS' value='iso' /> $Lang::tr{'generate iso'}
+ </td>
+</tr>
+<tr><td align='center' colspan='2'>
+ <input type='hidden' name='ACTION' value='backup' />
+ <input type='image' alt='$Lang::tr{'backup'}' title='$Lang::tr{'backup'}' src='/images/document-save.png' />
+</td></tr>
+</table>
+</form>
+END
+;
+&Header::closebox();
+
+############################################################################################################################
+############################################ Backups des Systems downloaden ################################################
+
+&Header::openbox('100%', 'center', $Lang::tr{'backups'});
+
+print <<END
+<table width='95%' cellspacing='0'>
+END
+;
+foreach (@backups){
+chomp($_);
+my $Datei = "/var/ipfire/backup/".$_;
+my @Info = stat($Datei);
+my $Size = $Info[7] / 1024 / 1024;
+$Size = sprintf("%0.2f", $Size);
+print "<tr><td align='center'>$Lang::tr{'backup from'} $_ $Lang::tr{'size'} $Size MB</td><td width='5'><form method='post' action='$ENV{'SCRIPT_NAME'}'><input type='hidden' name='ACTION' value='download' /><input type='hidden' name='FILE' value='$_' /><input type='image' alt='$Lang::tr{'download'}' title='$Lang::tr{'download'}' src='/images/package-x-generic.png' /></form></td>";
+print "<td width='5'><form method='post' action='$ENV{'SCRIPT_NAME'}'><input type='hidden' name='ACTION' value='delete' /><input type='hidden' name='FILE' value='$_' /><input type='image' alt='$Lang::tr{'delete'}' title='$Lang::tr{'delete'}' src='/images/user-trash.png' /></form></td></tr>";
+}
+foreach (@backupisos){
+chomp($_);
+my $Datei = "/var/tmp/backupiso/".$_;
+my @Info = stat($Datei);
+my $Size = $Info[7] / 1024 / 1024;
+$Size = sprintf("%0.2f", $Size);
+print "<tr><td align='center'>$Lang::tr{'backup from'} $_ $Lang::tr{'size'} $Size MB</td><td width='5'><form method='post' action='$ENV{'SCRIPT_NAME'}'><input type='hidden' name='ACTION' value='downloadiso' /><input type='hidden' name='FILE' value='$_' /><input type='image' alt='$Lang::tr{'download'}' title='$Lang::tr{'download'}' src='/images/package-x-generic.png' /></form></td>";
+print "<td width='5'><form method='post' action='$ENV{'SCRIPT_NAME'}'><input type='hidden' name='ACTION' value='delete' /><input type='hidden' name='FILE' value='$_' /><input type='image' alt='$Lang::tr{'delete'}' title='$Lang::tr{'delete'}' src='/images/user-trash.png' /></form></td></tr>";
+}
+print <<END
+</table>
+END
+;
+&Header::closebox();
+
+############################################################################################################################
+############################################# Backups von Addons erstellen #################################################
+
+&Header::openbox('100%', 'center', 'addons');
+
+my @addonincluds = `ls /var/ipfire/backup/addons/includes/ 2>/dev/null`;
+my @addons = `ls /var/ipfire/backup/addons/backup/ 2>/dev/null`;
+my %addons;
+
+foreach (@addons){
+ my $addon=substr($_,0,length($_)-5);
+ $addons{$addon}='';
+}
+
+print "<table width='95%' cellspacing='0'>";
+foreach (@addonincluds){
+chomp($_);
+delete $addons{$_};
+my $Datei = "/var/ipfire/backup/addons/backup/".$_.".ipf";
+my @Info = stat($Datei);
+my $Size = $Info[7] / 1024;
+
+if ( -e $Datei ){
+ if ($Size < 1) {
+ $Size = sprintf("%.2f", $Size);
+ print "<tr><td align='center'>$Lang::tr{'backup from'} $_ $Lang::tr{'size'} $Size KB $Lang::tr{'date'} ".localtime($Info[9])."</td>";
+ } else {
+ $Size = sprintf("%2d", $Size);
+ print "<tr><td align='center'>$Lang::tr{'backup from'} $_ $Lang::tr{'size'} $Size KB $Lang::tr{'date'} ".localtime($Info[9])."</td>";
+
+ }
+
+print <<END
+ <td align='right' width='5'>
+ <form method='post' action='$ENV{'SCRIPT_NAME'}'>
+ <input type='hidden' name='ACTION' value='downloadaddon' />
+ <input type='hidden' name='FILE' value='$_.ipf' />
+ <input type='image' alt='$Lang::tr{'download'}' title='$Lang::tr{'download'}' src='/images/package-x-generic.png' />
+ </form>
+ </td>
+ <td align='right' width='5'>
+ <form method='post' action='$ENV{'SCRIPT_NAME'}'>
+ <input type='hidden' name='ACTION' value='delete' />
+ <input type='hidden' name='FILE' value='addons/backup/$_.ipf' />
+ <input type='image' alt='$Lang::tr{'delete'}' title='$Lang::tr{'delete'}' src='/images/user-trash.png' />
+ </form>
+ </td>
+END
+;
+}
+else{
+ print "<tr><td align='center'>$Lang::tr{'backup from'} $_ </td><td width='5' align='right'></td><td width='5' align='right'></td>";
+}
+print <<END
+ <td align='right' width='5'>
+ <form method='post' action='$ENV{'SCRIPT_NAME'}'>
+ <input type='hidden' name='ACTION' value='addonbackup' />
+ <input type='hidden' name='ADDON' value='$_' />
+ <input type='image' alt='$Lang::tr{'backup'}' title='$Lang::tr{'backup'}' src='/images/document-save.png' />
+ </form>
+ </td></tr>
+END
+;
+}
+foreach (keys(%addons)){
+chomp($_);
+my $Datei = "/var/ipfire/backup/addons/backup/".$_.".ipf";
+my @Info = stat($Datei);
+my $Size = $Info[7] / 1024;
+$Size = sprintf("%2d", $Size);
+print "<tr><td align='center'>$Lang::tr{'backup from'} $_ $Lang::tr{'size'} $Size KB $Lang::tr{'date'} ".localtime($Info[9])."</td>";
+print <<END
+ <td align='right' width='5'>
+ <form method='post' action='$ENV{'SCRIPT_NAME'}'>
+ <input type='hidden' name='ACTION' value='downloadaddon' />
+ <input type='hidden' name='FILE' value='$_.ipf' />
+ <input type='image' alt='$Lang::tr{'download'}' title='$Lang::tr{'download'}' src='/images/package-x-generic.png' />
+ </form>
+ </td>
+ <td align='right' width='5'>
+ <form method='post' action='$ENV{'SCRIPT_NAME'}'>
+ <input type='hidden' name='ACTION' value='delete' />
+ <input type='hidden' name='FILE' value='addons//backup/$_.ipf' />
+ <input type='image' alt='$Lang::tr{'delete'}' title='$Lang::tr{'delete'}' src='/images/user-trash.png' />
+ </form>
+ </td>
+ <td align='right' width='5'></td></tr>
+END
+;
+}
+
+print "</table>";
+&Header::closebox();
+
+############################################################################################################################
+####################################### Backups des Systems wiederherstellen ###############################################
+
+&Header::openbox('100%', 'center', $Lang::tr{'restore'});
+
+print <<END
+<table width='95%' cellspacing='0'>
+<tr><td align='center' colspan='2'><font color='red'><br />$Lang::tr{'backupwarning'}</font><br /><br /></td></tr>
+<tr><td align='left'>$Lang::tr{'backup'}</td><td align='left'><form method='post' enctype='multipart/form-data' action='$ENV{'SCRIPT_NAME'}'><input type="file" size='50' name="UPLOAD" /><input type='hidden' name='ACTION' value='restore' /><input type='hidden' name='FILE' /><input type='image' alt='$Lang::tr{'restore'}' title='$Lang::tr{'restore'}' src='/images/media-floppy.png' /></form></td></tr>
+<tr><td align='left'>$Lang::tr{'backupaddon'}</td><td align='left'><form method='post' enctype='multipart/form-data' action='$ENV{'SCRIPT_NAME'}'><input type="file" size='50' name="UPLOAD" /><input type='hidden' name='ACTION' value='restoreaddon' /><input type='hidden' name='FILE' /><input type='image' alt='$Lang::tr{'restore'}' title='$Lang::tr{'restore'}' src='/images/media-floppy.png' /></form></td></tr>
+</table>
+END
+;
+&Header::closebox();
+&Header::closebigbox();
+&Header::closepage();