%PDF- %PDF-
Direktori : /backups/router/usr/local/etc/inc/xmlrpc/ |
Current File : //backups/router/usr/local/etc/inc/xmlrpc/legacy.inc |
<?php /* * Copyright (C) 2015-2016 Deciso B.V. * Copyright (C) 2004-2010 Scott Ullrich <sullrich@gmail.com> * Copyright (C) 2005 Colin Smith <ethethlay@gmail.com> * 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. */ /** * request functions which may be registered by the xmlrpc system * @return array */ function xmlrpc_publishable_legacy() { $publish = [ 'filter_configure_xmlrpc', 'firmware_version_xmlrpc', 'restore_config_section_xmlrpc', ]; return $publish; } /* * does_vip_exist($vip): return true or false if a vip is * configured. */ function does_vip_exist($vip) { if (!$vip) { return false; } switch ($vip['mode']) { case "carp": case "ipalias": /* XXX: Make proper checks? */ $realif = get_real_interface($vip['interface']); if (!does_interface_exist($realif)) { return false; } break; case "proxyarp": /* XXX: Implement this */ default: return false; } foreach (array_keys(interfaces_addresses($realif, true)) as $vipips) { if ($vipips == "{$vip['subnet']}/{$vip['subnet_bits']}") { return true; } } return false; } /** * merge attributes from source array to destination * updates leaves and overwrites sequenced arrays (container types). * @param array $cnf_source source data * @param array $cnf_dest target */ function merge_config_attributes(&$cnf_source, &$cnf_dest) { foreach ($cnf_source as $cnf_key => &$cnf_value) { if (is_array($cnf_value)) { if ( !isset($cnf_dest[$cnf_key]) || !is_array($cnf_dest[$cnf_key]) || // new (count($cnf_dest[$cnf_key]) > 0 && isset($cnf_dest[$cnf_key][0])) || // sequenced item (count($cnf_dest[$cnf_key]) > 0 && isset($cnf_dest[$cnf_key]['@attributes']['uuid'])) // mvc array ) { // (re)set destination array when new or containing a sequenced list of items $cnf_dest[$cnf_key] = []; } merge_config_attributes($cnf_value, $cnf_dest[$cnf_key]); } else { $cnf_dest[$cnf_key] = $cnf_value; } } } /** * retrieve firmware version * @return array */ function firmware_version_xmlrpc() { return [ 'base' => ['version' => shell_safe('opnsense-version -v base')], 'firmware' => ['version' => shell_safe('opnsense-version -v core')], 'kernel' => ['version' => shell_safe('opnsense-version -v kernel')], ]; } /** * filter reconfigure * @return mixed */ function filter_configure_xmlrpc() { require_once("filter.inc"); require_once("system.inc"); require_once("util.inc"); require_once("interfaces.inc"); system_routing_configure(); system_resolver_configure(); filter_configure(); return true; } /** * restore config section * @param $new_config * @return bool */ function restore_config_section_xmlrpc($new_config) { global $config; // lock config write during merge OPNsense\Core\Config::getInstance()->lock(); require_once("interfaces.inc"); require_once("filter.inc"); // save old config $old_config = $config; // Some sections should just be copied and not merged, namely if there's a risk of attributes being removed // without being seen by the remote (backup) side. // (ipsec, openvpn, nat can probably moved out later by specifying a better path to the attribute) $sync_full = ['ipsec', 'wol', 'dnsmasq', 'openvpn', 'nat', 'dhcpd', 'dhcpv6']; $sync_full_done = []; foreach ($sync_full as $syncfull) { if (isset($new_config[$syncfull])) { $config[$syncfull] = $new_config[$syncfull]; unset($new_config[$syncfull]); $sync_full_done[] = $syncfull; } } $vhidVipsInNewConfig = []; if (isset($new_config['virtualip']['vip'])) { foreach ($new_config['virtualip']['vip'] as $vip) { $vhidVipsInNewConfig[get_unique_vip_key($vip)] = $vip; } } $vipbackup = []; $oldvips = []; if (isset($new_config['virtualip']['vip']) && isset($config['virtualip']['vip'])) { foreach ($config['virtualip']['vip'] as $vipindex => $vip) { if (!empty($vip['vhid'])) { // rc.filter_synchronize only sends CARP VIPs and IP Aliases with a VHID. Keep the rest like it was. $vipKey = get_unique_vip_key($vip); $oldvips[$vipKey] = $vip; // Remove entries that are present locally, but are not present in the new config. if (!array_key_exists($vipKey, $vhidVipsInNewConfig)) { unset($config['virtualip']['vip'][$vipindex]); } } else { $vipbackup[] = $vip; } } } // merge config attributes. merge_config_attributes($new_config, $config); if (count($vipbackup) > 0) { // if $new_config contained VIPs and the old config contained VIPs with no VHID, prepend original VIPs foreach ($vipbackup as $vip) { array_unshift($config['virtualip']['vip'], $vip); } } /* Log what happened */ $mergedkeys = implode(",", array_merge(array_keys($new_config), $sync_full_done)); write_config(sprintf('Merged %s config sections from XMLRPC client.', $mergedkeys)); /* * Handle virtual ips */ if (isset($new_config['virtualip']['vip'])) { $proxyarp = false; $pfsync = false; if (isset($config['virtualip']['vip'])) { foreach ($config['virtualip']['vip'] as $vip) { $vipKey = get_unique_vip_key($vip); if (!empty($vip['vhid']) && isset($oldvips[$vipKey])) { $is_changed = false; foreach (['password', 'advskew', 'subnet', 'subnet_bits', 'advbase'] as $chk_key) { if ($oldvips[$vipKey][$chk_key] != $vip[$chk_key]) { $is_changed = true; break; } } if (!$is_changed) { unset($oldvips[$vipKey]); if (does_vip_exist($vip)) { continue; // Skip reconfiguring this VIP since nothing has changed. } } } switch ($vip['mode']) { case "proxyarp": $proxyarp = true; break; case "ipalias": interface_ipalias_configure($vip); break; case "carp": interface_carp_configure($vip); $pfsync = true; break; } } } // remove old (carp/ipalias-with-vhid) virtual ip's foreach ($oldvips as $oldvip) { interface_vip_bring_down($oldvip); } if ($pfsync) { interfaces_pfsync_configure(); } if ($proxyarp) { interface_proxyarp_configure(); } } if (isset($old_config['ipsec']['enable']) !== isset($config['ipsec']['enable'])) { plugins_configure('ipsec'); } unset($old_config); return true; } function get_unique_vip_key($vip) { if ($vip['mode'] === 'carp') { return "{$vip['mode']}_{$vip['interface']}_vip{$vip['vhid']}"; } else { return "{$vip['mode']}_{$vip['interface']}_vip{$vip['vhid']}_{$vip['subnet']}_{$vip['subnet_bits']}"; } }