2.0) define('SQUID_LOCALBASE', '/usr/pbi/squid-' . php_uname("m")); else define('SQUID_LOCALBASE','/usr/local'); define('SQUID_CONFBASE',SQUID_LOCALBASE . '/etc/squid'); define('SQUID_BASE', '/var/squid/'); define('SQUID_ACLDIR', '/var/squid/acl'); define('SQUID_PASSWD', '/var/etc/squid.passwd'); $valid_acls = array(); 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); } } } } /* setup cache */ function squid_dash_z() { global $config; $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(!is_dir($cachedir.'/')) { log_error("Creating Squid cache dir $cachedir"); @mkdir($cachedir, 0755, true); // 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"); sleep(5); mwexec(SQUID_LOCALBASE . "/sbin/squid -k kill"); // 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"); } 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; /* migrate existing csv config fields */ $settingsauth = $config['installedpackages']['squidauth']['config'][0]; $settingscache = $config['installedpackages']['squidcache']['config'][0]; $settingsnac = $config['installedpackages']['squidnac']['config'][0]; /* 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']; } } 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 and suid root */ // XXX: Bug #5114 if(file_exists(SQUID_LOCALBASE . "/libexec/squid/pinger")) exec("/bin/chmod a+x " . SQUID_LOCALBASE . "/libexec/squid/pinger"); exec("/bin/chmod u+s " . SQUID_LOCALBASE . "/libexec/squid/pinger"); if(file_exists(SQUID_LOCALBASE . "/etc/rc.d/squid")) exec("/bin/rm " . SQUID_LOCALBASE . "/etc/rc.d/squid"); squid_write_rcfile(); exec("chmod a+rx " . SQUID_LOCALBASE . "/libexec/squid/dnsserver"); if(file_exists("/usr/local/pkg/swapstate_check.php")) exec("/bin/chmod a+x /usr/local/pkg/swapstate_check.php"); foreach (array( SQUID_CONFBASE, SQUID_ACLDIR, SQUID_BASE ) as $dir) { @mkdir($dir, 0755, true); 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 -D"); } else { update_status("Reloading Squid for configuration sync... One moment please..."); log_error("Reloading Squid for configuration sync"); mwexec(SQUID_LOCALBASE . "/sbin/squid -k reconfigure"); } /* 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); $settings = &$config['installedpackages']['squidcache']['config'][0]; $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 swap.state ... One moment please..."); update_output_window("$plswait_txt"); mwexec('rm -rf $cachedir/swap.state'); 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 '.' 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); $i++) $field['options']['option'][] = array('name' => $names[$i], 'value' => $values[$i]); } function squid_validate_general($post, &$input_errors) { global $config; $settings = $config['installedpackages']['squid']['config'][0]; $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 \'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"; } 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'; }} } function squid_validate_upstream($post, &$input_errors) { if ($post['proxy_forwarding'] == 'on') { $addr = trim($post['proxy_addr']); 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('proxy_port' => 'TCP port', 'icp_port' => '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) { foreach (explode("\n", $post[$hosts]) as $host) { $host = trim($host); if (!empty($host) && !is_ipaddr($host)) $input_errors[] = "The host '$host' is not a valid IP address"; } } 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 (!empty($mgr) && !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 percentaged value"; } } 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')) { $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 $g, $config; if (function_exists("platform_booting")) { if (platform_booting()) { return; } } elseif ($g['booting']) { return; } $rotate_is_installed = false; $swapstate_is_installed = false; if(!$config['cron']['item']) return; $settings = $config['installedpackages']['squidcache']['config'][0]; $x=0; $rotate_job_id=-1; $swapstate_job_id=-1; foreach($config['cron']['item'] as $item) { if(strstr($item['task_name'], "squid_rotate_logs")) { $rotate_job_id = $x; } elseif(strstr($item['task_name'], "squid_check_swapstate")) { $swapstate_job_id = $x; } $x++; } $need_write = false; switch($should_install) { case true: $cachedir =($settings['harddisk_cache_location'] ? $settings['harddisk_cache_location'] : '/var/squid/cache'); if($rotate_job_id < 0) { $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'] = "/bin/rm {$cachedir}/swap.state; " . SQUID_LOCALBASE . "/sbin/squid -k rotate"; $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"; $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_resync_general() { global $g, $config, $valid_acls; $settings = $config['installedpackages']['squid']['config'][0]; $conf = "# This file is automatically generated by pfSense\n"; $conf = "# Do not edit manually !\n"; $port = ($settings['proxy_port'] ? $settings['proxy_port'] : 3128); $ifaces = ($settings['active_interface'] ? $settings['active_interface'] : 'lan'); $real_ifaces = array(); foreach (explode(",", $ifaces) as $i => $iface) { $real_ifaces[] = squid_get_real_interface_address($iface); if($real_ifaces[$i][0]) { $conf .= "http_port {$real_ifaces[$i][0]}:$port\n"; } } if (($settings['transparent_proxy'] == 'on')) { $conf .= "http_port 127.0.0.1:" . $settings['proxy_port'] . " transparent\n"; } $icp_port = ($settings['icp_port'] ? $settings['icp_port'] : 0); $pidfile = "{$g['varrun_path']}/squid.pid"; $language = ($settings['error_language'] ? $settings['error_language'] : 'English'); $errordir = SQUID_CONFBASE . '/errors/' . $language; $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'); $logdir_cache = $logdir . '/cache.log'; $logdir_access = ($settings['log_enabled'] == 'on' ? $logdir . '/access.log' : '/dev/null'); $conf .= << 'src', 'banned_hosts' => 'src', 'whitelist' => 'dstdom_regex -i', 'blacklist' => 'dstdom_regex -i', ); foreach ($options as $option => $directive) { $contents = base64_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 .= << $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 all\n"; } else $conf .= "delay_access 1 allow all\n"; return $conf; } function squid_resync_auth() { global $config, $valid_acls; if (!is_array($config['installedpackages']['squidauth'])) { $config['installedpackages']['squidauth']['config'][0] = array(); } if (!is_array($config['installedpackages']['squidnac'])) { $config['installedpackages']['squidnac']['config'][0] = array(); } if (!is_array($config['installedpackages']['squid'])) { $config['installedpackages']['squid']['config'][0] = array(); } $settings = $config['installedpackages']['squidauth']['config'][0]; $settingsnac = $config['installedpackages']['squidnac']['config'][0]; $settingsconfig = $config['installedpackages']['squid']['config'][0]; $conf = ''; // Custom Options if(!empty($config['installedpackages']['squid']['config'][0]['custom_options'])) { $custopts = explode(";", ($config['installedpackages']['squid']['config'][0]['custom_options'])); $conf .= "# Custom options\n"; foreach ($custopts as $custopt) { $conf .= $custopt."\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 precendence over blacklist if(! empty($settingsnac['unrestricted_hosts'])) { if (squid_is_valid_acl('unrestricted_hosts')) { $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 precendence 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"; } } $transparent_proxy = ($settingsconfig['transparent_proxy'] == 'on'); $auth_method = (($settings['auth_method'] && !$transparent_proxy) ? $settings['auth_method'] : 'none'); // Allow the remaining ACLs if no authentication is set 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 = base64_decode($settings['no_auth_hosts']); if (!empty($noauth)) { foreach (explode("\n", $noauth) as $host) { $host = trim($host); $conf .= "acl noauth src $host\n"; } $valid_acls[] = 'noauth'; } // Set up the external authentication programs $auth_ttl = ($settings['auth_ttl'] ? $settings['auth_ttl'] : 60); $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/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/squid_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/squid_radius_auth -w {$settings['radius_secret']} -h {$settings['auth_server']} $port\n"; break; case 'msnt': $conf .= "auth_param basic program " . SQUID_LOCALBASE . "/libexec/squid/msnt_auth\n"; squid_resync_msnt(); break; } $conf .= << EOD; } else { $javascript = << EOD; } print($javascript); } function squid_print_javascript_auth2() { print("\n"); } function squid_generate_rules($type) { global $config; $squid_conf = $config['installedpackages']['squid']['config'][0]; 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; } $ifaces = explode(",", $squid_conf['active_interface']); $ifaces = array_map('convert_friendly_interface_to_real_interface_name', $ifaces); $port = ($squid_conf['proxy_port'] ? $squid_conf['proxy_port'] : 3128); $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"; switch($type) { case 'nat': $rules .= "\n# Setup Squid proxy redirect\n"; if ($squid_conf['private_subnet_proxy_off'] == 'on') { foreach ($ifaces as $iface) { $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"; } /* 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 80\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 80\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 ($ifaces as $iface) { $rules .= "no rdr on $iface proto tcp from { $exempt_ip } to any port 80\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 80\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 80\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 ($ifaces as $iface) { $rules .= "no rdr on $iface proto tcp from any to { $exempt_dest } port 80\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 80\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 80\n"; } } foreach ($ifaces as $iface) { $rules .= "rdr on $iface proto tcp from any to !($iface) port 80 -> 127.0.0.1 port " . $squid_conf['proxy_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 80 -> 127.0.0.1 port " . $squid_conf['proxy_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 80 -> 127.0.0.1 port " . $squid_conf['proxy_port'] . "\n"; } $rules .= "\n"; break; case 'filter': case 'rule': foreach ($ifaces as $iface) { $rules .= "# Setup squid pass rules for proxy\n"; $rules .= "pass in quick on $iface proto tcp from any to !($iface) port 80 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() { $rc = array(); $SQUID_LOCALBASE = SQUID_LOCALBASE; $rc['file'] = 'squid.sh'; $rc['start'] = <</dev/null killall pinger 2>/dev/null EOD; $rc['restart'] = << "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")); conf_mount_ro(); } ?>