aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFernando Lemos <fernandotcl@pfsense.org>2006-09-05 14:55:17 +0000
committerFernando Lemos <fernandotcl@pfsense.org>2006-09-05 14:55:17 +0000
commitf92d86eff5e525ac55ac396a0ca0341d92aa0365 (patch)
tree2683941472df9e4f8396765299a4fa13da231dcf
parentdb4e2078da574a50ffa115ba41febc22a9bd1ce4 (diff)
downloadpfsense-packages-f92d86eff5e525ac55ac396a0ca0341d92aa0365.tar.gz
pfsense-packages-f92d86eff5e525ac55ac396a0ca0341d92aa0365.tar.bz2
pfsense-packages-f92d86eff5e525ac55ac396a0ca0341d92aa0365.zip
New Squid stuff, to be backported or whatever.
-rw-r--r--packages/squid-head/squid.inc841
-rw-r--r--packages/squid-head/squid.xml171
-rw-r--r--packages/squid-head/squid_auth.xml156
-rw-r--r--packages/squid-head/squid_cache.xml134
-rw-r--r--packages/squid-head/squid_monitor.sh44
-rw-r--r--packages/squid-head/squid_nac.xml101
-rw-r--r--packages/squid-head/squid_traffic.xml109
-rw-r--r--packages/squid-head/squid_upstream.xml87
-rw-r--r--packages/squid-head/squid_users.xml74
9 files changed, 1717 insertions, 0 deletions
diff --git a/packages/squid-head/squid.inc b/packages/squid-head/squid.inc
new file mode 100644
index 00000000..c28fccc1
--- /dev/null
+++ b/packages/squid-head/squid.inc
@@ -0,0 +1,841 @@
+<?php
+require_once('globals.inc');
+require_once('config.inc');
+require_once('util.inc');
+require_once('pfsense-utils.inc');
+require_once('pkg-utils.inc');
+require_once('filter.inc');
+require_once('service-utils.inc');
+
+define('RC_BASE', '/usr/local/etc/rc.d');
+define('SQUID_CONFBASE', '/usr/local/etc/squid');
+define('SQUID_LOGDIR', '/var/squid/log');
+define('SQUID_CACHEDIR', '/var/squid/cache');
+define('SQUID_ACLDIR', '/var/squid/acl');
+define('SQUID_PASSWD', '/var/etc/squid.passwd');
+define('MSNTAUTH_CONF', '/usr/local/etc/squid/msntauth.conf');
+
+$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";
+ if (is_dir($path))
+ squid_chown_recursive($path, $user, $group);
+ else {
+ chown($path, $user);
+ chgrp($path, $group);
+ }
+ }
+ }
+}
+
+function squid_is_valid_acl($acl) {
+ global $valid_acls;
+
+ return in_array($acl, $valid_acls);
+}
+
+function squid_install_command() {
+ /* Create cache */
+ update_output_window('Initializing cache... This may take a moment...');
+ mwexec('/usr/local/sbin/squid -z');
+
+ $rc = array();
+ $rc['file'] = 'squid.sh';
+ $rc['start'] = '/usr/local/sbin/squid -D';
+ $rc['stop'] = RC_BASE . "/proxy_monitor.sh stop\n";
+ $rc['stop'] .= <<<EOD
+/usr/local/sbin/squid -k shutdown
+# Just to be sure...
+killall squid 2>/dev/null
+sleep 1
+killall squid 2>/dev/null
+
+EOD;
+ $rc['restart'] = <<<EOD
+if [ -z "`pgrep squid`" ]; then
+ /usr/local/sbin/squid -D
+ else
+ /usr/local/sbin/squid -k reconfigure
+ fi
+
+EOD;
+ write_rcfile($rc);
+
+ $rc = array();
+ $rc['file'] = 'proxy_monitor.sh';
+ $rc['start'] = '/usr/local/bin/squid_monitor.sh';
+ $rc['stop'] = 'killall squid_monitor.sh';
+ write_rcfile($rc);
+
+ foreach (array( SQUID_CONFBASE,
+ SQUID_LOGDIR,
+ SQUID_ACLDIR,
+ ) as $dir) {
+ make_dirs($dir);
+ squid_chown_recursive($dir, 'proxy', 'proxy');
+ }
+
+ restart_service('squid');
+ sleep(1);
+ restart_service('proxy_monitor');
+
+ if (!file_exists(SQUID_CONFBASE . '/mime.conf') && file_exists(SQUID_CONFBASE . '/mime.conf.default'))
+ copy(SQUID_CONFBASE . '/mime.conf.default', SQUID_CONFBASE . '/mime.conf');
+}
+
+function squid_deinstall_command() {
+ stop_service('proxy_monitor');
+ stop_service('squid');
+
+ filter_configure();
+
+ mwexec('rm -rf ' . SQUID_CACHEDIR);
+}
+
+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) - 1; $i++)
+ $field['options']['option'][] = array('name' => $names[$i], 'value' => $values[$i]);
+}
+
+function squid_validate_general($post, $input_errors) {
+ $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';
+
+ $children = $post['redirect_children'];
+ if (!empty($children) && !is_numeric($children))
+ $input_errors[] = 'You must enter a valid number for the \'Redirect children\' 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 < 1))
+ $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\'';
+
+ foreach (explode(',', $post['donotcache']) as $host) {
+ $host = trim($host);
+ if (!is_ipaddr($host) && !is_domain($host))
+ $input_errors[] = "$host is not a valid IP or host name";
+ }
+}
+
+function squid_validate_nac($post, $input_errors) {
+ $allowed_subnets = explode(',', trim($post['allowed_subnets']));
+ foreach ($allowed_subnets as $subnet) {
+ $subnet = trim($subnet);
+ if (!is_subnet($subnet))
+ $input_errors[] = "'$subnet' is not a valid CIDR range";
+ }
+
+ foreach (array( 'unrestricted_hosts',
+ 'banned_hosts',
+ 'whitelist',
+ 'blacklist',
+ ) as $hosts) {
+ foreach (explode(',', $post[$hosts]) as $host) {
+ $host = trim($host);
+ if (!empty($host) && !is_ipaddr($host))
+ $input_errors[] = "'$host' is not a valid IP address";
+ }
+ }
+
+ foreach (array('unrestricted_macs', 'banned_macs') as $macs) {
+ foreach (explode(',', $post[$macs]) as $mac) {
+ $mac = trim($mac);
+ if (!empty($mac) && !is_macaddr($mac))
+ $input_errors[] = "'$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[] = "'$time' is not a valid time range";
+ }
+}
+
+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";
+ }
+}
+
+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':
+ $required = array(
+ 'ldap_basedn' => 'LDAP base DN',
+ 'ldap_filter' => 'LDAP filter',
+ );
+ foreach ($required as $field => $descr) {
+ $value = trim($post[$field]);
+ if (empty($value))
+ $input_errors[] = "The field '$descr' is required";
+ }
+
+ $user = trim($post['ldap_user']);
+ $password = trim($post['ldap_password']);
+ if (!empty($password) && empty($user))
+ $input_errors[] = 'You must specify an username if you specify a password';
+
+ break;
+ case 'radius':
+ $secret = trim($post['radius_secret']);
+ if (empty($secret))
+ $input_errors[] = 'The field \'RADIUS secret\' is required';
+ break;
+ case 'msnt':
+ $bdc = $post['msnt_bdc'];
+ if (!empty($bdc) && !is_ipaddr($bdc) && !is_domain($bdc))
+ $input_errors[] = "'$bdc' isn't a valid IP address or domain name";
+ $domain = $post['msnt_domain'];
+ if (empty($domain) || !is_domain($domain))
+ $input_errors[] = 'You must enter a valid domain name in the \'NT domain\' field';
+ break;
+ }
+
+ $no_auth = explode(',', trim($post['no_auth_hosts']));
+ foreach ($no_auth as $host) {
+ $host = trim($host);
+ if (!empty($host) && !is_subnet($host))
+ $input_errors[] = "'$host' isn't a valid CIDR range";
+ }
+ }
+}
+
+function squid_resync_general() {
+ global $g, $config, $valid_acls;
+
+ $settings = $config['installedpackages']['squid']['config'][0];
+ $conf = '';
+
+ if ($settings['transparent_proxy'] == 'on') {
+ $conf .= <<<EOD
+httpd_accel_host virtual
+httpd_accel_port 80
+httpd_accel_with_proxy on
+httpd_accel_uses_host_header on
+
+EOD;
+ }
+
+ $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 (!empty($real_ifaces[$i][0]))
+ $conf .= "http_port {$real_ifaces[$i][0]}:$port\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;
+ $hostname = $settings['visible_hostname'] ? $settings['visible_hostname'] : 'localhost';
+ $email = $settings['admin_email'] ? $settings['admin_email'] : 'admin@localhost';
+
+ $logdir_cache = SQUID_LOGDIR . '/cache.log';
+ $logdir_access = $settings['log_enabled'] == 'on' ? SQUID_LOGDIR . '/access.log' : '/dev/null';
+
+ $conf .= <<<EOD
+icp_port $icp_port
+
+pid_filename $pidfile
+cache_effective_user proxy
+cache_effective_group proxy
+error_directory $errordir
+visible_hostname $hostname
+cache_mgr $email
+
+cache_access_log $logdir_access
+cache_log $logdir_cache
+cache_store_log none
+
+EOD;
+
+ if ($settings['allow_interface'] == 'on') {
+ $src = '';
+ foreach ($real_ifaces as $iface) {
+ list($ip, $mask) = $iface;
+ $ip = long2ip(ip2long($ip) & ip2long($mask));
+ $src .= " $ip/$mask";
+ }
+ $conf .= "acl localnet src $src\n";
+ $valid_acls[] = 'localnet';
+ }
+
+ restart_service('proxy_monitor');
+
+ return $conf;
+}
+
+function squid_resync_cache() {
+ global $config;
+
+ $settings = $config['installedpackages']['squidcache']['config'][0];
+
+ $cachedir = SQUID_CACHEDIR;
+ $disk_cache_size = $settings['harddisk_cache_size'] ? $settings['harddisk_cache_size'] : 100;
+ $level1 = $settings['level1_subdirs'] ? $settings['level1_subdirs'] : 16;
+ $memory_cache_size = $settings['memory_cache_size'] ? $settings['memory_cache_size'] : 8;
+ $max_objsize = $settings['maximum_object_size'] ? $settings['maximum_object_size'] : 4;
+ $min_objsize = $settings['minimum_object_size'] ? $settings['minimum_object_size'] : 0;
+ $cache_policy = $settings['cache_replacement_policy'] ? $settings['cache_replacement_policy'] : 'heap LFUDA';
+ $memory_policy = $settings['memory_replacement_policy'] ? $settings['memory_replacement_policy'] : 'heap GSDF';
+ $offline_mode = $settings['enable_offline'] == 'on' ? 'on' : 'off';
+
+ $conf = <<<EOD
+cache_dir diskd $cachedir $disk_cache_size $level1 256
+cache_mem $memory_cache_size MB
+maximum_object_size $max_objsize KB
+minimum_object_size $min_objsize KB
+cache_replacement_policy $cache_policy
+memory_replacement_policy $memory_policy
+offline_mode $offline_mode
+
+EOD;
+
+ $donotcache = trim(implode("\n", array_map('trim', explode(',', $settings['donotcache']))));
+ if (!empty($donotcache)) {
+ file_put_contents(SQUID_ACLDIR . '/donotcache.acl', $donotcache);
+ $conf .= 'acl donotcache dstdomain "' . SQUID_ACLDIR . "/donotcache.acl\"\n";
+ $conf .= 'no_cache deny donotcache';
+ }
+
+ return $conf;
+}
+
+function squid_resync_upstream() {
+ global $config;
+ $settings = $config['installedpackages']['squidupstream']['config'][0];
+
+ $conf = '';
+ if ($settings['proxy_forwarding'] == 'on') {
+ $conf .= "cache_peer {$settings['proxy_addr']} parent {$settings['proxy_port']} {$settings['icp_port']} ";
+
+ if (!empty($settings['username']))
+ $conf .= " login={$settings['username']}";
+ if (!empty($settings['password']))
+ $conf .= ":{$settings['password']}";
+ }
+
+ return $conf;
+}
+
+function squid_resync_redirector() {
+ global $config;
+
+ $httpav_enabled = $config['installedpackages']['clamav']['config'][0]['scan_http'] == 'on';
+ if ($httpav_enabled)
+ return ('redirect_program /usr/local/bin/squirm');
+ return '# No redirector configured';
+}
+
+function squid_resync_nac() {
+ global $config, $valid_acls;
+
+ $settings = $config['installedpackages']['squidnac']['config'][0];
+
+ $conf = <<<EOD
+acl all src 0.0.0.0/0
+acl localhost src 127.0.0.1
+acl safeports port 21 70 80 210 280 443 488 563 591 631 777 901 1025-65535
+acl sslports port 443 563
+acl manager proto cache_object
+acl purge method PURGE
+acl connect method CONNECT
+acl dynamic urlpath_regex cgi-bin \?
+
+EOD;
+
+ $allowed = implode(' ', array_map('trim', explode(',', $settings['allowed_subnets'])));
+ if (!empty($allowed)) {
+ $conf .= "acl allowed_subnets src $allowed\n";
+ $valid_acls[] = 'allowed_subnets';
+ }
+
+ $options = array( 'unrestricted_hosts' => 'src',
+ 'unrestricted_macs' => 'arp',
+ 'banned_hosts' => 'src',
+ 'banned_macs' => 'arp',
+ 'whitelist' => 'url_regex -i',
+ 'blacklist' => 'url_regex -i',
+ );
+ foreach ($options as $option => $directive) {
+ $contents = trim(implode("\n", array_map('trim', explode(',', $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;
+ }
+ }
+
+ $conf .= <<<EOD
+no_cache deny dynamic
+http_access allow manager localhost
+http_access deny manager
+http_access allow purge localhost
+http_access deny purge
+http_access deny !safeports
+http_access deny CONNECT !sslports
+
+http_access allow localhost
+
+EOD;
+
+ return $conf;
+}
+
+function squid_resync_traffic() {
+ global $config, $valid_acls;
+
+ $settings = $config['installedpackages']['squidtraffic']['config'][0];
+ $conf = '';
+
+ $up_limit = $settings['max_upload_size'] ? $settings['max_upload_size'] : 0;
+ $down_limit = $settings['max_download_size'] ? $settings['max_download_size'] : 0;
+ $conf .= "request_body_max_size $up_limit KB\n";
+ $conf .= 'reply_body_max_size ' . ($down_limit * 1024) . " allow all\n";
+
+ // Only apply throttling past 10MB
+ // XXX: Should this really be hardcoded?
+ $threshold = 10 * 1024 * 1024;
+ $overall = $settings['overall_throttling'];
+ if (!isset($overall) || ($overall == 0))
+ $overall = -1;
+ else
+ $overall *= 1024;
+ $perhost = $settings['perhost_throttling'];
+ if (!isset($perhost) || ($perhost == 0))
+ $perhost = -1;
+ else
+ $perhost *= 1024;
+ $conf .= <<<EOD
+delay_pools 1
+delay_class 1 2
+delay_parameters 1 $overall/$threshold $perhost/$threshold
+delay_initial_bucket_level 100%
+
+EOD;
+
+ foreach (array('unrestricted_hosts', 'unrestricted_macs') as $item) {
+ if (in_array($item, $valid_acls))
+ $conf .= "delay_access 1 deny $item\n";
+ }
+
+ if ($settings['throttle_specific'] == 'on') {
+ $exts = array();
+ $binaries = 'bin,cab,sea,ar,arj,tar,tgz,gz,tbz,bz2,zip,exe,com';
+ $cdimages = 'iso,bin,mds,nrg,gho,bwt,b5t,pqi';
+ $multimedia = 'aiff?,asf,avi,divx,mov,mp3,mp4,mpe?g,qt,ra?m';
+ foreach (array( 'throttle_binaries' => $binaries,
+ 'throttle_cdimages' => $cdimages,
+ 'throttle_multimedia' => $multimedia) as $field => $set) {
+ if ($settings[$field] == 'on')
+ $exts = array_merge($exts, explode(',', $set));
+ }
+
+ foreach (explode(',', $settings['throttle_others']) as $ext) {
+ if (!empty($ext)) $exts[] = $ext;
+ }
+
+ $contents = '';
+ foreach ($exts as $ext)
+ $contents .= "\.$ext\$\n";
+ file_put_contents(SQUID_ACLDIR . '/throttle_exts.acl', $contents);
+
+ $conf .= 'acl throttle_exts url_regex -i "' . SQUID_ACLDIR . '/throttle_exts.acl"';
+ $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;
+
+ $settings = $config['installedpackages']['squidauth']['config'][0];
+ $conf = '';
+
+ // Deny the banned guys before allowing the good guys
+ $banned = array( 'banned_hosts',
+ 'banned_macs',
+ );
+ $banned = array_filter($banned, 'squid_is_valid_acl');
+ foreach ($banned as $acl)
+ $conf .= "http_access deny $acl\n";
+
+ // Whitelist and blacklist also take precendence
+ if (squid_is_valid_acl('whitelist'))
+ $conf .= "http_access allow whitelist\n";
+ if (squid_is_valid_acl('blacklist'))
+ $conf .= "http_access deny blacklist\n";
+
+ $transparent_proxy = $config['installedpackages']['squid']['config'][0]['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') {
+ $allowed = array('localnet', 'allowed_subnets', 'unrestricted_hosts', 'unrestricted_macs');
+ $allowed = array_filter($allowed, 'squid_is_valid_acl');
+ foreach ($allowed as $acl)
+ $conf .= "http_access allow $acl\n";
+ }
+
+ else {
+ $noauth = implode(' ', array_map('trim', explode(',', $settings['no_auth_hosts'])));
+ if (!empty($noauth)) {
+ $conf .= "acl noauth src $noauth\n";
+ $valid_acls[] = 'noauth';
+ }
+
+ // Set up the external authentication programs
+ $auth_ttl = $settings['auth_ttl'] ? $settings['auth_ttl'] : 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 /usr/local/libexec/squid/ncsa_auth ' . SQUID_PASSWD . "\n";
+ break;
+ case 'ldap':
+ $port = isset($settings['auth_port']) ? ":{$settings['auth_port']}" : '';
+ $user = isset($settings['ldap_user']) ? "-D {$settings['ldap_user']}" : '';
+ $password = isset($settings['ldap_password']) ? "-w '{$settings['ldap_password']}'" : '';
+ $filter = isset($settings['ldap_filter']) ? "-f '{$settings['ldap_filter']}'" : '';
+ $conf .= "auth_param basic program /usr/local/libexec/squid/squid_ldap_auth -b {$settings['ldap_basedn']} $user $password $filter {$settings['auth_server']}$port\n";
+ break;
+ case 'radius':
+ $port = isset($settings['auth_port']) ? "-p {$settings['auth_server_port']}" : '';
+ $conf .= "auth_param basic program /usr/local/libexec/squid/squid_radius_auth -w {$settings['radius_secret']} -h {$settings['auth_server']} $port\n";
+ break;
+ case 'msnt':
+ $conf .= "auth_param basic program /usr/local/libexec/squid/msnt_auth\n";
+
+ $bdc = trim($settings['msnt_bdc']);
+ if (empty($bdc)) $bdc = $settings['auth_server'];
+ $msntauth_conf = "server {$settings['auth_server']} $bdc {$settings['msnt_domain']}\n";
+ file_put_contents(MSNTAUTH_CONF, $msntauth_conf);
+
+ break;
+ }
+ $conf .= <<<EOD
+auth_param basic children $processes
+auth_param basic realm $prompt
+auth_param basic credentialsttl $auth_ttl minutes
+acl password proxy_auth REQUIRED
+
+EOD;
+
+ // Onto the ACLs
+ $password = array('localnet', 'allowed_subnets');
+ $passwordless = array('unrestricted_hosts', 'unrestricted_macs');
+ if ($settings['unrestricted_auth'] == 'on') {
+ // Even the unrestricted hosts should authenticate
+ $password = array_merge($password, $passwordless);
+ $passwordless = array();
+ }
+ $passwordless[] = 'noauth';
+ $password = array_filter($password, 'squid_is_valid_acl');
+ $passwordless = array_filter($passwordless, 'squid_is_valid_acl');
+
+ // Allow the ACLs that don't need to authenticate
+ foreach ($passwordless as $acl)
+ $conf .= "http_access allow $acl\n";
+
+ // Allow the other ACLs as long as they authenticate
+ foreach ($password as $acl)
+ $conf .= "http_access allow password $acl\n";
+ }
+
+
+ $conf .= "http_access deny all\n";
+
+ return $conf;
+}
+
+function squid_resync_users() {
+ global $config;
+
+ $users = $config['installedpackages']['squidusers']['config'];
+ $contents = '';
+ if (is_array($users)) {
+ foreach ($users as $user)
+ $contents .= $user['username'] . ':' . crypt($user['password'], base64_encode($user['password'])) . "\n";
+ }
+ file_put_contents(SQUID_PASSWD, $contents);
+ chown(SQUID_PASSWD, 'proxy');
+ chmod(SQUID_PASSWD, 0600);
+}
+
+function squid_resync() {
+ $conf = squid_resync_general() . "\n";
+ $conf .= squid_resync_cache() . "\n";
+ $conf .= squid_resync_redirector() . "\n";
+ $conf .= squid_resync_upstream() . "\n";
+ $conf .= squid_resync_nac() . "\n";
+ $conf .= squid_resync_traffic() . "\n";
+ $conf .= squid_resync_auth();
+ squid_resync_users();
+
+ file_put_contents(SQUID_CONFBASE . '/squid.conf', $conf);
+
+ if (!is_dir(SQUID_CACHEDIR)) {
+ log_error(SQUID_CACHEDIR . ' does not exist. Creating.');
+ mwexec('/usr/local/sbin/squid -z');
+ }
+
+ restart_service('squid');
+ sleep(1);
+ restart_service('proxy_monitor');
+
+ filter_configure();
+}
+
+function squid_print_javascript_auth() {
+ global $config;
+ $transparent_proxy = $config['installedpackages']['squid']['config'][0]['transparent_proxy'] == 'on';
+
+ // No authentication for transparent proxy
+ if ($transparent_proxy) {
+ $javascript = <<<EOD
+<script language="JavaScript">
+<!--
+function on_auth_method_changed() {
+ document.iform.auth_method.disabled = 1;
+ document.iform.auth_server.disabled = 1;
+ document.iform.auth_server_port.disabled = 1;
+ document.iform.ldap_user.disabled = 1;
+ document.iform.ldap_password.disabled = 1;
+ document.iform.ldap_basedn.disabled = 1;
+ document.iform.ldap_filter.disabled = 1;
+ document.iform.radius_secret.disabled = 1;
+ document.iform.msnt_bdc.disabled = 1;
+ document.iform.msnt_domain.disabled = 1;
+ document.iform.auth_prompt.disabled = 1;
+ document.iform.auth_processes.disabled = 1;
+ document.iform.auth_ttl.disabled = 1;
+ document.iform.unrestricted_auth.disabled = 1;
+ document.iform.no_auth_hosts.disabled = 1;
+}
+-->
+</script>
+
+EOD;
+ }
+ else {
+ $javascript = <<<EOD
+<script language="JavaScript">
+<!--
+function on_auth_method_changed() {
+ var field = document.iform.auth_method;
+ var auth_method = field.options[field.selectedIndex].value;
+
+ if (auth_method == 'none') {
+ document.iform.auth_server.disabled = 1;
+ document.iform.auth_server_port.disabled = 1;
+ document.iform.ldap_user.disabled = 1;
+ document.iform.ldap_password.disabled = 1;
+ document.iform.ldap_basedn.disabled = 1;
+ document.iform.ldap_filter.disabled = 1;
+ document.iform.radius_secret.disabled = 1;
+ document.iform.msnt_bdc.disabled = 1;
+ document.iform.msnt_domain.disabled = 1;
+ document.iform.auth_prompt.disabled = 1;
+ document.iform.auth_processes.disabled = 1;
+ document.iform.auth_ttl.disabled = 1;
+ document.iform.unrestricted_auth.disabled = 1;
+ document.iform.no_auth_hosts.disabled = 1;
+ }
+ else {
+ document.iform.auth_prompt.disabled = 0;
+ document.iform.auth_processes.disabled = 0;
+ document.iform.auth_ttl.disabled = 0;
+ document.iform.unrestricted_auth.disabled = 0;
+ document.iform.no_auth_hosts.disabled = 0;
+ }
+
+ switch (auth_method) {
+ case 'local':
+ document.iform.auth_server.disabled = 1;
+ document.iform.auth_server_port.disabled = 1;
+ document.iform.ldap_user.disabled = 1;
+ document.iform.ldap_password.disabled = 1;
+ document.iform.ldap_basedn.disabled = 1;
+ document.iform.ldap_filter.disabled = 1;
+ document.iform.radius_secret.disabled = 1;
+ document.iform.msnt_bdc.disabled = 1;
+ document.iform.msnt_domain.disabled = 1;
+ break;
+ case 'ldap':
+ document.iform.auth_server.disabled = 0;
+ document.iform.auth_server_port.disabled = 0;
+ document.iform.ldap_user.disabled = 0;
+ document.iform.ldap_password.disabled = 0;
+ document.iform.ldap_basedn.disabled = 0;
+ document.iform.ldap_filter.disabled = 0;
+ document.iform.radius_secret.disabled = 1;
+ document.iform.msnt_bdc.disabled = 1;
+ document.iform.msnt_domain.disabled = 1;
+ break;
+ case 'radius':
+ document.iform.auth_server.disabled = 0;
+ document.iform.auth_server_port.disabled = 0;
+ document.iform.ldap_user.disabled = 1;
+ document.iform.ldap_password.disabled = 1;
+ document.iform.ldap_basedn.disabled = 1;
+ document.iform.ldap_filter.disabled = 1;
+ document.iform.radius_secret.disabled = 0;
+ document.iform.msnt_bdc.disabled = 1;
+ document.iform.msnt_domain.disabled = 1;
+ break;
+ case 'msnt':
+ document.iform.auth_server.disabled = 0;
+ document.iform.auth_server_port.disabled = 1;
+ document.iform.ldap_user.disabled = 1;
+ document.iform.ldap_password.disabled = 1;
+ document.iform.ldap_basedn.disabled = 1;
+ document.iform.ldap_filter.disabled = 1;
+ document.iform.radius_secret.disabled = 1;
+ document.iform.msnt_bdc.disabled = 0;
+ document.iform.msnt_domain.disabled = 0;
+ break;
+ }
+}
+-->
+</script>
+
+EOD;
+ }
+
+ print($javascript);
+}
+
+function squid_print_javascript_auth2() {
+ print("<script language=\"JavaScript\">on_auth_method_changed()</script>\n");
+}
+
+function squid_generate_rules($type) {
+ global $config;
+
+ $squid_conf = $config['installedpackages']['squid']['config'][0];
+ if (!is_service_running('squid') || ($squid_conf['transparent_proxy'] != 'on')) {
+ log_error('Squid is installed but not started. Not installing redirect rules.');
+ return;
+ }
+
+ $port = isset($squid_conf['proxy_port']) ? $squid_conf['proxy_port'] : 3128;
+ $ifaces = explode(',', $squid_conf['active_interface']);
+ $ifaces = array_map('convert_friendly_interface_to_real_interface_name', $ifaces);
+
+ switch($type) {
+ case 'nat':
+ foreach ($ifaces as $iface)
+ $rules .= "rdr on $iface inet proto tcp from any to !($iface) port 80 -> ($iface) port $port\n";
+ break;
+ case 'filter':
+ foreach ($ifaces as $iface)
+ $rules .= "pass quick on $iface inet proto tcp from any to !($iface) port 80 flags S/SA keep state\n";
+ break;
+ }
+
+ return $rules;
+}
+?>
diff --git a/packages/squid-head/squid.xml b/packages/squid-head/squid.xml
new file mode 100644
index 00000000..f538f65c
--- /dev/null
+++ b/packages/squid-head/squid.xml
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packagegui>
+ <include_file>squid.inc</include_file>
+
+ <!-- Installation -->
+ <additional_files_needed>
+ <item>http://www.pfsense.org/packages/config/squid.inc</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <item>http://www.pfsense.org/packages/config/squid_cache.xml</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <item>http://www.pfsense.org/packages/config/squid_nac.xml</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <item>http://www.pfsense.org/packages/config/squid_traffic.xml</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <item>http://www.pfsense.org/packages/config/squid_upstream.xml</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <item>http://www.pfsense.org/packages/config/squid_auth.xml</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <item>http://www.pfsense.org/packages/config/squid_users.xml</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <item>http://www.pfsense.org/packages/All/squid_monitor.sh</item>
+ <prefix>/usr/local/bin/</prefix>
+ <chmod>0755</chmod>
+ </additional_files_needed>
+ <custom_php_install_command>
+ squid_install_command();
+ </custom_php_install_command>
+ <custom_php_deinstall_command>
+ squid_deinstall_command();
+ </custom_php_deinstall_command>
+ <menu>
+ <name>Web proxy cache</name>
+ <tooltiptext>Modify the web proxy cache's settings</tooltiptext>
+ <section>Services</section>
+ <url>/pkg_edit.php?xml=squid.xml&amp;id=0</url>
+ </menu>
+ <service>
+ <name>Squid</name>
+ <description>Web proxy cache.</description>
+ <rcfile>squid.sh</rcfile>
+ <executable>squid</executable>
+ </service>
+
+ <!-- Interface -->
+ <name>squid</name>
+ <title>Proxy server: General settings</title>
+ <tabs>
+ <tab>
+ <text>General settings</text>
+ <url>/pkg_edit.php?xml=squid.xml&amp;id=0</url>
+ <active/>
+ </tab>
+ <tab>
+ <text>Upstream proxy</text>
+ <url>/pkg_edit.php?xml=squid_upstream.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Cache management</text>
+ <url>/pkg_edit.php?xml=squid_cache.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Access control</text>
+ <url>/pkg_edit.php?xml=squid_nac.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Traffic management</text>
+ <url>/pkg_edit.php?xml=squid_traffic.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Auth settings</text>
+ <url>/pkg_edit.php?xml=squid_auth.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Local users</text>
+ <url>/pkg.php?xml=squid_users.xml</url>
+ </tab>
+ </tabs>
+ <fields>
+ <field>
+ <fieldname>active_interface</fieldname>
+ <fielddescr>Proxy interface</fielddescr>
+ <description>The interface(s) the proxy server will bind to.</description>
+ <default_value>lan</default_value>
+ <required/>
+ <type>interfaces_selection</type>
+ <multiple/>
+ </field>
+ <field>
+ <fieldname>allow_interface</fieldname>
+ <fielddescr>Allow users on interface</fielddescr>
+ <description>If this field is checked, the users connected to the interface selected in the 'Proxy interface' field will be allowed to use the proxy, i.e., there will be no need to add the interface's subnet to the list of allowed subnets. This is just a shortcut.</description>
+ <default_value>on</default_value>
+ <required/>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <fieldname>transparent_proxy</fieldname>
+ <fielddescr>Transparent proxy</fielddescr>
+ <description>If transparent mode is enabled, all requests for destination port 80 will be forwarded to the proxy server without any additional configuration necessary.</description>
+ <required/>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <fieldname>log_enabled</fieldname>
+ <fielddescr>Enabled logging</fielddescr>
+ <description>This will enable the access log. Don't switch this on if you don't have much disk space left.</description>
+ <enablefields>log_query_terms,log_user_agents</enablefields>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <fieldname>proxy_port</fieldname>
+ <fielddescr>Proxy port</fielddescr>
+ <description>This is the port the proxy server will listen on.</description>
+ <required/>
+ <type>input</type>
+ <size>5</size>
+ <default_value>3128</default_value>
+ </field>
+ <field>
+ <fieldname>icp_port</fieldname>
+ <fielddescr>ICP port</fielddescr>
+ <description>This is the port the proxy server will send and receive ICP queries to and from neighbor caches. Leave this blank if you don't want the proxy server to communicate with neighbor caches through ICP.</description>
+ <type>input</type>
+ <size>5</size>
+ </field>
+ <field>
+ <fieldname>visible_hostname</fieldname>
+ <fielddescr>Visible hostname</fielddescr>
+ <description>This is the hostname to be displayed in proxy server error messages.</description>
+ <default_value>localhost</default_value>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>admin_email</fieldname>
+ <fielddescr>Administrator email</fielddescr>
+ <description>This is the email address displayed in error messages to the users.</description>
+ <default_value>admin@localhost</default_value>
+ <type>input</type>
+ </field>
+ <field>
+ <fielddescr>Language</fielddescr>
+ <fieldname>error_language</fieldname>
+ <description>Select the language in which the proxy server will display error messages to users.</description>
+ <default_value>English</default_value>
+ <type>select</type>
+ </field>
+ <field>
+ <fielddescr>Redirect children</fielddescr>
+ <fieldname>redirect_children</fieldname>
+ <description>Specify the number of redirectors to spawn (if using redirectors at all) when launching Squid. If you leave this field blank, Squid will start 5 redirector processes. If your network load is high, feel free to increase this value (at the expense of a higher memory consumption).</description>
+ <default_value>5</default_value>
+ <type>input</type>
+ </field>
+ </fields>
+ <custom_php_command_before_form>
+ squid_before_form_general(&amp;$pkg);
+ </custom_php_command_before_form>
+ <custom_php_validation_command>
+ squid_validate_general($_POST, &amp;$input_errors);
+ </custom_php_validation_command>
+<custom_php_resync_config_command>
+ squid_resync();
+ </custom_php_resync_config_command>
+</packagegui>
diff --git a/packages/squid-head/squid_auth.xml b/packages/squid-head/squid_auth.xml
new file mode 100644
index 00000000..b11d77a5
--- /dev/null
+++ b/packages/squid-head/squid_auth.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packagegui>
+ <include_file>squid.inc</include_file>
+ <name>squidauth</name>
+ <title>Proxy server: Authentication</title>
+ <tabs>
+ <tab>
+ <text>General settings</text>
+ <url>/pkg_edit.php?xml=squid.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Upstream proxy</text>
+ <url>/pkg_edit.php?xml=squid_upstream.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Cache management</text>
+ <url>/pkg_edit.php?xml=squid_cache.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Access control</text>
+ <url>/pkg_edit.php?xml=squid_nac.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Traffic management</text>
+ <url>/pkg_edit.php?xml=squid_traffic.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Auth settings</text>
+ <url>/pkg_edit.php?xml=squid_auth.xml&amp;id=0</url>
+ <active/>
+ </tab>
+ <tab>
+ <text>Local users</text>
+ <url>/pkg.php?xml=squid_users.xml</url>
+ </tab>
+ </tabs>
+ <fields>
+ <field>
+ <fielddescr>Authentication method</fielddescr>
+ <fieldname>auth_method</fieldname>
+ <description>Select an authentication method. This will allow users to be authenticated by local or external services.</description>
+ <default_value>none</default_value>
+ <type>select</type>
+ <options>
+ <option><name>None</name><value>none</value></option>
+ <option><name>Local</name><value>local</value></option>
+ <option><name>LDAP</name><value>ldap</value></option>
+ <option><name>RADIUS</name><value>radius</value></option>
+ <option><name>NT domain</name><value>msnt</value></option>
+ </options>
+ <onchange>on_auth_method_changed()</onchange>
+ </field>
+ <field>
+ <fieldname>auth_server</fieldname>
+ <fielddescr>Authentication server</fielddescr>
+ <description>Enter here the IP or hostname of the server that will perform the authentication. For NT domain authentication, this is the Primary Domain Controller (PDC).</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>auth_server_port</fieldname>
+ <fielddescr>Authentication server port</fielddescr>
+ <description>Enter here the port to use to connect to the authentication server. Leave this field blank to use the authentication method's default port.</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>ldap_user</fieldname>
+ <fielddescr>LDAP server user DN</fielddescr>
+ <description>Enter here the user distinguished name (DN) to bind to connect to the LDAP server (e.g., "cn=Administrator,cn=Users,dc=foobar,dc=com"). You can leave this field blank if you don't want to use authentication.</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>ldap_password</fieldname>
+ <fielddescr>LDAP password</fielddescr>
+ <description>Enter here the password to use to connect to the LDAP server. You may leave this field unfilled.</description>
+ <type>password</type>
+ </field>
+ <field>
+ <fieldname>ldap_basedn</fieldname>
+ <fielddescr>LDAP base DN</fielddescr>
+ <description>For LDAP authentication, enter here the base DN for the search (e.g., "cn=Users,dc=foobar,dc=com").</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>ldap_filter</fieldname>
+ <fielddescr>LDAP filter</fielddescr>
+ <description>Enter the string to be used to filter the results of the search, or leave this blank to get the results unfiltered. This must be in compliance with RFC 2254, and ocurrences of the string "%s" will be set to the username given to the proxy. You generally want something like '(sAMAccountName=%s)' here.</description>
+ <type>input</type>
+ <default_value>(sAMAccountName=%s)</default_value>
+ </field>
+ <field>
+ <fieldname>radius_secret</fieldname>
+ <fielddescr>RADIUS secret</fielddescr>
+ <description>The RADIUS secret for RADIUS authentication.</description>
+ <type>password</type>
+ </field>
+ <field>
+ <fieldname>msnt_bdc</fieldname>
+ <fielddescr>Backup Domain Controller</fielddescr>
+ <description>Enter the address of the Backup Domain Controller (BDC) or leave this field blank if you don't want to use a backup controller.</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>msnt_domain</fieldname>
+ <fielddescr>NT domain</fielddescr>
+ <description>Enter the NT domain to be used.</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>auth_prompt</fieldname>
+ <fielddescr>Authentication prompt</fielddescr>
+ <description>This string will be displayed at the top of the authentication request window.</description>
+ <default_value>Please enter your credentials to access the proxy</default_value>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>auth_processes</fieldname>
+ <fielddescr>Authentication processes</fielddescr>
+ <description>The number of authenticator processes to spawn. If many authentications are expected within a short timeframe, increase this number accordingly.</description>
+ <default_value>5</default_value>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>auth_ttl</fieldname>
+ <fielddescr>Authentication TTL</fielddescr>
+ <description>This specifies for how long (in minutes) the proxy server assumes an externally validated username and password combination is valid (Time To Live). When the TTL expires, the user will be prompted for credentials again.</description>
+ <default_value>60</default_value>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>unrestricted_auth</fieldname>
+ <fielddescr>Requiere authentication for unrestricted hosts</fielddescr>
+ <description>If this option is enabled, even users tagged as unrestricted through access control are required to authenticate to use the proxy.</description>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <fieldname>no_auth_hosts</fieldname>
+ <fielddescr>Subnets that don't need authentication</fielddescr>
+ <description>A comma-separated list of subnets (in CIDR range, e.g.: 10.5.0.0/16, 192.168.1.50/32) whose hosts won't be asked for authentication to access the proxy.</description>
+ <type>textarea</type>
+ <rows>5</rows>
+ <cols>50</cols>
+ </field>
+ </fields>
+ <custom_php_after_head_command>
+ squid_print_javascript_auth();
+ </custom_php_after_head_command>
+ <custom_php_validation_command>
+ squid_validate_auth($_POST, &amp;$input_errors);
+ </custom_php_validation_command>
+ <custom_php_after_form_command>
+ squid_print_javascript_auth2();
+ </custom_php_after_form_command>
+ <custom_php_resync_config_command>
+ squid_resync();
+ </custom_php_resync_config_command>
+</packagegui>
diff --git a/packages/squid-head/squid_cache.xml b/packages/squid-head/squid_cache.xml
new file mode 100644
index 00000000..057b35cf
--- /dev/null
+++ b/packages/squid-head/squid_cache.xml
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packagegui>
+ <include_file>squid.inc</include_file>
+ <name>squidcache</name>
+ <title>Proxy server: Cache management</title>
+ <tabs>
+ <tab>
+ <text>General settings</text>
+ <url>/pkg_edit.php?xml=squid.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Upstream proxy</text>
+ <url>/pkg_edit.php?xml=squid_upstream.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Cache management</text>
+ <url>/pkg_edit.php?xml=squid_cache.xml&amp;id=0</url>
+ <active/>
+ </tab>
+ <tab>
+ <text>Access control</text>
+ <url>/pkg_edit.php?xml=squid_nac.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Traffic management</text>
+ <url>/pkg_edit.php?xml=squid_traffic.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Auth settings</text>
+ <url>/pkg_edit.php?xml=squid_auth.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Local users</text>
+ <url>/pkg.php?xml=squid_users.xml</url>
+ </tab>
+ </tabs>
+ <fields>
+ <field>
+ <fielddescr>Hard disk cache size</fielddescr>
+ <fieldname>harddisk_cache_size</fieldname>
+ <description>This is the amount of disk space (in megabytes) to use for cached objects.</description>
+ <required/>
+ <default_value>100</default_value>
+ <type>input</type>
+ </field>
+ <field>
+ <fielddescr>Memory cache size</fielddescr>
+ <fieldname>memory_cache_size</fieldname>
+ <description>This is the amount of physical RAM (in megabytes) to be used for negative cache and in-transit objects. This value should not exceed more than 50% of the installed RAM. The minimum value is 1MB.</description>
+ <required/>
+ <default_value>8</default_value>
+ <type>input</type>
+ </field>
+ <field>
+ <fielddescr>Minimum object size</fielddescr>
+ <fieldname>minimum_object_size</fieldname>
+ <description>Objects smaller than the size specified (in kilobytes) will not be saved on disk. The default value is 0, meaning there is no minimum.</description>
+ <required/>
+ <default_value>0</default_value>
+ <type>input</type>
+ </field>
+ <field>
+ <fielddescr>Maximum object size</fielddescr>
+ <fieldname>maximum_object_size</fieldname>
+ <description>Objects larger than the size specified (in kilobytes) will not be saved on disk. If you wish to increase speed more than you want to save bandwidth, this should be set to a low value.</description>
+ <required/>
+ <default_value>4</default_value>
+ <type>input</type>
+ </field>
+ <field>
+ <fielddescr>Level 1 subdirectories</fielddescr>
+ <fieldname>level1_subdirs</fieldname>
+ <description>Each level 1 (L1) directory contains 256 subdirectories, so a value of 256 L1 directories will use a total of 65536 directories for the hard disk cache. This will significantly slow down the startup process of the proxy service, but can speed up the caching under certain conditions.</description>
+ <default_value>16</default_value>
+ <type>select</type>
+ <options>
+ <option><name>4</name><value>4</value></option>
+ <option><name>8</name><value>8</value></option>
+ <option><name>16</name><value>16</value></option>
+ <option><name>32</name><value>32</value></option>
+ <option><name>64</name><value>64</value></option>
+ <option><name>128</name><value>128</value></option>
+ <option><name>256</name><value>256</value></option>
+ </options>
+ </field>
+ <field>
+ <fielddescr>Memory replacement policy</fielddescr>
+ <fieldname>memory_replacement</fieldname>
+ <description>The memory replacement policy determines which objects are purged from memory when space is needed. The default policy for memory replacement is GSDF.</description>
+ <default_value>heap GSDF</default_value>
+ <type>select</type>
+ <options>
+ <option><name>LRU</name><value>LRU</value></option>
+ <option><name>Heap LRU</name><value>heap LRU</value></option>
+ <option><name>Heap LFUDA</name><value>heap LFUDA</value></option>
+ <option><name>Heap GDSF</name><value>heap GSDF</value></option>
+ </options>
+ </field>
+ <field>
+ <fielddescr>Cache replacement policy</fielddescr>
+ <fieldname>cache_replacement</fieldname>
+ <description>The cache replacement policy decides which objects will remain in cache and which objects are replaced to create space for the new objects. The default policy for cache replacement is LFUDA.</description>
+ <default_value>heap LFUDA</default_value>
+ <type>select</type>
+ <options>
+ <option><name>LRU</name><value>lru</value></option>
+ <option><name>Heap LRU</name><value>heap LRU</value></option>
+ <option><name>Heap LFUDA</name><value>heap LFUDA</value></option>
+ <option><name>Heap GDSF</name><value>heap GSDF</value></option>
+ </options>
+ </field>
+ <field>
+ <fielddescr>Do not cache</fielddescr>
+ <fieldname>donotcache</fieldname>
+ <description>The specified domains or IP addresses (separated by commas) will never be cached.</description>
+ <type>textarea</type>
+ <rows>5</rows>
+ <cols>50</cols>
+ </field>
+ <field>
+ <fielddescr>Enable offline mode</fielddescr>
+ <fieldname>enable_offline</fieldname>
+ <description>Enable this option and the proxy server will never try to validate cached objects. The offline mode also gives access to more cached information than the proposed feature would allow (stale cached versions, where the origin server should have been contacted).</description>
+ <required/>
+ <type>checkbox</type>
+ </field>
+ </fields>
+ <custom_php_validation_command>
+ squid_validate_cache($_POST, &amp;$input_errors);
+ </custom_php_validation_command>
+ <custom_php_resync_config_command>
+ squid_resync();
+ </custom_php_resync_config_command>
+</packagegui>
diff --git a/packages/squid-head/squid_monitor.sh b/packages/squid-head/squid_monitor.sh
new file mode 100644
index 00000000..62ce7bc7
--- /dev/null
+++ b/packages/squid-head/squid_monitor.sh
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+# Squid monitor 1.0
+# Written for pfSense's Squid Package
+# by Scott Ullrich
+#
+# This file is released under the BSD style
+#
+
+set -e
+
+LOOP_SLEEP=5
+
+if [ -f /var/run/squid_alarm ]; then
+rm /var/run/squid_alarm
+fi
+
+# Squid monitor 1.0
+while [ /bin/true ]; do
+ if [ ! -f /var/run/squid_alarm ]; then
+ NUM_PROCS=`ps awux | grep "squid -D" | grep -v "grep" | wc -l | awk '{ print $1 }'`
+ if [ $NUM_PROCS -lt 1 ]; then
+ # squid is down
+ echo "Squid has exited. Reconfiguring filter." | \
+ logger -p daemon.info -i -t Squid_Alarm
+ echo "Attempting restart..." | logger -p daemon.info -i -t Squid_Alarm
+ /usr/local/etc/rc.d/squid.sh start
+ sleep 3
+ echo "Reconfiguring filter..." | logger -p daemon.info -i -t Squid_Alarm
+ /etc/rc.filter_configure
+ touch /var/run/squid_alarm
+ fi
+ fi
+ NUM_PROCS=`ps awux | grep "squid -D" | grep -v "grep" | wc -l | awk '{ print $1 }'`
+ if [ $NUM_PROCS -gt 0 ]; then
+ if [ -f /var/run/squid_alarm ]; then
+ echo "Squid has resumed. Reconfiguring filter." | \
+ logger -p daemon.info -i -t Squid_Alarm
+/etc/rc.filter_configure
+ rm /var/run/squid_alarm
+ fi
+ fi
+ sleep $LOOP_SLEEP
+done
diff --git a/packages/squid-head/squid_nac.xml b/packages/squid-head/squid_nac.xml
new file mode 100644
index 00000000..b7bbf8c9
--- /dev/null
+++ b/packages/squid-head/squid_nac.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packagegui>
+ <include_file>squid.inc</include_file>
+ <name>squidnac</name>
+ <title>Proxy server: Access control</title>
+ <tabs>
+ <tab>
+ <text>General settings</text>
+ <url>/pkg_edit.php?xml=squid.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Upstream proxy</text>
+ <url>/pkg_edit.php?xml=squid_upstream.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Cache management</text>
+ <url>/pkg_edit.php?xml=squid_cache.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Access control</text>
+ <url>/pkg_edit.php?xml=squid_nac.xml&amp;id=0</url>
+ <active/>
+ </tab>
+ <tab>
+ <text>Traffic management</text>
+ <url>/pkg_edit.php?xml=squid_traffic.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Auth settings</text>
+ <url>/pkg_edit.php?xml=squid_auth.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Local users</text>
+ <url>/pkg.php?xml=squid_users.xml</url>
+ </tab>
+ </tabs>
+ <fields>
+ <field>
+ <fieldname>allowed_subnets</fieldname>
+ <fielddescr>Allowed subnets</fielddescr>
+ <description>Those are the subnets (separated by commas) that are allowed to use the proxy. The subnets must be expressed as CIDR ranges (e.g.: 192.168.1.0/24). Note that the proxy interface subnet is already an allowed subnet. All the other subnets won't be able to use the proxy.</description>
+ <type>textarea</type>
+ <rows>5</rows>
+ <cols>50</cols>
+ </field>
+ <field>
+ <fieldname>unrestricted_hosts</fieldname>
+ <fielddescr>Unrestricted IPs</fielddescr>
+ <description>The IP addresses specified here (separated by commas) won't be filtered out by the other access control directives set in this page.</description>
+ <type>textarea</type>
+ <rows>5</rows>
+ <cols>50</cols>
+ </field>
+ <field>
+ <fieldname>unrestricted_macs</fieldname>
+ <fielddescr>Unrestricted MAC Addresses</fielddescr>
+ <description>The MAC addresses specified here (separated by commas) won't be filtered out by the other access control directives set in this page.</description>
+ <type>textarea</type>
+ <rows>5</rows>
+ <cols>50</cols>
+ </field>
+ <field>
+ <fieldname>banned_hosts</fieldname>
+ <fielddescr>Banned host addresses</fielddescr>
+ <description>The IP addresses specified here (separated by commas) won't be allowed to use the proxy.</description>
+ <type>textarea</type>
+ <rows>5</rows>
+ <cols>50</cols>
+ </field>
+ <field>
+ <fieldname>banned_macs</fieldname>
+ <fielddescr>Banned MAC addresses</fielddescr>
+ <description>The MAC addresses specified here (separated by commas) won't be allowed to use the proxy.</description>
+ <type>textarea</type>
+ <rows>5</rows>
+ <cols>50</cols>
+ </field>
+ <field>
+ <fieldname>whitelist</fieldname>
+ <fielddescr>Whitelist</fielddescr>
+ <description>Those are the sites (separated by commas) that will be accessable to the users that are allowed to use the proxy.</description>
+ <type>textarea</type>
+ <rows>5</rows>
+ <cols>50</cols>
+ </field>
+ <field>
+ <fieldname>blacklist</fieldname>
+ <fielddescr>Blacklist</fielddescr>
+ <description>Those are the sites (separated by commas) that will be blocked to the users that are allowed to use the proxy.</description>
+ <type>textarea</type>
+ <rows>5</rows>
+ <cols>50</cols>
+ </field>
+ </fields>
+ <custom_php_validation_command>
+ squid_validate_nac($_POST, &amp;$input_errors);
+ </custom_php_validation_command>
+ <custom_php_resync_config_command>
+ squid_resync();
+ </custom_php_resync_config_command>
+</packagegui>
diff --git a/packages/squid-head/squid_traffic.xml b/packages/squid-head/squid_traffic.xml
new file mode 100644
index 00000000..f9ebcf5c
--- /dev/null
+++ b/packages/squid-head/squid_traffic.xml
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packagegui>
+ <include_file>squid.inc</include_file>
+ <name>squidtraffic</name>
+ <title>Proxy server: Traffic management</title>
+ <tabs>
+ <tab>
+ <text>General settings</text>
+ <url>/pkg_edit.php?xml=squid.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Upstream proxy</text>
+ <url>/pkg_edit.php?xml=squid_upstream.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Cache management</text>
+ <url>/pkg_edit.php?xml=squid_cache.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Access control</text>
+ <url>/pkg_edit.php?xml=squid_nac.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Traffic management</text>
+ <url>/pkg_edit.php?xml=squid_traffic.xml&amp;id=0</url>
+ <active/>
+ </tab>
+ <tab>
+ <text>Auth settings</text>
+ <url>/pkg_edit.php?xml=squid_auth.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Local users</text>
+ <url>/pkg.php?xml=squid_users.xml</url>
+ </tab>
+ </tabs>
+ <fields>
+ <field>
+ <fieldname>max_download_size</fieldname>
+ <fielddescr>Maximum download size</fielddescr>
+ <description>Limit the maximum total download size to the size specified here (in kilobytes). Set to 0 to disable.</description>
+ <default_value>0</default_value>
+ <required/>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>max_upload_size</fieldname>
+ <fielddescr>Maximum upload size</fielddescr>
+ <description>Limit the maximum total upload size to the size specified here (in kilobytes). Set to 0 to disable.</description>
+ <default_value>0</default_value>
+ <required/>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>overall_throttling</fieldname>
+ <fielddescr>Overall bandwidth throttling</fielddescr>
+ <description>This value specifies (in kilobytes per second) the bandwidth throttle for downloads. Users will gradually have their download speed increased according to this value. Set to 0 to disable bandwidth throttling.</description>
+ <default_value>0</default_value>
+ <required/>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>perhost_throttling</fieldname>
+ <fielddescr>Per-host throttling</fielddescr>
+ <description>This value specifies the download throttling per host. Set to 0 to disable this.</description>
+ <default_value>0</default_value>
+ <required/>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>throttle_specific</fieldname>
+ <fielddescr>Throttle only specific extensions</fielddescr>
+ <description>Leave this checked to be able to choose the extensions that throttling will be applied to. Otherwise, all files will be throttled.</description>
+ <default_value>on</default_value>
+ <type>checkbox</type>
+ <enablefields>throttle_binaries,throttle_cdimages,throttle_multimedia,throttle_others</enablefields>
+ </field>
+ <field>
+ <fieldname>throttle_binaries</fieldname>
+ <fielddescr>Throttle binary files</fielddescr>
+ <description>Check this to apply bandwidth throttle to binary files. This includes compressed archives and executables.</description>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <fieldname>throttle_cdimages</fieldname>
+ <fielddescr>Throttle CD images</fielddescr>
+ <description>Check this to apply bandwidth throttle to CD image files.</description>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <fieldname>throttle_multimedia</fieldname>
+ <fielddescr>Throttle multimedia files</fielddescr>
+ <description>Check this to apply bandwidth throttle to multimedia files, such as movies or songs.</description>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <fieldname>throttle_others</fieldname>
+ <fielddescr>Throttle other extensions</fielddescr>
+ <description>Comma-separated list of extensions to apply bandwidth throttle to.</description>
+ <type>input</type>
+ </field>
+ </fields>
+ <custom_php_validation_command>
+ squid_validate_traffic($_POST, &amp;$input_errors);
+ </custom_php_validation_command>
+ <custom_php_resync_config_command>
+ squid_resync();
+ </custom_php_resync_config_command>
+</packagegui>
diff --git a/packages/squid-head/squid_upstream.xml b/packages/squid-head/squid_upstream.xml
new file mode 100644
index 00000000..7954bc7f
--- /dev/null
+++ b/packages/squid-head/squid_upstream.xml
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packagegui>
+ <include_file>squid.inc</include_file>
+ <name>squidupstream</name>
+ <title>Proxy server: Upstream proxy settings</title>
+ <tabs>
+ <tab>
+ <text>General settings</text>
+ <url>/pkg_edit.php?xml=squid.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Upstream proxy</text>
+ <url>/pkg_edit.php?xml=squid_upstream.xml&amp;id=0</url>
+ <active/>
+ </tab>
+ <tab>
+ <text>Cache management</text>
+ <url>/pkg_edit.php?xml=squid_cache.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Access control</text>
+ <url>/pkg_edit.php?xml=squid_nac.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Traffic management</text>
+ <url>/pkg_edit.php?xml=squid_traffic.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Auth settings</text>
+ <url>/pkg_edit.php?xml=squid_auth.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Local users</text>
+ <url>/pkg.php?xml=squid_users.xml</url>
+ </tab>
+ </tabs>
+ <fields>
+ <field>
+ <fielddescr>Enable forwarding</fielddescr>
+ <fieldname>proxy_forwarding</fieldname>
+ <description>This option enables the proxy server to forward requests to an upstream server.</description>
+ <required/>
+ <type>checkbox</type>
+ <enablefields>proxy_addr,proxy_port,icp_port,username,password</enablefields>
+ </field>
+ <field>
+ <fielddescr>Hostname</fielddescr>
+ <fieldname>proxy_addr</fieldname>
+ <description>Enter here the IP address or host name of the upstream proxy.</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fielddescr>TCP port</fielddescr>
+ <fieldname>proxy_port</fieldname>
+ <description>Enter the port to use to connect to the upstream proxy.</description>
+ <default_value>3128</default_value>
+ <type>input</type>
+ <size>5</size>
+ </field>
+ <field>
+ <fielddescr>ICP port</fielddescr>
+ <fieldname>icp_port</fieldname>
+ <description>Enter the port to connect to the upstream proxy for the ICP protocol. Use port number 7 to disable ICP communication between the proxies.</description>
+ <default_value>7</default_value>
+ <type>input</type>
+ <size>5</size>
+ </field>
+ <field>
+ <fielddescr>Username</fielddescr>
+ <fieldname>username</fieldname>
+ <description>If the upstream proxy requires a username, specify it here.</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fielddescr>Password</fielddescr>
+ <fieldname>password</fieldname>
+ <description>If the upstream proxy requires a password, specify it here.</description>
+ <type>password</type>
+ </field>
+ </fields>
+ <custom_php_validation_command>
+ squid_validate_upstream($_POST, &amp;$input_errors);
+ </custom_php_validation_command>
+ <custom_php_resync_config_command>
+ squid_resync();
+ </custom_php_resync_config_command>
+</packagegui>
diff --git a/packages/squid-head/squid_users.xml b/packages/squid-head/squid_users.xml
new file mode 100644
index 00000000..89989cde
--- /dev/null
+++ b/packages/squid-head/squid_users.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packagegui>
+ <include_file>squid.inc</include_file>
+ <name>squidusers</name>
+ <title>Proxy server: Local users</title>
+ <delete_string>A proxy server user has been deleted.</delete_string>
+ <addedit_string>A proxy server user has been created/modified.</addedit_string>
+ <tabs>
+ <tab>
+ <text>General settings</text>
+ <url>/pkg_edit.php?xml=squid.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Upstream proxy</text>
+ <url>/pkg_edit.php?xml=squid_upstream.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Cache management</text>
+ <url>/pkg_edit.php?xml=squid_cache.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Access control</text>
+ <url>/pkg_edit.php?xml=squid_nac.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Traffic management</text>
+ <url>/pkg_edit.php?xml=squid_traffic.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Auth settings</text>
+ <url>/pkg_edit.php?xml=squid_auth.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Local users</text>
+ <url>/pkg.php?xml=squid_users.xml</url>
+ <active/>
+ </tab>
+ </tabs>
+ <adddeleteeditpagefields>
+ <columnitem>
+ <fieldname>username</fieldname>
+ <fielddescr>Username</fielddescr>
+ </columnitem>
+ <columnitem>
+ <fieldname>description</fieldname>
+ <fielddescr>Description</fielddescr>
+ </columnitem>
+ </adddeleteeditpagefields>
+ <fields>
+ <field>
+ <fieldname>username</fieldname>
+ <fielddescr>Username</fielddescr>
+ <description>Enter the username here.</description>
+ <required/>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>password</fieldname>
+ <fielddescr>Password</fielddescr>
+ <description>Enter the password here.</description>
+ <required/>
+ <type>password</type>
+ </field>
+ <field>
+ <fieldname>description</fieldname>
+ <fielddescr>Description</fielddescr>
+ <description>You may enter a description here for your reference (not parsed).</description>
+ <type>input</type>
+ </field>
+ </fields>
+ <custom_php_resync_config_command>
+ squid_resync_users();
+ </custom_php_resync_config_command>
+</packagegui>