diff --git a/src/etc/inc/unbound.inc b/src/etc/inc/unbound.inc index 7ab7ed4a3..d114d821f 100644 --- a/src/etc/inc/unbound.inc +++ b/src/etc/inc/unbound.inc @@ -1,6 +1,7 @@ Copyright (C) 2014 Warren Baker All rights reserved. @@ -514,20 +515,27 @@ function unbound_add_host_entries() { $host_entries = ""; $added_item = array(); foreach($config['unbound']['hosts'] as $host) { - $current_host = $host['host']; - if ($host['host'] != "") + if ($host['host'] != "") { $host['host'] = $host['host']."."; - if (!$added_item[$current_host]) { - $host_entries .= "local-data-ptr: \"{$host['ip']} {$host['host']}{$host['domain']}\"\n"; - if (is_ipaddrv6($host['ip'])) - $host_entries .= "local-data: \"{$host['host']}{$host['domain']} IN AAAA {$host['ip']}\"\n"; - else - $host_entries .= "local-data: \"{$host['host']}{$host['domain']} IN A {$host['ip']}\"\n"; - if (!empty($host['descr']) && isset($config['unbound']['txtsupport'])) - $host_entries .= "local-data: '{$host['host']}{$host['domain']} TXT \"".addslashes($host['descr'])."\"'\n"; + } + /* Backwards compatibility for records created before introducing RR types. */ + if (!isset($host['rr'])) { + $host['rr'] = (is_ipaddrv6($host['ip'])) ? 'AAAA' : 'A'; + } - // Do not add duplicate entries - $added_item[$current_host] = true; + switch ($host['rr']) { + case 'A': + case 'AAAA': + $host_entries .= "local-data-ptr: \"{$host['ip']} {$host['host']}{$host['domain']}\"\n"; + $host_entries .= "local-data: \"{$host['host']}{$host['domain']} IN {$host['rr']} {$host['ip']}\"\n"; + break; + case 'MX': + $host_entries .= "local-data: \"{$host['host']}{$host['domain']} IN MX {$host['mxprio']} {$host['mx']}\"\n"; + break; + } + + if (!empty($host['descr']) && isset($config['unbound']['txtsupport'])) { + $host_entries .= "local-data: '{$host['host']}{$host['domain']} TXT \"".addslashes($host['descr'])."\"'\n"; } } $unbound_entries .= $host_entries; diff --git a/src/opnsense/mvc/app/models/OPNsense/Base/Menu/Menu.xml b/src/opnsense/mvc/app/models/OPNsense/Base/Menu/Menu.xml index a289330b4..09b3d9fae 100644 --- a/src/opnsense/mvc/app/models/OPNsense/Base/Menu/Menu.xml +++ b/src/opnsense/mvc/app/models/OPNsense/Base/Menu/Menu.xml @@ -240,10 +240,11 @@ - + + - + diff --git a/src/www/services_unbound.php b/src/www/services_unbound.php index cc51b657f..9ffaab2ea 100644 --- a/src/www/services_unbound.php +++ b/src/www/services_unbound.php @@ -38,14 +38,6 @@ if (!is_array($config['unbound'])) $config['unbound'] = array(); $a_unboundcfg =& $config['unbound']; -if (!is_array($config['unbound']['hosts'])) - $config['unbound']['hosts'] = array(); -$a_hosts =& $config['unbound']['hosts']; - -if (!is_array($config['unbound']['domainoverrides'])) - $config['unbound']['domainoverrides'] = array(); -$a_domainOverrides = &$config['unbound']['domainoverrides']; - if (isset($config['unbound']['enable'])) $pconfig['enable'] = true; if (isset($config['unbound']['dnssec'])) @@ -141,26 +133,6 @@ if ($_POST) { } } -if ($_GET['act'] == "del") { - if ($_GET['type'] == 'host') { - if ($a_hosts[$_GET['id']]) { - unset($a_hosts[$_GET['id']]); - write_config(); - mark_subsystem_dirty('unbound'); - header("Location: services_unbound.php"); - exit; - } - } elseif ($_GET['type'] == 'doverride') { - if ($a_domainOverrides[$_GET['id']]) { - unset($a_domainOverrides[$_GET['id']]); - write_config(); - mark_subsystem_dirty('unbound'); - header("Location: services_unbound.php"); - exit; - } - } -} - $closehead = false; include_once("head.inc"); @@ -361,131 +333,6 @@ function show_advanced_dns() { -
- -
- -
-

-
- -
- - -
-
-
- - - - - - - - - - - - - - - - - - - - - -
- - - - - -
-
-   - -   - -   - -   - - - - - - -
')" class="btn btn-default btn-xs">
-
- -
-
-
- -
- -
- -
- -
-

-
- -
-

-
- -
-
- - - - - - - - - - - - - - - - - - - - -
- - - - - -
-
-   - -   - -   - - - - - - -
')" class="btn btn-default btn-xs">
-
-
-
-
-
diff --git a/src/www/services_unbound_domainoverride_edit.php b/src/www/services_unbound_domainoverride_edit.php index af34aa8cd..2ea815168 100644 --- a/src/www/services_unbound_domainoverride_edit.php +++ b/src/www/services_unbound_domainoverride_edit.php @@ -32,7 +32,7 @@ require_once("guiconfig.inc"); require_once("services.inc"); require_once("interfaces.inc"); -$referer = (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/services_unbound.php'); +$referer = (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/services_unbound_overrides.php'); if (!is_array($config['unbound']['domainoverrides'])) $config['unbound']['domainoverrides'] = array(); @@ -96,7 +96,7 @@ if ($_POST) { write_config(); - header("Location: services_unbound.php"); + header("Location: services_unbound_overrides.php"); exit; } } diff --git a/src/www/services_unbound_host_edit.php b/src/www/services_unbound_host_edit.php index 3b69452d0..bbdfad1e9 100644 --- a/src/www/services_unbound_host_edit.php +++ b/src/www/services_unbound_host_edit.php @@ -1,6 +1,7 @@ Copyright (C) 2014-2015 Deciso B.V. Copyright (C) 2014 Warren Baker Copyright (C) 2003-2004 Bob Zoller and Manuel Kasper . @@ -32,7 +33,7 @@ require_once("guiconfig.inc"); require_once("services.inc"); require_once("interfaces.inc"); -$referer = (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/services_unbound.php'); +$referer = (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/services_unbound_overrides.php'); function hostcmp($a, $b) { return strcasecmp($a['host'], $b['host']); @@ -58,9 +59,17 @@ if (isset($_POST['id']) && is_numericint($_POST['id'])) $id = $_POST['id']; if (isset($id) && $a_hosts[$id]) { +/* Backwards compatibility for records created before introducing different RR types. */ + if (!isset($a_hosts[$id]['rr'])) { + $a_hosts[$id]['rr'] = 'A'; + } + $pconfig['host'] = $a_hosts[$id]['host']; $pconfig['domain'] = $a_hosts[$id]['domain']; + $pconfig['rr'] = $a_hosts[$id]['rr']; $pconfig['ip'] = $a_hosts[$id]['ip']; + $pconfig['mxprio'] = $a_hosts[$id]['mxprio']; + $pconfig['mx'] = $a_hosts[$id]['mx']; $pconfig['descr'] = $a_hosts[$id]['descr']; $pconfig['aliases'] = $a_hosts[$id]['aliases']; } @@ -71,19 +80,48 @@ if ($_POST) { $pconfig = $_POST; /* input validation */ - $reqdfields = explode(" ", "domain ip"); - $reqdfieldsn = array(gettext("Domain"),gettext("IP address")); + $reqdfields = explode(" ", "domain rr"); + $reqdfieldsn = array(gettext("Domain"),gettext("Type")); do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors); - if (($_POST['host'] && !is_hostname($_POST['host']))) + if (($_POST['host'] && !is_hostname($_POST['host']))) { $input_errors[] = gettext("The hostname can only contain the characters A-Z, 0-9 and '-'."); + } - if (($_POST['domain'] && !is_domain($_POST['domain']))) + if (($_POST['domain'] && !is_domain($_POST['domain']))) { $input_errors[] = gettext("A valid domain must be specified."); + } - if (($_POST['ip'] && !is_ipaddr($_POST['ip']))) - $input_errors[] = gettext("A valid IP address must be specified."); + switch ($_POST['rr']) { + case 'A': /* also: AAAA */ + $reqdfields = explode(" ", "ip"); + $reqdfieldsn = array(gettext("IP address")); + + do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors); + + if (($_POST['ip'] && !is_ipaddr($_POST['ip']))) { + $input_errors[] = gettext("A valid IP address must be specified."); + } + break; + case 'MX': + $reqdfields = explode(" ", "mxprio mx"); + $reqdfieldsn = array(gettext("MX Priority"), gettext("MX Host")); + + do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors); + + if (($_POST['mxprio'] && !is_numericint($_POST['mxprio']))) { + $input_errors[] = gettext("A valid MX priority must be specified."); + } + + if (($_POST['mx'] && !is_domain($_POST['mx']))) { + $input_errors[] = gettext("A valid MX host must be specified."); + } + break; + default: + $input_errors[] = gettext("A valid resource record type must be specified."); + break; + } /* collect aliases */ $aliases = array(); @@ -120,26 +158,24 @@ if ($_POST) { $input_errors[] = gettext("A valid domain must be specified in alias list."); } - /* check for overlaps */ - foreach ($a_hosts as $hostent) { - if (isset($id) && ($a_hosts[$id]) && ($a_hosts[$id] === $hostent)) - continue; - - if (($hostent['host'] == $_POST['host']) && ($hostent['domain'] == $_POST['domain']) - && ((is_ipaddrv4($hostent['ip']) && is_ipaddrv4($_POST['ip'])) || (is_ipaddrv6($hostent['ip']) && is_ipaddrv6($_POST['ip'])))) { - $input_errors[] = gettext("This host/domain already exists."); - break; - } - } - if (!$input_errors) { $hostent = array(); $hostent['host'] = $_POST['host']; $hostent['domain'] = $_POST['domain']; + $hostent['rr'] = $_POST['rr']; $hostent['ip'] = $_POST['ip']; + $hostent['mxprio'] = $_POST['mxprio']; + $hostent['mx'] = $_POST['mx']; $hostent['descr'] = $_POST['descr']; $hostent['aliases']['item'] = $aliases; + /* Destinguish between A and AAAA by parsing the passed IP address */ + if ($_POST['rr'] == 'A') { + if (is_ipaddrv6($_POST['ip'])) { + $hostent['rr'] = 'AAAA'; + } + } + if (isset($id) && $a_hosts[$id]) $a_hosts[$id] = $hostent; else @@ -150,7 +186,7 @@ if ($_POST) { write_config(); - header("Location: services_unbound.php"); + header("Location: services_unbound_overrides.php"); exit; } } @@ -174,6 +210,25 @@ include("head.inc"); rowname[2] = "aliasdescription"; rowtype[2] = "textbox"; rowsize[2] = "20"; + + function type_change() { + switch (jQuery('#rr').val()) { + case 'A': + jQuery('#ip').prop('disabled', false); + jQuery('#mxprio').prop('disabled', true); + jQuery('#mx').prop('disabled', true); + break; + case 'MX': + jQuery('#ip').prop('disabled', true); + jQuery('#mxprio').prop('disabled', false); + jQuery('#mx').prop('disabled', false); + break; + default: + jQuery('#ip').prop('disabled', false); + jQuery('#mxprio').prop('disabled', false); + jQuery('#mx').prop('disabled', false); + } + } //]]> @@ -215,13 +270,46 @@ include("head.inc"); - + + + +
+ A AAAA
+ + + +

192.168.100.100 fd00:abcd::1
+ + + +
+
+ 10
+ + + + + +
+
+ mail.example.com
+ + @@ -305,4 +393,9 @@ include("head.inc"); + diff --git a/src/www/services_unbound_overrides.php b/src/www/services_unbound_overrides.php new file mode 100644 index 000000000..8233560c8 --- /dev/null +++ b/src/www/services_unbound_overrides.php @@ -0,0 +1,269 @@ + + Copyright (C) 2014-2015 Deciso B.V. + Copyright (C) 2014 Warren Baker + 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. +*/ + +require_once("guiconfig.inc"); +require_once("unbound.inc"); +require_once("services.inc"); +require_once("system.inc"); +require_once("pfsense-utils.inc"); +require_once("interfaces.inc"); + +if (!is_array($config['unbound'])) + $config['unbound'] = array(); +$a_unboundcfg =& $config['unbound']; + +if (!is_array($config['unbound']['hosts'])) + $config['unbound']['hosts'] = array(); +$a_hosts =& $config['unbound']['hosts']; + +/* Backwards compatibility for records created before introducing RR types. */ +foreach ($a_hosts as $i => $hostent) { + if (!isset($hostent['rr'])) { + $a_hosts[$i]['rr'] = (is_ipaddrv6($hostent['ip'])) ? 'AAAA' : 'A'; + } +} + +if (!is_array($config['unbound']['domainoverrides'])) + $config['unbound']['domainoverrides'] = array(); +$a_domainOverrides = &$config['unbound']['domainoverrides']; + +if ($_POST) { + unset($input_errors); + + if ($_POST['apply']) { + $retval = services_unbound_configure(); + $savemsg = get_std_save_message(); + if ($retval == 0) { + clear_subsystem_dirty('unbound'); + } + /* Update resolv.conf in case the interface bindings exclude localhost. */ + system_resolvconf_generate(); + } +} + +if ($_GET['act'] == "del") { + if ($_GET['type'] == 'host') { + if ($a_hosts[$_GET['id']]) { + unset($a_hosts[$_GET['id']]); + write_config(); + mark_subsystem_dirty('unbound'); + header("Location: services_unbound_overrides.php"); + exit; + } + } elseif ($_GET['type'] == 'doverride') { + if ($a_domainOverrides[$_GET['id']]) { + unset($a_domainOverrides[$_GET['id']]); + write_config(); + mark_subsystem_dirty('unbound'); + header("Location: services_unbound_overrides.php"); + exit; + } + } +} + +$closehead = false; +$pgtitle = array(gettext('Services'), gettext('DNS Resolver'), gettext('Overrides')); +include_once("head.inc"); + +?> + + + + + +
+
+
+ + 0) print_input_errors($input_errors); ?> + +
+ " . gettext("You must apply the changes in order for them to take effect."));?>
+ + +
+ +
+ +
+ +
+

+
+ +
+ + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+
+   + +   + +   + + + +   + + + + + + +
')" class="btn btn-default btn-xs">
+
+ +
+
+
+ +
+ +
+ +
+ +
+

+
+ +
+

+
+ +
+
+ + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+
+   + +   + +   + + + + + + +
')" class="btn btn-default btn-xs">
+
+
+
+
+
+
+ +
+
+
+ + + +