<?php /* pfblocker.inc part of the Postfix package for pfSense Copyright (C) 2010 Erik Fonnesbeck Copyright (C) 2011-2012 Marcello Coutinho 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("util.inc"); require_once("functions.inc"); require_once("pkg-utils.inc"); require_once("globals.inc"); require_once("filter.inc"); require_once("services.inc"); $uname=posix_uname(); if ($uname['machine']=='amd64') ini_set('memory_limit', '250M'); function pfb_text_area_decode($text){ return preg_replace('/\r\n/', "\n",base64_decode($text)); } function cb_get_real_interface_address($iface) { global $config; $iface = convert_friendly_interface_to_real_interface_name($iface); $line = trim(shell_exec("ifconfig $iface | grep inet | grep -v inet6")); list($dummy, $ip, $dummy2, $netmask) = explode(" ", $line); return array($ip, long2ip(hexdec($netmask))); } function sync_package_pfblocker($cron="") { global $g,$config; # detect boot process or update via cron if (is_array($_POST) && $cron==""){ if (!preg_match("/\w+/",$_POST['__csrf_magic'])){ log_error("No pfBlocker action during boot process."); return; } } log_error("Starting pfBlocker sync process."); conf_mount_rw(); #apply fetch timeout to pfsense-utils.inc $pfsense_utils=file_get_contents('/etc/inc/pfsense-utils.inc'); $new_pfsense_utils=preg_replace("/\/usr\/bin\/fetch -q/","/usr/bin/fetch -T 5 -q",$pfsense_utils); if ($new_pfsense_utils != $pfsense_utils){ file_put_contents('/etc/inc/pfsense-utils.inc',$new_pfsense_utils, LOCK_EX); } $pfblocker_enable=$config['installedpackages']['pfblocker']['config'][0]['enable_cb']; $pfblocker_config=$config['installedpackages']['pfblocker']['config'][0]; $table_limit =($config['system']['maximumtableentries']!= ""?$config['system']['maximumtableentries']:"100000"); #get local web gui configuration $web_local=($config['system']['webgui']['protocol'] != ""?$config['system']['webgui']['protocol']:"http"); $port = $config['system']['webgui']['port']; if($port == "") { if($config['system']['webgui']['protocol'] == "http"){ $port = "80"; } else{ $port = "443"; } } $web_local .= "://127.0.0.1:".$port.'/pfblocker.php'; #check folders $pfbdir='/usr/local/pkg/pfblocker'; $pfb_alias_dir='/usr/local/pkg/pfblocker_aliases'; $pfsense_alias_dir='/var/db/aliastables/'; if (!is_dir($pfbdir)){ mkdir ($pfbdir,0755); } if (!is_dir($pfb_alias_dir)){ mkdir ($pfb_alias_dir,0755); } if (! is_dir($pfsense_alias_dir)){ mkdir ($pfsense_alias_dir,0755); } $continents= array( "Africa" => "pfBlockerAfrica", "Antartica" => "pfBlockerAntartica", "Asia" => "pfBlockerAsia", "Europe" => "pfBlockerEurope", "North America" => "pfBlockerNorthAmerica", "Oceania" => "pfBlockerOceania", "South America" => "pfBlockerSouthAmerica", "Top Spammers" => "pfBlockerTopSpammers"); #create rules vars and arrays $new_aliases=array(); $new_aliases_list=array(); $permit_inbound=array(); $permit_outbound=array(); $deny_inbound=array(); $deny_outbound=array(); $aliases_list=array(); #check if pfblocker is enabled or not. $deny_action_inbound=($pfblocker_config['inbound_deny_action']!= ""?$pfblocker_config['inbound_deny_action']:"block"); $deny_action_outbound=($pfblocker_config['outbound_deny_action']!= ""?$pfblocker_config['outbound_deny_action']:"reject"); $base_rule= array( "id" => "", "tag"=> "", "tagged"=> "", "max"=> "", "max-src-nodes"=>"", "max-src-conn"=> "", "max-src-states"=>"", "statetimeout"=>"", "statetype"=>"keep state", "os"=> ""); ############################################# # Assign Countries # ############################################# foreach ($continents as $continent => $pfb_alias){ ${$continent}=""; if (is_array($config['installedpackages']['pfblocker'.strtolower(preg_replace('/ /','',$continent))]['config'])){ $continent_config=$config['installedpackages']['pfblocker'.strtolower(preg_replace('/ /','',$continent))]['config'][0]; if ($continent_config['action'] != 'Disabled' && $continent_config['action'] != '' && $pfblocker_enable == "on"){ foreach (explode(",", $continent_config['countries']) as $iso){ #var_dump ($iso); if ($iso <> "" && file_exists($pfbdir.'/'.$iso.'.txt')){ ${$continent} .= file_get_contents($pfbdir.'/'.$iso.'.txt'); } } if($continent_config['countries'] != "" && $pfblocker_enable == "on"){ #write alias files file_put_contents($pfb_alias_dir.'/'.$pfb_alias.'.txt',${$continent},LOCK_EX); file_put_contents($pfsense_alias_dir.'/'.$pfb_alias.'.txt',${$continent}, LOCK_EX); #Create alias config $new_aliases_list[]=$pfb_alias; $new_aliases[]=array( "name"=> $pfb_alias, "url"=> $web_local.'?pfb='.$pfb_alias, "updatefreq"=> "32", "address"=>"", "descr"=> "pfBlocker country list", "type"=> "urltable", "detail"=> "DO NOT EDIT THIS ALIAS"); #Create rule if action permits switch($continent_config['action']){ case "Deny_Both": $rule = $base_rule; $rule["type"] = $deny_action_inbound; $rule["descr"]= "$pfb_alias auto rule"; $rule["source"]= array("address"=> $pfb_alias); $rule["destination"]=array("any"=>""); if ($pfblocker_config['enable_log']){ $rule["log"]=""; } $deny_inbound[]=$rule; case "Deny_Outbound": $rule = $base_rule; $rule["type"] = $deny_action_outbound; $rule["descr"]= "$pfb_alias auto rule"; $rule["source"]=array("any"=>""); $rule["destination"]= array("address"=> $pfb_alias); if ($pfblocker_config['enable_log']){ $rule["log"]=""; } $deny_outbound[]=$rule; break; case "Deny_Inbound": $rule = $base_rule; $rule["type"] = $deny_action_inbound; $rule["descr"]= "$pfb_alias auto rule"; $rule["source"]= array("address"=> $pfb_alias); $rule["destination"]=array("any"=>""); if ($pfblocker_config['enable_log']){ $rule["log"]=""; } $deny_inbound[]=$rule; break; case "Permit_Outbound": $rule = $base_rule; $rule["type"] = "pass"; $rule["descr"]= "$pfb_alias auto rule"; $rule["source"]=array("any"=>""); $rule["destination"]= array("address"=> $pfb_alias); if ($pfblocker_config['enable_log']){ $rule["log"]=""; } $permit_outbound[]=$rule; break; case "Permit_Inbound": $rule = $base_rule; $rule["type"] = "pass"; $rule["descr"]= "$pfb_alias auto rule"; $rule["source"]= array("address"=> $pfb_alias); $rule["destination"]=array("any"=>""); if ($pfblocker_config['enable_log']){ $rule["log"]=""; } $permit_inbound[]=$rule; break; } } } else{ #unlink continent list if any unlink_if_exists($pfb_alias_dir.'/'.$pfb_alias.'.txt'); } } #mark pfctl aliastable for cleanup if (!in_array($pfb_alias, $aliases_list)){ $aliases_list[]=$pfb_alias; } } ############################################# # Assign lists # ############################################# #print "<pre>"; if($config['installedpackages']['pfblockerlists']['config'] != ""){ foreach($config['installedpackages']['pfblockerlists']['config'] as $list){ $alias="pfBlocker".preg_replace("/\W/","",$list['aliasname']); #print $list['aliasname'].$list['action']." ".$alias." ".$row['url']."<br>"; if ($alias != "pfBlocker" && $list['action'] != "" && $list['action'] != 'Disabled' && $pfblocker_enable == "on"){ #remove empty lists files if any if (is_array($list['row'])){ foreach ($list['row'] as $row){ #print $list['aliasname'].$list['action'].$list['cron']." ".$alias." ".$row['url']."$update_local<br>"; if ($row['url'] != ""){ $md5_url = md5($row['url']); if (file_exists($pfbdir."/".$md5_url.".txt")){ ${$alias}.= file_get_contents($pfbdir.'/'.$md5_url.'.txt'); } else{ if ($row['format'] == "gz"){ $url_list= gzfile($row['url']); } else{ $url_list= file($row['url']); } #extract range lists $new_file=""; if (is_array($url_list)){ foreach ($url_list as $line){ # Network range 192.168.0.0-192.168.0.254 if (preg_match("/(\d+\.\d+\.\d+\.\d+)-(\d+\.\d+\.\d+\.\d+)/",$line,$matches)){ $a_cidr = ip_range_to_subnet_array($matches[1],$matches[2]); if (is_array($a_cidr)) { foreach ($a_cidr as $cidr) { ${$alias}.= $cidr."\n"; $new_file.= $cidr."\n"; } } } # CIDR format 192.168.0.0/16 else if (preg_match("/(\d+\.\d+\.\d+\.\d+\/\d+)/",$line,$matches)){ ${$alias}.= $matches[1]."\n"; $new_file.= $matches[1]."\n"; } # Single ip addresses else if (preg_match("/(\d+\.\d+\.\d+\.\d+)\s+/",$line,$matches)){ ${$alias}.= $matches[1]."/32\n"; $new_file.= $matches[1]."/32\n"; } } } if ($new_file != ""){ file_put_contents($pfbdir.'/'.$md5_url.'.txt',$new_file, LOCK_EX); } } } } } #check custom network list if (pfb_text_area_decode($list['custom']) != ""){ ${$alias}.=pfb_text_area_decode($list['custom'])."\n"; } #save alias file if not empty if (${$alias} == ""){ unlink_if_exists($pfb_alias_dir.'/'.$alias.'.txt'); } else{ file_put_contents($pfb_alias_dir.'/'.$alias.'.txt',${$alias}, LOCK_EX); file_put_contents($pfsense_alias_dir.'/'.$alias.'.txt',${$alias}, LOCK_EX); #create alias $new_aliases_list[]=$alias; $new_aliases[]=array( "name"=> $alias, "url"=> $web_local.'?pfb='.$alias, "updatefreq"=> "32", "address"=>"", "descr"=> "pfBlocker user list", "type"=> "urltable", "detail"=> "DO NOT EDIT THIS ALIAS"); #Create rule if action permits switch($list['action']){ case "Deny_Both": $rule = $base_rule; $rule["type"] = $deny_action_inbound; $rule["descr"]= "$alias auto rule"; $rule["source"]= array("address"=> $alias); $rule["destination"]=array("any"=>""); if ($pfblocker_config['enable_log']){ $rule["log"]=""; } $deny_inbound[]=$rule; case "Deny_Outbound": $rule = $base_rule; $rule["type"] = $deny_action_outbound; $rule["descr"]= "$alias auto rule"; $rule["source"]=array("any"=>""); $rule["destination"]= array("address"=> $alias); if ($pfblocker_config['enable_log']){ $rule["log"]=""; } $deny_outbound[]=$rule; break; case "Deny_Inbound": $rule = $base_rule; $rule["type"] = $deny_action_inbound; $rule["descr"]= "$alias auto rule"; $rule["source"]= array("address"=> $alias); $rule["destination"]=array("any"=>""); if ($pfblocker_config['enable_log']){ $rule["log"]=""; } $deny_inbound[]=$rule; break; case "Permit_Outbound": $rule = $base_rule; $rule["type"] = "pass"; $rule["descr"]= "$alias auto rule"; $rule["source"]=array("any"=>""); $rule["destination"]= array("address"=> $alias); if ($pfblocker_config['enable_log']){ $rule["log"]=""; } $permit_outbound[]=$rule; break; case "Permit_Inbound": $rule = $base_rule; $rule["type"] = "pass"; $rule["descr"]= "$alias auto rule"; $rule["source"]= array("address"=> $alias); $rule["destination"]=array("any"=>""); if ($pfblocker_config['enable_log']){ $rule["log"]=""; } $permit_inbound[]=$rule; break; } } #mark pfctl aliastable for cleanup if (!in_array($alias, $aliases_list)){ $aliases_list[]=$alias; } } else{ #unlink previous pfblocker alias list if any unlink_if_exists($pfb_alias_dir.'/'.$alias.'.txt'); } } } #update pfsense alias table if (is_array($config['aliases']['alias'])){ $aliases=$config['aliases']['alias']; foreach($aliases as $cbalias){ if (preg_match("/pfBlocker/",$cbalias['name'])){ #mark pfctl aliastable for cleaning if (!in_array($cbalias['name'], $aliases_list)){ $aliases_list[]=$cbalias['name']; #mark aliastable for cleaning } #remove previous aliastable file if alias is not defined any more if (!in_array($cbalias['name'], $new_aliases_list)){ unlink_if_exists("/var/db/aliastables/".$cbalias['name'].".txt"); } } else{ $new_aliases[]= $cbalias; if (file_exists($pfb_alias_dir.'/'.$alias.'.txt') && $message ==""){ preg_match("/(\d+)/",exec("/usr/bin/wc -l ".$pfb_alias_dir.'/'.$alias.'.txt'),$matches); } if (($matches[1] * 2.1)>= $table_limit ){ #alias table too large $message= $alias .' alias table is too large. Reduce networks in list or increase "Firewall Maximum Table Entries" value to at least '. (int)($matches[1] * 2.1) .' in "system - advanced - Firewall/NAT".'; } } } } #apply new alias table to xml if ($message == ""){ $config['aliases']['alias']=$new_aliases; } #exit; ############################################# # Assign rules # ############################################# #print "<pre>"; #var_dump($permit_inbound); #var_dump($permit_outbound); #var_dump($deny_inbound); #var_dump($deny_outbound); #var_dump($pfblocker_config['inbound_interface']); #print count($deny_inbound) .count($deny_inbound); # Inbound filter options $inbound_interfaces = explode(",",$pfblocker_config['inbound_interface']); if (count($deny_inbound) > 0 || count($permit_inbound) > 0){ if($pfblocker_config['inbound_interface'] == ""){ $message="Unable to apply rules.Inbound Interface option not configured."; } if (in_array("lo0",$inbound_interfaces)){ $message="Floating rules are not implemented in pfBlocker yet, choose Inbound Interface other than loopback or change action to Alias only."; } } # Outbound filter options $outbound_interfaces = explode(",",$pfblocker_config['outbound_interface']); if (count($deny_outbound) > 0 || count($permit_outbound) > 0){ if($pfblocker_config['outbound_interface'] == ""){ $message="Unable to apply rules.Outbound Interface option not configured."; } if (in_array("lo0",$outbound_interfaces)){ $message="Floating rules are not implemented in pfBlocker yet, choose Outbound Interface other than loopback or change action to Alias only."; } } if ($message == ""){ $rules=$config['filter']['rule']; $new_rules=array(); $interfaces_processed=array(); # The rules in the config come in priority order, # but the interface to which each rule applies can be all mixed up in the list. # e.g. some WAN rules, then some LAN rules, then some floating rules, then more # LAN rules, some OPT1 rules, some more LAN rules and so on. # So we have to allow for this, and only add pfBlocker rules the first time an # interface is found in the rules list. foreach ($rules as $rule){ # If this next rule is for a non-blank interface, different from any interface already processed, # then add any needed pfblocker rules to the interface. This puts pfblocker rules at the # top of the list for each interface, after any built-in rules (e.g. anti-lockout) $found_new_interface = TRUE; foreach ($interfaces_processed as $processed_interface){ if ($processed_interface == $rule['interface']){ $found_new_interface = FALSE; } } if (($rule['interface'] != "") && ($found_new_interface)){ $interfaces_processed[] = $rule['interface']; #apply pfblocker rules if enabled #Inbound foreach ($inbound_interfaces as $inbound_interface){ if ($inbound_interface==$rule['interface']){ #permit rules if (is_array($permit_inbound)){ foreach ($permit_inbound as $cb_rules){ $cb_rules['interface']=$rule['interface']; $new_rules[]=$cb_rules; } } #deny rules if (is_array($deny_inbound)){ foreach ($deny_inbound as $cb_rules){ $cb_rules['interface']=$rule['interface']; $new_rules[]=$cb_rules; } } } } #Outbound foreach ($outbound_interfaces as $outbound_interface){ if ($outbound_interface==$rule['interface']){ #permit rules if (is_array($permit_outbound)){ foreach ($permit_outbound as $cb_rules){ $cb_rules['interface']=$rule['interface']; $new_rules[]=$cb_rules; } } #deny rules if (is_array($deny_outbound)){ foreach ($deny_outbound as $cb_rules){ $cb_rules['interface']=$rule['interface']; $new_rules[]=$cb_rules; } } } } } #include all rules that are not from pfBlocker if (!preg_match("/pfBlocker.*rule/",$rule['descr']) && ($rule['interface'] != "" || $rule['floating']=="yes")){ $new_rules[]=$rule; } } $config['filter']['rule']=$new_rules; } if ($message == ""){ #check cron $cron_found=0; $cron_cmd="/usr/local/bin/php -q /usr/local/www/pfblocker.php cron"; if (is_array($config['cron']['item'])){ $new_cron=array(); foreach($config['cron']['item'] as $cron){ if (preg_match("/usr.local.www.pfblocker.php cron/",$cron["command"])){ #fix 0.1.4.6 missing php path if($cron["command"]==$cron_cmd && $pfblocker_enable == "on"){ $new_cron['item'][]=$cron; $cron_found=1; } } else{ $new_cron['item'][]=$cron; } } if ($cron_found == 0){ if($pfblocker_enable == "on"){ $new_cron['item'][]=array( "minute" => "0", "hour" => "*", "mday" => "*", "month" => "*", "wday" => "*", "who" => "root", "command"=> $cron_cmd); } $config['cron']=$new_cron; } } # to be removed in final version $aliases_list[]="pfBlockerInbound"; #remove previous version lists $aliases_list[]="pfBlockerOutbound"; #remove previous version lists $aliases_list[]="pfBlockerWL"; #remove previous version lists #exit; #update pfctrl tables foreach ($aliases_list as $table){ exec("/sbin/pfctl -t " . escapeshellarg($table) . " -T kill 2>&1", $result_pfb); } #uncheck donation and credits check box $config['installedpackages']['pfblocker']['config'][0]['donation']=""; $config['installedpackages']['pfblocker']['config'][0]['credits']=""; #write config write_config(); #update cron if ($cron_found == 0){ configure_cron(); } #load filter file after editing filter_configure(); #sync config pfblocker_sync_on_changes(); } else{ log_error("[pfBlocker] ".$message); file_notice("pfBlocker", $message, "pfblocker rule apply", ""); } conf_mount_ro(); } function pfblocker_validate_input($post, &$input_errors) { global $config; foreach ($post as $key => $value) { if (empty($value)) continue; if($key == "message_size_limit" && !is_numeric($value)) $input_errors[] = "Message size limit must be numeric."; if($key == "process_limit" && !is_numeric($value)) $input_errors[] = "Process limit must be numeric."; if($key == "freq" && (!preg_match("/^\d+(h|m|d)$/",$value) || $value == 0)) $input_errors[] = "A valid number with a time reference is required for the field 'Frequency'"; if (substr($key, 0, 2) == "dc" && !is_hostname($value)) $input_errors[] = "{$value} is not a valid host name."; if (substr($key, 0, 6) == "domain" && is_numeric(substr($key, 6))) { if (!is_domain($value)) $input_errors[] = "{$value} is not a valid domain name."; } else if (substr($key, 0, 12) == "mailserverip" && is_numeric(substr($key, 12))) { if (empty($post['domain' . substr($key, 12)])) $input_errors[] = "Domain for {$value} cannot be blank."; if (!is_ipaddr($value) && !is_hostname($value)) $input_errors[] = "{$value} is not a valid IP address or host name."; } } } function pfblocker_php_install_command() { include_once '/usr/local/www/pfblocker.php'; pfblocker_get_countries(); sync_package_pfblocker(); } function pfblocker_php_deinstall_command() { global $config; $config['installedpackages']['pfblocker']['config'][0]['enable_cb']=""; write_config(); sync_package_pfblocker(); } /* Uses XMLRPC to synchronize the changes to a remote node */ function pfblocker_sync_on_changes() { global $config, $g; log_error("[pfblocker] pfblocker_xmlrpc_sync.php is starting."); $synconchanges = $config['installedpackages']['pfblockersync']['config'][0]['synconchanges']; if(!$synconchanges) return; foreach ($config['installedpackages']['pfblockersync']['config'] as $rs ){ foreach($rs['row'] as $sh){ $sync_to_ip = $sh['ipaddress']; $password = $sh['password']; if($password && $sync_to_ip){ pfblocker_do_xmlrpc_sync($sync_to_ip, $password); } } } log_error("[pfblocker] pfblocker_xmlrpc_sync.php is ending."); } /* Do the actual XMLRPC sync */ function pfblocker_do_xmlrpc_sync($sync_to_ip, $password) { global $config, $g; if(!$password) return; if(!$sync_to_ip) return; $xmlrpc_sync_neighbor = $sync_to_ip; if($config['system']['webgui']['protocol'] != "") { $synchronizetoip = $config['system']['webgui']['protocol']; $synchronizetoip .= "://"; } $port = $config['system']['webgui']['port']; /* if port is empty lets rely on the protocol selection */ if($port == "") { if($config['system']['webgui']['protocol'] == "http"){ $port = "80"; } else{ $port = "443"; } } $synchronizetoip .= $sync_to_ip; /* xml will hold the sections to sync */ $xml = array(); $xml['pfblocker'] = $config['installedpackages']['pfblocker']; $xml['pfblockerlists'] = $config['installedpackages']['pfblockerlists']; $xml['pfblockertopspammers'] = $config['installedpackages']['pfblockertopspammers']; $xml['pfblockerafrica'] = $config['installedpackages']['pfblockerafrica']; $xml['pfblockerantartica'] = $config['installedpackages']['pfblockerantartica']; $xml['pfblockerasia'] = $config['installedpackages']['pfblockerasia']; $xml['pfblockereurope'] = $config['installedpackages']['pfblockereurope']; $xml['pfblockernorthamerica'] = $config['installedpackages']['pfblockernorthamerica']; $xml['pfblockeroceania'] = $config['installedpackages']['pfblockeroceania']; $xml['pfblockersouthamerica'] = $config['installedpackages']['pfblockersouthamerica']; /* assemble xmlrpc payload */ $params = array( XML_RPC_encode($password), XML_RPC_encode($xml) ); /* set a few variables needed for sync code borrowed from filter.inc */ $url = $synchronizetoip; log_error("Beginning pfblocker XMLRPC sync to {$url}:{$port}."); $method = 'pfsense.merge_installedpackages_section_xmlrpc'; $msg = new XML_RPC_Message($method, $params); $cli = new XML_RPC_Client('/xmlrpc.php', $url, $port); $cli->setCredentials('admin', $password); if($g['debug']){ $cli->setDebug(1); } /* send our XMLRPC message and timeout after 250 seconds */ $resp = $cli->send($msg, "250"); if(!$resp) { $error = "A communications error occurred while attempting pfblocker XMLRPC sync with {$url}:{$port}."; log_error($error); file_notice("sync_settings", $error, "pfblocker Settings Sync", ""); } elseif($resp->faultCode()) { $cli->setDebug(1); $resp = $cli->send($msg, "250"); $error = "An error code was received while attempting pfblocker XMLRPC sync with {$url}:{$port} - Code " . $resp->faultCode() . ": " . $resp->faultString(); log_error($error); file_notice("sync_settings", $error, "pfblocker Settings Sync", ""); } else { log_error("pfblocker XMLRPC sync successfully completed with {$url}:{$port}."); } /* tell pfblocker to reload our settings on the destionation sync host. */ $method = 'pfsense.exec_php'; $execcmd = "require_once('/usr/local/pkg/pfblocker.inc');\n"; $execcmd .= "sync_package_pfblocker();"; /* assemble xmlrpc payload */ $params = array( XML_RPC_encode($password), XML_RPC_encode($execcmd) ); log_error("pfblocker XMLRPC reload data {$url}:{$port}."); $msg = new XML_RPC_Message($method, $params); $cli = new XML_RPC_Client('/xmlrpc.php', $url, $port); $cli->setCredentials('admin', $password); $resp = $cli->send($msg, "250"); if(!$resp) { $error = "A communications error occurred while attempting pfblocker XMLRPC sync with {$url}:{$port} (exec_php)."; log_error($error); file_notice("sync_settings", $error, "pfblocker Settings Sync", ""); } elseif($resp->faultCode()) { $cli->setDebug(1); $resp = $cli->send($msg, "250"); $error = "An error code was received while attempting pfblocker XMLRPC exec with {$url}:{$port} - Code " . $resp->faultCode() . ": " . $resp->faultString(); log_error($error); file_notice("sync_settings", $error, "pfblocker Settings Sync", ""); } else { log_error("pfblocker XMLRPC reload data success with {$url}:{$port} (exec_php)."); } } ?>