From da55e467dde94534c6ac83cee329d9800b07467c Mon Sep 17 00:00:00 2001 From: Scott Ullrich Date: Sat, 24 May 2008 04:56:57 +0000 Subject: Just because elvis is dead, does not mean our auto updating system needs to be. Bring it back from the dead and make it match the new world order. Add a custom URL firmware update page which will have snapshot support shortly. --- etc/inc/globals.inc | 3 +- usr/local/www/system_firmware.php | 9 +- usr/local/www/system_firmware_auto.php | 240 ++++++++++++--------- usr/local/www/system_firmware_check.php | 326 +++++++++++------------------ usr/local/www/system_firmware_settings.php | 72 +------ 5 files changed, 284 insertions(+), 366 deletions(-) diff --git a/etc/inc/globals.inc b/etc/inc/globals.inc index 1fab6c5..c21c954 100644 --- a/etc/inc/globals.inc +++ b/etc/inc/globals.inc @@ -74,6 +74,7 @@ $g = array( "captiveportal_element_sizelimit" => 262144, "xmlrpcpath" => "/pfSense/xmlrpc.php", "embeddedbootupslice" => "/dev/ad0a", + "update_url" => "http://updates.pfSense.com/_updaters", "wireless_regex" => "/^(ndis|wi|ath|an|ral|ural|wai|iwi|awi|wlan)/", "vlan_native_supp" => array("vge", "bfe", "dc", "fxp", "gem", "hme", "rl", "sis", "ste", "tl", "tx", "xl"), "vlan_long_frame" => array("vge", "bfe", "bge", "dc", "em", "fxp", "gem", "hme", "ixgb", "le", "nge", "re", "rl", "sis", "sk", "ste", "ti", "tl", "tx", "txp", "vr", "xl") @@ -85,4 +86,4 @@ $iptos = array("lowdelay", "throughput", "reliability"); /* TCP flags */ $tcpflags = array("syn", "ack", "fin", "rst", "psh", "urg"); -?> +?> \ No newline at end of file diff --git a/usr/local/www/system_firmware.php b/usr/local/www/system_firmware.php index b6270ba..ea25156 100755 --- a/usr/local/www/system_firmware.php +++ b/usr/local/www/system_firmware.php @@ -31,6 +31,10 @@ $d_isfwfile = 1; require_once("guiconfig.inc"); + +$curcfg = $config['system']['firmware']; + + require_once("xmlrpc_client.inc"); /* Allow additional execution time 0 = no limit. */ @@ -135,6 +139,7 @@ if ($_POST && !file_exists($d_firmwarelock_path)) { } } +$pgtitle = array("Diagnostics","Firmware"); include("head.inc"); ?> @@ -165,8 +170,8 @@ print_info_box($sig_warning); diff --git a/usr/local/www/system_firmware_auto.php b/usr/local/www/system_firmware_auto.php index 7a4b339..285eed2 100755 --- a/usr/local/www/system_firmware_auto.php +++ b/usr/local/www/system_firmware_auto.php @@ -1,11 +1,12 @@ +#!/usr/local/bin/php + + + + +
- - -
+ + + - + + -
-
-
- - - - +
- -
-
/images/misc/progress_bar.gif' width='280' height='23' name='progressbar' id='progressbar'>
-
- - - - -
-
+ + +
+ + + +
+
+ + + + + + + +
+ + + +
+ +
+
+
+
+ + + + +
+
- +
@@ -92,72 +109,107 @@ include("head.inc"); $latest_version) + $needs_system_upgrade = true; -if($_GET['category'] == 'full') { - $tocheck = 'all'; - $categories = array('firmware', 'kernel', 'base'); +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."); +} + +/* launch external upgrade helper */ +$external_upgrade_helper_text = "/etc/rc.firmware pfSenseupgrade "; +if($needs_system_upgrade == true) + $external_upgrade_helper_text .= "/tmp/latest.tgz"; + +$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 }'`); + +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 { - $tocheck = array($_GET['category']); - $categories = $tocheck; + update_status("Downloading complete."); + 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}"); } -$static_output = "Downloading current version information... "; -update_status($static_output); -update_output_window($static_output); +/* + Helper functions +*/ -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']); +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 e3fec38..4298991 100755 --- a/usr/local/www/system_firmware_check.php +++ b/usr/local/www/system_firmware_check.php @@ -1,232 +1,150 @@ . + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. -Header("Location: system_firmware.php"); -exit; + 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. -require_once("guiconfig.inc"); -require_once("xmlrpc.inc"); + 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. +*/ + +$d_isfwfile = 1; +require("guiconfig.inc"); -if(isset($config['system']['disablefirmwarecheck'])) - Header("Location: system_firmware.php"); +$curcfg = $config['system']['firmware']; -$versions = check_firmware_version(); -$pgtitle = array("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."); } 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 165a995..a620fcd 100755 --- a/usr/local/www/system_firmware_settings.php +++ b/usr/local/www/system_firmware_settings.php @@ -27,27 +27,16 @@ 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']); } write_config(); } @@ -62,27 +51,13 @@ include("head.inc");