From 00b1a7ebc15f7ebd597cf6d6a2e6cbcfeccf6c28 Mon Sep 17 00:00:00 2001 From: Scott Ullrich Date: Sat, 24 May 2008 06:38:59 +0000 Subject: [PATCH] Add back auto update support. Discussed-with: cmb --- usr/local/www/system_firmware.php | 34 ++- usr/local/www/system_firmware_auto.php | 271 +++++++++++------ usr/local/www/system_firmware_check.php | 329 ++++++++------------- usr/local/www/system_firmware_settings.php | 105 +++---- 4 files changed, 358 insertions(+), 381 deletions(-) diff --git a/usr/local/www/system_firmware.php b/usr/local/www/system_firmware.php index 5a22cd7250..ea25156bc6 100755 --- a/usr/local/www/system_firmware.php +++ b/usr/local/www/system_firmware.php @@ -31,15 +31,22 @@ $d_isfwfile = 1; require_once("guiconfig.inc"); + +$curcfg = $config['system']['firmware']; + + require_once("xmlrpc_client.inc"); +/* Allow additional execution time 0 = no limit. */ +ini_set('max_execution_time', '3600'); +ini_set('max_input_time', '3600'); + /* if upgrade in progress, alert user */ if(file_exists($d_firmwarelock_path)) { - $pgtitle = "System: Firmware: Manual Update"; + $pgtitle = array("System","Firmware","Manual Update"); include("head.inc"); echo "\n"; include("fbegin.inc"); - echo "

\n"; echo "
\n"; print_info_box("An upgrade is currently in progress.

The firewall will reboot when the operation is complete.

"); echo "
\n"; @@ -61,7 +68,7 @@ if ($_POST && !file_exists($d_firmwarelock_path)) { unset($input_errors); unset($sig_warning); - + if (stristr($_POST['Submit'], "Enable")) $mode = "enable"; else if (stristr($_POST['Submit'], "Disable")) @@ -120,7 +127,10 @@ if ($_POST && !file_exists($d_firmwarelock_path)) { /* fire up the update script in the background */ touch($d_firmwarelock_path); $savemsg = "The firmware is now being updated. The firewall will reboot automatically."; - mwexec_bg("/etc/rc.firmware pfSenseupgrade {$g['upload_path']}/firmware.tgz"); + if(stristr($_FILES['ulfile']['tmp_name'],"bdiff")) + mwexec_bg("/etc/rc.firmware delta_update {$g['upload_path']}/firmware.tgz"); + else + mwexec_bg("/etc/rc.firmware pfSenseupgrade {$g['upload_path']}/firmware.tgz"); } else { $savemsg = "Firmware image missing or other error, please try again."; } @@ -129,13 +139,12 @@ if ($_POST && !file_exists($d_firmwarelock_path)) { } } -$pgtitle = "System: Firmware: Manual Update"; +$pgtitle = array("Diagnostics","Firmware"); include("head.inc"); ?> -

"") print_info_box($fwinfo); ?> @@ -161,8 +170,8 @@ print_info_box($sig_warning); @@ -172,7 +181,7 @@ print_info_box($sig_warning);
- +
Invoke pfSense Manual UpgradeInvoke Manual Upgrade
  @@ -180,11 +189,6 @@ print_info_box($sig_warning); upload" below, then choose the image file (-*.tgz) to be uploaded.
Click "Upgrade firmware" to start the upgrade process.

- - This platform cannot be upgraded. Consider using option 13 from the console. - - - @@ -204,7 +208,7 @@ print_info_box($sig_warning); echo ""; echo ""; echo ""; - echo "

"; + echo "

"; } } ?> diff --git a/usr/local/www/system_firmware_auto.php b/usr/local/www/system_firmware_auto.php index 98e46fb46d..aef4a7127d 100755 --- a/usr/local/www/system_firmware_auto.php +++ b/usr/local/www/system_firmware_auto.php @@ -2,10 +2,10 @@ /* $Id$ */ /* system_firmware_auto.php - part of pfSense (http://www.pfsense.com) - - Copyright (C) 2005 Scott Ullrich and Colin Smith + Copyright (C) 2005 Scott Ullrich + Based originally on system_firmware.php + (C)2003-2004 Manuel Kasper All rights reserved. Redistribution and use in source and binary forms, with or without @@ -28,61 +28,78 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - TODO: - * modify pfSense.com XMLRPC server to return md5 hashes of firmware updates. */ -Header("Location: system_firmware.php"); -exit; +require("guiconfig.inc"); -require_once("guiconfig.inc"); -require_once("xmlrpc.inc"); +$curcfg = $config['system']['firmware']; -$pgtitle = "System: Firmware: Auto Update"; +if(isset($curcfg['alturl']['enable'])) + $updater_url = "{$config['system']['firmware']['alturl']['firmwareurl']}"; +else + $updater_url = $g['update_url']; + +$pgtitle = array("Diagnostics","Firmware","Auto Update"); include("head.inc"); ?> + + + + + -

- - -
+ + + - + + -
-
-
- - - - +
- -
-
/images/misc/progress_bar.gif' width='280' height='23' name='progressbar' id='progressbar'>
-
- - - - -
-
+ + +
+ + + +
+
+ + + + + + + +
+ + + +
+ +
+
+
+
+ + + + +
+
- +
@@ -93,72 +110,134 @@ include("head.inc"); $latest_version) + $needs_system_upgrade = true; + +if($needs_system_upgrade == true) { + update_status("Downloading updates ..."); + $status = download_file_with_progress_bar("{$updater_url}/latest.tgz", "/tmp/latest.tgz"); + $status = download_file_with_progress_bar("{$updater_url}/latest.tgz.sha256", "/tmp/latest.tgz.sha256"); + update_output_window("{$g['product_name']} download complete."); } -$static_output = "Downloading current version information... "; -update_status($static_output); -update_output_window($static_output); +/* launch external upgrade helper */ +$external_upgrade_helper_text = "/etc/rc.firmware pfSenseupgrade "; +if($needs_system_upgrade == true) + $external_upgrade_helper_text .= "/tmp/latest.tgz"; -if(file_exists("/tmp/versioncheck.cache")) { - $versions = unserialize("/tmp/versioncheck.cache"); - if(time() - $versions['cachetime'] > 300) { // Our cached data is stale, get a new copy. - $versions = check_firmware_version($tocheck); - } else { // Our cached data is relatively currently, remove the cachetime label. - unset($versions['cachetime']); +$downloaded_latest_tgz_sha256 = str_replace("\n", "", `sha256 /tmp/latest.tgz | awk '{ print $4 }'`); +$upgrade_latest_tgz_sha256 = str_replace("\n", "", `cat /tmp/latest.tgz.sha256 | awk '{ print $4 }'`); + +$sigchk = 0; + +if(!isset($curcfg['alturl']['enable'])) + $sigchk = verify_digital_signature("/tmp/latest.tgz"); + +if ($sigchk == 1) + $sig_warning = "The digital signature on this image is invalid."; +else if ($sigchk == 2) + $sig_warning = "This image is not digitally signed."; +else if (($sigchk == 3) || ($sigchk == 4)) + $sig_warning = "There has been an error verifying the signature on this image."; + +if (!verify_gzip_file("/tmp/latest.tgz")) { + update_status("The image file is corrupt."); + update_output_window("Update cannot continue"); + unlink("{$g['upload_path']}/latest.tgz"); + require("fend.inc"); + exit; +} + +if ($sigchk) { + update_status($sig_warning); + update_output_window("Update cannot continue"); + unlink("{$g['upload_path']}/latest.tgz"); + require("fend.inc"); + exit; +} + +if($downloaded_latest_tgz_sha256 <> $upgrade_latest_tgz_sha256) { + update_status("Downloading complete but sha256 does not match."); + update_output_window("Auto upgrade aborted. \n\nDownloaded SHA256: $downloaded_latest_tgz_sha256 \n\nNeeded SHA256: $upgrade_latest_tgz_sha256"); +} else { + update_output_window("{$g['product_name']} is now upgrading.\\n\\nThe firewall will reboot once the operation is completed."); + echo "\n"; + exec_rc_script_async("{$external_upgrade_helper_text}"); +} + +/* + Helper functions +*/ + +function download_file_with_progress_bar($url_file, $destination_file) { + global $ch, $fout, $file_size, $downloaded, $counter; + $file_size = 1; + $downloaded = 1; + /* open destination file */ + $fout = fopen($destination_file, "wb"); + + /* + Originally by Author: Keyvan Minoukadeh + Modified by Scott Ullrich to return Content-Length size + */ + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url_file); + curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'read_header'); + curl_setopt($ch, CURLOPT_WRITEFUNCTION, 'read_body'); + curl_setopt($ch, CURLOPT_NOPROGRESS, '1'); + + curl_exec($ch); + fclose($fout); + return 1; + + if ($error = curl_error($ch)) { + return -1; } } -$static_output .= "done.\n"; -update_output_window($static_output); - -foreach($categories as $index => $key) { - $bdiff_errors = array(); - if(is_array($versions[$key][0])) { // Make sure we really need to update this section. - $didupdate = true; - update_status("Found required " . $key . " updates. Downloading..."); - $static_output .= "Downloading " . $key . " updates... "; - update_output_window($static_output); - foreach($versions[$key] as $ver) { // Begin system updates. - foreach($update_types as $type) if(in_array($type, array_keys($ver))) $url_type = $type; - $tofetch = "pfSense-" . ucfirst($url_type) . "-" . ucfirst($key) . "-Update-" . $ver['version'] . ".tgz"; - $static_output_bak = $static_output; - $static_output .= "\n\t" . $ver['version'] . "-" . $ver['name'] . " "; - update_output_window($static_output); - download_file_with_progress_bar("http://www.pfsense.com/updates/" . $tofetch, "/tmp/" . $tofetch); - if($url_type == "binary") { - exec("/etc/rc.firmware delta_update " . "/tmp/" . $tofetch, $bdiff_errors); - if(is_string($bdiff_errors[0])) { - unlink_if_exists("/tmp/" . $tofetch); - $static_output .= "failed!\n"; - update_output_window($static_output); - break; - } - } else { - $tofetch = "pfSense-" . ucfirst($url_type) . "-Update-" . $ver['version'] . ".tgz"; - exec("/etc/rc.firmware pfSenseupgrade " . "/tmp/" . $tofetch); - unlink_if_exists("/tmp/" . $tofetch); - } - $static_output = $static_output_bak . "done.\n"; - } +function read_header($ch, $string) { + global $file_size, $ch, $fout; + $length = strlen($string); + ereg("(Content-Length:) (.*)", $string, $regs); + if($regs[2] <> "") { + $file_size = intval($regs[2]); } + return $length; } -if($didupdate == true) { - update_status("Update finished. Rebooting..."); - exec("/etc/rc.reboot"); -} else { - update_status("No updates required."); +function read_body($ch, $string) { + global $fout, $file_size, $downloaded, $counter, $version, $latest_version, $current_installed_pfsense_version; + $length = strlen($string); + $downloaded += intval($length); + $downloadProgress = round(100 * (1 - $downloaded / $file_size), 0); + $downloadProgress = 100 - $downloadProgress; + $a = $file_size; + $b = $downloaded; + $c = $downloadProgress; + $text = " Auto Update Download Status\\n"; + $text .= "---------------------------------\\n"; + $text .= " Latest Version : {$latest_version}\\n"; + $text .= " Current Version : {$current_installed_pfsense_version}\\n"; + $text .= " File size : {$a}\\n"; + $text .= " Downloaded : {$b}\\n"; + $text .= " Percent : {$c}%\\n"; + $text .= "---------------------------------\\n"; + $counter++; + if($counter > 150) { + update_output_window($text); + update_progress_bar($downloadProgress); + $counter = 0; + } + fwrite($fout, $string); + echo "\n"; + return $length; } -echo "\n"; -?> +?> \ No newline at end of file diff --git a/usr/local/www/system_firmware_check.php b/usr/local/www/system_firmware_check.php index 3563e073d7..903cd79585 100755 --- a/usr/local/www/system_firmware_check.php +++ b/usr/local/www/system_firmware_check.php @@ -1,233 +1,158 @@ . + All rights reserved. - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. - THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. */ -Header("Location: system_firmware.php"); -exit; +$d_isfwfile = 1; +require("guiconfig.inc"); -require_once("guiconfig.inc"); -require_once("xmlrpc.inc"); +$curcfg = $config['system']['firmware']; -if(isset($config['system']['disablefirmwarecheck'])) - Header("Location: system_firmware.php"); - -$versions = check_firmware_version(); -$pgtitle = "System: Firmware: Auto Update"; include("head.inc"); ?> + + + + + + + + -

- - - -
+

System: Firmware: Auto Upgrade

+ + + + + - - -
-
- -
- - - - - - - $version) { - if($key == "current") continue; - $currentver = array_shift(explode('-', $currentvers[$key]['version'])); - if($version == 1) { - $img = "./themes/".$g['theme']."/images/icons/icon_pass.gif"; - $pastlatest = true; - } elseif( strcmp($currentver , $version[count($version) - 1]['version']) ){ - $img = "./themes/".$g['theme']."/images/icons/icon_pass.gif"; - $pastlatest = true; - } else { - $allinstall = true; - $img = "./themes/".$g['theme']."/images/icons/icon_block.gif"; - } -?> - - - - - - - - - - - - - - - -
ActCategoryInstalledCurrent -
- -
- -
-
- - - - - - - -
Needed Updates
-
-
- - - - - - - - - $value) { - if(($key == "current") or ($value == 1)) continue; - if(is_array($value)) { - foreach($value as $version) { - if(!$version['time']) $version['time'] = "Unknown"; - if(!$version['size']) $version['size'] = "Unknown"; - if(!$version['type']) $version['type'] = "Unknown"; - $version['category'] = $key; - $times[$version['time']][] = $version; - } - } - } - } - asort($times); - if(is_array($times)) { - foreach($times as $time) { - foreach($time as $version) { -?> - - - - - - - - + + + + + +
ReleasedCategoryVersionSizeType
- -
+ + + + +
+ +
+ + + + + +
+ + +
+ +
-
-
- +
- - - - -
- - - -
- +
+ + +
+

+

+
+
+ +

+ $latest_version) + $needs_system_upgrade = true; + +if(!$latest_version) { + if(isset($curcfg['alturl']['enable'])) + update_output_window("Could not contact custom update server."); + else + update_output_window("Could not contact {$g['product_name']} update server {$updater_url}."); } else { - print_info_box("Unable to receive version information."); + if($needs_system_upgrade) { + echo "\n"; + update_output_window("A new version is now available. \n\nNew version: {$latest_version}"); + } else { + update_output_window("You are on the latest version."); + } } ?> -

- - + + + + + + + + \ No newline at end of file diff --git a/usr/local/www/system_firmware_settings.php b/usr/local/www/system_firmware_settings.php index 1373b8fc04..4dc457cfa0 100755 --- a/usr/local/www/system_firmware_settings.php +++ b/usr/local/www/system_firmware_settings.php @@ -27,27 +27,18 @@ POSSIBILITY OF SUCH DAMAGE. */ -Header("Location: system_firmware.php"); -exit; - require("guiconfig.inc"); if ($_POST) { - /* input validation */ - if($_POST['firmwareurl'] && !is_string($_POST['firmwareurl'])) { - $input_errors[] = "The base XMLRPC URL must be a string."; - } - if($_POST['firmwarepath'] && !is_string($_POST['firmwarepath'])) { - $input_errors[] = "The XMLRPC path must be a string."; - } if (!$input_errors) { - $config['system']['firmware']['branch'] = $_POST['branch']; if($_POST['alturlenable'] == "yes") { - $config['system']['firmware']['alturl']['enable'] = ""; + $config['system']['firmware']['alturl']['enable'] = true; $config['system']['firmware']['alturl']['firmwareurl'] = $_POST['firmwareurl']; - $config['system']['firmware']['alturl']['firmwarepath'] = $_POST['firmwarepath']; } else { unset($config['system']['firmware']['alturl']['enable']); + unset($config['system']['firmware']['alturl']['firmwareurl']); + unset($config['system']['firmware']['alturl']); + unset($config['system']['firmware']); } write_config(); } @@ -55,34 +46,25 @@ if ($_POST) { $curcfg = $config['system']['firmware']; -$pgtitle = "System: Firmware: Settings"; +$pgtitle = array("System","Firmware","Settings"); include("head.inc"); -?> +exec("fetch -q -o /tmp/manifest \"{$g['update_manifest']}\""); +if(file_exists("/tmp/manifest")) { + $preset_urls_split = split("\n", file_get_contents("/tmp/manifest")); +} +?> +