Share Pastebin
Guest
Public paste!

Andy Lai

By: a guest | Mar 14th, 2010 | Syntax: Python | Size: 48.03 KB | Hits: 164 | Expires: Never
Copy text to clipboard
  1. <?php
  2. /* $Id$ */
  3. /*
  4.         squid.inc
  5.         Copyright (C) 2006-2009 Scott Ullrich
  6.         Copyright (C) 2006 Fernando Lemos
  7.         Copyright (C) 2008 Martin Fuchs
  8.         All rights reserved.
  9.  
  10.         Redistribution and use in source and binary forms, with or without
  11.         modification, are permitted provided that the following conditions are met:
  12.  
  13.         1. Redistributions of source code must retain the above copyright notice,
  14.            this list of conditions and the following disclaimer.
  15.  
  16.         2. Redistributions in binary form must reproduce the above copyright
  17.            notice, this list of conditions and the following disclaimer in the
  18.            documentation and/or other materials provided with the distribution.
  19.  
  20.         THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
  21.         INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  22.         AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  23.         AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
  24.         OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  25.         SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  26.         INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  27.         CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  28.         ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  29.         POSSIBILITY OF SUCH DAMAGE.
  30. */
  31.  
  32. require_once('globals.inc');
  33. require_once('config.inc');
  34. require_once('util.inc');
  35. require_once('pfsense-utils.inc');
  36. require_once('pkg-utils.inc');
  37. require_once('service-utils.inc');
  38.  
  39. if(!function_exists("filter_configure"))
  40.         require_once("filter.inc");
  41.  
  42. define('SQUID_CONFBASE', '/usr/local/etc/squid');
  43. define('SQUID_ACLDIR', '/var/squid/acl');
  44. define('SQUID_PASSWD', '/var/etc/squid.passwd');
  45.  
  46. $valid_acls = array();
  47.  
  48. function squid_get_real_interface_address($iface) {
  49.         global $config;
  50.  
  51.         $iface = convert_friendly_interface_to_real_interface_name($iface);
  52.         $line = trim(shell_exec("ifconfig $iface | grep inet | grep -v inet6"));
  53.         list($dummy, $ip, $dummy2, $netmask) = explode(" ", $line);
  54.  
  55.         return array($ip, long2ip(hexdec($netmask)));
  56. }
  57.  
  58. function squid_chown_recursive($dir, $user, $group) {
  59.         chown($dir, $user);
  60.         chgrp($dir, $group);
  61.         $handle = opendir($dir) ;
  62.         while (($item = readdir($handle)) !== false) {
  63.                 if (($item != ".") && ($item != "..")) {
  64.                         $path = "$dir/$item";
  65.                         if (is_dir($path))
  66.                                 squid_chown_recursive($path, $user, $group);
  67.                         else {
  68.                                 chown($path, $user);
  69.                                 chgrp($path, $group);
  70.                         }
  71.                 }
  72.         }
  73. }
  74.  
  75. /* setup cache */
  76. function squid_dash_z() {
  77.         global $config;
  78.         $settings = $config['installedpackages']['squidcache']['config'][0];
  79.         $cachedir =($settings['harddisk_cache_location'] ? $settings['harddisk_cache_location'] : '/var/squid/cache');
  80.  
  81.         if(!is_dir($cachedir.'/')) {
  82.                 log_error("Creating Squid cache dir $cachedir");
  83.                 make_dirs($cachedir);
  84.                 squid_chown_recursive($cachedir, 'proxy', 'proxy');
  85.         }
  86.  
  87.         if(!is_dir($cachedir.'/00/')) {
  88.                 log_error("Creating squid cache subdirs in $cachedir");
  89.                 mwexec("/usr/local/sbin/squid -k shutdown");
  90.                 sleep(5);
  91.                 mwexec("/usr/local/sbin/squid -k kill");
  92.                 mwexec("/usr/local/sbin/squid -z");
  93.         }
  94.  
  95.         if(file_exists("/var/squid/cache/swap.state"))
  96.                 exec("chmod a+rw /var/squid/cache/swap.state");
  97.  
  98. }
  99.  
  100. function squid_is_valid_acl($acl) {
  101.         global $valid_acls;
  102.         if(!is_array($valid_acls))
  103.                 return;
  104.         return in_array($acl, $valid_acls);
  105. }
  106.  
  107. function squid_install_command() {
  108.         global $config;
  109.         /* migrate existing csv config fields */
  110.         $settingsauth = $config['installedpackages']['squidauth']['config'][0];
  111.         $settingscache = $config['installedpackages']['squidcache']['config'][0];
  112.         $settingsnac = $config['installedpackages']['squidnac']['config'][0];
  113.  
  114.         /* migrate auth settings */
  115.         if (!empty($settingsauth['no_auth_hosts'])) {
  116.                 if(strstr($settingsauth['no_auth_hosts'], ",")) {
  117.                         $settingsauth['no_auth_hosts'] = base64_encode(implode("\n", explode(",", $settingsauth['no_auth_hosts'])));
  118.                         $config['installedpackages']['squidauth']['config'][0]['no_auth_hosts'] = $settingsauth['no_auth_hosts'];
  119.                 }
  120.         }
  121.  
  122.         /* migrate cache settings */
  123.         if (!empty($settingscache['donotcache'])) {
  124.                 if(strstr($settingscache['donotcache'], ",")) {
  125.                         $settingscache['donotcache'] = base64_encode(implode("\n", explode(",", $settingscache['donotcache'])));
  126.                         $config['installedpackages']['squidcache']['config'][0]['donotcache'] = $settingscache['donotcache'];
  127.                 }
  128.         }
  129.  
  130.         /* migrate nac settings */
  131.         if(! empty($settingsnac['allowed_subnets'])) {
  132.                 if(strstr($settingsnac['allowed_subnets'], ",")) {
  133.                         $settingsnac['allowed_subnets'] = base64_encode(implode("\n", explode(",", $settingsnac['allowed_subnets'])));
  134.                         $config['installedpackages']['squidnac']['config'][0]['allowed_subnets'] = $settingsnac['allowed_subnets'];
  135.                 }
  136.         }
  137.  
  138.         if(! empty($settingsnac['banned_hosts'])) {
  139.                 if(strstr($settingsnac['banned_hosts'], ",")) {
  140.                         $settingsnac['banned_hosts'] = base64_encode(implode("\n", explode(",", $settingsnac['banned_hosts'])));
  141.                         $config['installedpackages']['squidnac']['config'][0]['banned_hosts'] = $settingsnac['banned_hosts'];
  142.                 }
  143.         }
  144.  
  145.         if(! empty($settingsnac['banned_macs'])) {
  146.                 if(strstr($settingsnac['banned_macs'], ",")) {
  147.                         $settingsnac['banned_macs'] = base64_encode(implode("\n", explode(",", $settingsnac['banned_macs'])));
  148.                         $config['installedpackages']['squidnac']['config'][0]['banned_macs'] = $settingsnac['banned_macs'];
  149.                 }
  150.         }
  151.  
  152.         if(! empty($settingsnac['unrestricted_hosts'])) {
  153.                 if(strstr($settingsnac['unrestricted_hosts'], ",")) {
  154.                         $settingsnac['unrestricted_hosts'] = base64_encode(implode("\n", explode(",", $settingsnac['unrestricted_hosts'])));
  155.                         $config['installedpackages']['squidnac']['config'][0]['unrestricted_hosts'] = $settingsnac['unrestricted_hosts'];
  156.                 }
  157.         }
  158.  
  159.         if(! empty($settingsnac['unrestricted_macs'])) {
  160.                 if(strstr($settingsnac['unrestricted_macs'], ",")) {
  161.                         $settingsnac['unrestricted_macs'] = base64_encode(implode("\n", explode(",", $settingsnac['unrestricted_macs'])));
  162.                         $config['installedpackages']['squidnac']['config'][0]['unrestricted_macs'] = $settingsnac['unrestricted_macs'];
  163.                 }
  164.         }
  165.  
  166.         if(! empty($settingsnac['whitelist'])) {
  167.                 if(strstr($settingsnac['whitelist'], ",")) {
  168.                         $settingsnac['whitelist'] = base64_encode(implode("\n", explode(",", $settingsnac['whitelist'])));
  169.                         $config['installedpackages']['squidnac']['config'][0]['whitelist'] = $settingsnac['whitelist'];
  170.                 }
  171.         }
  172.  
  173.         if(! empty($settingsnac['blacklist'])) {
  174.                 if(strstr($settingsnac['blacklist'], ",")) {
  175.                         $settingsnac['blacklist'] = base64_encode(implode("\n", explode(",", $settingsnac['blacklist'])));
  176.                         $config['installedpackages']['squidnac']['config'][0]['blacklist'] = $settingsnac['blacklist'];
  177.                 }
  178.         }
  179.        
  180.         update_status("Writing configuration... One moment please...");
  181.        
  182.         write_config();
  183.  
  184.         /* create cache */
  185.         update_status("Creating squid cache pools... One moment please...");
  186.         squid_dash_z();
  187.         /* make sure pinger is executable */
  188.         if(file_exists("/usr/local/libexec/squid/pinger"))
  189.                 exec("/bin/chmod a+x /usr/local/libexec/squid/pinger");
  190.         if(file_exists("/usr/local/etc/rc.d/squid"))
  191.                 exec("/bin/rm /usr/local/etc/rc.d/squid");
  192.         $rc = array();
  193.         $rc['file'] = 'squid.sh';
  194.         $rc['start'] = <<<EOD
  195. if [ -z "`ps auxw | grep "[s]quid -D"|awk '{print $2}'`" ];then
  196.         /usr/local/sbin/squid -D
  197. fi
  198.  
  199. EOD;
  200.         $rc['stop'] = <<<EOD
  201. /usr/local/sbin/squid -k shutdown
  202. # Just to be sure...
  203. sleep 5
  204. killall -9 squid 2>/dev/null
  205. killall pinger 2>/dev/null
  206.  
  207. EOD;
  208.         $rc['restart'] = <<<EOD
  209. if [ -z "`ps auxw | grep "[s]quid -D"|awk '{print $2}'`" ];then
  210.                 /usr/local/sbin/squid -D
  211.         else
  212.                 /usr/local/sbin/squid -k reconfigure
  213.         fi
  214.  
  215. EOD;
  216.         update_status("Writing rc.d files... One moment please...");
  217.         write_rcfile($rc);
  218.  
  219.         exec("chmod a+rx /usr/local/libexec/squid/dnsserver");
  220.  
  221.         foreach (array( SQUID_CONFBASE,
  222.                         SQUID_ACLDIR,
  223.         ) as $dir) {
  224.                         make_dirs($dir);
  225.                         squid_chown_recursive($dir, 'proxy', 'proxy');
  226.         }
  227.  
  228.         /* kill any running proxy alarm scripts */
  229.         update_status("Checking for running processes... One moment please...");
  230.         log_error("Stopping any running proxy monitors");
  231.         mwexec("ps awux | grep \"proxy_monitor\" | grep -v \"grep\" | grep -v \"php\" | awk '{ print $2 }' | xargs kill");
  232.         sleep(1);
  233.  
  234.         if (!file_exists(SQUID_CONFBASE . '/mime.conf') && file_exists(SQUID_CONFBASE . '/mime.conf.default'))
  235.                 copy(SQUID_CONFBASE . '/mime.conf.default', SQUID_CONFBASE . '/mime.conf');
  236.  
  237.         update_status("Checking cache... One moment please...");
  238.         squid_dash_z();
  239.  
  240.         if (!is_service_running('squid')) {
  241.                 update_status("Starting... One moment please...");
  242.                 log_error("Starting Squid");
  243.                 mwexec_bg("/usr/local/sbin/squid -D");
  244.         } else {
  245.                 update_status("Reloading Squid for configuration sync... One moment please...");
  246.                 log_error("Reloading Squid for configuration sync");
  247.                 mwexec("/usr/local/sbin/squid -k reconfigure");
  248.         }
  249.  
  250.         /* restart proxy alarm scripts */
  251.         log_error("Starting a proxy monitor script");
  252.         mwexec_bg("/usr/local/etc/rc.d/proxy_monitor.sh");
  253.  
  254.         update_status("Reconfiguring filter... One moment please...");
  255.         filter_configure();
  256. }
  257.  
  258. function squid_deinstall_command() {
  259.         global $config, $g;
  260.         $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.";
  261.         squid_install_cron(false);
  262.         $settings = &$config['installedpackages']['squidcache']['config'][0];
  263.         $cachedir =($settings['harddisk_cache_location'] ? $settings['harddisk_cache_location'] : '/var/squid/cache');
  264.         $logdir = ($settings['log_dir'] ? $settings['log_dir'] : '/var/squid/log');
  265.         update_status("Removing swap.state ... One moment please...");
  266.         update_output_window("$plswait_txt");
  267.         mwexec('rm -rf $cachedir/swap.state');
  268.         mwexec('rm -rf $logdir');
  269.         update_status("Finishing package cleanup.");
  270.         mwexec('rm -f /usr/local/etc/rc.d/proxy_monitor.sh');
  271.         mwexec("ps awux | grep \"proxy_monitor\" | grep -v \"grep\" | grep -v \"php\" | awk '{ print $2 }' | xargs kill");
  272.         mwexec("ps awux | grep \"squid\" | grep -v \"grep\" | awk '{ print $2 }' | xargs kill");
  273.         mwexec("ps awux | grep \"dnsserver\" | grep -v \"grep\" | awk '{ print $2 }' | xargs kill");
  274.         mwexec("ps awux | grep \"unlinkd\" | grep -v \"grep\" | awk '{ print $2 }' | xargs kill");
  275.         update_status("Reloading filter...");
  276.         filter_configure_sync();
  277. }
  278.  
  279. function squid_before_form_general($pkg) {
  280.         $values = get_dir(SQUID_CONFBASE . '/errors/');
  281.         // Get rid of '..' and '.'
  282.         array_shift($values);
  283.         array_shift($values);
  284.         $name = array();
  285.         foreach ($values as $value)
  286.                 $names[] = implode(" ", explode("_", $value));
  287.  
  288.         $i = 0;
  289.         foreach ($pkg['fields']['field'] as $field) {
  290.                 if ($field['fieldname'] == 'error_language')
  291.                         break;
  292.                 $i++;
  293.         }
  294.         $field = &$pkg['fields']['field'][$i];
  295.  
  296.         for ($i = 0; $i < count($values) - 1; $i++)
  297.                 $field['options']['option'][] = array('name' => $names[$i], 'value' => $values[$i]);
  298. }
  299.  
  300. function squid_validate_general($post, $input_errors) {
  301.         global $config;
  302.         $settings = $config['installedpackages']['squid']['config'][0];
  303.         $port = ($settings['proxy_port'] ? $settings['proxy_port'] : 3128);
  304.         $port = $post['proxy_port'] ? $post['proxy_port'] : $port;
  305.  
  306.         $icp_port = trim($post['icp_port']);
  307.         if (!empty($icp_port) && !is_port($icp_port))
  308.                 $input_errors[] = 'You must enter a valid port number in the \'ICP port\' field';
  309.  
  310.         if (substr($post['log_dir'], -1, 1) == '/')
  311.                 $input_errors[] = 'You may not end log location with an / mark';
  312.  
  313.         if ($post['log_dir']{0} != '/')
  314.                 $input_errors[] = 'You must start log location with a / mark';
  315.         if (strlen($post['log_dir']) <= 3)
  316.                 $input_errors[] = "That is not a valid log location dir";
  317.  
  318.         $log_rotate = trim($post['log_rotate']);
  319.         if (!empty($log_rotate) && (!is_numeric($log_rotate) or ($log_rotate < 1)))
  320.                 $input_errors[] = 'You must enter a valid number of days \'Log rotate\' field';
  321.  
  322.         $webgui_port = $config['system']['webgui']['port'];
  323.         if(($config['system']['webgui']['port'] == "") && ($config['system']['webgui']['protocol'] == "http")) {
  324.                 $webgui_port = 80;
  325.         }
  326.         if(($config['system']['webgui']['port'] == "") && ($config['system']['webgui']['protocol'] == "https")) {
  327.                 $webgui_port = 443;
  328.         }
  329.  
  330.         if (($post['transparent_proxy'] != 'on') && ($port == $webgui_port)) {
  331.                 $input_errors[] = "You can not run squid on the same port as the webgui";
  332.         }
  333.  
  334.         if (($post['transparent_proxy'] != 'on') && ($post['private_subnet_proxy_off'] == 'on')) {
  335.                 $input_errors[] = "You can not bypass traffic to private subnets  without using the transparent proxy.";
  336.         }
  337.        
  338.         if (($post['transparent_proxy'] != 'on') && !empty($post['defined_ip_proxy_off'])) {
  339.                 $input_errors[] = "You can not bypass traffic from specific IPs without using the transparent proxy.";
  340.         }      
  341.  
  342.         foreach (array('defined_ip_proxy_off') as $hosts) {
  343.                 foreach (explode(";", $post[$hosts]) as $host) {
  344.                         $host = trim($host);
  345.                         if (!empty($host) && !is_ipaddr($host))
  346.                                 $input_errors[] = "The entry '$host' is not a valid IP address";
  347.                 }
  348.         }
  349.  
  350.   if(!empty($post['dns_nameservers'])) {
  351.          $altdns = explode(";", ($post['dns_nameservers']));
  352.          foreach ($altdns as $dnssrv) {
  353.     if (!is_ipaddr($dnssrv))
  354.       $input_errors[] = 'You must enter a valid IP address in the \'Alternate DNS servers\' field';
  355.          }}
  356. }
  357.  
  358. function squid_validate_upstream($post, $input_errors) {
  359.         if ($post['proxy_forwarding'] == 'on') {
  360.                 $addr = trim($post['proxy_addr']);
  361.                 if (empty($addr))
  362.                         $input_errors[] = 'The field \'Hostname\' is required';
  363.                 else {
  364.                         if (!is_ipaddr($addr) && !is_domain($addr))
  365.                                 $input_errors[] = 'You must enter a valid IP address or host name in the \'Proxy hostname\' field';
  366.                 }
  367.  
  368.                 foreach (array('proxy_port' => 'TCP port', 'icp_port' => 'ICP port') as $field => $name) {
  369.                         $port = trim($post[$field]);
  370.                         if (empty($port))
  371.                                 $input_errors[] = "The field '$name' is required";
  372.                         else {
  373.                                         if (!is_port($port))
  374.                                         $input_errors[] = "The field '$name' must contain a valid port number, between 0 and 65535";
  375.                         }
  376.                 }
  377.         }
  378. }
  379.  
  380. function squid_validate_cache($post, $input_errors) {
  381.         $num_fields = array(    'harddisk_cache_size' => 'Hard disk cache size',
  382.                                 'memory_cache_size' => 'Memory cache size',
  383.                                 'maximum_object_size' => 'Maximum object size',
  384.         );
  385.         foreach ($num_fields as $field => $name) {
  386.                 $value = trim($post[$field]);
  387.                 if (!is_numeric($value) || ($value < 0))
  388.                         $input_errors[] = "You must enter a valid value for '$field'";
  389.         }
  390.  
  391.         $value = trim($post['minimum_object_size']);
  392.         if (!is_numeric($value) || ($value < 0))
  393.                 $input_errors[] = 'You must enter a valid value for \'Minimum object size\'';
  394.  
  395.   if (!empty($post['cache_swap_low'])) {
  396.     $value = trim($post['cache_swap_low']);
  397.           if (!is_numeric($value) || ($value > 100))
  398.           $input_errors[] = 'You must enter a valid value for \'Low-water-mark\'';
  399.         }
  400.  
  401.   if (!empty($post['cache_swap_high'])) {              
  402.          $value = trim($post['cache_swap_high']);
  403.          if (!is_numeric($value) || ($value > 100))
  404.                 $input_errors[] = 'You must enter a valid value for \'High-water-mark\'';              
  405.   }
  406.  
  407.         if ($post['donotcache'] != "") {
  408.                 foreach (split("\n", $post['donotcache']) as $host) {
  409.                         $host = trim($host);
  410.                         if (!is_ipaddr($host) && !is_domain($host))
  411.                                 $input_errors[] = "The host '$host' is not a valid IP or host name";
  412.                 }
  413.         }
  414.  
  415.         squid_dash_z();
  416.  
  417. }
  418.  
  419. function squid_validate_nac($post, $input_errors) {
  420.         $allowed_subnets = explode("\n", $post['allowed_subnets']);
  421.         foreach ($allowed_subnets as $subnet) {
  422.                 $subnet = trim($subnet);
  423.                 if (!empty($subnet) && !is_subnet($subnet))
  424.                         $input_errors[] = "The subnet '$subnet' is not a valid CIDR range";
  425.         }
  426.  
  427.         foreach (array( 'unrestricted_hosts', 'banned_hosts') as $hosts) {
  428.                 foreach (explode("\n", $post[$hosts]) as $host) {
  429.                         $host = trim($host);
  430.                         if (!empty($host) && !is_ipaddr($host))
  431.                                 $input_errors[] = "The host '$host' is not a valid IP address";
  432.                 }
  433.         }
  434.  
  435.         foreach (array('unrestricted_macs', 'banned_macs') as $macs) {
  436.                 foreach (explode("\n", $post[$macs]) as $mac) {
  437.                         $mac = trim($mac);
  438.                         if (!empty($mac) && !is_macaddr($mac))
  439.                                 $input_errors[] = "The mac '$mac' is not a valid MAC address";
  440.                 }
  441.         }
  442.  
  443.         foreach (explode(",", $post['timelist']) as $time) {
  444.                 $time = trim($time);
  445.                 if (!empty($time) && !squid_is_timerange($time))
  446.                         $input_errors[] = "The time range '$time' is not a valid time range";
  447.         }
  448.  
  449.   if(!empty($post['ext_cachemanager'])) {
  450.          $extmgr = explode(";", ($post['ext_cachemanager']));
  451.          foreach ($extmgr as $mgr) {
  452.     if (!is_ipaddr($mgr))
  453.       $input_errors[] = 'You must enter a valid IP address in the \'External Cache Manager\' field';
  454.          }}
  455. }
  456.  
  457. function squid_validate_traffic($post, $input_errors) {
  458.         $num_fields = array(    'max_download_size' => 'Maximum download size',
  459.                                 'max_upload_size' => 'Maximum upload size',
  460.                                 'perhost_throttling' => 'Per-host bandwidth throttling',
  461.                                 'overall_throttling' => 'Overall bandwidth throttling',
  462.         );
  463.         foreach ($num_fields as $field => $name) {
  464.                 $value = trim($post[$field]);
  465.                 if (!is_numeric($value) || ($value < 0))
  466.                         $input_errors[] = "The field '$name' must contain a positive number";
  467.         }
  468.  
  469.   if (!empty($post['quick_abort_min'])) {              
  470.          $value = trim($post['quick_abort_min']);
  471.      if (!is_numeric($value))
  472.            $input_errors[] = "The field 'Finish when remaining KB' must contain a positive number";    
  473.   }    
  474.  
  475.   if (!empty($post['quick_abort_max'])) {              
  476.          $value = trim($post['quick_abort_max']);
  477.      if (!is_numeric($value))
  478.            $input_errors[] = "The field 'Abort when remaining KB' must contain a positive number";     
  479.   }    
  480.                
  481.   if (!empty($post['quick_abort_pct'])) {              
  482.          $value = trim($post['quick_abort_pct']);
  483.      if (!is_numeric($value) || ($value > 100))
  484.            $input_errors[] = "The field 'Finish when remaining %' must contain a percentaged value";   
  485.   }    
  486.  
  487. }
  488.  
  489. function squid_validate_auth($post, $input_errors) {
  490.         $num_fields = array(    array('auth_processes', 'Authentication processes', 1),
  491.                                 array('auth_ttl', 'Authentication TTL', 0),
  492.         );
  493.         foreach ($num_fields as $field) {
  494.                 $value = trim($post[$field[0]]);
  495.                 if (!empty($value) && (!is_numeric($value) || ($value < $field[2])))
  496.                         $input_errors[] = "The field '{$field[1]}' must contain a valid number greater than {$field[2]}";
  497.         }
  498.  
  499.         $auth_method = $post['auth_method'];
  500.         if (($auth_method != 'none') && ($auth_method != 'local')) {
  501.                 $server = trim($post['auth_server']);
  502.                 if (empty($server))
  503.                         $input_errors[] = 'The field \'Authentication server\' is required';
  504.                 else if (!is_ipaddr($server) && !is_domain($server))
  505.                         $input_errors[] = 'The field \'Authentication server\' must contain a valid IP address or domain name';
  506.  
  507.                 $port = trim($post['auth_server_port']);
  508.                 if (!empty($port) && !is_port($port))
  509.                         $input_errors[] = 'The field \'Authentication server port\' must contain a valid port number';
  510.  
  511.                 switch ($auth_method) {
  512.                         case 'ldap':
  513.                                 $user = trim($post['ldap_user']);
  514.                                 if (empty($user))
  515.                                         $input_errors[] = 'The field \'LDAP server user DN\' is required';
  516.                                 else if (!$user)
  517.                                         $input_errors[] = 'The field \'LDAP server user DN\' must be a valid domain name';
  518.                                 break;
  519.                         case 'radius':
  520.                                 $secret = trim($post['radius_secret']);
  521.                                 if (empty($secret))
  522.                                         $input_errors[] = 'The field \'RADIUS secret\' is required';
  523.                                 break;
  524.                         case 'msnt':
  525.                                 foreach (explode(",", trim($post['msnt_secondary'])) as $server) {
  526.                                         if (!empty($server) && !is_ipaddr($server) && !is_domain($server))
  527.                                                 $input_errors[] = "The host '$server' is not a valid IP address or domain name";
  528.                                 }
  529.                                 break;
  530.                 }
  531.  
  532.                 $no_auth = explode("\n", $post['no_auth_hosts']);
  533.                 foreach ($no_auth as $host) {
  534.                         $host = trim($host);
  535.                         if (!empty($host) && !is_subnet($host))
  536.                                 $input_errors[] = "The host '$host' is not a valid CIDR range";
  537.                 }
  538.         }
  539. }
  540.  
  541. function squid_install_cron($should_install) {
  542.         global $config, $g;
  543.         if($g['booting']==true)
  544.                 return;
  545.         $is_installed = false;
  546.         if(!$config['cron']['item'])
  547.                 return;
  548.         $x=0;
  549.         foreach($config['cron']['item'] as $item) {
  550.                 if(strstr($item['command'], "/usr/local/sbin/squid")) {
  551.                         $is_installed = true;
  552.                         break;
  553.                 }
  554.                 $x++;
  555.         }
  556.         switch($should_install) {
  557.                 case true:
  558.                         if(!$is_installed) {
  559.                                 $cron_item = array();
  560.                                 $cron_item['minute'] = "0";
  561.                                 $cron_item['hour'] = "0";
  562.                                 $cron_item['mday'] = "*";
  563.                                 $cron_item['month'] = "*";
  564.                                 $cron_item['wday'] = "*";
  565.                                 $cron_item['who'] = "root";
  566.                                 $cron_item['command'] = "/usr/local/sbin/squid -k rotate";             
  567.                                 $config['cron']['item'][] = $cron_item;
  568.                                 parse_config(true);
  569.                                 write_config("Squid Log Rotation");
  570.                                 configure_cron();
  571.                         }
  572.                 break;
  573.                 case false:
  574.                         if($is_installed == true) {
  575.                                 if($x > 0) {
  576.                                         unset($config['cron']['item'][$x]);
  577.                                         parse_config(true);
  578.                                         write_config();
  579.                                 }
  580.                                 configure_cron();
  581.                         }
  582.                 break;
  583.         }
  584. }
  585.  
  586. function squid_resync_general() {
  587.         global $g, $config, $valid_acls;
  588.  
  589.         $settings = $config['installedpackages']['squid']['config'][0];
  590.         $conf = "# This file is automatically generated by pfSense\n";
  591.         $conf = "# Do not edit manually !\n";
  592.  
  593.         $port = ($settings['proxy_port'] ? $settings['proxy_port'] : 3128);
  594.         $ifaces = ($settings['active_interface'] ? $settings['active_interface'] : 'lan');
  595.         $real_ifaces = array();
  596.         foreach (explode(",", $ifaces) as $i => $iface) {
  597.                 $real_ifaces[] = squid_get_real_interface_address($iface);
  598.                 if($real_ifaces[$i][0]) {
  599.                         $conf .= "http_port {$real_ifaces[$i][0]}:$port\n";
  600.                 }
  601.         }
  602.         if (($settings['transparent_proxy'] == 'on')) {
  603.                 $conf .= "http_port 127.0.0.1:80 transparent\n";
  604.         }
  605.         $icp_port = ($settings['icp_port'] ? $settings['icp_port'] : 0);
  606.  
  607.         $pidfile = "{$g['varrun_path']}/squid.pid";
  608.         $language = ($settings['error_language'] ? $settings['error_language'] : 'English');
  609.         $errordir = SQUID_CONFBASE . '/errors/' . $language;
  610.         $icondir = SQUID_CONFBASE . '/icons';
  611.         $hostname = ($settings['visible_hostname'] ? $settings['visible_hostname'] : 'localhost');
  612.         $email = ($settings['admin_email'] ? $settings['admin_email'] : 'admin@localhost');
  613.  
  614.         $logdir = ($settings['log_dir'] ? $settings['log_dir'] : '/var/squid/log');
  615.  
  616.         $logdir_cache = $logdir . '/cache.log';
  617.         $logdir_access = ($settings['log_enabled'] == 'on' ? $logdir . '/access.log' : '/dev/null');
  618.  
  619.         $conf .= <<<EOD
  620. icp_port $icp_port
  621.  
  622. pid_filename $pidfile
  623. cache_effective_user proxy
  624. cache_effective_group proxy
  625. error_directory $errordir
  626. icon_directory $icondir
  627. visible_hostname $hostname
  628. cache_mgr $email
  629. access_log $logdir_access
  630. cache_log $logdir_cache
  631. cache_store_log none
  632.  
  633. EOD;
  634.  
  635.   if (!empty($settings['log_rotate'])) {
  636.     $conf .= "logfile_rotate {$settings['log_rotate']}\n";
  637.     squid_install_cron(true);
  638.     }
  639.   else {
  640.     squid_install_cron(false);
  641.     }
  642.  
  643.         $conf .= <<<EOD
  644. shutdown_lifetime 3 seconds
  645.  
  646. EOD;
  647.  
  648.         if ($settings['allow_interface'] == 'on') {
  649.                 $src = '';
  650.                 foreach ($real_ifaces as $iface) {
  651.                         list($ip, $mask) = $iface;
  652.                         $ip = long2ip(ip2long($ip) & ip2long($mask));
  653.                         $src .= " $ip/$mask";
  654.                 }
  655.                 $conf .= "# Allow local network(s) on interface(s)\n";
  656.                 $conf .= "acl localnet src $src\n";
  657.                 $valid_acls[] = 'localnet';
  658.         }
  659.         if ($settings['disable_xforward']) $conf .= "forwarded_for off\n";
  660.         if ($settings['disable_via']) $conf .= "via off\n";
  661.         if ($settings['disable_squidversion']) $conf .= "httpd_suppress_version_string on\n";
  662.         if (!empty($settings['uri_whitespace'])) $conf .= "uri_whitespace {$settings['uri_whitespace']}\n";
  663.   else $conf .= "uri_whitespace strip\n"; //only used for first run
  664.  
  665.         if(!empty($settings['dns_nameservers'])) {
  666.           $altdns = explode(";", ($settings['dns_nameservers']));
  667.     $conf .= "dns_nameservers ";
  668.          foreach ($altdns as $dnssrv) {
  669.     $conf .= $dnssrv." ";
  670.          }
  671. //  $conf .= "\n";  //Kill blank line after DNS-Servers
  672.    }
  673.        
  674.   return $conf;
  675. }
  676.  
  677.  
  678. function squid_resync_cache() {
  679.         global $config;
  680.  
  681.         $settings = $config['installedpackages']['squidcache']['config'][0];
  682.  
  683.         $cachedir =($settings['harddisk_cache_location'] ? $settings['harddisk_cache_location'] : '/var/squid/cache');
  684.         $disk_cache_size = ($settings['harddisk_cache_size'] ? $settings['harddisk_cache_size'] : 100);
  685.         $disk_cache_system = ($settings['harddisk_cache_system'] ? $settings['harddisk_cache_system'] : 'aufs');
  686.         $level1 = ($settings['level1_subdirs'] ? $settings['level1_subdirs'] : 16);
  687.         $memory_cache_size = ($settings['memory_cache_size'] ? $settings['memory_cache_size'] : 8);
  688.         $max_objsize = ($settings['maximum_object_size'] ? $settings['maximum_object_size'] : 10);
  689.         $min_objsize = ($settings['minimum_object_size'] ? $settings['minimum_object_size'] : 0);
  690.         $cache_policy = ($settings['cache_replacement_policy'] ? $settings['cache_replacement_policy'] : 'heap LFUDA');
  691.         $memory_policy = ($settings['memory_replacement_policy'] ? $settings['memory_replacement_policy'] : 'heap GDSF');
  692.         $offline_mode = ($settings['enable_offline'] == 'on' ? 'on' : 'off');
  693.  
  694.         $conf = <<<EOD
  695. cache_mem $memory_cache_size MB
  696. maximum_object_size_in_memory 32 KB
  697. memory_replacement_policy $memory_policy
  698. cache_replacement_policy $cache_policy
  699. cache_dir $disk_cache_system $cachedir $disk_cache_size $level1 256
  700. minimum_object_size $min_objsize KB
  701. maximum_object_size $max_objsize KB
  702. offline_mode $offline_mode
  703.  
  704. EOD;
  705.  
  706.         if (!empty($settings['cache_swap_low'])) $conf .= "cache_swap_low {$settings['cache_swap_low']}\n";
  707.         if (!empty($settings['cache_swap_high'])) $conf .= "cache_swap_high {$settings['cache_swap_high']}\n";
  708.  
  709.         $donotcache = base64_decode($settings['donotcache']);
  710.         if (!empty($donotcache)) {
  711.                 file_put_contents(SQUID_ACLDIR . '/donotcache.acl', $donotcache);
  712.                 $conf .= 'acl donotcache dstdomain "' . SQUID_ACLDIR . "/donotcache.acl\"\n";
  713.                 $conf .= 'cache deny donotcache';
  714.         }
  715.         elseif (file_exists(SQUID_ACLDIR . '/donotcache.acl')) {
  716.      unlink(SQUID_ACLDIR . '/donotcache.acl');
  717.     }
  718.  
  719.         return $conf;
  720. }
  721.  
  722. function squid_resync_upstream() {
  723.         global $config;
  724.         $settings = $config['installedpackages']['squidupstream']['config'][0];
  725.  
  726.         $conf = '';
  727.         if ($settings['proxy_forwarding'] == 'on') {
  728.                 $conf .= "cache_peer {$settings['proxy_addr']} parent {$settings['proxy_port']} ";
  729.                 if ($settings['icp_port'] == '7')
  730.                   $conf .= "{$settings['icp_port']} no-query";
  731.     else
  732.       $conf .= "{$settings['icp_port']}";
  733.  
  734.                 if (!empty($settings['username']))
  735.                         $conf .= " login={$settings['username']}";
  736.                 if (!empty($settings['password']))
  737.                         $conf .= ":{$settings['password']}";
  738.         }
  739.  
  740.         return $conf;
  741. }
  742.  
  743. function squid_resync_redirector() {
  744.         global $config;
  745.  
  746.         $httpav_enabled = ($config['installedpackages']['clamav']['config'][0]['scan_http'] == 'on');
  747.         if ($httpav_enabled) {
  748.                 $conf = "url_rewrite_program /usr/local/bin/squirm\n";
  749.         } else {
  750.                 $conf = "# No redirector configured\n";
  751.         }
  752.         return $conf;
  753. }
  754.  
  755. function squid_resync_nac() {
  756.         global $config, $valid_acls;
  757.  
  758.   $port = ($settings['proxy_port'] ? $settings['proxy_port'] : 3128);
  759.   $settings = $config['installedpackages']['squidnac']['config'][0];
  760.         $webgui_port = $config['system']['webgui']['port'];
  761.  
  762.         $conf = <<<EOD
  763.  
  764. # Setup some default acls
  765. # --BEGIN-- videocache config for squid
  766. url_rewrite_program /usr/local/bin/python /usr/share/videocache/videocache.py
  767. url_rewrite_children 30
  768. acl videocache_allow_url url_regex -i \.youtube\.com\/videoplayback
  769. acl videocache_allow_url url_regex -i \.youtube\.com\/get_video\?
  770. acl videocache_allow_url url_regex -i \.googlevideo\.com\/videoplayback \.googlevideo\.com\/videoplay \.googlevideo\.com\/get_video\?
  771. acl videocache_allow_url url_regex -i \.google\.com\/videoplayback \.google\.com\/videoplay \.google\.com\/get_video\?
  772. acl videocache_allow_url url_regex -i \.google\.[a-z][a-z]\/videoplayback \.google\.[a-z][a-z]\/videoplay \.google\.[a-z][a-z]\/get_video\?
  773. acl videocache_allow_url url_regex -i (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/videoplayback\?
  774. acl videocache_allow_url url_regex -i (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/videoplay\?
  775. acl videocache_allow_url url_regex -i (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/get_video\?
  776. acl videocache_allow_url url_regex -i proxy[a-z0-9\-][a-z0-9][a-z0-9][a-z0-9]?\.dailymotion\.com\/
  777. acl videocache_allow_url url_regex -i vid\.akm\.dailymotion\.com\/
  778. acl videocache_allow_url url_regex -i [a-z0-9][0-9a-z][0-9a-z]?[0-9a-z]?[0-9a-z]?\.xtube\.com\/(.*)flv
  779. acl videocache_allow_url url_regex -i bitcast\.vimeo\.com\/vimeo\/videos\/
  780. acl videocache_allow_url url_regex -i va\.wrzuta\.pl\/wa[0-9][0-9][0-9][0-9]?
  781. acl videocache_allow_url url_regex -i \.files\.youporn\.com\/(.*)\/flv\/
  782. acl videocache_allow_url url_regex -i \.msn\.com\.edgesuite\.net\/(.*)\.flv
  783. acl videocache_allow_url url_regex -i media[a-z0-9]?[a-z0-9]?[a-z0-9]?\.tube8\.com\/ mobile[a-z0-9]?[a-z0-9]?[a-z0-9]?\.tube8\.com\/
  784. acl videocache_allow_url url_regex -i \.mais\.uol\.com\.br\/(.*)\.flv
  785. acl videocache_allow_url url_regex -i \.video[a-z0-9]?[a-z0-9]?\.blip\.tv\/(.*)\.(flv|avi|mov|mp3|m4v|mp4|wmv|rm|ram)
  786. acl videocache_allow_url url_regex -i video\.break\.com\/(.*)\.(flv|mp4)
  787. acl videocache_allow_dom dstdomain .mccont.com dl.redtube.com .cdn.dailymotion.com
  788. acl videocache_deny_url url_regex -i http:\/\/[a-z][a-z]\.youtube\.com http:\/\/www\.youtube\.com
  789. url_rewrite_access deny videocache_deny_url
  790. url_rewrite_access allow videocache_allow_url
  791. url_rewrite_access allow videocache_allow_dom
  792. redirector_bypass on
  793. # --END-- videocache config for squid
  794. acl all src 0.0.0.0/0.0.0.0
  795. acl localhost src 192.168.1.1/255.255.255.255
  796. acl safeports port 21 70 80 210 280 443 488 563 591 631 777 901 $webgui_port $port 1025-65535
  797. acl sslports port 443 563 $webgui_port
  798. acl manager proto cache_object
  799. acl purge method PURGE
  800. acl connect method CONNECT
  801. acl dynamic urlpath_regex cgi-bin \?
  802.  
  803. EOD;
  804.  
  805.         $allowed_subnets = explode("\n", base64_decode($settings['allowed_subnets']));
  806.         $allowed = "";
  807.         foreach ($allowed_subnets as $subnet) {
  808.                 if(!empty($subnet)) {
  809.                         $subnet = trim($subnet);
  810.                         $allowed .= "$subnet ";
  811.                 }
  812.         }
  813.         if (!empty($allowed)) {
  814.                 $conf .= "acl allowed_subnets src $allowed\n";
  815.                 $valid_acls[] = 'allowed_subnets';
  816.         }
  817.  
  818.         $options = array(       'unrestricted_hosts' => 'src',
  819.                                 'banned_hosts' => 'src',
  820.                                 'whitelist' => 'dstdom_regex -i',
  821.                                 'blacklist' => 'dstdom_regex -i',
  822.         );
  823.         foreach ($options as $option => $directive) {
  824.                 $contents = base64_decode($settings[$option]);
  825.                 if (!empty($contents)) {
  826.                         file_put_contents(SQUID_ACLDIR . "/$option.acl", $contents);
  827.                         $conf .= "acl $option $directive \"" . SQUID_ACLDIR . "/$option.acl\"\n";
  828.                         $valid_acls[] = $option;
  829.                 }
  830.                 elseif (file_exists(SQUID_ACLDIR . "/$option.acl")) {
  831.       unlink(SQUID_ACLDIR . "/$option.acl");
  832.     }
  833.         }
  834.  
  835.         $conf .= <<<EOD
  836. cache deny dynamic
  837. http_access allow manager localhost
  838.  
  839. EOD;
  840.  
  841.         if(!empty($settings['ext_cachemanager'])) {
  842.           $extmgr = explode(";", ($settings['ext_cachemanager']));
  843.     $count = 1;
  844.     $conf .= "\n# Allow external cache managers\n";
  845. //    $conf .= "acl ext_manager src ".$settings['ext_cachemanager']."\n";
  846.          foreach ($extmgr as $mgr) {
  847.     $conf .= "acl ext_manager_".$count." src ";
  848.     $conf .= $mgr." ";
  849.     $conf .= "\n";
  850.     $conf .= "http_access allow manager ext_manager_".$count."\n";
  851.     $count += 1;
  852.          }}
  853.        
  854.   $conf .= <<<EOD
  855.  
  856. http_access deny manager
  857. http_access allow purge localhost
  858. http_access deny purge
  859. http_access deny !safeports
  860. http_access deny CONNECT !sslports
  861.  
  862. # Always allow localhost connections
  863. http_access allow localhost
  864.  
  865. EOD;
  866.  
  867.         return $conf;
  868. }
  869.  
  870. function squid_resync_traffic() {
  871.         global $config, $valid_acls;
  872.         if(!is_array($valid_acls))
  873.                 return;
  874.         $settings = $config['installedpackages']['squidtraffic']['config'][0];
  875.         $conf = '';
  876.  
  877.   if (!empty($settings['quick_abort_min']) || ($settings['quick_abort_min']) == "0") $conf .= "quick_abort_min {$settings['quick_abort_min']} KB\n";
  878.   if (!empty($settings['quick_abort_max']) || ($settings['quick_abort_max']) == "0") $conf .= "quick_abort_max {$settings['quick_abort_max']} KB\n";
  879.   if (!empty($settings['quick_abort_pct'])) $conf .= "quick_abort_pct {$settings['quick_abort_pct']}\n";       
  880.  
  881.         $up_limit = ($settings['max_upload_size'] ? $settings['max_upload_size'] : 0);
  882.         $down_limit = ($settings['max_download_size'] ? $settings['max_download_size'] : 0);
  883.         $conf .= "request_body_max_size $up_limit KB\n";
  884.         $conf .= 'reply_body_max_size ' . ($down_limit * 1024) . " allow all\n";
  885.  
  886.         // Only apply throttling past 10MB
  887.         // XXX: Should this really be hardcoded?
  888.         $threshold = 10 * 1024 * 1024;
  889.         $overall = $settings['overall_throttling'];
  890.         if (!isset($overall) || ($overall == 0))
  891.                 $overall = -1;
  892.         else
  893.                 $overall *= 1024;
  894.         $perhost = $settings['perhost_throttling'];
  895.         if (!isset($perhost) || ($perhost == 0))
  896.                 $perhost = -1;
  897.         else
  898.                 $perhost *= 1024;
  899.         $conf .= <<<EOD
  900. delay_pools 1
  901. delay_class 1 2
  902. delay_parameters 1 $overall/$overall $perhost/$perhost
  903. delay_initial_bucket_level 100
  904.  
  905. EOD;
  906.  
  907.         if(! empty($settings['unrestricted_hosts'])) {
  908.                 foreach (array('unrestricted_hosts') as $item) {
  909.                         if (in_array($item, $valid_acls))
  910.                                 $conf .= "# Do not throttle unrestricted hosts\n";
  911.                                 $conf .= "delay_access 1 deny $item\n";
  912.                 }
  913.         }
  914.  
  915.         if ($settings['throttle_specific'] == 'on') {
  916.                 $exts = array();
  917.                 $binaries = 'bin,cab,sea,ar,arj,tar,tgz,gz,tbz,bz2,zip,7z,exe,com';
  918.                 $cdimages = 'iso,bin,mds,nrg,gho,bwt,b5t,pqi';
  919.                 $multimedia = 'aiff?,asf,avi,divx,mov,mp3,mp4,wmv,mpe?g,qt,ra?m';
  920.                 foreach (array( 'throttle_binaries' => $binaries,
  921.                                 'throttle_cdimages' => $cdimages,
  922.                                 'throttle_multimedia' => $multimedia) as $field => $set) {
  923.                         if ($settings[$field] == 'on')
  924.                                 $exts = array_merge($exts, explode(",", $set));
  925.                 }
  926.  
  927.                 foreach (explode(",", $settings['throttle_others']) as $ext) {
  928.                         if (!empty($ext)) $exts[] = $ext;
  929.                 }
  930.  
  931.                 $contents = '';
  932.                 foreach ($exts as $ext)
  933.                         $contents .= "\.$ext\$\n";
  934.                 file_put_contents(SQUID_ACLDIR . '/throttle_exts.acl', $contents);
  935.  
  936.                 $conf .= "# Throttle extensions matched in the url\n";
  937.                 $conf .= "acl throttle_exts urlpath_regex -i \"" . SQUID_ACLDIR . "/throttle_exts.acl\"\n";
  938.                 $conf .= "delay_access 1 allow throttle_exts\n";
  939.                 $conf .= "delay_access 1 deny all\n";
  940.         }
  941.         else
  942.                 $conf .= "delay_access 1 allow all\n";
  943.  
  944.         return $conf;
  945. }
  946.  
  947. function squid_resync_auth() {
  948.         global $config, $valid_acls;
  949.  
  950.         $settings = $config['installedpackages']['squidauth']['config'][0];
  951.         $settingsnac = $config['installedpackages']['squidnac']['config'][0];
  952.         $settingsconfig = $config['installedpackages']['squid']['config'][0];
  953.         $conf = '';
  954.  
  955.         // Deny the banned guys before allowing the good guys
  956.         if(! empty($settingsnac['banned_hosts'])) {
  957.                 if (squid_is_valid_acl('banned_hosts')) {
  958.                         $conf .= "# These hosts are banned\n";
  959.                         $conf .= "http_access deny banned_hosts\n";
  960.                 }
  961.         }
  962.         if(! empty($settingsnac['banned_macs'])) {
  963.                 if (squid_is_valid_acl('banned_macs')) {
  964.                         $conf .= "# These macs are banned\n";
  965.                         $conf .= "http_access deny banned_macs\n";
  966.                 }
  967.         }
  968.  
  969.         // Unrestricted hosts take precendence over blacklist
  970.         if(! empty($settingsnac['unrestricted_hosts'])) {
  971.                 if (squid_is_valid_acl('unrestricted_hosts')) {
  972.                         $conf .= "# These hosts do not have any restrictions\n";
  973.                         $conf .= "http_access allow unrestricted_hosts\n";
  974.                 }
  975.         }
  976.         if(! empty($settingsnac['unrestricted_macs'])) {
  977.                 if (squid_is_valid_acl('unrestricted_macs')) {
  978.                         $conf .= "# These hosts do not have any restrictions\n";
  979.                         $conf .= "http_access allow unrestricted_macs\n";
  980.                 }
  981.         }
  982.  
  983.         // Whitelist and blacklist also take precendence over other allow rules
  984.         if(! empty($settingsnac['whitelist'])) {
  985.                 if (squid_is_valid_acl('whitelist')) {
  986.                         $conf .= "# Always allow access to whitelist domains\n";
  987.                         $conf .= "http_access allow whitelist\n";
  988.                 }
  989.         }
  990.         if(! empty($settingsnac['blacklist'])) {
  991.                 if (squid_is_valid_acl('blacklist')) {
  992.                         $conf .= "# Block access to blacklist domains\n";
  993.                         $conf .= "http_access deny blacklist\n";
  994.                 }
  995.         }
  996.  
  997.         $transparent_proxy = ($settingsconfig['transparent_proxy'] == 'on');
  998.         $auth_method = (($settings['auth_method'] && !$transparent_proxy) ? $settings['auth_method'] : 'none');
  999.         // Allow the remaining ACLs if no authentication is set
  1000.         if ($auth_method == 'none') {
  1001.                 if ($settingsconfig['allow_interface'] == 'on') {
  1002.                         $conf .= "# Allow local network(s) on interface(s)\n";
  1003.                         $allowed = array('localnet', 'allowed_subnets');
  1004.                         $allowed = array_filter($allowed, 'squid_is_valid_acl');
  1005.                         foreach ($allowed as $acl)
  1006.                                 $conf .= "http_access allow $acl\n";
  1007.                 }
  1008.         }
  1009.         else {
  1010.                 $noauth = implode(' ', explode("\n", base64_decode($settings['no_auth_hosts'])));
  1011.                 if (!empty($noauth)) {
  1012.                         $conf .= "acl noauth src $noauth\n";
  1013.                         $valid_acls[] = 'noauth';
  1014.                 }
  1015.  
  1016.                 // Set up the external authentication programs
  1017.                 $auth_ttl = ($settings['auth_ttl'] ? $settings['auth_ttl'] : 60);
  1018.                 $processes = ($settings['auth_processes'] ? $settings['auth_processes'] : 5);
  1019.                 $prompt = ($settings['auth_prompt'] ? $settings['auth_prompt'] : 'Please enter your credentials to access the proxy');
  1020.                 switch ($auth_method) {
  1021.                         case 'local':
  1022.                                 $conf .= 'auth_param basic program /usr/local/libexec/squid/ncsa_auth ' . SQUID_PASSWD . "\n";
  1023.                                 break;
  1024.                         case 'ldap':
  1025.                                 $port = (isset($settings['auth_port']) ? ":{$settings['auth_port']}" : '');
  1026.                                 $password = (isset($settings['ldap_pass']) ? "-w {$settings['ldap_pass']}" : '');
  1027.                                 $conf .= "auth_param basic program /usr/local/libexec/squid/squid_ldap_auth -v {$settings['ldap_version']} -b {$settings['ldap_basedomain']} -D {$settings['ldap_user']} $password -f \"{$settings['ldap_filter']}\" -u uid -P {$settings['auth_server']}$port\n";
  1028.                                 break;
  1029.                         case 'radius':
  1030.                                 $port = (isset($settings['auth_port']) ? "-p {$settings['auth_server_port']}" : '');
  1031.                                 $conf .= "auth_param basic program /usr/local/libexec/squid/squid_radius_auth -w {$settings['radius_secret']} -h {$settings['auth_server']} $port\n";
  1032.                                 break;
  1033.                         case 'msnt':
  1034.                                 $conf .= "auth_param basic program /usr/local/libexec/squid/msnt_auth\n";
  1035.                                 break;
  1036.                 }
  1037.                 $conf .= <<<EOD
  1038. auth_param basic children $processes
  1039. auth_param basic realm $prompt
  1040. auth_param basic credentialsttl $auth_ttl minutes
  1041. acl password proxy_auth REQUIRED
  1042.  
  1043. EOD;
  1044.  
  1045.                 // Onto the ACLs
  1046.                 $password = array('localnet', 'allowed_subnets');
  1047.                 $passwordless = array('unrestricted_hosts');
  1048.                 if ($settings['unrestricted_auth'] == 'on') {
  1049.                         // Even the unrestricted hosts should authenticate
  1050.                         $password = array_merge($password, $passwordless);
  1051.                         $passwordless = array();
  1052.                 }
  1053.                 $passwordless[] = 'noauth';
  1054.                 $password = array_filter($password, 'squid_is_valid_acl');
  1055.                 $passwordless = array_filter($passwordless, 'squid_is_valid_acl');
  1056.  
  1057.                 // Allow the ACLs that don't need to authenticate
  1058.                 foreach ($passwordless as $acl)
  1059.                         $conf .= "http_access allow $acl\n";
  1060.  
  1061.                 // Allow the other ACLs as long as they authenticate
  1062.                 foreach ($password as $acl)
  1063.                         $conf .= "http_access allow password $acl\n";
  1064.         }
  1065.  
  1066.  if(!empty($config['installedpackages']['squid']['config'][0]['custom_options'])) {
  1067.          $custopts = explode(";", ($config['installedpackages']['squid']['config'][0]['custom_options']));
  1068.          $conf .= "# Custom options\n";
  1069.          foreach ($custopts as $custopt) {
  1070.                         $conf .= $custopt."\n";
  1071.          }
  1072.         }
  1073.  
  1074.         $conf .= "# Default block all to be sure\n";
  1075.         $conf .= "http_access deny all\n";
  1076.  
  1077.         return $conf;
  1078. }
  1079.  
  1080. function squid_resync_users() {
  1081.         global $config;
  1082.  
  1083.         $users = $config['installedpackages']['squidusers']['config'];
  1084.         $contents = '';
  1085.         if (is_array($users)) {
  1086.                 foreach ($users as $user)
  1087.                         $contents .= $user['username'] . ':' . crypt($user['password'], base64_encode($user['password'])) . "\n";
  1088.         }
  1089.         file_put_contents(SQUID_PASSWD, $contents);
  1090.         chown(SQUID_PASSWD, 'proxy');
  1091.         chmod(SQUID_PASSWD, 0600);
  1092. }
  1093.  
  1094. function squid_resync() {
  1095.         global $config;
  1096.         conf_mount_rw();
  1097.         $conf = squid_resync_general() . "\n";
  1098.         $conf .= squid_resync_cache() . "\n";
  1099.         $conf .= squid_resync_redirector() . "\n";
  1100.         $conf .= squid_resync_upstream() . "\n";
  1101.         $conf .= squid_resync_nac() . "\n";
  1102.         $conf .= squid_resync_traffic() . "\n";
  1103.         $conf .= squid_resync_auth();
  1104.         squid_resync_users();
  1105.  
  1106.         /* make sure pinger is executable */
  1107.         if(file_exists("/usr/local/libexec/squid/pinger"))
  1108.                 exec("chmod a+x /usr/local/libexec/squid/pinger");
  1109.  
  1110.         foreach (array( SQUID_CONFBASE,
  1111.                         SQUID_ACLDIR,
  1112.         ) as $dir) {
  1113.                         make_dirs($dir);
  1114.                         squid_chown_recursive($dir, 'proxy', 'proxy');
  1115.         }
  1116.  
  1117.         file_put_contents(SQUID_CONFBASE . '/squid.conf', $conf);
  1118.  
  1119.         $log_dir = $config['installedpackages']['squid']['config'][0]['log_dir'].'/';
  1120.  
  1121.         if(!is_dir($log_dir)) {
  1122.                 log_error("Creating squid log dir $log_dir");
  1123.                 make_dirs($log_dir);
  1124.                 squid_chown_recursive($log_dir, 'proxy', 'proxy');
  1125.         }
  1126.  
  1127.         squid_dash_z();
  1128.  
  1129.         if (!is_service_running('squid')) {
  1130.                 log_error("Starting Squid");
  1131.                 mwexec_bg("/usr/local/sbin/squid -D");
  1132.         } else {
  1133.                 log_error("Reloading Squid for configuration sync");
  1134.                 mwexec("/usr/local/sbin/squid -k reconfigure");
  1135.         }
  1136.  
  1137.         filter_configure();
  1138.         conf_mount_ro();
  1139. }
  1140.  
  1141. function squid_print_javascript_auth() {
  1142.         global $config;
  1143.         $transparent_proxy = ($config['installedpackages']['squid']['config'][0]['transparent_proxy'] == 'on');
  1144.  
  1145.         // No authentication for transparent proxy
  1146.         if ($transparent_proxy) {
  1147.                 $javascript = <<<EOD
  1148. <script language="JavaScript">
  1149. <!--
  1150. function on_auth_method_changed() {
  1151.         document.iform.auth_method.disabled = 1;
  1152.         document.iform.auth_server.disabled = 1;
  1153.         document.iform.auth_server_port.disabled = 1;
  1154.         document.iform.ldap_user.disabled = 1;
  1155.         document.iform.ldap_version.disabled = 1;
  1156.         document.iform.ldap_filter.disabled = 1;
  1157.         document.iform.ldap_password.disabled = 1;
  1158.         document.iform.ldap_basedomain.disabled = 1;
  1159.         document.iform.radius_secret.disabled = 1;
  1160.         document.iform.msnt_secondary.disabled = 1;
  1161.         document.iform.auth_prompt.disabled = 1;
  1162.         document.iform.auth_processes.disabled = 1;
  1163.         document.iform.auth_ttl.disabled = 1;
  1164.         document.iform.unrestricted_auth.disabled = 1;
  1165.         document.iform.no_auth_hosts.disabled = 1;
  1166. }
  1167. -->
  1168. </script>
  1169.  
  1170. EOD;
  1171.         }
  1172.         else {
  1173.                 $javascript = <<<EOD
  1174. <script language="JavaScript">
  1175. <!--
  1176. function on_auth_method_changed() {
  1177.         var field = document.iform.auth_method;
  1178.         var auth_method = field.options[field.selectedIndex].value;
  1179.  
  1180.         if (auth_method == 'none') {
  1181.                 document.iform.auth_server.disabled = 1;
  1182.                 document.iform.auth_server_port.disabled = 1;
  1183.                 document.iform.ldap_user.disabled = 1;
  1184.                 document.iform.ldap_version.disabled = 1;
  1185.                 document.iform.ldap_filter.disabled = 1;
  1186.                 document.iform.ldap_password.disabled = 1;
  1187.                 document.iform.ldap_basedomain.disabled = 1;
  1188.                 document.iform.radius_secret.disabled = 1;
  1189.                 document.iform.msnt_secondary.disabled = 1;
  1190.                 document.iform.auth_prompt.disabled = 1;
  1191.                 document.iform.auth_processes.disabled = 1;
  1192.                 document.iform.auth_ttl.disabled = 1;
  1193.                 document.iform.unrestricted_auth.disabled = 1;
  1194.                 document.iform.no_auth_hosts.disabled = 1;
  1195.         }
  1196.         else {
  1197.                 document.iform.auth_prompt.disabled = 0;
  1198.                 document.iform.auth_processes.disabled = 0;
  1199.                 document.iform.auth_ttl.disabled = 0;
  1200.                 document.iform.unrestricted_auth.disabled = 0;
  1201.                 document.iform.no_auth_hosts.disabled = 0;
  1202.         }
  1203.  
  1204.         switch (auth_method) {
  1205.                 case 'local':
  1206.                         document.iform.auth_server.disabled = 1;
  1207.                         document.iform.auth_server_port.disabled = 1;
  1208.                         document.iform.ldap_user.disabled = 1;
  1209.                         document.iform.ldap_password.disabled = 1;
  1210.                         document.iform.ldap_version.disabled = 1;
  1211.                         document.iform.ldap_filter.disabled = 1;
  1212.                         document.iform.ldap_basedomain.disabled = 1;
  1213.                         document.iform.radius_secret.disabled = 1;
  1214.                         document.iform.msnt_secondary.disabled = 1;
  1215.                         break;
  1216.                 case 'ldap':
  1217.                         document.iform.auth_server.disabled = 0;
  1218.                         document.iform.auth_server_port.disabled = 0;
  1219.                         document.iform.ldap_user.disabled = 0;
  1220.                         document.iform.ldap_password.disabled = 0;
  1221.                         document.iform.ldap_version.disabled = 0;
  1222.                         document.iform.ldap_filter.disabled = 0;
  1223.                         document.iform.ldap_basedomain.disabled = 0;
  1224.                         document.iform.radius_secret.disabled = 1;
  1225.                         document.iform.msnt_secondary.disabled = 1;
  1226.                         break;
  1227.                 case 'radius':
  1228.                         document.iform.auth_server.disabled = 0;
  1229.                         document.iform.auth_server_port.disabled = 0;
  1230.                         document.iform.ldap_user.disabled = 1;
  1231.                         document.iform.ldap_password.disabled = 1;
  1232.                         document.iform.ldap_version.disabled = 1;
  1233.                         document.iform.ldap_filter.disabled = 1;
  1234.                         document.iform.ldap_basedomain.disabled = 1;
  1235.                         document.iform.radius_secret.disabled = 0;
  1236.                         document.iform.msnt_secondary.disabled = 1;
  1237.                         break;
  1238.                 case 'msnt':
  1239.                         document.iform.auth_server.disabled = 0;
  1240.                         document.iform.auth_server_port.disabled = 1;
  1241.                         document.iform.ldap_user.disabled = 1;
  1242.                         document.iform.ldap_password.disabled = 1;
  1243.                         document.iform.ldap_version.disabled = 1;
  1244.                         document.iform.ldap_filter.disabled = 1;
  1245.                         document.iform.ldap_basedomain.disabled = 1;
  1246.                         document.iform.radius_secret.disabled = 1;
  1247.                         document.iform.msnt_secondary.disabled = 0;
  1248.                         break;
  1249.         }
  1250. }
  1251. -->
  1252. </script>
  1253.  
  1254. EOD;
  1255.         }
  1256.  
  1257.         print($javascript);
  1258. }
  1259.  
  1260. function squid_print_javascript_auth2() {
  1261.         print("<script language=\"JavaScript\">on_auth_method_changed()</script>\n");
  1262. }
  1263.  
  1264. function squid_generate_rules($type) {
  1265.         global $config;
  1266.  
  1267.         $squid_conf = $config['installedpackages']['squid']['config'][0];
  1268.         if (!is_service_running('squid')) {
  1269.                 log_error("SQUID is installed but not started.  Not installing redirect rules.");
  1270.                 return;
  1271.         }
  1272.  
  1273.         if (($squid_conf['transparent_proxy'] != 'on') || ($squid_conf['allow_interface'] != 'on')) {
  1274.                 return;
  1275.         }
  1276.  
  1277.         $ifaces = explode(",", $squid_conf['active_interface']);
  1278.         $ifaces = array_map('convert_friendly_interface_to_real_interface_name', $ifaces);
  1279.         $port = ($squid_conf['proxy_port'] ? $squid_conf['proxy_port'] : 3128);
  1280.  
  1281.         $fw_aliases = filter_generate_aliases();
  1282.         if(strstr($fw_aliases, "pptp ="))
  1283.                 $PPTP_ALIAS = "\$pptp";
  1284.         else
  1285.                 $PPTP_ALIAS = "\$PPTP";
  1286.         if(strstr($fw_aliases, "PPPoE ="))
  1287.                 $PPPOE_ALIAS = "\$PPPoE";
  1288.         else
  1289.                 $PPPOE_ALIAS = "\$pppoe";
  1290.                
  1291.         switch($type) {
  1292.                 case 'nat':
  1293.                         $rules .= "\n# Setup Squid proxy redirect\n";
  1294.                         if ($squid_conf['private_subnet_proxy_off'] == 'on') {
  1295.                                 foreach ($ifaces as $iface) {
  1296.                                         $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 80\n";        
  1297.                                 }
  1298.                         }
  1299.                         if (!empty($squid_conf['defined_ip_proxy_off'])) {
  1300.                                 $defined_ip_proxy_off = explode(";", $squid_conf['defined_ip_proxy_off']);
  1301.                                 $exempt_ip = "";
  1302.                                 foreach ($defined_ip_proxy_off as $ip_proxy_off) {
  1303.                                         if(!empty($ip_proxy_off)) {
  1304.                                                 $ip_proxy_off = trim($ip_proxy_off);
  1305.                                                 $exempt_ip .= ", $ip_proxy_off";
  1306.                                         }
  1307.                                 }
  1308.                                 $exempt_ip = substr($exempt_ip,2);
  1309.                                 foreach ($ifaces as $iface) {
  1310.                                         $rules .= "no rdr on $iface proto tcp from { $exempt_ip } to any port 80\n";        
  1311.                                 }          
  1312.                         }    
  1313.                         foreach ($ifaces as $iface) {
  1314.                                 $rules .= "rdr on $iface proto tcp from any to !($iface) port 80 -> 127.0.0.1 port 80\n";
  1315.                         }
  1316.                         /* Handle PPPOE case */
  1317.                         if($config['pppoe']['mode'] == "server" && $config['pppoe']['localip']) {
  1318.                                 $rules .= "rdr on $PPPOE_ALIAS proto tcp from any to !127.0.0.1 port 80 -> 127.0.0.1 port 80\n";
  1319.                         }
  1320.                         /* Handle PPTP case */
  1321.                         if($config['pptpd']['mode'] == "server" && $config['pptpd']['localip']) {
  1322.                                 $rules .= "rdr on $PPTP_ALIAS proto tcp from any to !127.0.0.1 port 80 -> 127.0.0.1 port 80\n";
  1323.                         }
  1324.                         $rules .= "\n";
  1325.                         break;
  1326.                 case 'filter':
  1327.                 case 'rule':
  1328.                         foreach ($ifaces as $iface) {
  1329.                                 $rules .= "# Setup squid pass rules for proxy\n";
  1330.                                 $rules .= "pass in quick on $iface proto tcp from any to !($iface) port 80 flags S/SA keep state\n";
  1331.                                 $rules .= "pass in quick on $iface proto tcp from any to !($iface) port $port flags S/SA keep state\n";
  1332.                                 $rules .= "\n";
  1333.                         };
  1334.                         if($config['pppoe']['mode'] == "server" && $config['pppoe']['localip']) {
  1335.                                 $rules .= "pass in quick on $PPPOE_ALIAS proto tcp from any to !127.0.0.1 port $port flags S/SA keep state\n";                 
  1336.                         }                      
  1337.                         if($config['pptpd']['mode'] == "server" && $config['pptpd']['localip']) {
  1338.                                 $rules .= "pass in quick on $PPTP_ALIAS proto tcp from any to !127.0.0.1 port $port flags S/SA keep state\n";
  1339.                         }
  1340.                         break;
  1341.                 default:
  1342.                         break;
  1343.         }
  1344.  
  1345.         return $rules;
  1346. }
  1347.  
  1348. ?>