diff options
Diffstat (limited to 'src/usr/local/www/services_ntpd.php')
-rw-r--r-- | src/usr/local/www/services_ntpd.php | 553 |
1 files changed, 553 insertions, 0 deletions
diff --git a/src/usr/local/www/services_ntpd.php b/src/usr/local/www/services_ntpd.php new file mode 100644 index 0000000..412678b --- /dev/null +++ b/src/usr/local/www/services_ntpd.php @@ -0,0 +1,553 @@ +<?php +/* + services_ntpd.php + + Copyright (C) 2013 Dagorlad + Copyright (C) 2012 Jim Pingle + Copyright (C) 2013-2015 Electric Sheep Fencing, LP + 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. + + 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. +*/ +/* + pfSense_MODULE: ntpd +*/ + +##|+PRIV +##|*IDENT=page-services-ntpd +##|*NAME=Services: NTP +##|*DESCR=Allow access to the 'Services: NTP' page. +##|*MATCH=services_ntpd.php* +##|-PRIV + +define(NUMTIMESERVERS, 10); // The maximum number of configurable time servers +require("guiconfig.inc"); +require_once('rrd.inc'); +require_once("shaper.inc"); + +if (!is_array($config['ntpd'])) { + $config['ntpd'] = array(); +} + +if (empty($config['ntpd']['interface'])) { + if (is_array($config['installedpackages']['openntpd']) && is_array($config['installedpackages']['openntpd']['config']) && + is_array($config['installedpackages']['openntpd']['config'][0]) && !empty($config['installedpackages']['openntpd']['config'][0]['interface'])) { + $pconfig['interface'] = explode(",", $config['installedpackages']['openntpd']['config'][0]['interface']); + unset($config['installedpackages']['openntpd']); + write_config("Upgraded settings from openttpd"); + } else { + $pconfig['interface'] = array(); + } +} else { + $pconfig['interface'] = explode(",", $config['ntpd']['interface']); +} + +if($_GET['addrow']) + $maxrows = $_GET['addrow'] + 1; +else + $maxrows = 3; + +if ($_POST) { + unset($input_errors); + $pconfig = $_POST; + + if (!$input_errors) { + if (is_array($_POST['interface'])) { + $config['ntpd']['interface'] = implode(",", $_POST['interface']); + } elseif (isset($config['ntpd']['interface'])) { + unset($config['ntpd']['interface']); + } + + if (!empty($_POST['gpsport']) && file_exists('/dev/'.$_POST['gpsport'])) { + $config['ntpd']['gpsport'] = $_POST['gpsport']; + } elseif (isset($config['ntpd']['gpsport'])) { + unset($config['ntpd']['gpsport']); + } + + unset($config['ntpd']['prefer']); + unset($config['ntpd']['noselect']); + $timeservers = ''; + + for ($i = 0; $i < 10; $i++) { + $tserver = trim($_POST["server{$i}"]); + if (!empty($tserver)) { + $timeservers .= "{$tserver} "; + if (!empty($_POST["servprefer{$i}"])) { + $config['ntpd']['prefer'] .= "{$tserver} "; + } + if (!empty($_POST["servselect{$i}"])) { + $config['ntpd']['noselect'] .= "{$tserver} "; + } + } + } + if (trim($timeservers) == "") { + $timeservers = "pool.ntp.org"; + } + $config['system']['timeservers'] = trim($timeservers); + + if (!empty($_POST['ntporphan']) && ($_POST['ntporphan'] < 17) && ($_POST['ntporphan'] != '12')) { + $config['ntpd']['orphan'] = $_POST['ntporphan']; + } elseif (isset($config['ntpd']['orphan'])) { + unset($config['ntpd']['orphan']); + } + + if (!empty($_POST['logpeer'])) { + $config['ntpd']['logpeer'] = $_POST['logpeer']; + } elseif (isset($config['ntpd']['logpeer'])) { + unset($config['ntpd']['logpeer']); + } + + if (!empty($_POST['logsys'])) { + $config['ntpd']['logsys'] = $_POST['logsys']; + } elseif (isset($config['ntpd']['logsys'])) { + unset($config['ntpd']['logsys']); + } + + if (!empty($_POST['clockstats'])) { + $config['ntpd']['clockstats'] = $_POST['clockstats']; + } elseif (isset($config['ntpd']['clockstats'])) { + unset($config['ntpd']['clockstats']); + } + + if (!empty($_POST['loopstats'])) { + $config['ntpd']['loopstats'] = $_POST['loopstats']; + } elseif (isset($config['ntpd']['loopstats'])) { + unset($config['ntpd']['loopstats']); + } + + if (!empty($_POST['peerstats'])) { + $config['ntpd']['peerstats'] = $_POST['peerstats']; + } elseif (isset($config['ntpd']['peerstats'])) { + unset($config['ntpd']['peerstats']); + } + + if (empty($_POST['kod'])) { + $config['ntpd']['kod'] = 'on'; + } elseif (isset($config['ntpd']['kod'])) { + unset($config['ntpd']['kod']); + } + + if (empty($_POST['nomodify'])) { + $config['ntpd']['nomodify'] = 'on'; + } elseif (isset($config['ntpd']['nomodify'])) { + unset($config['ntpd']['nomodify']); + } + + if (!empty($_POST['noquery'])) { + $config['ntpd']['noquery'] = $_POST['noquery']; + } elseif (isset($config['ntpd']['noquery'])) { + unset($config['ntpd']['noquery']); + } + + if (!empty($_POST['noserve'])) { + $config['ntpd']['noserve'] = $_POST['noserve']; + } elseif (isset($config['ntpd']['noserve'])) { + unset($config['ntpd']['noserve']); + } + + if (empty($_POST['nopeer'])) { + $config['ntpd']['nopeer'] = 'on'; + } elseif (isset($config['ntpd']['nopeer'])) { + unset($config['ntpd']['nopeer']); + } + + if (empty($_POST['notrap'])) { + $config['ntpd']['notrap'] = 'on'; + } elseif (isset($config['ntpd']['notrap'])) { + unset($config['ntpd']['notrap']); + } + + if ((empty($_POST['statsgraph'])) == (isset($config['ntpd']['statsgraph']))) { + $enable_rrd_graphing = true; + } + if (!empty($_POST['statsgraph'])) { + $config['ntpd']['statsgraph'] = $_POST['statsgraph']; + } elseif (isset($config['ntpd']['statsgraph'])) { + unset($config['ntpd']['statsgraph']); + } + if (isset($enable_rrd_graphing)) { + enable_rrd_graphing(); + } + + if (!empty($_POST['leaptxt'])) { + $config['ntpd']['leapsec'] = base64_encode($_POST['leaptxt']); + } elseif (isset($config['ntpd']['leapsec'])) { + unset($config['ntpd']['leapsec']); + } + + if (is_uploaded_file($_FILES['leapfile']['tmp_name'])) { + $config['ntpd']['leapsec'] = base64_encode(file_get_contents($_FILES['leapfile']['tmp_name'])); + } + + write_config("Updated NTP Server Settings"); + + $retval = 0; + $retval = system_ntp_configure(); + $savemsg = get_std_save_message($retval); + } +} + +function build_interface_list() { + global $pconfig; + + $iflist = array('options' => array(), 'selected' => array()); + + $interfaces = get_configured_interface_with_descr(); + $carplist = get_configured_carp_interface_list(); + + foreach ($carplist as $cif => $carpip) + $interfaces[$cif] = $carpip . " (" . get_vip_descr($carpip) .")"; + + $aliaslist = get_configured_ip_aliases_list(); + + foreach ($aliaslist as $aliasip => $aliasif) + $interfaces[$aliasip] = $aliasip." (".get_vip_descr($aliasip).")"; + + $size = (count($interfaces) < 10) ? count($interfaces) : 10; + + foreach ($interfaces as $iface => $ifacename) { + if (!is_ipaddr(get_interface_ip($iface)) && !is_ipaddr($iface)) + continue; + + $iflist['options']['$iface'] = $ifacename; + + if (in_array($iface, $pconfig['interface'])) + array_push($iflist['slected'], $iface); + + } + + return($iflist); +} + +$closehead = false; +$pconfig = &$config['ntpd']; +if (empty($pconfig['interface'])) { + $pconfig['interface'] = array(); +} else { + $pconfig['interface'] = explode(",", $pconfig['interface']); +} +$pgtitle = array(gettext("Services"), gettext("NTP")); +$shortcut_section = "ntp"; +include("head.inc"); + +if ($input_errors) + print_input_errors($input_errors); +if ($savemsg) + print_info_box($savemsg, 'success'); + +$tab_array = array(); +$tab_array[] = array(gettext("NTP"), true, "services_ntpd.php"); +$tab_array[] = array(gettext("Serial GPS"), false, "services_ntpd_gps.php"); +$tab_array[] = array(gettext("PPS"), false, "services_ntpd_pps.php"); +display_top_tabs($tab_array); + +require('classes/Form.class.php'); + +$form = new Form; + +$section = new Form_Section('NTP server configuration'); + +$iflist = build_interface_list(); + +$section->addInput(new Form_Select( + 'interface', + 'Interface', + $iflist['selected'], + $iflist['options'], + true +))->setHelp('Interfaces without an IP address will not be shown.' . '<br />' . + 'Selecting no interfaces will listen on all interfaces with a wildcard.' . '<br />' . + 'Selecting all interfaces will explicitly listen on only the interfaces/IPs specified.'); + +// NUMTIMESERVERS time servers are always available, but we only display a smaller number of these ($maxrows) +// Clicking the 'Add Row' button increments $maxrows so you can see more of time servers +$timeservers = explode( ' ', $config['system']['timeservers']); +for ($i = $j = 0; $i < NUMTIMESERVERS; $i++){ + + if($i >= $maxrows) + continue; + + $group = new Form_Group($i == 0 ? 'Time servers':''); + + $group->add(new Form_Input( + 'server' . $i, + null, + 'text', + $timeservers[$i] + )); + + $group->add(new Form_Checkbox( + 'servprefer' . $i, + null, + 'Prefer', + isset($config['ntpd']['prefer']) && isset($timeservers[$i]) && substr_count($config['ntpd']['prefer'], $timeservers[$i]) + )); + + $group->add(new Form_Checkbox( + 'servselect' . $i, + null, + 'NoSelect', + isset($config['ntpd']['noselect']) && isset($timeservers[$i]) && substr_count($config['ntpd']['noselect'], $timeservers[$i]) + )); + + $section->add($group); +} + +// Show the 'Add Rows' button only if we are currently displaying less than the maximum +// number of configured servers +if($maxrows < NUMTIMESERVERS) { + $btnaddrow = new Form_Button( + 'btnaddrow', + 'Add Server', + 'services_ntpd.php?addrow=' . $maxrows + ); + + $btnaddrow->removeClass('btn-primary')->addClass('btn-success btn-sm'); +} else + $btnaddrow = false; + +$section->addInput(new Form_StaticText( + null, + $btnaddrow +))->setHelp('For best results three to five servers should be configured here.' . '<br />' . + 'The prefer option indicates that NTP should favor the use of this server more than all others.' . '<br />' . + 'The noselect option indicates that NTP should not use this server for time, but stats for this server will be collected and displayed.'); + +$section->addInput(new Form_Input( + 'ntporphan', + 'Orphan mode', + 'text', + $pconfig['ntporphan'] +))->setHelp('Orphan mode allows the system clock to be used when no other clocks are available. ' . + 'The number here specifies the stratum reported during orphan mode and should normally be set to a number high enough ' . + 'to insure that any other servers available to clients are preferred over this server. (default: 12).'); + +$section->addInput(new Form_Checkbox( + 'statsgraph', + 'NTP Graphs', + 'Enable RRD graphs of NTP statistics (default: disabled).', + $pconfig['statsgraph'] +)); + +$section->addInput(new Form_Checkbox( + 'logpeer', + 'Syslog logging', + 'Enable logging of peer messages (default: disabled).', + $pconfig['logpeer'] +)); + +$section->addInput(new Form_Checkbox( + 'logsys', + null, + 'Enable logging of system messages (default: disabled).', + $pconfig['logsys'] +))->setHelp('These options enable additional messages from NTP to be written to the System Log ' . + '<a href="diag_logs_ntpd.php">' . 'Status > System Logs > NTP' . '</a>'); + +// Statistics logging section +$btnadvstats = new Form_Button( + 'btnadvstats', + 'Advanced' +); + +$btnadvstats->removeClass('btn-primary')->addClass('btn-default btn-sm'); + +$section->addInput(new Form_StaticText( + 'Statistics logging', + $btnadvstats +))->setHelp('Warning: These options will create persistant daily log files in /var/log/ntp.'); + +$section->addInput(new Form_Checkbox( + 'clockstats', + null, + 'Enable logging of reference clock statistics (default: disabled).', + $pconfig['clockstats'] +)); + +$section->addInput(new Form_Checkbox( + 'loopstats', + null, + 'Enable logging of clock discipline statistics (default: disabled).', + $pconfig['loopstats'] +)); + +$section->addInput(new Form_Checkbox( + 'peerstats', + null, + 'Enable logging of NTP peer statistics (default: disabled).', + $pconfig['peerstats'] +)); + +// Access restrictions section +$btnadvrestr = new Form_Button( + 'btnadvrestr', + 'Advanced' +); + +$btnadvrestr->removeClass('btn-primary')->addClass('btn-default btn-sm'); + +$section->addInput(new Form_StaticText( + 'Access Restrictions', + $btnadvrestr +))->setHelp('These options control access to NTP from the WAN.'); + +$section->addInput(new Form_Checkbox( + 'kod', + null, + 'Enable Kiss-o\'-death packets (default: enabled).', + $pconfig['kod'] +)); + +$section->addInput(new Form_Checkbox( + 'nomodify', + null, + 'Deny state modifications (i.e. run time configuration) by ntpq and ntpdc (default: enabled).', + $pconfig['nomodify'] +)); + +$section->addInput(new Form_Checkbox( + 'noquery', + null, + 'Disable ntpq and ntpdc queries (default: disabled).', + $pconfig['noquery'] +)); + +$section->addInput(new Form_Checkbox( + 'noserve', + null, + 'Disable all except ntpq and ntpdc queries (default: disabled).', + $pconfig['noserve'] +)); + +$section->addInput(new Form_Checkbox( + 'nopeer', + null, + 'Deny packets that attempt a peer association (default: enabled).', + $pconfig['nopeer'] +)); + +$section->addInput(new Form_Checkbox( + 'notrap', + null, + 'Deny mode 6 control message trap service (default: enabled).', + $pconfig['notrap'] +))->addClass('advrestrictions'); + +// Leap seconds section +$btnleap = new Form_Button( + 'btnleap', + 'Advanced' +); + +$btnleap->removeClass('btn-primary')->addClass('btn-default btn-sm'); + +$section->addInput(new Form_StaticText( + 'Leap seconds', + $btnleap +))->setHelp('A leap second file allows NTP to advertize an upcoming leap second addition or subtraction. ' . + 'Normally this is only useful if this server is a stratum 1 time server. '); + +$section->addInput(new Form_Textarea( + 'leaptext', + null, + base64_decode(chunk_split($pconfig['leapsec'])) +))->setHelp('Enter Leap second configuration as text OR select a file to upload'); + +$section->addInput(new Form_Input( + 'leapfile', + null, + 'file' +))->addClass('btn-default'); + +$form->add($section); +print($form); + +?> + +<script> +//<![CDATA[ +events.push(function(){ + + // Hides the <div> in which the specified input element lives so that the input, its label and help text are hidden + function hideInput(id, hide) { + if(hide) + $('#' + id).parent().parent('div').addClass('hidden'); + else + $('#' + id).parent().parent('div').removeClass('hidden'); + } + + // Hides the <div> in which the specified checkbox lives so that the checkbox, its label and help text are hidden + function hideCheckbox(id, hide) { + if(hide) + $('#' + id).parent().parent().parent('div').addClass('hidden'); + else + $('#' + id).parent().parent().parent('div').removeClass('hidden'); + } + + // Make the ‘clear’ button a plain button, not a submit button + $('#btnadvstats').prop('type','button'); + + // On click, show the controls in the stats section + $("#btnadvstats").click(function() { + hideCheckbox('clockstats', false); + hideCheckbox('loopstats', false); + hideCheckbox('peerstats', false); + }); + + // Make the ‘clear’ button a plain button, not a submit button + $('#btnadvrestr').prop('type','button'); + + // On click, show the controls in the restrictions section + $("#btnadvrestr").click(function() { + hideCheckbox('nomodify', false); + hideCheckbox('noquery', false); + hideCheckbox('noserve', false); + hideCheckbox('nopeer', false); + hideCheckbox('notrap', false); + }); + + // Make the ‘btnleap’ button a plain button, not a submit button + $('#btnleap').prop('type','button'); + + // On click, show the controls in the leap seconds section + $("#btnleap").click(function() { + hideInput('leaptext', false); + hideInput('leapfile', false); + }); + + // Set intial states + hideCheckbox('clockstats', true); + hideCheckbox('loopstats', true); + hideCheckbox('peerstats', true); + hideCheckbox('kod', true); + hideCheckbox('nomodify', true); + hideCheckbox('noquery', true); + hideCheckbox('noserve', true); + hideCheckbox('nopeer', true); + hideCheckbox('notrap', true); + hideInput('leaptext', true); + hideInput('leapfile', true); +}); +//]]> +</script> + +<?php include("foot.inc");
\ No newline at end of file |