aboutsummaryrefslogtreecommitdiffstats
path: root/config/squid3/34/squid.inc
diff options
context:
space:
mode:
authorMarcello Coutinho <marcellocoutinho@gmail.com>2014-11-20 16:09:48 -0200
committerMarcello Coutinho <marcellocoutinho@gmail.com>2014-11-20 16:09:48 -0200
commitc8539d3211d79c628b59bdcc3eb363cc00e93707 (patch)
treef7b27f153abe80be30a403ae1071a9e87bc88234 /config/squid3/34/squid.inc
parentcb0e9496e3e0c541bcd1e6ccca4526a549f137d8 (diff)
downloadpfsense-packages-c8539d3211d79c628b59bdcc3eb363cc00e93707.tar.gz
pfsense-packages-c8539d3211d79c628b59bdcc3eb363cc00e93707.tar.bz2
pfsense-packages-c8539d3211d79c628b59bdcc3eb363cc00e93707.zip
squid3.4 - first package files
Diffstat (limited to 'config/squid3/34/squid.inc')
-rwxr-xr-xconfig/squid3/34/squid.inc2463
1 files changed, 2463 insertions, 0 deletions
diff --git a/config/squid3/34/squid.inc b/config/squid3/34/squid.inc
new file mode 100755
index 00000000..87232c2b
--- /dev/null
+++ b/config/squid3/34/squid.inc
@@ -0,0 +1,2463 @@
+<?php
+/* $Id$ */
+/*
+ squid.inc
+ Copyright (C) 2006-2009 Scott Ullrich
+ Copyright (C) 2006 Fernando Lemos
+ Copyright (C) 2012 Martin Fuchs
+ Copyright (C) 2012-2014 Marcello Coutinho
+ Copyright (C) 2013 Gekkenhuis
+ 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('globals.inc');
+require_once('config.inc');
+require_once('util.inc');
+require_once('pfsense-utils.inc');
+require_once('pkg-utils.inc');
+require_once('service-utils.inc');
+
+if(!function_exists("filter_configure"))
+ require_once("filter.inc");
+
+$shortcut_section = "squid";
+$pfs_version = substr(trim(file_get_contents("/etc/version")),0,3);
+if (is_dir('/usr/pbi/squid-' . php_uname("m"))) {
+ if ($pfs_version == 2.2)
+ define('SQUID_LOCALBASE', '/usr/pbi/squid-' . php_uname("m")."/local");
+ else
+ define('SQUID_LOCALBASE', '/usr/pbi/squid-' . php_uname("m"));
+} else {
+ define('SQUID_LOCALBASE','/usr/local');
+}
+
+define('SQUID_CONFBASE', SQUID_LOCALBASE .'/etc/squid');
+define('SQUID_CONFFILE', SQUID_CONFBASE . '/squid.conf');
+define('SQUID_BASE', '/var/squid/');
+define('SQUID_ACLDIR', '/var/squid/acl');
+define('SQUID_PASSWD', '/var/etc/squid.passwd');
+define('SQUID_LIB','/var/squid/lib');
+define('SQUID_SSL_DB','/var/squid/lib/ssl_db');
+
+$valid_acls = array();
+
+$uname=posix_uname();
+if ($uname['machine']=='amd64')
+ ini_set('memory_limit', '250M');
+
+ function sq_text_area_decode($text){
+ return preg_replace('/\r\n/', "\n",base64_decode($text));
+}
+
+
+function squid_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 squid_chown_recursive($dir, $user, $group) {
+ chown($dir, $user);
+ chgrp($dir, $group);
+ $handle = opendir($dir) ;
+ while (($item = readdir($handle)) !== false) {
+ if (($item != ".") && ($item != "..")) {
+ $path = "$dir/$item";
+ // Recurse unless it's the cache dir, that is slow and rarely necessary.
+ if (is_dir($path) && (basename($dir) != "cache"))
+ squid_chown_recursive($path, $user, $group);
+ elseif (is_file($path)) {
+ chown($path, $user);
+ chgrp($path, $group);
+ }
+ }
+ }
+}
+
+function squid_check_clamav_user($user)
+ {
+ exec("/usr/sbin/pw usershow {$user}",$sq_ex_output,$sq_ex_return);
+ $user_arg=($sq_ex_return == 0?"mod":"add");
+ exec("/usr/sbin/pw user{$user_arg} {$user} -G wheel -u 9595 -s /sbin/nologin",$sq_ex_output,$sq_ex_return);
+ if ($sq_ex_return != 0)
+ log_error("Squid - Could not change clamav user settings. ".serialize($sq_ex_output));
+ }
+
+/* setup cache */
+function squid_dash_z($cache_action='none') {
+ global $config;
+
+ //Do nothing if there is no cache config
+ if (!is_array($config['installedpackages']['squidcache']['config']))
+ return;
+
+ $settings = $config['installedpackages']['squidcache']['config'][0];
+
+ // If the cache system is null, there is no need to initialize the (irrelevant) cache dir.
+ if ($settings['harddisk_cache_system'] == "null")
+ return;
+
+ $cachedir =($settings['harddisk_cache_location'] ? $settings['harddisk_cache_location'] : '/var/squid/cache');
+
+ if ($cache_action=="clean"){
+ rename ($cachedir,"{$cachedir}.old");
+ mwexec_bg("/bin/rm -rf {$cachedir}.old");
+ }
+
+ if(!is_dir($cachedir.'/')) {
+ log_error("Creating Squid cache dir $cachedir");
+ make_dirs($cachedir);
+ // Double check permissions here, should be safe to recurse cache dir if it's small here.
+ mwexec("/usr/sbin/chown -R proxy:proxy $cachedir");
+ }
+
+ if(!is_dir($cachedir.'/00/')) {
+ log_error("Creating squid cache subdirs in $cachedir");
+ mwexec(SQUID_LOCALBASE. "/sbin/squid -k shutdown -f " . SQUID_CONFFILE);
+ sleep(5);
+ mwexec(SQUID_LOCALBASE. "/sbin/squid -k kill -f " . SQUID_CONFFILE);
+ // Double check permissions here, should be safe to recurse cache dir if it's small here.
+ mwexec("/usr/sbin/chown -R proxy:proxy $cachedir");
+ mwexec(SQUID_LOCALBASE. "/sbin/squid -z -f " . SQUID_CONFFILE);
+ }
+
+ if(file_exists("/var/squid/cache/swap.state")) {
+ chown("/var/squid/cache/swap.state", "proxy");
+ chgrp("/var/squid/cache/swap.state", "proxy");
+ exec("chmod a+rw /var/squid/cache/swap.state");
+ }
+
+}
+
+function squid_is_valid_acl($acl) {
+ global $valid_acls;
+ if(!is_array($valid_acls))
+ return;
+ return in_array($acl, $valid_acls);
+}
+
+function squid_install_command() {
+ global $config;
+ global $g;
+ update_status("Checking if there is configuration to migrate... One moment please...");
+ /* migrate existing csv config fields */
+ if (is_array($config['installedpackages']['squidauth']['config']))
+ $settingsauth = $config['installedpackages']['squidauth']['config'][0];
+ if (is_array($config['installedpackages']['squidcache']['config']))
+ $settingscache = $config['installedpackages']['squidcache']['config'][0];
+ if (is_array($config['installedpackages']['squidnac']['config']))
+ $settingsnac = $config['installedpackages']['squidnac']['config'][0];
+ if (is_array($config['installedpackages']['squid']['config']))
+ $settingsgen = $config['installedpackages']['squid']['config'][0];
+
+ if (file_exists("/usr/local/pkg/check_ip.php"))
+ rename("/usr/local/pkg/check_ip.php",SQUID_LOCALBASE . "/libexec/squid/check_ip.php");
+ /* Set storage system */
+ if ($g['platform'] == "nanobsd") {
+ $config['installedpackages']['squidcache']['config'][0]['harddisk_cache_system'] = 'null';
+ }
+
+ /* migrate auth settings */
+ if (!empty($settingsauth['no_auth_hosts'])) {
+ if(strstr($settingsauth['no_auth_hosts'], ",")) {
+ $settingsauth['no_auth_hosts'] = base64_encode(implode("\n", explode(",", $settingsauth['no_auth_hosts'])));
+ $config['installedpackages']['squidauth']['config'][0]['no_auth_hosts'] = $settingsauth['no_auth_hosts'];
+ }
+ }
+
+ /* migrate cache settings */
+ if (!empty($settingscache['donotcache'])) {
+ if(strstr($settingscache['donotcache'], ",")) {
+ $settingscache['donotcache'] = base64_encode(implode("\n", explode(",", $settingscache['donotcache'])));
+ $config['installedpackages']['squidcache']['config'][0]['donotcache'] = $settingscache['donotcache'];
+ }
+ }
+
+ /* migrate nac settings */
+ if(! empty($settingsnac['allowed_subnets'])) {
+ if(strstr($settingsnac['allowed_subnets'], ",")) {
+ $settingsnac['allowed_subnets'] = base64_encode(implode("\n", explode(",", $settingsnac['allowed_subnets'])));
+ $config['installedpackages']['squidnac']['config'][0]['allowed_subnets'] = $settingsnac['allowed_subnets'];
+ }
+ }
+ if(! empty($settingsnac['banned_hosts'])) {
+ if(strstr($settingsnac['banned_hosts'], ",")) {
+ $settingsnac['banned_hosts'] = base64_encode(implode("\n", explode(",", $settingsnac['banned_hosts'])));
+ $config['installedpackages']['squidnac']['config'][0]['banned_hosts'] = $settingsnac['banned_hosts'];
+ }
+ }
+
+ if(! empty($settingsnac['banned_macs'])) {
+ if(strstr($settingsnac['banned_macs'], ",")) {
+ $settingsnac['banned_macs'] = base64_encode(implode("\n", explode(",", $settingsnac['banned_macs'])));
+ $config['installedpackages']['squidnac']['config'][0]['banned_macs'] = $settingsnac['banned_macs'];
+ }
+ }
+
+ if(! empty($settingsnac['unrestricted_hosts'])) {
+ if(strstr($settingsnac['unrestricted_hosts'], ",")) {
+ $settingsnac['unrestricted_hosts'] = base64_encode(implode("\n", explode(",", $settingsnac['unrestricted_hosts'])));
+ $config['installedpackages']['squidnac']['config'][0]['unrestricted_hosts'] = $settingsnac['unrestricted_hosts'];
+ }
+ }
+
+ if(! empty($settingsnac['unrestricted_macs'])) {
+ if(strstr($settingsnac['unrestricted_macs'], ",")) {
+ $settingsnac['unrestricted_macs'] = base64_encode(implode("\n", explode(",", $settingsnac['unrestricted_macs'])));
+ $config['installedpackages']['squidnac']['config'][0]['unrestricted_macs'] = $settingsnac['unrestricted_macs'];
+ }
+ }
+
+ if(! empty($settingsnac['whitelist'])) {
+ if(strstr($settingsnac['whitelist'], ",")) {
+ $settingsnac['whitelist'] = base64_encode(implode("\n", explode(",", $settingsnac['whitelist'])));
+ $config['installedpackages']['squidnac']['config'][0]['whitelist'] = $settingsnac['whitelist'];
+ }
+ }
+
+ if(! empty($settingsnac['blacklist'])) {
+ if(strstr($settingsnac['blacklist'], ",")) {
+ $settingsnac['blacklist'] = base64_encode(implode("\n", explode(",", $settingsnac['blacklist'])));
+ $config['installedpackages']['squidnac']['config'][0]['blacklist'] = $settingsnac['blacklist'];
+ }
+ }
+
+ if(! empty($settingsnac['block_user_agent'])) {
+ if(strstr($settingsnac['block_user_agent'], ",")) {
+ $settingsnac['block_user_agent'] = base64_encode(implode("\n", explode(",", $settingsnac['block_user_agent'])));
+ $config['installedpackages']['squidnac']['config'][0]['block_user_agent'] = $settingsnac['block_user_agent'];
+ }
+ }
+
+ if(! empty($settingsnac['block_reply_mime_type'])) {
+ if(strstr($settingsnac['block_reply_mime_type'], ",")) {
+ $settingsnac['block_reply_mime_type'] = base64_encode(implode("\n", explode(",", $settingsnac['block_reply_mime_type'])));
+ $config['installedpackages']['squidnac']['config'][0]['block_reply_mime_type'] = $settingsnac['block_reply_mime_type'];
+ }
+ }
+
+ /*Migrate reverse settings*/
+ if (is_array($config['installedpackages']['squidreverse'])){
+ $old_reverse_settings=$config['installedpackages']['squidreverse']['config'][0];
+
+ //Settings
+ if (!is_array($config['installedpackages']['squidreversegeneral'])){
+ $config['installedpackages']['squidreversegeneral']['config'][0]=$old_reverse_settings;
+ unset ($config['installedpackages']['squidreversegeneral']['config'][0]['reverse_cache_peer']);
+ unset ($config['installedpackages']['squidreversegeneral']['config'][0]['reverse_uri']);
+ unset ($config['installedpackages']['squidreversegeneral']['config'][0]['reverse_acl']);
+ }
+
+ //PEERS
+ if (!is_array($config['installedpackages']['squidreversepeer'])){
+ foreach (explode("\n",sq_text_area_decode($old_reverse_settings['reverse_cache_peer'])) as $cache_peers)
+ foreach (explode(";",$cache_peers) as $cache_peer)
+ $config['installedpackages']['squidreversepeer']['config'][]=array('description'=>'migrated',
+ 'enable'=> 'on',
+ 'name'=> $cache_peer[0],
+ 'port'=> $cache_peer[1],
+ 'protocol' => $cache_peer[2]);
+ }
+
+ //MAPPINGS
+ if (!is_array($config['installedpackages']['squidreverseuri'])){
+ foreach (explode("\n",sq_text_area_decode($old_reverse_settings['reverse_acl'])) as $acls){
+ foreach (explode(";",$acls) as $acl)
+ array_push(${'peer_'.$acl[0]},$acl[1]);
+ }
+ foreach (explode("\n",sq_text_area_decode($old_reverse_settings['reverse_uri'])) as $uris)
+ foreach (explode(";",$uris) as $uri){
+ $peer_list=(is_array(${'peer_'.$uri[0]})?implode(",",${'peer_'.$uri[0]}):"");
+ $config['installedpackages']['squidreverseuri']['config'][]=array('description'=>'migrated',
+ 'enable'=> 'on',
+ 'name'=> $uri[0],
+ 'uri'=> $uri[1],
+ 'vhost' => $uri[2],
+ 'peers'=>$peer_list);
+ }
+ }
+ }
+
+ update_status("Writing configuration... One moment please...");
+
+ write_config();
+
+ /* create cache */
+ update_status("Creating squid cache pools... One moment please...");
+ squid_dash_z();
+ /* make sure pinger is executable */
+ if(file_exists(SQUID_LOCALBASE. "/libexec/squid/pinger"))
+ exec("/bin/chmod a+x ". SQUID_LOCALBASE. "/libexec/squid/pinger");
+ if(file_exists("/usr/local/etc/rc.d/squid"))
+ exec("/bin/rm /usr/local/etc/rc.d/squid");
+ squid_write_rcfile();
+ if(file_exists("/usr/local/pkg/swapstate_check.php"))
+ exec("/bin/chmod a+x /usr/local/pkg/swapstate_check.php");
+ write_rcfile(array(
+ "file" => "sqp_monitor.sh",
+ "start" => "/usr/local/pkg/sqpmon.sh &",
+ "stop" => "ps awux | grep \"sqpmon\" | grep -v \"grep\" | grep -v \"php\" | awk '{ print $2 }' | xargs kill"));
+
+ foreach (array( SQUID_CONFBASE,
+ SQUID_ACLDIR,
+ SQUID_BASE,
+ SQUID_LIB,
+ SQUID_SSL_DB ) as $dir) {
+ make_dirs($dir);
+ squid_chown_recursive($dir, 'proxy', 'proxy');
+ }
+
+ /* kill any running proxy alarm scripts */
+ update_status("Checking for running processes... One moment please...");
+ log_error("Stopping any running proxy monitors");
+ mwexec("/usr/local/etc/rc.d/sqp_monitor.sh stop");
+ sleep(1);
+
+ if (!file_exists(SQUID_CONFBASE . '/mime.conf') && file_exists(SQUID_CONFBASE . '/mime.conf.default'))
+ copy(SQUID_CONFBASE . '/mime.conf.default', SQUID_CONFBASE . '/mime.conf');
+
+ update_status("Checking cache... One moment please...");
+ squid_dash_z();
+
+ if (!is_service_running('squid')) {
+ update_status("Starting... One moment please...");
+ log_error("Starting Squid");
+ mwexec_bg(SQUID_LOCALBASE. "/sbin/squid -f " . SQUID_CONFFILE);
+ } else {
+ update_status("Reloading Squid for configuration sync... One moment please...");
+ log_error("Reloading Squid for configuration sync");
+ mwexec_bg(SQUID_LOCALBASE. "/sbin/squid -k reconfigure -f " . SQUID_CONFFILE);
+ }
+
+ /* restart proxy alarm scripts */
+ log_error("Starting a proxy monitor script");
+ mwexec_bg("/usr/local/etc/rc.d/sqp_monitor.sh start");
+
+ update_status("Reconfiguring filter... One moment please...");
+ filter_configure();
+}
+
+function squid_deinstall_command() {
+ global $config, $g;
+ $plswait_txt = "This operation may take quite some time, please be patient. Do not press stop or attempt to navigate away from this page during this process.";
+ squid_install_cron(false);
+ if (is_array($config['installedpackages']['squidcache']))
+ $settings = $config['installedpackages']['squidcache']['config'][0];
+ else
+ $settings = array();
+ $cachedir =($settings['harddisk_cache_location'] ? $settings['harddisk_cache_location'] : '/var/squid/cache');
+ $logdir = ($settings['log_dir'] ? $settings['log_dir'] : '/var/squid/logs');
+ update_status("Removing cache ... One moment please...");
+ update_output_window("$plswait_txt");
+ mwexec_bg('rm -rf $cachedir');
+ mwexec('rm -rf $logdir');
+ update_status("Finishing package cleanup.");
+ mwexec("/usr/local/etc/rc.d/sqp_monitor.sh stop");
+ mwexec('rm -f /usr/local/etc/rc.d/sqp_monitor.sh');
+ mwexec("ps awux | grep \"squid\" | grep -v \"grep\" | awk '{ print $2 }' | xargs kill");
+ mwexec("ps awux | grep \"dnsserver\" | grep -v \"grep\" | awk '{ print $2 }' | xargs kill");
+ mwexec("ps awux | grep \"unlinkd\" | grep -v \"grep\" | awk '{ print $2 }' | xargs kill");
+ update_status("Reloading filter...");
+ filter_configure();
+}
+
+function squid_before_form_general(&$pkg) {
+ $values = get_dir(SQUID_CONFBASE . '/errors/');
+ // Get rid of '..' and '.' and ...
+ array_shift($values);
+ array_shift($values);
+ array_shift($values);
+ array_shift($values);
+
+ $name = array();
+ foreach ($values as $value)
+ $names[] = implode(" ", explode("_", $value));
+
+ $i = 0;
+ foreach ($pkg['fields']['field'] as $field) {
+ if ($field['fieldname'] == 'error_language')
+ break;
+ $i++;
+ }
+ $field = &$pkg['fields']['field'][$i];
+
+ for ($i = 0; $i < count($values) - 1; $i++)
+ $field['options']['option'][] = array('name' => $names[$i], 'value' => $values[$i]);
+}
+
+function squid_validate_general($post, &$input_errors) {
+ global $config;
+ if (is_array($config['installedpackages']['squid']))
+ $settings = $config['installedpackages']['squid']['config'][0];
+ else
+ $settings = array();
+ $port = ($settings['proxy_port'] ? $settings['proxy_port'] : 3128);
+ $port = $post['proxy_port'] ? $post['proxy_port'] : $port;
+
+ $icp_port = trim($post['icp_port']);
+ if (!empty($icp_port) && !is_port($icp_port))
+ $input_errors[] = 'You must enter a valid port number in the \'ICP port\' field';
+
+ if (substr($post['log_dir'], -1, 1) == '/')
+ $input_errors[] = 'You may not end log location with an / mark';
+
+ if ($post['log_dir']{0} != '/')
+ $input_errors[] = 'You must start log location with a / mark';
+ if (strlen($post['log_dir']) <= 3)
+ $input_errors[] = "That is not a valid log location dir";
+
+ $log_rotate = trim($post['log_rotate']);
+ if (!empty($log_rotate) && (!is_numeric($log_rotate) or ($log_rotate < 1)))
+
+ $input_errors[] = 'You must enter a valid number of days in the \'Log rotate\' field';
+
+ $webgui_port = $config['system']['webgui']['port'];
+ if(($config['system']['webgui']['port'] == "") && ($config['system']['webgui']['protocol'] == "http")) {
+ $webgui_port = 80;
+ }
+ if(($config['system']['webgui']['port'] == "") && ($config['system']['webgui']['protocol'] == "https")) {
+ $webgui_port = 443;
+ }
+
+ if (($post['transparent_proxy'] != 'on') && ($port == $webgui_port)) {
+ $input_errors[] = "You can not run squid on the same port as the webgui";
+ }
+
+ if (($post['ssl_proxy'] == 'on') && ( $post['dca'] == '')) {
+ $input_errors[] = "SSL interception cannot be enabled without a CA.";
+ }
+
+ foreach (array('defined_ip_proxy_off') as $hosts) {
+ foreach (explode(";", $post[$hosts]) as $host) {
+ $host = trim($host);
+ if (!empty($host) && !is_ipaddr($host) && !is_alias($host) && !is_hostname($host) && !is_subnet($host))
+ $input_errors[] = "The entry '$host' is not a valid IP address, hostname, or alias";
+ }
+ }
+ foreach (array('defined_ip_proxy_off_dest') as $hosts) {
+ foreach (explode(";", $post[$hosts]) as $host) {
+ $host = trim($host);
+ if (!empty($host) && !is_ipaddr($host) && !is_alias($host) && !is_hostname($host) && !is_subnet($host))
+ $input_errors[] = "The entry '$host' is not a valid IP address, hostname, or alias";
+ }
+ }
+
+ if(!empty($post['dns_nameservers'])) {
+ $altdns = explode(";", ($post['dns_nameservers']));
+ foreach ($altdns as $dnssrv) {
+ if (!is_ipaddr($dnssrv))
+ $input_errors[] = 'You must enter a valid IP address in the \'Alternate DNS servers\' field';
+ break;
+ }}
+}
+
+function squid_validate_upstream($post, &$input_errors) {
+ if ($post['enabled'] == 'on') {
+ $addr = trim($post['proxyaddr']);
+ if (empty($addr))
+ $input_errors[] = 'The field \'Hostname\' is required';
+ else {
+ if (!is_ipaddr($addr) && !is_domain($addr))
+ $input_errors[] = 'You must enter a valid IP address or host name in the \'Proxy hostname\' field';
+ }
+
+ foreach (array('proxyport' => 'TCP port', 'icpport' => 'ICP port') as $field => $name) {
+ $port = trim($post[$field]);
+ if (empty($port))
+ $input_errors[] = "The field '$name' is required";
+ else {
+ if (!is_port($port))
+ $input_errors[] = "The field '$name' must contain a valid port number, between 0 and 65535";
+ }
+ }
+ }
+}
+
+function squid_validate_cache($post, &$input_errors) {
+ $num_fields = array( 'harddisk_cache_size' => 'Hard disk cache size',
+ 'memory_cache_size' => 'Memory cache size',
+ 'maximum_object_size' => 'Maximum object size',
+ );
+ foreach ($num_fields as $field => $name) {
+ $value = trim($post[$field]);
+ if (!is_numeric($value) || ($value < 0))
+ $input_errors[] = "You must enter a valid value for '$field'";
+ }
+
+ $value = trim($post['minimum_object_size']);
+ if (!is_numeric($value) || ($value < 0))
+ $input_errors[] = 'You must enter a valid value for \'Minimum object size\'';
+
+ if (!empty($post['cache_swap_low'])) {
+ $value = trim($post['cache_swap_low']);
+ if (!is_numeric($value) || ($value > 100))
+ $input_errors[] = 'You must enter a valid value for \'Low-water-mark\'';
+ }
+
+ if (!empty($post['cache_swap_high'])) {
+ $value = trim($post['cache_swap_high']);
+ if (!is_numeric($value) || ($value > 100))
+ $input_errors[] = 'You must enter a valid value for \'High-water-mark\'';
+ }
+
+ if ($post['donotcache'] != "") {
+ foreach (split("\n", $post['donotcache']) as $host) {
+ $host = trim($host);
+ if (!is_ipaddr($host) && !is_domain($host))
+ $input_errors[] = "The host '$host' is not a valid IP or host name";
+ }
+ }
+
+ squid_dash_z();
+
+}
+
+function squid_validate_nac($post, &$input_errors) {
+ $allowed_subnets = explode("\n", $post['allowed_subnets']);
+ foreach ($allowed_subnets as $subnet) {
+ $subnet = trim($subnet);
+ if (!empty($subnet) && !is_subnet($subnet))
+ $input_errors[] = "The subnet '$subnet' is not a valid CIDR range";
+ }
+
+ foreach (array( 'unrestricted_hosts', 'banned_hosts') as $hosts) {
+
+ if (preg_match_all("@([0-9.]+)(/[0-9.]+|)@",$_POST[$hosts],$matches)){
+ for ($x=0;$x < count($matches[1]);$x++){
+ if ($matches[2][$x] == ""){
+ if (!is_ipaddr($matches[1][$x]))
+ $input_errors[] = "'{$matches[1][$x]}' is not a valid IP address";
+ }
+ else{
+ if (!is_subnet($matches[0][$x]))
+ $input_errors[] = "The subnet '{$matches[0][$x]}' is not a valid CIDR range";
+ }
+ }
+ }
+ }
+
+ foreach (array('unrestricted_macs', 'banned_macs') as $macs) {
+ foreach (explode("\n", $post[$macs]) as $mac) {
+ $mac = trim($mac);
+ if (!empty($mac) && !is_macaddr($mac))
+ $input_errors[] = "The mac '$mac' is not a valid MAC address";
+ }
+ }
+
+ foreach (explode(",", $post['timelist']) as $time) {
+ $time = trim($time);
+ if (!empty($time) && !squid_is_timerange($time))
+ $input_errors[] = "The time range '$time' is not a valid time range";
+ }
+
+ if(!empty($post['ext_cachemanager'])) {
+ $extmgr = explode(";", ($post['ext_cachemanager']));
+ foreach ($extmgr as $mgr) {
+ if (!is_ipaddr($mgr))
+ $input_errors[] = 'You must enter a valid IP address in the \'External Cache Manager\' field';
+ }}
+}
+
+function squid_validate_traffic($post, &$input_errors) {
+ $num_fields = array( 'max_download_size' => 'Maximum download size',
+ 'max_upload_size' => 'Maximum upload size',
+ 'perhost_throttling' => 'Per-host bandwidth throttling',
+ 'overall_throttling' => 'Overall bandwidth throttling',
+ );
+ foreach ($num_fields as $field => $name) {
+ $value = trim($post[$field]);
+ if (!is_numeric($value) || ($value < 0))
+ $input_errors[] = "The field '$name' must contain a positive number";
+ }
+
+ if (!empty($post['quick_abort_min'])) {
+ $value = trim($post['quick_abort_min']);
+ if (!is_numeric($value))
+ $input_errors[] = "The field 'Finish when remaining KB' must contain a positive number";
+ }
+
+ if (!empty($post['quick_abort_max'])) {
+ $value = trim($post['quick_abort_max']);
+ if (!is_numeric($value))
+ $input_errors[] = "The field 'Abort when remaining KB' must contain a positive number";
+ }
+
+ if (!empty($post['quick_abort_pct'])) {
+ $value = trim($post['quick_abort_pct']);
+ if (!is_numeric($value) || ($value > 100))
+ $input_errors[] = "The field 'Finish when remaining %' must contain a percentage";
+ }
+}
+
+function squid_validate_reverse($post, &$input_errors) {
+
+ if(!empty($post['reverse_ip'])) {
+ $reverse_ip = explode(";", ($post['reverse_ip']));
+ foreach ($reverse_ip as $reip) {
+ if (!is_ipaddr(trim($reip)))
+ $input_errors[] = 'You must enter a valid IP address in the \'User-defined reverse-proxy IPs\' field'.' -> \''.$reip.'\' is invalid.';
+ }}
+
+ $fqdn = trim($post['reverse_external_fqdn']);
+ if (!empty($fqdn) && !is_domain($fqdn))
+ $input_errors[] = 'The field \'external FQDN\' must contain a valid domain name';
+
+ $port = trim($post['reverse_http_port']);
+ if (!empty($port) && !is_port($port))
+ $input_errors[] = 'The field \'reverse HTTP port\' must contain a valid port number';
+
+ $port = trim($post['reverse_https_port']);
+ if (!empty($port) && !is_port($port))
+ $input_errors[] = 'The field \'reverse HTTPS port\' must contain a valid port number';
+
+ if ($post['reverse_ssl_cert'] == 'none')
+ $input_errors[] = 'A valid certificate for the external interface must be selected';
+
+ if (($post['reverse_https'] != 'on') && ($post['reverse_owa'] == 'on')) {
+ $input_errors[] = "You have to enable reverse HTTPS before enabling OWA support.";
+ }
+
+ if(!empty($post['reverse_owa_ip'])) {
+ $reverse_owa_ip = explode(";", ($post['reverse_owa_ip']));
+ foreach ($reverse_owa_ip as $reowaip) {
+ if (!is_ipaddr(trim($reowaip)))
+ $input_errors[] = 'You must enter a valid IP address in the \'CAS-Array / OWA frontend IP address\' field'.' -> \''.$reowaip.'\' is invalid.';
+ }}
+
+ $contents = $post['reverse_cache_peer'];
+ if(!empty($contents)) {
+ $defs = explode("\r\n", ($contents));
+ foreach ($defs as $def) {
+ $cfg = explode(";",($def));
+ if (!is_ipaddr($cfg[1]))
+ $input_errors[] = "please choose a valid IP in the cache peer configuration.";
+ if (!is_port($cfg[2]))
+ $input_errors[] = "please choose a valid port in the cache peer configuration.";
+ if (($cfg[3] != 'HTTPS') && ($cfg[3] != 'HTTP'))
+ $input_errors[] = "please choose HTTP or HTTPS in the cache peer configuration.";
+ }}
+
+
+}
+
+function squid_validate_auth($post, &$input_errors) {
+ $num_fields = array( array('auth_processes', 'Authentication processes', 1),
+ array('auth_ttl', 'Authentication TTL', 0),
+ );
+ foreach ($num_fields as $field) {
+ $value = trim($post[$field[0]]);
+ if (!empty($value) && (!is_numeric($value) || ($value < $field[2])))
+ $input_errors[] = "The field '{$field[1]}' must contain a valid number greater than {$field[2]}";
+ }
+
+ $auth_method = $post['auth_method'];
+ if (($auth_method != 'none') && ($auth_method != 'local') && ($auth_method != 'cp')) {
+ $server = trim($post['auth_server']);
+ if (empty($server))
+ $input_errors[] = 'The field \'Authentication server\' is required';
+ else if (!is_ipaddr($server) && !is_domain($server))
+ $input_errors[] = 'The field \'Authentication server\' must contain a valid IP address or domain name';
+
+ $port = trim($post['auth_server_port']);
+ if (!empty($port) && !is_port($port))
+ $input_errors[] = 'The field \'Authentication server port\' must contain a valid port number';
+
+ switch ($auth_method) {
+ case 'ldap':
+ $user = trim($post['ldap_user']);
+ if (empty($user))
+ $input_errors[] = 'The field \'LDAP server user DN\' is required';
+ else if (!$user)
+ $input_errors[] = 'The field \'LDAP server user DN\' must be a valid domain name';
+ break;
+ case 'radius':
+ $secret = trim($post['radius_secret']);
+ if (empty($secret))
+ $input_errors[] = 'The field \'RADIUS secret\' is required';
+ break;
+ case 'msnt':
+ foreach (explode(",", trim($post['msnt_secondary'])) as $server) {
+ if (!empty($server) && !is_ipaddr($server) && !is_domain($server))
+ $input_errors[] = "The host '$server' is not a valid IP address or domain name";
+ }
+ break;
+ }
+
+ $no_auth = explode("\n", $post['no_auth_hosts']);
+ foreach ($no_auth as $host) {
+ $host = trim($host);
+ if (!empty($host) && !is_subnet($host))
+ $input_errors[] = "The host '$host' is not a valid CIDR range";
+ }
+ }
+}
+
+function squid_install_cron($should_install) {
+ global $config, $g;
+ if($g['booting']==true)
+ return;
+ $rotate_is_installed = false;
+ $swapstate_is_installed = false;
+
+ if(!$config['cron']['item'])
+ return;
+
+ if (is_array($config['installedpackages']['squidcache']))
+ $settings = $config['installedpackages']['squidcache']['config'][0];
+ else
+ $settings = array();
+
+ $x=0;
+ $rotate_job_id=-1;
+ $swapstate_job_id=-1;
+ $cron_cmd=($settings['clear_cache']=='on' ? "/usr/local/pkg/swapstate_check.php clean; " : "");
+ $cron_cmd .= SQUID_LOCALBASE."/sbin/squid -k rotate -f " . SQUID_CONFFILE;
+ $need_write = false;
+ foreach($config['cron']['item'] as $item) {
+ if(strstr($item['task_name'], "squid_rotate_logs")) {
+ $rotate_job_id = $x;
+ if ($item['command'] != $cron_cmd){
+ $config['cron']['item'][$x]['command']=$cron_cmd;
+ $need_write = true;
+ }
+ } elseif(strstr($item['task_name'], "squid_check_swapstate")) {
+ $swapstate_job_id = $x;
+ }
+ $x++;
+ }
+ switch($should_install) {
+ case true:
+ $cachedir =($settings['harddisk_cache_location'] ? $settings['harddisk_cache_location'] : '/var/squid/cache');
+ if($rotate_job_id < 0) {
+ $cron_item['command']=($settings['clear_cache']=='on' ? "/usr/local/pkg/swapstate_check.php clean; " : "");
+ $cron_item = array();
+ $cron_item['task_name'] = "squid_rotate_logs";
+ $cron_item['minute'] = "0";
+ $cron_item['hour'] = "0";
+ $cron_item['mday'] = "*";
+ $cron_item['month'] = "*";
+ $cron_item['wday'] = "*";
+ $cron_item['who'] = "root";
+ $cron_item['command'] .= $cron_cmd;
+ /* Add this cron_item as a new entry at the end of the item array. */
+ $config['cron']['item'][] = $cron_item;
+ $need_write = true;
+ }
+ if($swapstate_job_id < 0) {
+ $cron_item = array();
+ $cron_item['task_name'] = "squid_check_swapstate";
+ $cron_item['minute'] = "*/15";
+ $cron_item['hour'] = "*";
+ $cron_item['mday'] = "*";
+ $cron_item['month'] = "*";
+ $cron_item['wday'] = "*";
+ $cron_item['who'] = "root";
+ $cron_item['command'] = "/usr/local/pkg/swapstate_check.php";
+ /* Add this cron_item as a new entry at the end of the item array. */
+ $config['cron']['item'][] = $cron_item;
+ $need_write = true;
+ }
+ if ($need_write) {
+ parse_config(true);
+ write_config("Adding Squid Cron Jobs");
+ }
+ break;
+ case false:
+ if($rotate_job_id >= 0) {
+ unset($config['cron']['item'][$rotate_job_id]);
+ $need_write = true;
+ }
+ if($swapstate_job_id >= 0) {
+ unset($config['cron']['item'][$swapstate_job_id]);
+ $need_write = true;
+ }
+ if ($need_write) {
+ parse_config(true);
+ write_config("Removing Squid Cron Jobs");
+ }
+ break;
+ }
+ configure_cron();
+}
+
+function squid_check_ca_hashes(){
+ global $config,$g;
+
+ #check certificates
+ $cert_count=0;
+ if (is_dir(SQUID_LOCALBASE. '/share/certs'))
+ if ($handle = opendir(SQUID_LOCALBASE.'/share/certs')) {
+ while (false !== ($file = readdir($handle)))
+ if (preg_match ("/\d+.0/",$file))
+ $cert_count++;
+ }
+ closedir($handle);
+ if ($cert_count < 10){
+ conf_mount_rw();
+ #create ca-root hashes from ca-root-nss package
+ log_error("Creating root certificate bundle hashes from the Mozilla Project");
+ $cas=file(SQUID_LOCALBASE.'/share/certs/ca-root-nss.crt');
+ $cert=0;
+ foreach ($cas as $ca){
+ if (preg_match("/--BEGIN CERTIFICATE--/",$ca))
+ $cert=1;
+ if ($cert == 1)
+ $crt.=$ca;
+ if (preg_match("/-END CERTIFICATE-/",$ca)){
+ file_put_contents("/tmp/cert.pem",$crt, LOCK_EX);
+ $cert_hash=array();
+ exec("/usr/bin/openssl x509 -hash -noout -in /tmp/cert.pem",$cert_hash);
+ file_put_contents(SQUID_LOCALBASE."/share/certs/".$cert_hash[0].".0",$crt,LOCK_EX);
+ $crt="";
+ $cert=0;
+ }
+ }
+ }
+}
+
+function squid_resync_general() {
+ global $g, $config, $valid_acls;
+
+ if (is_array($config['installedpackages']['squid']))
+ $settings = $config['installedpackages']['squid']['config'][0];
+ else
+ $settings=array();
+ $conf = "# This file is automatically generated by pfSense\n";
+ $conf .= "# Do not edit manually !\n\n";
+ #Check ssl interception
+ if (($settings['ssl_proxy'] == 'on')) {
+ squid_check_ca_hashes();
+ $srv_cert = lookup_ca($settings["dca"]);
+ if ($srv_cert != false) {
+ if(base64_decode($srv_cert['prv'])) {
+ #check if ssl_db was initilized by squid
+ if (! file_exists("/var/squid/lib/ssl_db/serial")){
+ if (is_dir("/var/squid/lib/ssl_db")){
+ mwexec("/bin/rm -rf /var/squid/lib/ssl_db");
+ }
+ mwexec(SQUID_LOCALBASE."/libexec/squid/ssl_crtd -c -s /var/squid/lib/ssl_db/");
+ }
+ #force squid user permission on /var/squid/lib/ssl_db/
+ squid_chown_recursive("/var/squid/lib/ssl_db/", 'proxy', 'proxy');
+ # cert, key, version, cipher,options, clientca, cafile, capath, crlfile, dhparams,sslflags, and sslcontext
+ $crt_pk=SQUID_CONFBASE."/serverkey.pem";
+ $crt_capath=SQUID_LOCALBASE."/share/certs/";
+ file_put_contents($crt_pk,base64_decode($srv_cert['prv']).base64_decode($srv_cert['crt']));
+ $sslcrtd_children= ($settings['sslcrtd_children'] ? $settings['sslcrtd_children'] : 5);
+ $ssl_interception.="ssl-bump generate-host-certificates=on dynamic_cert_mem_cache_size=".($sslcrtd_children*2)."MB cert={$crt_pk} capath={$crt_capath}\n";
+ $interception_checks = "sslcrtd_program ".SQUID_LOCALBASE."/libexec/squid/ssl_crtd -s /var/squid/lib/ssl_db -M 4MB -b 2048\n";
+ $interception_checks .= "sslcrtd_children {$sslcrtd_children}\n";
+ $interception_checks .= "sslproxy_capath {$crt_capath}\n";
+ if (preg_match("/sslproxy_cert_error/",$settings["interception_checks"]))
+ $interception_checks.="sslproxy_cert_error allow all\n";
+ if (preg_match("/sslproxy_flags/",$settings["interception_checks"]))
+ $interception_checks.="sslproxy_flags DONT_VERIFY_PEER\n";
+ if ($settings["interception_adapt"] != ""){
+ foreach (explode(",",$settings["interception_adapt"]) as $adapt)
+ $interception_checks.="sslproxy_cert_adapt {$adapt} all\n";
+ }
+ }
+ }
+ }
+ $port = ($settings['proxy_port'] ? $settings['proxy_port'] : 3128);
+ $ssl_port = ($settings['ssl_proxy_port'] ? $settings['ssl_proxy_port'] : 3127);
+
+#Read assigned interfaces
+ $real_ifaces = array();
+
+ if($settings['active_interface'])
+ $proxy_ifaces = explode(",", $settings['active_interface']);
+ else
+ $proxy_ifaces=array("lan");
+
+ if ($settings['transparent_proxy']=="on"){
+ $transparent_ifaces = explode(",", $settings['transparent_active_interface']);
+ foreach ($transparent_ifaces as $t_iface){
+ $t_iface_ip = squid_get_real_interface_address($t_iface);
+ if($t_iface_ip[0])
+ $real_ifaces[]=$t_iface_ip;
+ }
+ }
+ else{
+ $transparent_ifaces=array();
+ }
+
+ if ($settings['ssl_proxy']=="on"){
+ $ssl_ifaces = explode(",", $settings['ssl_active_interface']);
+ foreach ($ssl_ifaces as $s_iface){
+ $s_iface_ip = squid_get_real_interface_address($s_iface);
+ if($s_iface_ip[0])
+ $real_ifaces[]=$s_iface_ip;
+ }
+ }
+ else{
+ $ssl_ifaces=array();
+ }
+
+ #check all proxy interfaces selected
+ foreach ($proxy_ifaces as $iface) {
+ $iface_ip = squid_get_real_interface_address($iface);
+ if($iface_ip[0]) {
+ $real_ifaces[]=$iface_ip;
+ if (in_array($iface,$ssl_ifaces))
+ $conf .= "http_port {$iface_ip[0]}:{$port} {$ssl_interception}\n";
+ else
+ $conf .= "http_port {$iface_ip[0]}:{$port}\n";
+ }
+ }
+
+ if (($settings['transparent_proxy'] == 'on')) {
+ if ($settings['ssl_proxy'] == "on" && count($ssl_ifaces)>0){
+ $conf .= "http_port 127.0.0.1:{$port} intercept {$ssl_interception}\n";
+ $conf .= "https_port 127.0.0.1:{$ssl_port} intercept {$ssl_interception}\n";
+ }
+ else{
+ $conf .= "http_port 127.0.0.1:{$port} intercept\n";
+ }
+ }
+ $icp_port = ($settings['icp_port'] ? $settings['icp_port'] : 0);
+ $dns_v4_first= ($settings['dns_v4_first'] == "on" ? "on" : "off" );
+ $pidfile = "{$g['varrun_path']}/squid.pid";
+ $language = ($settings['error_language'] ? $settings['error_language'] : 'en');
+ $icondir = SQUID_CONFBASE . '/icons';
+ $hostname = ($settings['visible_hostname'] ? $settings['visible_hostname'] : 'localhost');
+ $email = ($settings['admin_email'] ? $settings['admin_email'] : 'admin@localhost');
+
+ $logdir = ($settings['log_dir'] ? $settings['log_dir'] : '/var/squid/logs');
+ if (! is_dir($logdir)){
+ make_dirs($logdir);
+ squid_chown_recursive($logdir, 'proxy', 'proxy');
+ }
+ $logdir_cache = $logdir . '/cache.log';
+ $logdir_access = ($settings['log_enabled'] == 'on' ? $logdir . '/access.log' : '/dev/null');
+ $pinger_helper = ($settings['disable_pinger']) =='on' ? 'off' : 'on';
+ $pinger_program=SQUID_LOCALBASE."/libexec/squid/pinger";
+
+ $conf .= <<< EOD
+icp_port {$icp_port}
+dns_v4_first {$dns_v4_first}
+pid_filename {$pidfile}
+cache_effective_user proxy
+cache_effective_group proxy
+error_default_language {$language}
+icon_directory {$icondir}
+visible_hostname {$hostname}
+cache_mgr {$email}
+access_log {$logdir_access}
+cache_log {$logdir_cache}
+cache_store_log none
+netdb_filename {$logdir}/netdb.state
+pinger_enable {$pinger_helper}
+pinger_program {$pinger_program}
+{$interception_checks}
+
+EOD;
+
+// Per squid docs, setting logfile_rotate to 0 is safe and causes a simple close/reopen.
+$rotate = empty($settings['log_rotate']) ? 0 : $settings['log_rotate'];
+$conf .= "logfile_rotate {$rotate}\n";
+$conf .= "debug_options rotate={$rotate}\n";
+squid_install_cron(true);
+
+ $conf .= <<< EOD
+shutdown_lifetime 3 seconds
+
+EOD;
+
+ if ($settings['allow_interface'] == 'on') {
+ $src = '';
+ foreach ($real_ifaces as $iface) {
+ list($ip, $mask) = $iface;
+ $ip = long2ip(ip2long($ip) & ip2long($mask));
+ $mask = 32-log((ip2long($mask) ^ ip2long('255.255.255.255'))+1,2);
+ if (!preg_match("@$ip/$mask@",$src))
+ $src .= " $ip/$mask";
+ }
+ $conf .= "# Allow local network(s) on interface(s)\n";
+ $conf .= "acl localnet src $src\n";
+ $valid_acls[] = 'localnet';
+ }
+ if ($settings['disable_xforward']) $conf .= "forwarded_for off\n";
+ if ($settings['disable_via']) $conf .= "via off\n";
+ if ($settings['disable_squidversion']) $conf .= "httpd_suppress_version_string on\n";
+ if (!empty($settings['uri_whitespace'])) $conf .= "uri_whitespace {$settings['uri_whitespace']}\n";
+ else $conf .= "uri_whitespace strip\n"; //only used for first run
+
+ if(!empty($settings['dns_nameservers'])) {
+ $altdns = explode(";", ($settings['dns_nameservers']));
+ $conf .= "dns_nameservers ";
+ foreach ($altdns as $dnssrv) {
+ $conf .= $dnssrv." ";
+ }
+// $conf .= "\n"; //Kill blank line after DNS-Servers
+ }
+
+ return $conf;
+}
+
+
+function squid_resync_cache() {
+ global $config, $g;
+ if (is_array($config['installedpackages']['squidcache']))
+ $settings = $config['installedpackages']['squidcache']['config'][0];
+ else
+ $settings = array();
+ //apply cache settings
+ $cachedir =($settings['harddisk_cache_location'] ? $settings['harddisk_cache_location'] : '/var/squid/cache');
+ $disk_cache_size = ($settings['harddisk_cache_size'] ? $settings['harddisk_cache_size'] : 100);
+ $level1 = ($settings['level1_subdirs'] ? $settings['level1_subdirs'] : 16);
+ $memory_cache_size = ($settings['memory_cache_size'] ? $settings['memory_cache_size'] : 8);
+ $max_objsize = ($settings['maximum_object_size'] ? $settings['maximum_object_size']." KB" : "10 KB");
+ $min_objsize = ($settings['minimum_object_size'] ? $settings['minimum_object_size'] : 0);
+ $max_objsize_in_mem = ($settings['maximum_objsize_in_mem'] ? $settings['maximum_objsize_in_mem'] : 32);
+ $cache_policy = ($settings['cache_replacement_policy'] ? $settings['cache_replacement_policy'] : 'heap LFUDA');
+ $memory_policy = ($settings['memory_replacement_policy'] ? $settings['memory_replacement_policy'] : 'heap GDSF');
+ $offline_mode = ($settings['enable_offline'] == 'on' ? 'on' : 'off');
+ $conf = '';
+ if (!isset($settings['harddisk_cache_system'])) {
+ if ($g['platform'] == "nanobsd" || !is_array ($config['installedpackages']['squidcache']['config']))
+ $disk_cache_system = 'null';
+ else
+ $disk_cache_system = 'ufs';
+ }
+ else{
+ $disk_cache_system = $settings['harddisk_cache_system'];
+ }
+ #'null' storage type dropped. In-memory cache is always present. Remove all cache_dir options to prevent on-disk caching.
+ if ($disk_cache_system != "null") {
+ $disk_cache_opts = "cache_dir {$disk_cache_system} {$cachedir} {$disk_cache_size} {$level1} 256";
+ }
+//check dynamic content
+if(empty($settings['cache_dynamic_content'])){
+ $conf.='acl dynamic urlpath_regex cgi-bin \?'."\n";
+ $conf.="cache deny dynamic\n";
+}
+else{
+ if(preg_match('/youtube/',$settings['refresh_patterns'])){
+ $conf.=<<< EOC
+# Break HTTP standard for flash videos. Keep them in cache even if asked not to.
+refresh_pattern -i \.flv$ 10080 90% 999999 ignore-no-cache override-expire ignore-private
+
+# Let the clients favorite video site through with full caching
+acl youtube dstdomain .youtube.com
+cache allow youtube
+
+EOC;
+ }
+ if(preg_match('/windows/',$settings['refresh_patterns'])){
+ $conf.=<<< EOC
+
+# Windows Update refresh_pattern
+range_offset_limit -1
+refresh_pattern -i microsoft.com/.*\.(cab|exe|ms[i|u|f]|asf|wm[v|a]|dat|zip) 4320 80% 43200 reload-into-ims
+refresh_pattern -i windowsupdate.com/.*\.(cab|exe|ms[i|u|f]|asf|wm[v|a]|dat|zip) 4320 80% 43200 reload-into-ims
+refresh_pattern -i windows.com/.*\.(cab|exe|ms[i|u|f]|asf|wm[v|a]|dat|zip) 4320 80% 43200 reload-into-ims
+
+EOC;
+ }
+
+if(preg_match('/symantec/',$settings['refresh_patterns'])){
+ $conf.=<<< EOC
+
+# Symantec refresh_pattern
+range_offset_limit -1
+refresh_pattern liveupdate.symantecliveupdate.com/.*\.(cab|exe|dll|msi) 10080 100% 43200 reload-into-ims
+refresh_pattern symantecliveupdate.com/.*\.(cab|exe|dll|msi) 10080 100% 43200 reload-into-ims
+
+EOC;
+ }
+if(preg_match('/avast/',$settings['refresh_patterns'])){
+ $conf.=<<< EOC
+
+# Avast refresh_pattern
+range_offset_limit -1
+refresh_pattern avast.com/.*\.(vpu|cab|stamp|exe) 10080 100% 43200 reload-into-ims
+
+EOC;
+ }
+if(preg_match('/avira/',$settings['refresh_patterns'])){
+ $conf.=<<< EOC
+
+# Avira refresh_pattern
+range_offset_limit -1
+refresh_pattern personal.avira-update.com/.*\.(cab|exe|dll|msi|gz) 10080 100% 43200 reload-into-ims
+
+EOC;
+ }
+ $refresh_conf=<<< EOC
+
+# Add any of your own refresh_pattern entries above these.
+refresh_pattern ^ftp: 1440 20% 10080
+refresh_pattern ^gopher: 1440 0% 1440
+refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
+refresh_pattern . 0 20% 4320
+
+EOC;
+}
+
+ If ($settings['custom_refresh_patterns'] !="")
+ $conf .= sq_text_area_decode($settings['custom_refresh_patterns'])."\n";
+
+ $conf .= <<< EOD
+
+cache_mem $memory_cache_size MB
+maximum_object_size_in_memory {$max_objsize_in_mem} KB
+memory_replacement_policy {$memory_policy}
+cache_replacement_policy {$cache_policy}
+$disk_cache_opts
+minimum_object_size {$min_objsize} KB
+maximum_object_size {$max_objsize}
+offline_mode {$offline_mode}
+
+EOD;
+
+ if (!empty($settings['cache_swap_low'])) $conf .= "cache_swap_low {$settings['cache_swap_low']}\n";
+ if (!empty($settings['cache_swap_high'])) $conf .= "cache_swap_high {$settings['cache_swap_high']}\n";
+
+ $donotcache = sq_text_area_decode($settings['donotcache']);
+ if (!empty($donotcache)) {
+ file_put_contents(SQUID_ACLDIR . '/donotcache.acl', $donotcache);
+ $conf .= 'acl donotcache dstdomain "' . SQUID_ACLDIR . "/donotcache.acl\"\n";
+ $conf .= "cache deny donotcache\n";
+ }
+ elseif (file_exists(SQUID_ACLDIR . '/donotcache.acl')) {
+ unlink(SQUID_ACLDIR . '/donotcache.acl');
+ }
+ $conf .= "cache allow all\n";
+ return $conf.$refresh_conf;
+}
+
+function squid_resync_upstream() {
+ global $config;
+ $conf = "\n#Remote proxies\n";
+ if (is_array($config['installedpackages']['squidremote']['config']))
+ foreach ($config['installedpackages']['squidremote']['config'] as $settings){
+ if ($settings['enable'] == 'on') {
+ $conf .= "cache_peer {$settings['proxyaddr']} {$settings['hierarchy']} {$settings['proxyport']} ";
+ if ($settings['icpport'] == '7')
+ $conf .= "{$settings['icpport']} {$settings['icpoptions']} {$settings['peermethod']} {$settings['allowmiss']} ";
+ else
+ $conf .= "{$settings['icpport']} ";
+ #auth settings
+ if (!empty($settings['username']) && !empty($settings['password'])){
+ $conf .= " login={$settings['username']}:{$settings['password']}";
+ }
+ else{
+ $conf .= "{$settings['authoption']} ";
+ }
+ #other options settings
+ if (!empty($settings['weight']))
+ $conf .= "weight={$settings['weight']} ";
+ if (!empty($settings['basetime']))
+ $conf .= "basetime={$settings['basetime']} ";
+ if (!empty($settings['ttl']))
+ $conf .= "ttl={$settings['ttl']} ";
+ if (!empty($settings['nodelay']))
+ $conf .= "no-delay";
+ }
+ $conf .= "\n";
+ }
+ return $conf;
+}
+
+function squid_resync_redirector() {
+ global $config;
+
+ $httpav_enabled = ($config['installedpackages']['clamav']['config'][0]['scan_http'] == 'on');
+ if ($httpav_enabled) {
+ $conf = "url_rewrite_program /usr/local/bin/squirm\n";
+ } else {
+ $conf = "# No redirector configured\n";
+ }
+ return $conf;
+}
+
+function squid_resync_nac() {
+ global $config, $valid_acls;
+
+ $port = ($settings['proxy_port'] ? $settings['proxy_port'] : 3128);
+ if (is_array($config['installedpackages']['squidnac']))
+ $settings = $config['installedpackages']['squidnac']['config'][0];
+ else
+ $settings = array();
+ $webgui_port = $config['system']['webgui']['port'];
+ $addtl_ports = $settings['addtl_ports'];
+ $addtl_sslports = $settings['addtl_sslports'];
+ $port = ($settings['proxy_port'] ? $settings['proxy_port'] : 3128);
+ $ssl_port = ($settings['ssl_proxy_port'] ? $settings['ssl_proxy_port'] : 3127);
+ $conf = <<< EOD
+
+# Setup some default acls
+# From 3.2 further configuration cleanups have been done to make things easier and safer. The manager, localhost, and to_localhost ACL definitions are now built-in.
+# acl localhost src 127.0.0.1/32
+acl allsrc src all
+acl safeports port 21 70 80 210 280 443 488 563 591 631 777 901 $webgui_port $port $ssl_port 1025-65535 $addtl_ports
+acl sslports port 443 563 $webgui_port $addtl_sslports
+
+# From 3.2 further configuration cleanups have been done to make things easier and safer. The manager, localhost, and to_localhost ACL definitions are now built-in.
+#acl manager proto cache_object
+
+acl purge method PURGE
+acl connect method CONNECT
+
+# Define protocols used for redirects
+acl HTTP proto HTTP
+acl HTTPS proto HTTPS
+
+EOD;
+
+ $allowed_subnets = preg_replace("/\s+/"," ",sq_text_area_decode($settings['allowed_subnets']));
+ #$allowed = "";
+ #foreach ($allowed_subnets as $subnet) {
+ # if(!empty($subnet)) {
+ # $subnet = trim($subnet);
+ # $allowed .= "$subnet ";
+ # }
+ #}
+ if (!empty($allowed_subnets)) {
+ $conf .= "acl allowed_subnets src $allowed_subnets\n";
+ $valid_acls[] = 'allowed_subnets';
+ }
+
+ $options = array( 'unrestricted_hosts' => 'src',
+ 'banned_hosts' => 'src',
+ 'whitelist' => 'dstdom_regex -i',
+ 'blacklist' => 'dstdom_regex -i',
+ 'block_user_agent' => 'browser -i',
+ 'block_reply_mime_type' => 'rep_mime_type -i',
+ );
+ foreach ($options as $option => $directive) {
+ $contents = sq_text_area_decode($settings[$option]);
+ if (!empty($contents)) {
+ file_put_contents(SQUID_ACLDIR . "/$option.acl", $contents);
+ $conf .= "acl $option $directive \"" . SQUID_ACLDIR . "/$option.acl\"\n";
+ $valid_acls[] = $option;
+ }
+ elseif (file_exists(SQUID_ACLDIR . "/$option.acl")) {
+ unlink(SQUID_ACLDIR . "/$option.acl");
+ }
+ }
+
+ $conf .= <<< EOD
+http_access allow manager localhost
+
+EOD;
+
+ if (is_array($config['installedpackages']['squidcache'])){
+ $settings_ch = $config['installedpackages']['squidcache']['config'][0];
+ if(!empty($settings_ch['ext_cachemanager'])) {
+ $extmgr = explode(";", ($settings_ch['ext_cachemanager']));
+ $conf .= "\n# Allow external cache managers\n";
+ foreach ($extmgr as $mgr) {
+ $conf .= "acl ext_manager src {$mgr}\n";
+ }
+ $conf .= "http_access allow manager ext_manager\n";
+ }
+ }
+
+ $conf .= <<< EOD
+
+http_access deny manager
+http_access allow purge localhost
+http_access deny purge
+http_access deny !safeports
+http_access deny CONNECT !sslports
+
+# Always allow localhost connections
+# From 3.2 further configuration cleanups have been done to make things easier and safer.
+# The manager, localhost, and to_localhost ACL definitions are now built-in.
+# http_access allow localhost
+
+EOD;
+
+ return $conf;
+}
+
+function squid_resync_antivirus(){
+ global $config;
+
+ if (is_array($config['installedpackages']['squidantivirus']))
+ $antivirus_config = $config['installedpackages']['squidantivirus']['config'][0];
+ else
+ $antivirus_config = array();
+
+ if ($antivirus_config['enable']=="on"){
+ switch ($antivirus_config['client_info']){
+ case "both":
+ $icap_send_client_ip="on";
+ $icap_send_client_username="on";
+ break;
+ case "IP":
+ $icap_send_client_ip="on";
+ $icap_send_client_username="off";
+ break;
+ case "username":
+ $icap_send_client_ip="off";
+ $icap_send_client_username="on";
+ break;
+ case "none":
+ $icap_send_client_ip="off";
+ $icap_send_client_username="off";
+ break;
+ }
+ if (is_array($config['installedpackages']['squid']))
+ $squid_config=$config['installedpackages']['squid']['config'][0];
+ $clwarn="clwarn.cgi.en_EN";
+ if (preg_match("/de/i",$squid_config['error_language']))
+ $clwarn="clwarn.cgi.de_DE";
+ if (preg_match("/ru/i",$squid_config['error_language']))
+ $clwarn="clwarn.cgi.ru_RU";
+ if (preg_match("/fr/i",$squid_config['error_language']))
+ $clwarn="clwarn.cgi.fr_FR";
+ if (preg_match("/pt_br/i",$squid_config['error_language']))
+ $clwarn="clwarn.cgi.pt_BR";
+ $clwarn_file="/usr/local/www/clwarn.cgi";
+ copy(SQUID_LOCALBASE."/libexec/squidclamav/{$clwarn}",$clwarn_file);
+
+ #fix perl path on clwarn.cgi
+ $clwarn_file_new=file_get_contents($clwarn_file);
+ $c_pattern[]="@/usr/\S+/perl@";
+ $c_replacement[]=SQUID_LOCALBASE."/bin/perl";
+ /*$c_pattern[]="@redirect \S+/clwarn.cgi@";
+ $gui_proto=$config['system']['webgui']['protocol'];
+ $gui_port=$config['system']['webgui']['port'];
+ if($gui_port == "") {
+ $gui_port($gui_proto == "http"?"80":"443");
+ }
+ $c_replacement[]=SQUID_LOCALBASE."redirect {$gui_proto}://127.0.0.1:{$gui_port}/clwarn.cgi";
+ */
+ $clwarn_file_new=preg_replace($c_pattern, $c_replacement,$clwarn_file_new);
+ file_put_contents($clwarn_file, $clwarn_file_new,LOCK_EX);
+
+ #fix clwarn.cgi file permission
+ chmod($clwarn_file,0755);
+
+ $conf = <<< EOF
+icap_enable on
+icap_send_client_ip {$icap_send_client_ip}
+icap_send_client_username {$icap_send_client_username}
+icap_client_username_encode off
+icap_client_username_header X-Authenticated-User
+icap_preview_enable on
+icap_preview_size 1024
+
+icap_service service_req reqmod_precache bypass=0 icap://127.0.0.1:1344/squidclamav
+icap_service service_resp respmod_precache bypass=0 icap://127.0.0.1:1344/squidclamav
+
+adaptation_access service_req allow all
+adaptation_access service_resp allow all
+
+EOF;
+ #check if icap is enabled on rc.conf.local
+ if (file_exists("/etc/rc.conf.local")){
+ $rc_old_file=file("/etc/rc.conf.local");
+ foreach ($rc_old_file as $rc_line){
+ if (preg_match("/^(c_icap_enable|clamav_clamd_enable)/",$rc_line,$matches)){
+ $rc_file.=$matches[1].'="YES"'."\n";
+ ${$matches[1]}="ok";
+ }
+ else
+ $rc_file.=$rc_line;
+ }
+ }
+ if (!isset($c_icap_enable))
+ $rc_file.='c_icap_enable="YES"'."\n";
+ if (!isset($clamav_clamd_enable))
+ $rc_file.='clamav_clamd_enable="YES"'."\n";
+ file_put_contents("/etc/rc.conf.local",$rc_file,LOCK_EX);
+ squid_check_clamav_user('clamav');
+ #patch sample files to pfsense dirs
+ #squidclamav.conf
+ if (!file_exists(SQUID_LOCALBASE."/etc/c-icap/squidclamav.conf.sample"))
+ if (file_exists(SQUID_LOCALBASE."/etc/c-icap/squidclamav.conf.default")){
+ $sample_file=file_get_contents(SQUID_LOCALBASE."/etc/c-icap/squidclamav.conf.default");
+ $clamav_m[0]="@/var/run/clamav/clamd.ctl@";
+ $clamav_r[0]="/var/run/clamav/clamd.sock";
+ file_put_contents(SQUID_LOCALBASE."/etc/c-icap/squidclamav.conf.sample",preg_replace($clamav_m,$clamav_r,$sample_file),LOCK_EX);
+ }
+ #c-icap.conf
+ if (!file_exists(SQUID_LOCALBASE."/etc/c-icap/c-icap.conf.sample"))
+ if (file_exists(SQUID_LOCALBASE."/etc/c-icap/c-icap.conf.default")){
+ $sample_file=file_get_contents(SQUID_LOCALBASE."/etc/c-icap/c-icap.conf.default");
+ if (! preg_match ("/squidclamav/"))
+ $sample_file.="\nService squidclamav squidclamav.so\n";
+
+ file_put_contents(SQUID_LOCALBASE."/etc/c-icap/c-icap.conf.sample",$sample_file,LOCK_EX);
+ }
+ $loadsample=0;
+ if ($antivirus_config['squidclamav'] =="" && file_exists(SQUID_LOCALBASE."/etc/c-icap/squidclamav.conf.sample")){
+ $config['installedpackages']['squidantivirus']['config'][0]['squidclamav']=base64_encode(file_get_contents(SQUID_LOCALBASE."/etc/c-icap/squidclamav.conf.sample"));
+ $loadsample++;
+ }
+ if ($antivirus_config['c-icap_conf'] =="" && file_exists(SQUID_LOCALBASE."/etc/c-icap/c-icap.conf.sample")){
+ $config['installedpackages']['squidantivirus']['config'][0]['c-icap_conf']=base64_encode(file_get_contents(SQUID_LOCALBASE."/etc/c-icap/c-icap.conf.sample"));
+ $loadsample++;
+ }
+ if ($antivirus_config['squidclamav'] =="" && file_exists(SQUID_LOCALBASE."/etc/c-icap/c-icap.magic.default")){
+ $config['installedpackages']['squidantivirus']['config'][0]['c-icap_magic']=base64_encode(file_get_contents(SQUID_LOCALBASE."/etc/c-icap/c-icap.magic.default"));
+ $loadsample++;
+ }
+ if($loadsample > 0){
+ write_config();
+ $antivirus_config = $config['installedpackages']['squidantivirus']['config'][0];
+ }
+ #check dirs
+ $dirs=array("/var/run/c-icap" => "clamav",
+ "/var/log/c-icap" => "clamav",
+ "/var/log/clamav" => "clamav",
+ "/var/run/clamav" => "clamav",
+ "/var/db/clamav" => "clamav");
+ foreach ($dirs as $dir_path => $dir_user){
+ if (!is_dir($dir_path))
+ make_dirs($dir_path);
+ squid_chown_recursive($dir_path, $dir_user, "wheel");
+ }
+ #Check clamav database
+ if (count(glob("/var/db/clamav/*d"))==0){
+ log_error("Squid - Missing /var/db/clamav/*.cvd or *.cld files. Running freshclam on background.");
+ mwexec_bg(SQUID_LOCALBASE."/bin/freshclam");
+ }
+ #check startup scripts on pfsense > 2.1
+ if (preg_match("/usr.pbi/",SQUID_LOCALBASE)){
+ $rcd_files = scandir(SQUID_LOCALBASE."/etc/rc.d");
+ foreach($rcd_files as $rcd_file)
+ if (!file_exists("/usr/local/etc/rc.d/{$rcd_file}"))
+ symlink (SQUID_LOCALBASE."/etc/rc.d/{$rcd_file}","/usr/local/etc/rc.d/{$rcd_file}");
+ }
+
+ #write advanced icap config files
+ file_put_contents(SQUID_LOCALBASE."/etc/c-icap/squidclamav.conf",base64_decode($antivirus_config['squidclamav']),LOCK_EX);
+ file_put_contents(SQUID_LOCALBASE."/etc/c-icap/c-icap.conf",base64_decode($antivirus_config['c-icap_conf']),LOCK_EX);
+ file_put_contents(SQUID_LOCALBASE."/etc/c-icap/c-icap.magic",base64_decode($antivirus_config['c-icap_magic']),LOCK_EX);
+
+ #check antivirus daemons
+ #check icap
+ if (is_process_running("c-icap")){
+ mwexec_bg('/bin/echo -n "reconfigure" > /var/run/c-icap/c-icap.ctl');
+ }
+ else{
+ #check c-icap user on startup file
+ $c_icap_rcfile="/usr/local/etc/rc.d/c-icap";
+ if (file_exists($c_icap_rcfile)){
+ $sample_file=file_get_contents($c_icap_rcfile);
+ $cicapm[0]="@c_icap_user=.*}@";
+ $cicapr[0]='c_icap_user="clamav"}';
+ file_put_contents($c_icap_rcfile,preg_replace($cicapm,$cicapr,$sample_file),LOCK_EX);
+ }
+ mwexec_bg("/usr/local/etc/rc.d/c-icap start");
+ }
+ #check clamav
+ if (is_process_running("clamd"))
+ mwexec_bg("/usr/local/etc/rc.d/clamav-clamd reload");
+ else
+ mwexec_bg("/usr/local/etc/rc.d/clamav-clamd start");
+ }
+return $conf;
+}
+
+function squid_resync_traffic() {
+ global $config, $valid_acls;
+
+ if(!is_array($valid_acls))
+ return;
+ if (is_array($config['installedpackages']['squidtraffic']))
+ $settings = $config['installedpackages']['squidtraffic']['config'][0];
+ else
+ $settings = array();
+
+ $conf = '';
+ if (!empty($settings['quick_abort_min']) || ($settings['quick_abort_min']) == "0")
+ $conf .= "quick_abort_min {$settings['quick_abort_min']} KB\n";
+ if (!empty($settings['quick_abort_max']) || ($settings['quick_abort_max']) == "0")
+ $conf .= "quick_abort_max {$settings['quick_abort_max']} KB\n";
+ if (!empty($settings['quick_abort_pct']))
+ $conf .= "quick_abort_pct {$settings['quick_abort_pct']}\n";
+
+ $up_limit = ($settings['max_upload_size'] ? $settings['max_upload_size'] : 0);
+ $down_limit = ($settings['max_download_size'] ? $settings['max_download_size'] : 0);
+ $conf .= "request_body_max_size $up_limit KB\n";
+ if ($down_limit != 0)
+ $conf .= 'reply_body_max_size ' . $down_limit . " KB allsrc \n";
+
+
+ // Only apply throttling past 10MB
+ // XXX: Should this really be hardcoded?
+ $threshold = 10 * 1024 * 1024;
+ $overall = $settings['overall_throttling'];
+ if (!isset($overall) || ($overall == 0))
+ $overall = -1;
+ else
+ $overall *= 1024;
+ $perhost = $settings['perhost_throttling'];
+ if (!isset($perhost) || ($perhost == 0))
+ $perhost = -1;
+ else
+ $perhost *= 1024;
+ $conf .= <<< EOD
+delay_pools 1
+delay_class 1 2
+delay_parameters 1 $overall/$overall $perhost/$perhost
+delay_initial_bucket_level 100
+
+EOD;
+
+ if(! empty($settings['unrestricted_hosts'])) {
+ foreach (array('unrestricted_hosts') as $item) {
+ if (in_array($item, $valid_acls))
+ $conf .= "# Do not throttle unrestricted hosts\n";
+ $conf .= "delay_access 1 deny $item\n";
+ }
+ }
+
+ if ($settings['throttle_specific'] == 'on') {
+ $exts = array();
+ $binaries = 'bin,cab,sea,ar,arj,tar,tgz,gz,tbz,bz2,zip,7z,exe,com';
+ $cdimages = 'iso,bin,mds,nrg,gho,bwt,b5t,pqi';
+ $multimedia = 'aiff?,asf,avi,divx,mov,mp3,mp4,wmv,mpe?g,qt,ra?m';
+ foreach (array( 'throttle_binaries' => $binaries,
+ 'throttle_cdimages' => $cdimages,
+ 'throttle_multimedia' => $multimedia) as $field => $set) {
+ if ($settings[$field] == 'on')
+ $exts = array_merge($exts, explode(",", $set));
+ }
+
+ foreach (explode(",", $settings['throttle_others']) as $ext) {
+ if (!empty($ext)) $exts[] = $ext;
+ }
+
+ $contents = '';
+ foreach ($exts as $ext)
+ $contents .= "\.$ext\$\n";
+ file_put_contents(SQUID_ACLDIR . '/throttle_exts.acl', $contents);
+
+ $conf .= "# Throttle extensions matched in the url\n";
+ $conf .= "acl throttle_exts urlpath_regex -i \"" . SQUID_ACLDIR . "/throttle_exts.acl\"\n";
+ $conf .= "delay_access 1 allow throttle_exts\n";
+ $conf .= "delay_access 1 deny allsrc\n";
+ }
+ else
+ $conf .= "delay_access 1 allow allsrc\n";
+
+ return $conf;
+}
+
+function squid_get_server_certs() {
+ global $config;
+ $cert_arr = array();
+ $cert_arr[] = array('refid' => 'none', 'descr' => 'none');
+ foreach ($config['cert'] as $cert) {
+ $cert_arr[] = array('refid' => $cert['refid'], 'descr' => $cert['descr']);
+ }
+ return $cert_arr;
+}
+
+#squid reverse
+include('/usr/local/pkg/squid_reverse.inc');
+
+function squid_resync_auth() {
+ global $config, $valid_acls;
+ $write_config=0;
+ if (!is_array($config['installedpackages']['squidauth']['config'])){
+ $config['installedpackages']['squidauth']['config'][]=array('auth_method'=> "none");
+ $write_config++;
+ }
+ $settings = $config['installedpackages']['squidauth']['config'][0];
+ if (is_array($config['installedpackages']['squidnac']['config']))
+ $settingsnac = $config['installedpackages']['squidnac']['config'][0];
+ else
+ $settingsnac = array();
+
+ if (is_array($config['installedpackages']['squid']['config']))
+ $settingsconfig = $config['installedpackages']['squid']['config'][0];
+ else
+ $settingsconfig = array();
+
+ if ($write_config > 0)
+ write_config();
+
+ $conf = '';
+
+ // SSL interception acl options part 1
+ if ($settingsconfig['ssl_proxy'] == "on" && ! empty($settingsnac['whitelist'])){
+ $conf .= "always_direct allow whitelist\n";
+ $conf .= "ssl_bump none whitelist\n";
+ }
+
+ // Package integration
+ if(!empty($settingsconfig['custom_options'])){
+ $co_preg[0]='/;/';
+ $co_rep[0]="\n";
+ $co_preg[1]="/redirect_program/";
+ $co_rep[1]="url_rewrite_program";
+ $co_preg[2]="/redirector_bypass/";
+ $co_rep[2]="url_rewrite_bypass";
+ $conf.="# Package Integration\n".preg_replace($co_preg,$co_rep,$settingsconfig['custom_options'])."\n\n";
+ }
+
+ // Custom User Options before authentication acls
+ $conf .= "# Custom options before auth\n".sq_text_area_decode($settingsconfig['custom_options_squid3'])."\n\n";
+
+ // Deny the banned guys before allowing the good guys
+ if(! empty($settingsnac['banned_hosts'])) {
+ if (squid_is_valid_acl('banned_hosts')) {
+ $conf .= "# These hosts are banned\n";
+ $conf .= "http_access deny banned_hosts\n";
+ }
+ }
+ if(! empty($settingsnac['banned_macs'])) {
+ if (squid_is_valid_acl('banned_macs')) {
+ $conf .= "# These macs are banned\n";
+ $conf .= "http_access deny banned_macs\n";
+ }
+ }
+
+ // Unrestricted hosts take precedence over blacklist
+ if(! empty($settingsnac['unrestricted_hosts'])) {
+ if (squid_is_valid_acl('unrestricted_hosts') && $settings['unrestricted_auth']!= "on") {
+ $conf .= "# These hosts do not have any restrictions\n";
+ $conf .= "http_access allow unrestricted_hosts\n";
+ }
+ }
+ if(! empty($settingsnac['unrestricted_macs'])) {
+ if (squid_is_valid_acl('unrestricted_macs')) {
+ $conf .= "# These hosts do not have any restrictions\n";
+ $conf .= "http_access allow unrestricted_macs\n";
+ }
+ }
+
+ // Whitelist and blacklist also take precedence over other allow rules
+ if(! empty($settingsnac['whitelist'])) {
+ if (squid_is_valid_acl('whitelist')) {
+ $conf .= "# Always allow access to whitelist domains\n";
+ $conf .= "http_access allow whitelist\n";
+ }
+ }
+ if(! empty($settingsnac['blacklist'])) {
+ if (squid_is_valid_acl('blacklist')) {
+ $conf .= "# Block access to blacklist domains\n";
+ $conf .= "http_access deny blacklist\n";
+ }
+ }
+ if(! empty($settingsnac['block_user_agent'])) {
+ if (squid_is_valid_acl('block_user_agent')) {
+ $conf .= "# Block access with user agents and browsers\n";
+ $conf .= "http_access deny block_user_agent\n";
+ }
+ }
+ if(! empty($settingsnac['block_reply_mime_type'])) {
+ if (squid_is_valid_acl('block_reply_mime_type')) {
+ $conf .= "# Block access with mime type in the reply\n";
+ $conf .= "http_reply_access deny block_reply_mime_type\n";
+ }
+ }
+
+ // SSL interception acl options part 2
+ /*if ($settingsconfig['ssl_proxy'] == "on"){
+ $conf .= "always_direct allow all\n";
+ $conf .= "ssl_bump server-first all\n";
+ }*/
+
+ // Include squidguard denied acl log in squid
+ if ($settingsconfig['log_sqd'])
+ $conf .= "acl sglog url_regex -i sgr=ACCESSDENIED\n";
+
+ $transparent_proxy = ($settingsconfig['transparent_proxy'] == 'on');
+ if ($transparent_proxy){
+ if (preg_match ("/(none|cp)/",$settings['auth_method']))
+ $auth_method=$settings['auth_method'];
+ else
+ $auth_method="none";
+ }
+ else{
+ $auth_method=$settings['auth_method'];
+ }
+ // Allow the remaining ACLs if no authentication is set
+ if ($auth_method == 'none' || $auth_method == 'cp') {
+ // Include squidguard denied acl log in squid
+ if ($settingsconfig['log_sqd'])
+ $conf .="http_access deny sglog\n";
+ }
+ if ($auth_method == 'none' ) {
+ $conf .="# Setup allowed acls\n";
+ $allowed = array('allowed_subnets');
+ if ($settingsconfig['allow_interface'] == 'on') {
+ $conf .= "# Allow local network(s) on interface(s)\n";
+ $allowed[] = "localnet";
+ }
+ $allowed = array_filter($allowed, 'squid_is_valid_acl');
+ foreach ($allowed as $acl)
+ $conf .= "http_access allow $acl\n";
+ }
+ else {
+ $noauth = implode(' ', explode("\n", base64_decode($settings['no_auth_hosts'])));
+ if (!empty($noauth)) {
+ $conf .= "acl noauth src $noauth\n";
+ $valid_acls[] = 'noauth';
+ }
+
+ // Set up the external authentication programs
+ $auth_ttl = ($settings['auth_ttl'] ? $settings['auth_ttl'] : 5);
+ $processes = ($settings['auth_processes'] ? $settings['auth_processes'] : 5);
+ $prompt = ($settings['auth_prompt'] ? $settings['auth_prompt'] : 'Please enter your credentials to access the proxy');
+ switch ($auth_method) {
+ case 'local':
+ $conf .= 'auth_param basic program '.SQUID_LOCALBASE.'/libexec/squid/basic_ncsa_auth ' . SQUID_PASSWD . "\n";
+ break;
+ case 'ldap':
+ $port = (isset($settings['auth_server_port']) ? ":{$settings['auth_server_port']}" : '');
+ $password = (isset($settings['ldap_pass']) ? "-w {$settings['ldap_pass']}" : '');
+ $conf .= "auth_param basic program " . SQUID_LOCALBASE . "/libexec/squid/basic_ldap_auth -v {$settings['ldap_version']} -b {$settings['ldap_basedomain']} -D {$settings['ldap_user']} $password -f \"{$settings['ldap_filter']}\" -u {$settings['ldap_userattribute']} -P {$settings['auth_server']}$port\n";
+ break;
+ case 'radius':
+ $port = (isset($settings['auth_server_port']) ? "-p {$settings['auth_server_port']}" : '');
+ $conf .= "auth_param basic program ". SQUID_LOCALBASE . "/libexec/squid/basic_radius_auth -w {$settings['radius_secret']} -h {$settings['auth_server']} $port\n";
+ break;
+ case 'cp':
+ $conf .= "external_acl_type check_cp children-startup={$processes} ttl={$auth_ttl} %SRC ". SQUID_LOCALBASE . "/libexec/squid/check_ip.php\n";
+ $conf .= "acl password external check_cp\n";
+ break;
+ case 'msnt':
+ $conf .= "auth_param basic program ". SQUID_LOCALBASE . "/libexec/squid/basic_msnt_auth\n";
+ squid_resync_msnt();
+ break;
+ }
+ if ($auth_method != 'cp'){
+ $conf .= <<< EOD
+auth_param basic children $processes
+auth_param basic realm $prompt
+auth_param basic credentialsttl $auth_ttl minutes
+acl password proxy_auth REQUIRED
+
+EOD;
+ }
+ // Custom User Options after authentication definition
+ $conf .= "# Custom options after auth\n".sq_text_area_decode($settingsconfig['custom_options2_squid3'])."\n\n";
+
+ // SSL interception acl options part 2
+ if ($settingsconfig['ssl_proxy'] == "on"){
+ $conf .= "always_direct allow all\n";
+ $conf .= "ssl_bump server-first all\n";
+ }
+ // Onto the ACLs
+ $password = array('localnet', 'allowed_subnets');
+ $passwordless = array('unrestricted_hosts');
+ if ($settings['unrestricted_auth'] == 'on') {
+ // Even the unrestricted hosts should authenticate
+ $password = array_merge($password, $passwordless);
+ $passwordless = array();
+ }
+ $passwordless[] = 'noauth';
+ $password = array_filter($password, 'squid_is_valid_acl');
+ $passwordless = array_filter($passwordless, 'squid_is_valid_acl');
+
+ // Allow the ACLs that don't need to authenticate
+ foreach ($passwordless as $acl)
+ $conf .= "http_access allow $acl\n";
+
+ //if ($auth_method != 'cp'){
+ // Include squidguard denied acl log in squid
+ if ($settingsconfig['log_sqd'])
+ $conf .="http_access deny password sglog\n";
+
+ // Allow the other ACLs as long as they authenticate
+ foreach ($password as $acl)
+ $conf .= "http_access allow password $acl\n";
+ // }
+ }
+
+ $conf .= "# Default block all to be sure\n";
+ $conf .= "http_access deny allsrc\n";
+
+ return $conf;
+}
+
+function squid_resync_users() {
+ global $config;
+
+ $users = $config['installedpackages']['squidusers']['config'];
+ $contents = '';
+ if (is_array($users)) {
+ foreach ($users as $user)
+ $contents .= $user['username'] . ':' . crypt($user['password'], base64_encode($user['password'])) . "\n";
+ }
+ file_put_contents(SQUID_PASSWD, $contents);
+ chown(SQUID_PASSWD, 'proxy');
+ chmod(SQUID_PASSWD, 0600);
+}
+
+function squid_resync_msnt() {
+ global $config;
+
+ if (is_array($config['installedpackages']['squidauth']))
+ $settings = $config['installedpackages']['squidauth']['config'][0];
+ else
+ $settings = array();
+ $pdcserver = $settings['auth_server'];
+ $bdcserver = str_replace(',',' ',$settings['msnt_secondary']);
+ $ntdomain = $settings['auth_ntdomain'];
+
+ file_put_contents(SQUID_CONFBASE."/msntauth.conf","server {$pdcserver} {$bdcserver} {$ntdomain}");
+ chown(SQUID_CONFBASE."/msntauth.conf", 'proxy');
+ chmod(SQUID_CONFBASE."/msntauth.conf", 0600);
+}
+
+function squid_resync($via_rpc="no") {
+ global $config;
+
+ # detect boot process
+ if (is_array($_POST)){
+ if (preg_match("/\w+/",$_POST['__csrf_magic']))
+ unset($boot_process);
+ else
+ $boot_process="on";
+ }
+
+ log_error("[Squid] - Squid_resync function call pr:".is_process_running('squid')." bp:".isset($boot_process)." rpc:".$via_rpc);
+
+ if (is_process_running('squid') && isset($boot_process) && $via_rpc=="no")
+ return;
+
+ conf_mount_rw();
+ foreach (array( SQUID_CONFBASE,
+ SQUID_ACLDIR,
+ SQUID_BASE,
+ SQUID_LIB,
+ SQUID_SSL_DB ) as $dir) {
+ make_dirs($dir);
+ chown($dir, 'proxy');
+ chgrp($dir, 'proxy');
+ squid_chown_recursive($dir, 'proxy', 'proxy');
+ }
+ $conf = squid_resync_general() . "\n";
+ $conf .= squid_resync_cache() . "\n";
+ $conf .= squid_resync_redirector() . "\n";
+ $conf .= squid_resync_upstream() . "\n";
+ $conf .= squid_resync_nac() . "\n";
+ $conf .= squid_resync_traffic() . "\n";
+ $conf .= squid_resync_reverse() . "\n";
+ $conf .= squid_resync_auth()."\n";
+ $conf .= squid_resync_antivirus();
+ squid_resync_users();
+ squid_write_rcfile();
+
+ if(!isset($boot_process) || $via_rpc="yes")
+ squid_sync_on_changes();
+
+ #write config file
+ file_put_contents(SQUID_CONFBASE . '/squid.conf', $conf);
+
+ /* make sure pinger is executable */
+ if(file_exists(SQUID_LOCALBASE . "/libexec/squid/pinger"))
+ exec("chmod a+x " . SQUID_LOCALBASE . "/libexec/squid/pinger");
+
+ $log_dir="";
+ #check if squid is enabled
+ if (is_array($config['installedpackages']['squid']['config'])){
+ if ($config['installedpackages']['squid']['config'][0]['active_interface']!= "")
+ $log_dir = $config['installedpackages']['squid']['config'][0]['log_dir'].'/';
+ }
+ #check if squidreverse is enabled
+ else if (is_array($config['installedpackages']['squidreversegeneral']['config'])){
+ if ($config['installedpackages']['squidreversegeneral']['config'][0]['reverse_interface'] != "")
+ $log_dir="/var/squid/logs/";
+ }
+ #do not start squid if there is no log dir
+ if ($log_dir != ""){
+ if(!is_dir($log_dir)) {
+ log_error("Creating squid log dir $log_dir");
+ make_dirs($log_dir);
+ squid_chown_recursive($log_dir, 'proxy', 'proxy');
+ }
+
+ squid_dash_z();
+
+ if (!is_service_running('squid')) {
+ log_error("Starting Squid");
+ mwexec(SQUID_LOCALBASE . "/sbin/squid -f " . SQUID_CONFFILE);
+ }
+ else {
+ if (!isset($boot_process)){
+ log_error("Reloading Squid for configuration sync");
+ mwexec(SQUID_LOCALBASE . "/sbin/squid -k reconfigure -f " . SQUID_CONFFILE);
+ }
+ }
+
+ // Sleep for a couple seconds to give squid a chance to fire up fully.
+ for ($i=0; $i < 10; $i++) {
+ if (!is_service_running('squid'))
+ sleep(1);
+ }
+ filter_configure();
+ }
+ conf_mount_ro();
+}
+
+function squid_print_javascript_auth() {
+ global $config;
+ $transparent_proxy = ($config['installedpackages']['squid']['config'][0]['transparent_proxy'] == 'on');
+
+ // No authentication for transparent proxy
+ if ($transparent_proxy and preg_match("/(local|ldap|radius|msnt|ntlm)/",$config['installedpackages']['squidauth']['config'][0]['auth_method'])) {
+ $javascript = <<< EOD
+<script language="JavaScript">
+<!--
+function on_auth_method_changed() {
+ document.iform.auth_method.disabled = 1;
+ document.iform.auth_server.disabled = 1;
+ document.iform.auth_ntdomain.disabled = 1;
+ document.iform.auth_server_port.disabled = 1;
+ document.iform.ldap_user.disabled = 1;
+ document.iform.ldap_version.disabled = 1;
+ document.iform.ldap_userattribute.disabled = 1;
+ document.iform.ldap_filter.disabled = 1;
+ document.iform.ldap_pass.disabled = 1;
+ document.iform.ldap_basedomain.disabled = 1;
+ document.iform.radius_secret.disabled = 1;
+ document.iform.msnt_secondary.disabled = 1;
+ document.iform.auth_prompt.disabled = 1;
+ document.iform.auth_processes.disabled = 1;
+ document.iform.auth_ttl.disabled = 1;
+ document.iform.unrestricted_auth.disabled = 1;
+ document.iform.no_auth_hosts.disabled = 1;
+}
+-->
+</script>
+
+EOD;
+ }
+ else {
+ $javascript = <<< EOD
+<script language="JavaScript">
+<!--
+function on_auth_method_changed() {
+ var field = document.iform.auth_method;
+ var auth_method = field.options[field.selectedIndex].value;
+
+ if (auth_method == 'none') {
+ document.iform.auth_server.disabled = 1;
+ document.iform.auth_server_port.disabled = 1;
+ document.iform.auth_ntdomain.disabled = 1;
+ document.iform.ldap_user.disabled = 1;
+ document.iform.ldap_version.disabled = 1;
+ document.iform.ldap_userattribute.disabled = 1;
+ document.iform.ldap_filter.disabled = 1;
+ document.iform.ldap_pass.disabled = 1;
+ document.iform.ldap_basedomain.disabled = 1;
+ document.iform.radius_secret.disabled = 1;
+ document.iform.msnt_secondary.disabled = 1;
+ document.iform.auth_prompt.disabled = 1;
+ document.iform.auth_processes.disabled = 1;
+ document.iform.auth_ttl.disabled = 1;
+ document.iform.unrestricted_auth.disabled = 1;
+ document.iform.no_auth_hosts.disabled = 1;
+ }
+ else {
+ document.iform.auth_prompt.disabled = 0;
+ document.iform.auth_processes.disabled = 0;
+ document.iform.auth_ttl.disabled = 0;
+ document.iform.unrestricted_auth.disabled = 0;
+ document.iform.no_auth_hosts.disabled = 0;
+ }
+
+ switch (auth_method) {
+ case 'local':
+ document.iform.auth_server.disabled = 1;
+ document.iform.auth_server_port.disabled = 1;
+ document.iform.auth_ntdomain.disabled = 1;
+ document.iform.ldap_user.disabled = 1;
+ document.iform.ldap_pass.disabled = 1;
+ document.iform.ldap_version.disabled = 1;
+ document.iform.ldap_userattribute.disabled = 1;
+ document.iform.ldap_filter.disabled = 1;
+ document.iform.ldap_basedomain.disabled = 1;
+ document.iform.radius_secret.disabled = 1;
+ document.iform.msnt_secondary.disabled = 1;
+ break;
+ case 'ldap':
+ document.iform.auth_server.disabled = 0;
+ document.iform.auth_server_port.disabled = 0;
+ document.iform.ldap_user.disabled = 0;
+ document.iform.ldap_pass.disabled = 0;
+ document.iform.ldap_version.disabled = 0;
+ document.iform.ldap_userattribute.disabled = 0;
+ document.iform.ldap_filter.disabled = 0;
+ document.iform.ldap_basedomain.disabled = 0;
+ document.iform.radius_secret.disabled = 1;
+ document.iform.msnt_secondary.disabled = 1;
+ document.iform.auth_ntdomain.disabled = 1;
+ break;
+ case 'radius':
+ document.iform.auth_server.disabled = 0;
+ document.iform.auth_server_port.disabled = 0;
+ document.iform.ldap_user.disabled = 1;
+ document.iform.ldap_pass.disabled = 1;
+ document.iform.ldap_version.disabled = 1;
+ document.iform.ldap_userattribute.disabled = 1;
+ document.iform.ldap_filter.disabled = 1;
+ document.iform.ldap_basedomain.disabled = 1;
+ document.iform.radius_secret.disabled = 0;
+ document.iform.msnt_secondary.disabled = 1;
+ document.iform.auth_ntdomain.disabled = 1;
+ break;
+ case 'msnt':
+ document.iform.auth_server.disabled = 0;
+ document.iform.auth_server_port.disabled = 1;
+ document.iform.auth_ntdomain.disabled = 0;
+ document.iform.ldap_user.disabled = 1;
+ document.iform.ldap_pass.disabled = 1;
+ document.iform.ldap_version.disabled = 1;
+ document.iform.ldap_userattribute.disabled = 1;
+ document.iform.ldap_filter.disabled = 1;
+ document.iform.ldap_basedomain.disabled = 1;
+ document.iform.radius_secret.disabled = 1;
+ document.iform.msnt_secondary.disabled = 0;
+ break;
+ case 'cp':
+ document.iform.auth_server.disabled = 1;
+ document.iform.auth_server_port.disabled = 1;
+ document.iform.auth_ntdomain.disabled = 1;
+ document.iform.ldap_user.disabled = 1;
+ document.iform.ldap_version.disabled = 1;
+ document.iform.ldap_userattribute.disabled = 1;
+ document.iform.ldap_filter.disabled = 1;
+ document.iform.ldap_pass.disabled = 1;
+ document.iform.ldap_basedomain.disabled = 1;
+ document.iform.radius_secret.disabled = 1;
+ document.iform.msnt_secondary.disabled = 1;
+ document.iform.auth_prompt.disabled = 1;
+ document.iform.auth_processes.disabled = 0;
+ document.iform.auth_ttl.disabled = 0;
+ document.iform.unrestricted_auth.disabled = 1;
+ document.iform.no_auth_hosts.disabled = 1;
+ break;
+ }
+}
+-->
+</script>
+
+EOD;
+ }
+
+ print($javascript);
+}
+
+function squid_print_javascript_auth2() {
+ print("<script language=\"JavaScript\">on_auth_method_changed()</script>\n");
+}
+
+function squid_generate_rules($type) {
+ global $config;
+ $squid_conf = $config['installedpackages']['squid']['config'][0];
+ //check captive portal option
+ $cp_file='/etc/inc/captiveportal.inc';
+ $pfsense_version=preg_replace("/\s/","",file_get_contents("/etc/version"));
+ $port = ($settings['proxy_port'] ? $settings['proxy_port'] : 3128);
+ $cp_inc = file($cp_file);
+ $new_cp_inc="";
+ $found_rule=0;
+ foreach ($cp_inc as $line){
+ $new_line=$line;
+ //remove applied squid patch
+ if (preg_match('/skipto 65314 ip/',$line)){
+ $found_rule++;
+ $new_line ="";
+ }
+
+ if (substr($pfsense_version,0,3) > 2.0){
+ if (preg_match('/255.255.255.255/',$line) && $squid_conf['patch_cp']){
+ $found_rule++;
+ $new_line .= "\n\t".'$cprules .= "add {$rulenum} skipto 65314 ip from any to {$ips} '.$port.' in\n";'."\n";
+ $new_line .= "\t".'$cprules .= "add {$rulenum} skipto 65314 ip from {$ips} '.$port.' to any out\n";'."\n";
+ }
+ }
+ else{
+ //add squid patch option based on current config
+ if (preg_match('/set 1 pass ip from any to/',$line) && $squid_conf['patch_cp']){
+ $found_rule++;
+ $new_line = "\t".'$cprules .= "add {$rulenum} set 1 skipto 65314 ip from any to {$ips} '.$port.' in\n";'."\n";
+ $new_line .= $line;
+ }
+ if (preg_match('/set 1 pass ip from {/',$line) && $squid_conf['patch_cp']){
+ $found_rule++;
+ $new_line = "\t".'$cprules .= "add {$rulenum} set 1 skipto 65314 ip from {$ips} '.$port.' to any out\n";'."\n";
+ $new_line .= $line;
+ }
+ }
+ $new_cp_inc .= $new_line;
+ }
+ if (!file_exists('/root/'.$pfsense_version.'.captiveportal.inc.backup')) {
+ copy ($cp_file,'/root/'.$pfsense_version.'.captiveportal.inc.backup');
+ }
+ if($found_rule > 0){
+ file_put_contents($cp_file,$new_cp_inc, LOCK_EX);
+ }
+ //normal squid rule check
+ if (($squid_conf['transparent_proxy'] != 'on') || ($squid_conf['allow_interface'] != 'on')) {
+ return;
+ }
+
+ if (!is_service_running('squid')) {
+ log_error("SQUID is installed but not started. Not installing \"{$type}\" rules.");
+ return;
+ }
+ #Read assigned interfaces
+ $proxy_ifaces = explode(",", $squid_conf['active_interface']);
+ $proxy_ifaces = array_map('convert_friendly_interface_to_real_interface_name', $proxy_ifaces);
+ if ($squid_conf['transparent_proxy']=="on"){
+ $transparent_ifaces = explode(",", $squid_conf['transparent_active_interface']);
+ $transparent_ifaces = array_map('convert_friendly_interface_to_real_interface_name', $transparent_ifaces);
+ }
+ else{
+ $transparent_ifaces=array();
+ }
+ if ($squid_conf['ssl_proxy'] == "on"){
+ $ssl_ifaces = explode(",", $squid_conf['ssl_active_interface']);
+ $ssl_ifaces = array_map('convert_friendly_interface_to_real_interface_name', $ssl_ifaces);
+ }
+ else{
+ $ssl_ifaces=array();
+ }
+
+ $port = ($squid_conf['proxy_port'] ? $squid_conf['proxy_port'] : 3128);
+ $ssl_port = ($squid_conf['ssl_proxy_port'] ? $squid_conf['ssl_proxy_port'] : 3127);
+
+ $fw_aliases = filter_generate_aliases();
+ if(strstr($fw_aliases, "pptp ="))
+ $PPTP_ALIAS = "\$pptp";
+ else
+ $PPTP_ALIAS = "\$PPTP";
+ if(strstr($fw_aliases, "PPPoE ="))
+ $PPPOE_ALIAS = "\$PPPoE";
+ else
+ $PPPOE_ALIAS = "\$pppoe";
+
+ #define ports based on transparent options and ssl filtering
+ $pf_rule_port=($squid_conf['ssl_proxy'] == "on" ? "{80,443}" : "80");
+ switch($type) {
+ case 'nat':
+ $rules .= "\n# Setup Squid proxy redirect\n";
+ if ($squid_conf['private_subnet_proxy_off'] == 'on') {
+ foreach ($transparent_ifaces as $iface) {
+ $pf_transparent_rule_port=(in_array($iface,$ssl_ifaces) ? "{80,443}" : "80");
+ $rules .= "no rdr on $iface proto tcp from any to { 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 } port {$pf_transparent_rule_port}\n";
+ }
+ /* Handle PPPOE case */
+ if(($config['pppoe']['mode'] == "server" && $config['pppoe']['localip']) || (function_exists("is_pppoe_server_enabled") && is_pppoe_server_enabled())) {
+ $rules .= "no rdr on $PPPOE_ALIAS proto tcp from any to { 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 } port {$pf_rule_port}\n";
+ }
+ /* Handle PPTP case */
+ if($config['pptpd']['mode'] == "server" && $config['pptpd']['localip']) {
+ $rules .= "no rdr on $PPTP_ALIAS proto tcp from any to { 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 } port {$pf_rule_port}\n";
+ }
+ }
+ if (!empty($squid_conf['defined_ip_proxy_off'])) {
+ $defined_ip_proxy_off = explode(";", $squid_conf['defined_ip_proxy_off']);
+ $exempt_ip = "";
+ foreach ($defined_ip_proxy_off as $ip_proxy_off) {
+ if(!empty($ip_proxy_off)) {
+ $ip_proxy_off = trim($ip_proxy_off);
+ if (is_alias($ip_proxy_off))
+ $ip_proxy_off = '$'.$ip_proxy_off;
+ $exempt_ip .= ", $ip_proxy_off";
+ }
+ }
+ $exempt_ip = substr($exempt_ip,2);
+ foreach ($transparent_ifaces as $iface) {
+ $pf_transparent_rule_port=(in_array($iface,$ssl_ifaces) ? "{80,443}" : "80");
+ $rules .= "no rdr on $iface proto tcp from { $exempt_ip } to any port {$pf_transparent_rule_port}\n";
+ }
+ /* Handle PPPOE case */
+ if(($config['pppoe']['mode'] == "server" && $config['pppoe']['localip']) || (function_exists("is_pppoe_server_enabled") && is_pppoe_server_enabled())) {
+ $rules .= "no rdr on $PPPOE_ALIAS proto tcp from { $exempt_ip } to any port {$pf_rule_port}\n";
+ }
+ /* Handle PPTP case */
+ if($config['pptpd']['mode'] == "server" && $config['pptpd']['localip']) {
+ $rules .= "no rdr on $PPTP_ALIAS proto tcp from { $exempt_ip } to any port {$pf_rule_port}\n";
+ }
+ }
+ if (!empty($squid_conf['defined_ip_proxy_off_dest'])) {
+ $defined_ip_proxy_off_dest = explode(";", $squid_conf['defined_ip_proxy_off_dest']);
+ $exempt_dest = "";
+ foreach ($defined_ip_proxy_off_dest as $ip_proxy_off_dest) {
+ if(!empty($ip_proxy_off_dest)) {
+ $ip_proxy_off_dest = trim($ip_proxy_off_dest);
+ if (is_alias($ip_proxy_off_dest))
+ $ip_proxy_off_dest = '$'.$ip_proxy_off_dest;
+ $exempt_dest .= ", $ip_proxy_off_dest";
+ }
+ }
+ $exempt_dest = substr($exempt_dest,2);
+ foreach ($transparent_ifaces as $iface) {
+ $pf_transparent_rule_port=(in_array($iface,$ssl_ifaces) ? "{80,443}" : "80");
+ $rules .= "no rdr on $iface proto tcp from any to { $exempt_dest } port {$pf_transparent_rule_port}\n";
+ }
+ /* Handle PPPOE case */
+ if(($config['pppoe']['mode'] == "server" && $config['pppoe']['localip']) || (function_exists("is_pppoe_server_enabled") && is_pppoe_server_enabled())) {
+ $rules .= "no rdr on $PPPOE_ALIAS proto tcp from any to { $exempt_dest } port {$pf_rule_port}\n";
+ }
+ /* Handle PPTP case */
+ if($config['pptpd']['mode'] == "server" && $config['pptpd']['localip']) {
+ $rules .= "no rdr on $PPTP_ALIAS proto tcp from any to { $exempt_dest } port {$pf_rule_port}\n";
+ }
+ }
+ foreach ($transparent_ifaces as $t_iface) {
+ $pf_transparent_rule_port=(in_array($t_iface,$ssl_ifaces) ? "{80,443}" : "80");
+ $rules .= "rdr on $t_iface proto tcp from any to !($t_iface) port 80 -> 127.0.0.1 port {$port}\n";
+ if (in_array($t_iface,$ssl_ifaces))
+ $rules .= "rdr on $t_iface proto tcp from any to !($t_iface) port 443 -> 127.0.0.1 port {$ssl_port}\n";
+ }
+ /* Handle PPPOE case */
+ if(($config['pppoe']['mode'] == "server" && $config['pppoe']['localip']) || (function_exists("is_pppoe_server_enabled") && is_pppoe_server_enabled())) {
+ $rules .= "rdr on $PPPOE_ALIAS proto tcp from any to !127.0.0.1 port {$pf_rule_port} -> 127.0.0.1 port {$port}\n";
+ }
+ /* Handle PPTP case */
+ if($config['pptpd']['mode'] == "server" && $config['pptpd']['localip']) {
+ $rules .= "rdr on $PPTP_ALIAS proto tcp from any to !127.0.0.1 port {$pf_rule_port} -> 127.0.0.1 port {$port}\n";
+ }
+ $rules .= "\n";
+ break;
+ case 'filter':
+ case 'rule':
+ foreach ($transparent_ifaces as $iface) {
+ $pf_transparent_rule_port=(in_array($iface,$ssl_ifaces) ? "{80,443,{$port},{$ssl_port}}" : "{80,{$port}}");
+ $rules .= "# Setup squid pass rules for proxy\n";
+ $rules .= "pass in quick on $iface proto tcp from any to !($iface) port {$pf_transparent_rule_port} flags S/SA keep state\n";
+ #$rules .= "pass in quick on $iface proto tcp from any to !($iface) port {$port} flags S/SA keep state\n";
+ $rules .= "\n";
+ };
+ if($config['pppoe']['mode'] == "server" && $config['pppoe']['localip']) {
+ $rules .= "pass in quick on $PPPOE_ALIAS proto tcp from any to !127.0.0.1 port {$port} flags S/SA keep state\n";
+ }
+ if($config['pptpd']['mode'] == "server" && $config['pptpd']['localip']) {
+ $rules .= "pass in quick on $PPTP_ALIAS proto tcp from any to !127.0.0.1 port {$port} flags S/SA keep state\n";
+ }
+ break;
+ default:
+ break;
+ }
+
+ return $rules;
+}
+
+function squid_write_rcfile() {
+ /* Declare a variable for the SQUID_CONFFILE constant. */
+ /* Then the variable can be referenced easily in the Heredoc text that generates the rc file. */
+ $squid_conffile_var = SQUID_CONFFILE;
+ $squid_local_base = SQUID_LOCALBASE;
+ $rc = array();
+ $rc['file'] = 'squid.sh';
+ $rc['start'] = <<<EOD
+if [ -z "`ps auxw | grep "[s]quid "|awk '{print $2}'`" ];then
+ {$squid_local_base}/sbin/squid -f {$squid_conffile_var}
+fi
+
+EOD;
+
+ $rc['stop'] = <<<EOD
+{$squid_local_base}/sbin/squid -k shutdown -f {$squid_conffile_var}
+# Just to be sure...
+sleep 5
+
+if [ -f /usr/bin/ipcs ];then
+# http://man.chinaunix.net/newsoft/squid/Squid_FAQ/FAQ-22.html#ss22.8
+ipcs | grep '^[mq]' | awk '{printf "ipcrm -%s %s\\n", $1, $2}' | /bin/sh
+fi
+
+killall -9 squid 2>/dev/null
+killall pinger 2>/dev/null
+
+EOD;
+ $rc['restart'] = <<<EOD
+if [ -z "`ps auxw | grep "[s]quid "|awk '{print $2}'`" ];then
+ {$squid_local_base}/sbin/squid -f {$squid_conffile_var}
+ else
+ {$squid_local_base}/sbin/squid -k reconfigure -f {$squid_conffile_var}
+ fi
+
+EOD;
+ conf_mount_rw();
+ write_rcfile($rc);
+ conf_mount_ro();
+}
+
+/* Uses XMLRPC to synchronize the changes to a remote node */
+function squid_sync_on_changes() {
+ global $config, $g;
+ if (is_array($config['installedpackages']['squidsync']['config'])){
+ $squid_sync=$config['installedpackages']['squidsync']['config'][0];
+ $synconchanges = $squid_sync['synconchanges'];
+ $synctimeout = $squid_sync['synctimeout'];
+ switch ($synconchanges){
+ case "manual":
+ if (is_array($squid_sync[row])){
+ $rs=$squid_sync[row];
+ }
+ else{
+ log_error("[squid] xmlrpc sync is enabled but there is no hosts to push on squid config.");
+ return;
+ }
+ break;
+ case "auto":
+ if (is_array($config['installedpackages']['carpsettings']) && is_array($config['installedpackages']['carpsettings']['config'])){
+ $system_carp=$config['installedpackages']['carpsettings']['config'][0];
+ $rs[0]['ipaddress']=$system_carp['synchronizetoip'];
+ $rs[0]['username']=$system_carp['username'];
+ $rs[0]['password']=$system_carp['password'];
+ }
+ else{
+ log_error("[squid] xmlrpc sync is enabled but there is no system backup hosts to push squid config.");
+ return;
+ }
+ break;
+ default:
+ return;
+ break;
+ }
+ if (is_array($rs)){
+ log_error("[squid] xmlrpc sync is starting.");
+ foreach($rs as $sh){
+ $sync_to_ip = $sh['ipaddress'];
+ $password = $sh['password'];
+ if($sh['username'])
+ $username = $sh['username'];
+ else
+ $username = 'admin';
+ if($password && $sync_to_ip)
+ squid_do_xmlrpc_sync($sync_to_ip, $username, $password,$synctimeout);
+ }
+ log_error("[squid] xmlrpc sync is ending.");
+ }
+ }
+}
+/* Do the actual XMLRPC sync */
+function squid_do_xmlrpc_sync($sync_to_ip, $username, $password, $synctimeout) {
+ global $config, $g;
+
+ if(!$username)
+ return;
+
+ if(!$password)
+ return;
+
+ if(!$sync_to_ip)
+ return;
+
+ if(!$synctimeout)
+ $synctimeout=250;
+
+
+ $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['squid'] = $config['installedpackages']['squid'];
+ $xml['squidupstream'] = $config['installedpackages']['squidupstream'];
+ $xml['squidcache'] = $config['installedpackages']['squidcache'];
+ $xml['squidantivirus'] = $config['installedpackages']['squidanitivirus'];
+ $xml['squidnac'] = $config['installedpackages']['squidnac'];
+ $xml['squidtraffic'] = $config['installedpackages']['squidtraffic'];
+ $xml['squidreversegeneral'] = $config['installedpackages']['squidreversegeneral'];
+ $xml['squidreversepeer'] = $config['installedpackages']['squidreversepeer'];
+ $xml['squidreverseuri'] = $config['installedpackages']['squidreverseuri'];
+ $xml['squidauth'] = $config['installedpackages']['squidauth'];
+ $xml['squidusers'] = $config['installedpackages']['squidusers'];
+ /* 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("[Squid] Beginning squid 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($username, $password);
+ if($g['debug'])
+ $cli->setDebug(1);
+ /* send our XMLRPC message and timeout after defined sync timeout value*/
+ $resp = $cli->send($msg, $synctimeout);
+ if(!$resp) {
+ $error = "A communications error occurred while attempting squid XMLRPC sync with {$url}:{$port}.";
+ log_error($error);
+ file_notice("sync_settings", $error, "squid Settings Sync", "");
+ } elseif($resp->faultCode()) {
+ $cli->setDebug(1);
+ $resp = $cli->send($msg, $synctimeout);
+ $error = "An error code was received while attempting squid XMLRPC sync with {$url}:{$port} - Code " . $resp->faultCode() . ": " . $resp->faultString();
+ log_error($error);
+ file_notice("sync_settings", $error, "squid Settings Sync", "");
+ } else {
+ log_error("[Squid] XMLRPC sync successfully completed with {$url}:{$port}.");
+ }
+
+ /* tell squid to reload our settings on the destination sync host. */
+ $method = 'pfsense.exec_php';
+ $execcmd = "require_once('/usr/local/pkg/squid.inc');\n";
+ $execcmd .= "squid_resync('yes');";
+ /* assemble xmlrpc payload */
+ $params = array(
+ XML_RPC_encode($password),
+ XML_RPC_encode($execcmd)
+ );
+
+ log_error("[Squid] XMLRPC reload data {$url}:{$port}.");
+ $msg = new XML_RPC_Message($method, $params);
+ $cli = new XML_RPC_Client('/xmlrpc.php', $url, $port);
+ $cli->setCredentials($username, $password);
+ $resp = $cli->send($msg, $synctimeout);
+ if(!$resp) {
+ $error = "A communications error occurred while attempting squid XMLRPC sync with {$url}:{$port} (pfsense.exec_php).";
+ log_error($error);
+ file_notice("sync_settings", $error, "squid Settings Sync", "");
+ } elseif($resp->faultCode()) {
+ $cli->setDebug(1);
+ $resp = $cli->send($msg, $synctimeout);
+ $error = "[Squid] An error code was received while attempting squid XMLRPC sync with {$url}:{$port} - Code " . $resp->faultCode() . ": " . $resp->faultString();
+ log_error($error);
+ file_notice("sync_settings", $error, "squid Settings Sync", "");
+ } else {
+ log_error("squid XMLRPC reload data success with {$url}:{$port} (pfsense.exec_php).");
+ }
+
+}
+?>