diff options
author | Renato Botelho <renato@netgate.com> | 2016-08-18 16:38:38 -0300 |
---|---|---|
committer | Renato Botelho <renato@netgate.com> | 2016-08-18 16:42:19 -0300 |
commit | f81e7cc404bc3ede065c8c6315fdb5d26b2cfc5b (patch) | |
tree | b26ee1e257bb3ea118c829dbad16af5eb3bd2459 /src/usr/local | |
parent | 29cffce7787d342762774c51985afdc87aeaa89c (diff) | |
download | pfsense-f81e7cc404bc3ede065c8c6315fdb5d26b2cfc5b.zip pfsense-f81e7cc404bc3ede065c8c6315fdb5d26b2cfc5b.tar.gz |
Ticket #3734: Convert xmlrpc.php to use XML/RPC2/Server.php
Diffstat (limited to 'src/usr/local')
-rw-r--r-- | src/usr/local/www/xmlrpc.php | 875 |
1 files changed, 443 insertions, 432 deletions
diff --git a/src/usr/local/www/xmlrpc.php b/src/usr/local/www/xmlrpc.php index 8ebd7eb..0af7e38 100644 --- a/src/usr/local/www/xmlrpc.php +++ b/src/usr/local/www/xmlrpc.php @@ -29,232 +29,307 @@ require_once("config.inc"); require_once("functions.inc"); +require_once("auth.inc"); require_once("filter.inc"); require_once("ipsec.inc"); require_once("vpn.inc"); require_once("shaper.inc"); -require_once("xmlrpc_server.inc"); -require_once("xmlrpc.inc"); +require_once("XML/RPC2/Server.php"); -function xmlrpc_loop_detect() { - global $config; +class pfsense_xmlrpc_server { - /* grab sync to ip if enabled */ - if ($config['hasync']) { - $synchronizetoip = $config['hasync']['synchronizetoip']; - } - if ($synchronizetoip) { - if ($synchronizetoip == $_SERVER['REMOTE_ADDR']) { - return true; - } - } + private $loop_detected = false; + private $remote_addr; - return false; -} - -$xmlrpc_g = array( - "return" => array( - "true" => new XML_RPC_Response(new XML_RPC_Value(true, $XML_RPC_Boolean)), - "false" => new XML_RPC_Response(new XML_RPC_Value(false, $XML_RPC_Boolean)), - "authfail" => new XML_RPC_Response(new XML_RPC_Value(gettext("Authentication failed"), $XML_RPC_String)) - ) -); + private function auth($username, $password) { + global $config; -/* - * pfSense XMLRPC errors - * $XML_RPC_erruser + 1 = Auth failure - */ -$XML_RPC_erruser = 200; - -/* EXPOSED FUNCTIONS */ -$exec_php_doc = gettext("XMLRPC wrapper for eval(). This method must be called with two parameters: a string containing the local system\'s password followed by the PHP code to evaluate."); -$exec_php_sig = array( - array( - $XML_RPC_Boolean, // First signature element is return value. - $XML_RPC_String, // password - $XML_RPC_String, // shell code to exec - ) -); + if (!empty($username) && !empty($password)) { + $attributes = array(); + $authcfg = auth_get_authserver( + $config['system']['webgui']['authmode']); -function xmlrpc_authfail() { - log_auth("webConfigurator authentication error for 'admin' from {$_SERVER['REMOTE_ADDR']}"); -} + if (authenticate_user($username, $password, + $authcfg, $attributes) || + authenticate_user($username, $password)) { + return; + } + } -function exec_php_xmlrpc($raw_params) { - global $config, $xmlrpc_g; + log_auth("webConfigurator authentication error for '" . + $username . "' from " . $this->remote_addr); - $params = xmlrpc_params_to_php($raw_params); - if (!xmlrpc_auth($params)) { - xmlrpc_authfail(); - return $xmlrpc_g['return']['authfail']; + require_once("XML/RPC2/Exception.php"); + throw new XML_RPC2_FaultException( + gettext('Authentication failed'), -1); } - $exec_php = $params[0]; - eval($exec_php); - if ($toreturn) { - $response = XML_RPC_encode($toreturn); - return new XML_RPC_Response($response); - } else { - return $xmlrpc_g['return']['true']; + + private function array_overlay($a1, $a2) { + foreach ($a1 as $k => $v) { + if (!array_key_exists($k, $a2)) { + continue; + } + if (is_array($v) && is_array($a2[$k])) { + $a1[$k] = $this->array_overlay($v, $a2[$k]); + } else { + $a1[$k] = $a2[$k]; + } + } + + return $a1; } -} -/*****************************/ -$exec_shell_doc = gettext("XMLRPC wrapper for mwexec(). This method must be called with two parameters: a string containing the local system\'s password followed by an shell command to execute."); -$exec_shell_sig = array( - array( - $XML_RPC_Boolean, // First signature element is return value. - $XML_RPC_String, // password - $XML_RPC_String, // shell code to exec - ) -); + public function __construct() { + global $config; -function exec_shell_xmlrpc($raw_params) { - global $config, $xmlrpc_g; + $this->remote_addr = $_SERVER['remote_addr']; - $params = xmlrpc_params_to_php($raw_params); - if (!xmlrpc_auth($params)) { - xmlrpc_authfail(); - return $xmlrpc_g['return']['authfail']; + /* grab sync to ip if enabled */ + if (isset($config['hasync']['synchronizetoip']) && + $config['hasync']['synchronizetoip'] == $remote_addr) { + $this->loop_detected = true; + } } - $shell_cmd = $params[0]; - mwexec($shell_cmd); - return $xmlrpc_g['return']['true']; -} + /** + * Get host version information + * + * @param string $username + * @param string $password + * + * @return array + */ + public function host_firmware_version($username, $password) { + $this->auth($username, $password); -/*****************************/ -$backup_config_section_doc = gettext("XMLRPC wrapper for backup_config_section. This method must be called with two parameters: a string containing the local system\'s password followed by an array containing the keys to be backed up."); -$backup_config_section_sig = array( - array( - $XML_RPC_Struct, // First signature element is return value. - $XML_RPC_String, - $XML_RPC_Array - ) -); + return host_firmware_version(); + } -function backup_config_section_xmlrpc($raw_params) { - global $config, $xmlrpc_g; + /** + * Executes a PHP block of code + * + * @param string $username + * @param string $password + * @param string $code + * + * @return bool + */ + public function exec_php($username, $password, $code) { + $this->auth($username, $password); - if (xmlrpc_loop_detect()) { - log_error("Disallowing CARP sync loop"); - return; - } + eval($code); + if ($toreturn) { + return $toreturn; + } - $params = xmlrpc_params_to_php($raw_params); - if (!xmlrpc_auth($params)) { - xmlrpc_authfail(); - return $xmlrpc_g['return']['authfail']; + return true; } - $val = array_intersect_key($config, array_flip($params[0])); - return new XML_RPC_Response(XML_RPC_encode($val)); -} + /** + * Executes shell commands + * + * @param string $username + * @param string $password + * @param string $code + * + * @return bool + */ + public function exec_shell($username, $password, $code) { + $this->auth($username, $password); -/*****************************/ -$restore_config_section_doc = gettext("XMLRPC wrapper for restore_config_section. This method must be called with two parameters: a string containing the local system\'s password and an array to merge into the system\'s config. This function returns true upon completion."); -$restore_config_section_sig = array( - array( - $XML_RPC_Boolean, - $XML_RPC_String, - $XML_RPC_Struct - ) -); + mwexec($code); + return true; + } -function restore_config_section_xmlrpc($raw_params) { - global $config, $xmlrpc_g; + /** + * Backup chosen config sections + * + * @param string $username + * @param string $password + * @param array $section + * + * @return array + */ + public function backup_config_section($username, $password, $section) { + $this->auth($username, $password); - $old_config = $config; - $old_ipsec_enabled = ipsec_enabled(); + global $config; - if (xmlrpc_loop_detect()) { - log_error("Disallowing CARP sync loop"); - return; + return array_intersect_key($config, array_flip($section)); } - $params = xmlrpc_params_to_php($raw_params); - if (!xmlrpc_auth($params)) { - xmlrpc_authfail(); - return $xmlrpc_g['return']['authfail']; - } + /** + * Restore defined config section into local config + * + * @param string $username + * @param string $password + * @param array $sections + * + * @return bool + */ + public function restore_config_section($username, $password, $sections) { + $this->auth($username, $password); + + global $config; - // Some sections should just be copied and not merged or we end - // up unable to sync the deletion of the last item in a section - $sync_full = array('dnsmasq', 'unbound', 'ipsec', 'aliases', 'wol', 'load_balancer', 'openvpn', 'cert', 'ca', 'crl', 'schedules', 'filter', 'nat', 'dhcpd', 'dhcpv6'); - $sync_full_done = array(); - foreach ($sync_full as $syncfull) { - if (isset($params[0][$syncfull])) { - $config[$syncfull] = $params[0][$syncfull]; - unset($params[0][$syncfull]); - $sync_full_done[] = $syncfull; + $old_config = $config; + $old_ipsec_enabled = ipsec_enabled(); + + if ($this->loop_detected) { + log_error("Disallowing CARP sync loop"); + return true; + } + + /* + * Some sections should just be copied and not merged or we end + * up unable to sync the deletion of the last item in a section + */ + $sync_full_sections = array( + 'aliases', + 'ca', + 'cert', + 'crl', + 'dhcpd', + 'dhcpv6', + 'dnsmasq', + 'filter', + 'ipsec', + 'load_balancer', + 'nat', + 'openvpn', + 'schedules', + 'unbound', + 'wol', + ); + + $syncd_full_sections = array(); + + foreach ($sync_full_sections as $section) { + if (!isset($sections[$section])) { + continue; + } + + $config[$section] = $sections[$section]; + unset($sections[$section]); + $syncd_full_sections[] = $section; } - } - $vipbackup = array(); - $oldvips = array(); - if (isset($params[0]['virtualip'])) { - if (is_array($config['virtualip']['vip'])) { - foreach ($config['virtualip']['vip'] as $vipindex => $vip) { + $vipbackup = array(); + $oldvips = array(); + if (isset($sections['virtualip']) && + is_array($config['virtualip']['vip'])) { + foreach ($config['virtualip']['vip'] as $vip) { if ($vip['mode'] == "carp") { - $oldvips["{$vip['interface']}_vip{$vip['vhid']}"]['content'] = "{$vip['password']}{$vip['advskew']}{$vip['subnet']}{$vip['subnet_bits']}{$vip['advbase']}"; - $oldvips["{$vip['interface']}_vip{$vip['vhid']}"]['interface'] = $vip['interface']; - $oldvips["{$vip['interface']}_vip{$vip['vhid']}"]['subnet'] = $vip['subnet']; - } else if ($vip['mode'] == "ipalias" && (substr($vip['interface'], 0, 4) == '_vip' || strstr($vip['interface'], "lo0"))) { - $oldvips[$vip['subnet']]['content'] = "{$vip['interface']}{$vip['subnet']}{$vip['subnet_bits']}"; - $oldvips[$vip['subnet']]['interface'] = $vip['interface']; - $oldvips[$vip['subnet']]['subnet'] = $vip['subnet']; - } else if (($vip['mode'] == "ipalias" || $vip['mode'] == 'proxyarp') && !(substr($vip['interface'], 0, 4) == '_vip') || strstr($vip['interface'], "lo0")) { + $key = $vip['interface'] . + "_vip" . $vip['vhid']; + + $oldvips[$key]['content'] = + $vip['password'] . + $vip['advskew'] . + $vip['subnet'] . + $vip['subnet_bits'] . + $vip['advbase']; + $oldvips[$key]['interface'] = + $vip['interface']; + $oldvips[$key]['subnet'] = + $vip['subnet']; + } else if ($vip['mode'] == "ipalias" && + (substr($vip['interface'], 0, 4) == '_vip' + || strstr($vip['interface'], "lo0"))) { + $oldvips[$vip['subnet']]['content'] = + $vip['interface'] . + $vip['subnet'] . + $vip['subnet_bits']; + $oldvips[$vip['subnet']]['interface'] = + $vip['interface']; + $oldvips[$vip['subnet']]['subnet'] = + $vip['subnet']; + } else if (($vip['mode'] == "ipalias" || + $vip['mode'] == 'proxyarp') && + !(substr($vip['interface'], 0, 4) == '_vip') + || strstr($vip['interface'], "lo0")) { $vipbackup[] = $vip; } } } - } - // For vip section, first keep items sent from the master - $config = array_merge_recursive_unique($config, $params[0]); + /* For vip section, first keep items sent from the master */ + $config = array_merge_recursive_unique($config, $sections); - /* Then add ipalias and proxyarp types already defined on the backup */ - if (is_array($vipbackup) && !empty($vipbackup)) { - if (!is_array($config['virtualip'])) { - $config['virtualip'] = array(); - } - if (!is_array($config['virtualip']['vip'])) { - $config['virtualip']['vip'] = array(); - } - foreach ($vipbackup as $vip) { - array_unshift($config['virtualip']['vip'], $vip); + /* + * Then add ipalias and proxyarp types already defined + * on the backup + */ + if (is_array($vipbackup) && !empty($vipbackup)) { + if (!is_array($config['virtualip'])) { + $config['virtualip'] = array(); + } + if (!is_array($config['virtualip']['vip'])) { + $config['virtualip']['vip'] = array(); + } + foreach ($vipbackup as $vip) { + array_unshift($config['virtualip']['vip'], $vip); + } } - } - /* Log what happened */ - $mergedkeys = implode(",", array_merge(array_keys($params[0]), $sync_full_done)); - write_config(sprintf(gettext("Merged in config (%s sections) from XMLRPC client."), $mergedkeys)); - - /* - * The real work on handling the vips specially - * This is a copy of intefaces_vips_configure with addition of not reloading existing/not changed carps - */ - if (isset($params[0]['virtualip']) && is_array($config['virtualip']) && is_array($config['virtualip']['vip'])) { - $carp_setuped = false; - $anyproxyarp = false; - foreach ($config['virtualip']['vip'] as $vip) { - if ($vip['mode'] == "carp" && isset($oldvips["{$vip['interface']}_vip{$vip['vhid']}"])) { - if ($oldvips["{$vip['interface']}_vip{$vip['vhid']}"]['content'] == "{$vip['password']}{$vip['advskew']}{$vip['subnet']}{$vip['subnet_bits']}{$vip['advbase']}") { - if (does_vip_exist($vip)) { - unset($oldvips["{$vip['interface']}_vip{$vip['vhid']}"]); - continue; // Skip reconfiguring this vips since nothing has changed. + /* Log what happened */ + $mergedkeys = implode(",", array_merge(array_keys($sections), + $syncd_full_sections)); + write_config(sprintf(gettext( + "Merged in config (%s sections) from XMLRPC client."), + $mergedkeys)); + + /* + * The real work on handling the vips specially + * This is a copy of intefaces_vips_configure with addition of + * not reloading existing/not changed carps + */ + if (isset($sections['virtualip']) && + is_array($config['virtualip']) && + is_array($config['virtualip']['vip'])) { + $carp_setuped = false; + $anyproxyarp = false; + + foreach ($config['virtualip']['vip'] as $vip) { + $key = "{$vip['interface']}_vip{$vip['vhid']}"; + + if ($vip['mode'] == "carp" && + isset($oldvips[$key])) { + if ($oldvips[$key]['content'] == + $vip['password'] . + $vip['advskew'] . + $vip['subnet'] . + $vip['subnet_bits'] . + $vip['advbase'] && + does_vip_exist($vip)) { + unset($oldvips[$key]); + /* + * Skip reconfiguring this vips + * since nothing has changed. + */ + continue; } - } - } else if ($vip['mode'] == "ipalias" && strstr($vip['interface'], "_vip") && isset($oldvips[$vip['subnet']])) { - if ($oldvips[$vip['subnet']]['content'] == "{$vip['interface']}{$vip['subnet']}{$vip['subnet_bits']}") { - if (does_vip_exist($vip)) { - unset($oldvips[$vip['subnet']]); - continue; // Skip reconfiguring this vips since nothing has changed. + } elseif ($vip['mode'] == "ipalias" && + strstr($vip['interface'], "_vip") && + isset($oldvips[$vip['subnet']])) { + + $key = $vip['subnet']; + if ($oldvips[$key]['content'] == + $vip['interface'] . + $vip['subnet'] . + $vip['subnet_bits'] && + does_vip_exist($vip)) { + unset($oldvips[$key]); + /* + * Skip reconfiguring this vips + * since nothing has changed. + */ + continue; } + unset($oldvips[$key]); } - unset($oldvips[$vip['subnet']]); - } - switch ($vip['mode']) { + switch ($vip['mode']) { case "proxyarp": $anyproxyarp = true; break; @@ -262,308 +337,244 @@ function restore_config_section_xmlrpc($raw_params) { interface_ipalias_configure($vip); break; case "carp": - if ($carp_setuped == false) { - $carp_setuped = true; - } + $carp_setuped = true; interface_carp_configure($vip); break; + } } - } - /* Cleanup remaining old carps */ - foreach ($oldvips as $oldvipar) { - $oldvipif = get_real_interface($oldvipar['interface']); - if (!empty($oldvipif)) { + + /* Cleanup remaining old carps */ + foreach ($oldvips as $oldvipar) { + $oldvipif = get_real_interface( + $oldvipar['interface']); + + if (empty($oldvipif)) { + continue; + } + if (is_ipaddrv6($oldvipar['subnet'])) { - mwexec("/sbin/ifconfig " . escapeshellarg($oldvipif) . " inet6 " . escapeshellarg($oldvipar['subnet']) . " delete"); + mwexec("/sbin/ifconfig " . + escapeshellarg($oldvipif) . + " inet6 " . + escapeshellarg($oldvipar['subnet']) . + " delete"); } else { - pfSense_interface_deladdress($oldvipif, $oldvipar['subnet']); + pfSense_interface_deladdress($oldvipif, + $oldvipar['subnet']); } } + if ($carp_setuped == true) { + interfaces_sync_setup(); + } + if ($anyproxyarp == true) { + interface_proxyarp_configure(); + } } - if ($carp_setuped == true) { - interfaces_sync_setup(); - } - if ($anyproxyarp == true) { - interface_proxyarp_configure(); + + if ($old_ipsec_enabled !== ipsec_enabled()) { + vpn_ipsec_configure(); } - } - if ($old_ipsec_enabled !== ipsec_enabled()) { - vpn_ipsec_configure(); + unset($old_config); + + return true; } - unset($old_config); + /** + * Merge items into installedpackages config section + * + * @param string $username + * @param string $password + * @param array $section + * + * @return bool + */ + public function merge_installedpackages_section($username, $password, $section) { + $this->auth($username, $password); - return $xmlrpc_g['return']['true']; -} + global $config; -/*****************************/ -$merge_installedpackages_section_doc = gettext("XMLRPC wrapper for merging package sections. This method must be called with two parameters: a string containing the local system\'s password and an array to merge into the system\'s config. This function returns true upon completion."); -$merge_installedpackages_section_sig = array( - array( - $XML_RPC_Boolean, - $XML_RPC_String, - $XML_RPC_Struct - ) -); + if ($this->loop_detected) { + log_error("Disallowing CARP sync loop"); + return true; + } -function merge_installedpackages_section_xmlrpc($raw_params) { - global $config, $xmlrpc_g; + $config['installedpackages'] = array_merge( + $config['installedpackages'], $section); + $mergedkeys = implode(",", array_keys($section)); + write_config(sprintf(gettext( + "Merged in config (%s sections) from XMLRPC client."), + $mergedkeys)); - if (xmlrpc_loop_detect()) { - log_error("Disallowing CARP sync loop"); - return; + return true; } - $params = xmlrpc_params_to_php($raw_params); - if (!xmlrpc_auth($params)) { - xmlrpc_authfail(); - return $xmlrpc_g['return']['authfail']; - } - $config['installedpackages'] = array_merge($config['installedpackages'], $params[0]); - $mergedkeys = implode(",", array_keys($params[0])); - write_config(sprintf(gettext("Merged in config (%s sections) from XMLRPC client."), $mergedkeys)); + /** + * Merge items into config + * + * @param string $username + * @param string $password + * @param array $section + * + * @return bool + */ + public function merge_config_section($username, $password, $section) { + $this->auth($username, $password); - return $xmlrpc_g['return']['true']; -} + global $config; -/*****************************/ -$merge_config_section_doc = gettext("XMLRPC wrapper for merge_config_section. This method must be called with two parameters: a string containing the local system\'s password and an array to merge into the system\'s config. This function returns true upon completion."); -$merge_config_section_sig = array( - array( - $XML_RPC_Boolean, - $XML_RPC_String, - $XML_RPC_Struct - ) -); + if ($this->loop_detected) { + log_error("Disallowing CARP sync loop"); + return true; + } -function merge_config_section_xmlrpc($raw_params) { - global $config, $xmlrpc_g; + $config_new = $this->array_overlay($config, $section); + $config = $config_new; + $mergedkeys = implode(",", array_keys($section)); + write_config(sprintf(gettext( + "Merged in config (%s sections) from XMLRPC client."), + $mergedkeys)); - if (xmlrpc_loop_detect()) { - log_error("Disallowing CARP sync loop"); - return; + return true; } - $params = xmlrpc_params_to_php($raw_params); - if (!xmlrpc_auth($params)) { - xmlrpc_authfail(); - return $xmlrpc_g['return']['authfail']; - } - $config_new = array_overlay($config, $params[0]); - $config = $config_new; - $mergedkeys = implode(",", array_keys($params[0])); - write_config(sprintf(gettext("Merged in config (%s sections) from XMLRPC client."), $mergedkeys)); - return $xmlrpc_g['return']['true']; -} - -/*****************************/ -$filter_configure_doc = gettext("Basic XMLRPC wrapper for filter_configure. This method must be called with one parameter: a string containing the local system\'s password. This function returns true upon completion."); -$filter_configure_sig = array( - array( - $XML_RPC_Boolean, - $XML_RPC_String - ) -); - -function filter_configure_xmlrpc($raw_params) { - global $xmlrpc_g, $g, $config; - - $params = xmlrpc_params_to_php($raw_params); - if (!xmlrpc_auth($params)) { - xmlrpc_authfail(); - return $xmlrpc_g['return']['authfail']; - } - filter_configure(); - system_routing_configure(); - setup_gateways_monitor(); - relayd_configure(); - require_once("openvpn.inc"); - openvpn_resync_all(); - - /* The DNS Resolver and the DNS Forwarder may both be active so long as - * they are running on different ports. See ticket #5882 + /** + * Wrapper for filter_configure() + * + * @param string $username + * @param string $password + * + * @return bool */ - $need_dhcp_start = true; - if (isset($config['dnsmasq']['enable'])) { - /* Configure dnsmasq but tell it NOT to restart DHCP */ - services_dnsmasq_configure(false); - } else { - /* kill any running dnsmasq since it is not enabled. */ - if (file_exists("{$g['varrun_path']}/dnsmasq.pid")) { - sigkillbypid("{$g['varrun_path']}/dnsmasq.pid", "TERM"); + public function filter_configure($username, $password) { + $this->auth($username, $password); + + global $g, $config; + + filter_configure(); + system_routing_configure(); + setup_gateways_monitor(); + relayd_configure(); + require_once("openvpn.inc"); + openvpn_resync_all(); + + /* + * The DNS Resolver and the DNS Forwarder may both be active so + * long as * they are running on different ports. + * See ticket #5882 + */ + if (isset($config['dnsmasq']['enable'])) { + /* Configure dnsmasq but tell it NOT to restart DHCP */ + services_dnsmasq_configure(false); + } else { + /* kill any running dnsmasq instance */ + if (isvalidpid("{$g['varrun_path']}/dnsmasq.pid")) { + sigkillbypid("{$g['varrun_path']}/dnsmasq.pid", + "TERM"); + } } - } - if (isset($config['unbound']['enable'])) { - /* Configure unbound but tell it NOT to restart DHCP */ - services_unbound_configure(false); - } else { - /* kill any running Unbound instance since it is not enabled. */ - if (file_exists("{$g['varrun_path']}/unbound.pid")) { - sigkillbypid("{$g['varrun_path']}/unbound.pid", "TERM"); + if (isset($config['unbound']['enable'])) { + /* Configure unbound but tell it NOT to restart DHCP */ + services_unbound_configure(false); + } else { + /* kill any running Unbound instance */ + if (isvalidpid("{$g['varrun_path']}/unbound.pid")) { + sigkillbypid("{$g['varrun_path']}/unbound.pid", + "TERM"); + } } - } - - /* Call this separately since the above are manually set to skip the DHCP restart they normally perform. - * This avoids restarting dhcpd twice as described on ticket #3797 - */ - services_dhcpd_configure(); - - local_sync_accounts(); - return $xmlrpc_g['return']['true']; -} - -/*****************************/ -$carp_configure_doc = gettext("Basic XMLRPC wrapper for configuring CARP interfaces."); -$carp_configure_sig = array( - array( - $XML_RPC_Boolean, - $XML_RPC_String - ) -); - -function interfaces_carp_configure_xmlrpc($raw_params) { - global $xmlrpc_g; + /* + * Call this separately since the above are manually set to + * skip the DHCP restart they normally perform. + * This avoids restarting dhcpd twice as described on + * ticket #3797 + */ + services_dhcpd_configure(); - if (xmlrpc_loop_detect()) { - log_error("Disallowing CARP sync loop"); - return; - } + local_sync_accounts(); - $params = xmlrpc_params_to_php($raw_params); - if (!xmlrpc_auth($params)) { - xmlrpc_authfail(); - return $xmlrpc_g['return']['authfail']; + return true; } - interfaces_vips_configure(); - return $xmlrpc_g['return']['true']; -} + /** + * Wrapper for configuring CARP interfaces + * + * @param string $username + * @param string $password + * + * @return bool + */ + public function interfaces_carp_configure($username, $password) { + $this->auth($username, $password); -/*****************************/ -$pfsense_firmware_version_doc = gettext("Basic XMLRPC wrapper for host_firmware_version. This function will return the output of host_firmware_version upon completion."); + if ($this->loop_detected) { + log_error("Disallowing CARP sync loop"); + return true; + } -$pfsense_firmware_version_sig = array ( - array ( - $XML_RPC_Struct, - $XML_RPC_String - ) -); + interfaces_vips_configure(); -function pfsense_firmware_version_xmlrpc($raw_params) { - global $xmlrpc_g; + return true; + } - $params = xmlrpc_params_to_php($raw_params); - if (!xmlrpc_auth($params)) { - xmlrpc_authfail(); - return $xmlrpc_g['return']['authfail']; - } - return new XML_RPC_Response(XML_RPC_encode(host_firmware_version())); -} + /** + * Wrapper for rc.reboot + * + * @param string $username + * @param string $password + * + * @return bool + */ + public function reboot($username, $password) { + $this->auth($username, $password); -/*****************************/ -$reboot_doc = gettext("Basic XMLRPC wrapper for rc.reboot."); -$reboot_sig = array(array($XML_RPC_Boolean, $XML_RPC_String)); -function reboot_xmlrpc($raw_params) { - global $xmlrpc_g; + mwexec_bg("/etc/rc.reboot"); - $params = xmlrpc_params_to_php($raw_params); - if (!xmlrpc_auth($params)) { - xmlrpc_authfail(); - return $xmlrpc_g['return']['authfail']; + return true; } - mwexec_bg("/etc/rc.reboot"); - return $xmlrpc_g['return']['true']; -} + /** + * Wrapper for get_notices() + * + * @param string $username + * @param string $password + * @param string $category + * + * @return bool + */ + public function get_notices($username, $password, $category = 'all') { + $this->auth($username, $password); -/*****************************/ -$get_notices_sig = array( - array( - $XML_RPC_Array, - $XML_RPC_String - ), - array( - $XML_RPC_Array - ) -); + global $g; -function get_notices_xmlrpc($raw_params) { - global $g, $xmlrpc_g; + if (!function_exists("get_notices")) { + require_once("notices.inc"); + } + if (!$params) { + $toreturn = get_notices(); + } else { + $toreturn = get_notices($params); + } - $params = xmlrpc_params_to_php($raw_params); - if (!xmlrpc_auth($params)) { - xmlrpc_authfail(); - return $xmlrpc_g['return']['authfail']; + return $toreturn; } - if (!function_exists("get_notices")) { - require_once("notices.inc"); - } - if (!$params) { - $toreturn = get_notices(); - } else { - $toreturn = get_notices($params); - } - $response = new XML_RPC_Response(XML_RPC_encode($toreturn)); - - return $response; } $xmlrpclockkey = lock('xmlrpc', LOCK_EX); -/*****************************/ -$server = new XML_RPC_Server( - array( - 'pfsense.exec_shell' => array('function' => 'exec_shell_xmlrpc', - 'signature' => $exec_shell_sig, - 'docstring' => $exec_shell_doc), - 'pfsense.exec_php' => array('function' => 'exec_php_xmlrpc', - 'signature' => $exec_php_sig, - 'docstring' => $exec_php_doc), - 'pfsense.filter_configure' => array('function' => 'filter_configure_xmlrpc', - 'signature' => $filter_configure_sig, - 'docstring' => $filter_configure_doc), - 'pfsense.interfaces_carp_configure' => array('function' => 'interfaces_carp_configure_xmlrpc', - 'signature' => $carp_configure_sig, - 'docstring' => $carp_configure_doc), - 'pfsense.backup_config_section' => array('function' => 'backup_config_section_xmlrpc', - 'signature' => $backup_config_section_sig, - 'docstring' => $backup_config_section_doc), - 'pfsense.restore_config_section' => array('function' => 'restore_config_section_xmlrpc', - 'signature' => $restore_config_section_sig, - 'docstring' => $restore_config_section_doc), - 'pfsense.merge_config_section' => array('function' => 'merge_config_section_xmlrpc', - 'signature' => $merge_config_section_sig, - 'docstring' => $merge_config_section_doc), - 'pfsense.merge_installedpackages_section_xmlrpc' => array('function' => 'merge_installedpackages_section_xmlrpc', - 'signature' => $merge_installedpackages_section_sig, - 'docstring' => $merge_installedpackages_section_doc), - 'pfsense.host_firmware_version' => array('function' => 'pfsense_firmware_version_xmlrpc', - 'signature' => $pfsense_firmware_version_sig, - 'docstring' => $pfsense_firmware_version_doc), - 'pfsense.reboot' => array('function' => 'reboot_xmlrpc', - 'signature' => $reboot_sig, - 'docstring' => $reboot_doc), - 'pfsense.get_notices' => array('function' => 'get_notices_xmlrpc', - 'signature' => $get_notices_sig) - ) +XML_RPC2_Backend::setBackend('php'); +$HTTP_RAW_POST_DATA = file_get_contents('php://input'); + +$options = array( + 'prefix' => 'pfsense.', + 'encoding' => 'utf-8', + 'autoDocument' => true, ); -unlock($xmlrpclockkey); +$server = XML_RPC2_Server::create(new pfsense_xmlrpc_server(), $options); +$server->handleCall(); -function array_overlay($a1, $a2) { - foreach ($a1 as $k => $v) { - if (!array_key_exists($k, $a2)) { - continue; - } - if (is_array($v) && is_array($a2[$k])) { - $a1[$k] = array_overlay($v, $a2[$k]); - } else { - $a1[$k] = $a2[$k]; - } - } - return $a1; -} +unlock($xmlrpclockkey); ?> |