aboutsummaryrefslogtreecommitdiffstats
path: root/config/squid3
diff options
context:
space:
mode:
Diffstat (limited to 'config/squid3')
-rwxr-xr-xconfig/squid3/34/squid.inc1485
-rw-r--r--config/squid3/34/squid.xml52
-rw-r--r--config/squid3/34/squid_antivirus.inc797
-rwxr-xr-xconfig/squid3/34/squid_antivirus.xml111
-rwxr-xr-xconfig/squid3/34/squid_auth.xml3
-rwxr-xr-xconfig/squid3/34/squid_cache.xml1
-rw-r--r--config/squid3/34/squid_js.inc273
-rwxr-xr-xconfig/squid3/34/squid_reverse.inc71
-rwxr-xr-xconfig/squid3/34/squid_reverse.xml451
-rwxr-xr-xconfig/squid3/34/squid_reverse_general.xml7
-rwxr-xr-xconfig/squid3/34/squid_traffic.xml1
-rwxr-xr-xconfig/squid3/34/squid_users.xml3
12 files changed, 1784 insertions, 1471 deletions
diff --git a/config/squid3/34/squid.inc b/config/squid3/34/squid.inc
index db5f1b0c..15854317 100755
--- a/config/squid3/34/squid.inc
+++ b/config/squid3/34/squid.inc
@@ -41,6 +41,12 @@ require_once('service-utils.inc');
if (!function_exists("filter_configure")) {
require_once("filter.inc");
}
+/* Squid reverse proxy */
+require_once('/usr/local/pkg/squid_reverse.inc');
+/* Squid javascript helpers */
+require_once('/usr/local/pkg/squid_js.inc');
+/* Squid antivirus intergration features helpers */
+require_once('/usr/local/pkg/squid_antivirus.inc');
$shortcut_section = "squid";
@@ -71,10 +77,16 @@ if ($uname['machine'] == 'amd64') {
ini_set('memory_limit', '250M');
}
+/*
+ * Utility functions
+ */
+
+/* Handle base64 encoding and linebreaks in textarea configuration fields */
function sq_text_area_decode($text) {
return preg_replace('/\r\n/', "\n", base64_decode($text));
}
+/* Get interface IP and netmask for Squid interfaces */
function squid_get_real_interface_address($iface) {
if (!function_exists("get_interface_ip")) {
require_once("interfaces.inc");
@@ -83,52 +95,136 @@ function squid_get_real_interface_address($iface) {
return array(get_interface_ip($iface), gen_subnet_mask(get_interface_subnet($iface)));
}
+/* Check whether ACL is valid */
+function squid_is_valid_acl($acl) {
+ global $valid_acls;
+
+ if (!is_array($valid_acls)) {
+ return;
+ }
+
+ return in_array($acl, $valid_acls);
+}
+
+/* Recursively change ownership of directories */
function squid_chown_recursive($dir, $user, $group) {
if (empty($dir) || ($dir == '/') || ($dir == '/usr/local') || !is_dir($dir)) {
- log_error(gettext("Squid attempted to chown an invalid directory: {$dir}"));
+ log_error(gettext("[squid] Attempted to chown an invalid directory: '{$dir}'"));
return;
}
chown($dir, $user);
chgrp($dir, $group);
- $handle = opendir($dir) ;
- while (($item = readdir($handle)) !== false) {
- if (!empty($item) && ($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);
+ $handle = opendir($dir);
+ if ($handle) {
+ while (($item = readdir($handle)) !== false) {
+ if (!empty($item) && ($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);
+ }
}
}
+ } else {
+ log_error(gettext("[squid] squid_chown_recursive() call failed; permissions not set for directory: '{$dir}'"));
}
}
-function squid_check_clamav_user($user) {
- if (SQUID_BASE == '/usr/local') {
- return;
+/* Check whether Squid is enabled */
+function squid_enabled() {
+ global $config, $proxy_enabled;
+ $proxy_enabled = false;
+
+ if (is_array($config['installedpackages']['squid']['config'])) {
+ // check whether Squid is enabled ...
+ if ($config['installedpackages']['squid']['config'][0]['enable_squid'] == "on") {
+ // ... and has at least one interface configured ...
+ if ($config['installedpackages']['squid']['config'][0]['active_interface'] != "") {
+ $proxy_enabled = true;
+ } else {
+ // ... or has at least one reverse interface configured
+ if (is_array($config['installedpackages']['squidreversegeneral']['config'])) {
+ if ($config['installedpackages']['squidreversegeneral']['config'][0]['reverse_interface'] != "") {
+ $proxy_enabled = true;
+ }
+ }
+ }
+ }
}
+ return $proxy_enabled;
+}
- $_gc = exec("/usr/sbin/pw usershow {$user}", $sq_ex_output, $sq_ex_return);
- $user_arg = ($sq_ex_return == 0 ? "mod" : "add");
- $_gc = exec("/usr/sbin/pw user{$user_arg} {$user} -G wheel -u 9595 -s /sbin/nologin", $sq_ex_output, $sq_ex_return);
- if ($sq_ex_return != 0) {
- log_error("Squid - Could not change clamav user settings. " . serialize($sq_ex_output));
+/* Get list of certificates for SSL proxy */
+function squid_get_server_certs() {
+ global $config;
+ $cert_arr = array();
+ $cert_arr[] = array('refid' => 'none', 'descr' => 'none');
+ foreach ($config['cert'] as $cert) {
+ $cert_arr[] = array('refid' => $cert['refid'], 'descr' => $cert['descr']);
}
+ return $cert_arr;
}
-function squid_update_clamav() {
- log_error("Updating ClamAV definitions now... This will take a while. Check /var/log/clamav/freshclam.log for progress information.");
- mwexec_bg(SQUID_BASE . "/bin/freshclam --config-file=" . SQUID_BASE . "/etc/freshclam.conf");
+/* Handle root CA certificates bundle */
+function squid_check_ca_hashes() {
+ global $config, $g;
+
+ // check certificates
+ $cert_count = 0;
+ if (is_dir(SQUID_LOCALBASE . '/share/certs')) {
+ if ($handle = opendir(SQUID_LOCALBASE . '/share/certs')) {
+ while (false !== ($file = readdir($handle))) {
+ if (preg_match ("/\d+.0/", $file)) {
+ $cert_count++;
+ }
+ }
+ closedir($handle);
+ }
+ }
+ if ($cert_count < 10) {
+ conf_mount_rw();
+ // create ca-root hashes from ca-root-nss package
+ log_error("[squid] Creating root certificate bundle hashes from the Mozilla Project...");
+ $cas = file(SQUID_LOCALBASE . '/share/certs/ca-root-nss.crt');
+ $cert = 0;
+ foreach ($cas as $ca) {
+ if (preg_match("/--BEGIN CERTIFICATE--/", $ca)) {
+ $cert = 1;
+ }
+ if ($cert == 1) {
+ $crt .= $ca;
+ }
+ if (preg_match("/-END CERTIFICATE-/", $ca)) {
+ file_put_contents("/tmp/cert.pem", $crt, LOCK_EX);
+ $cert_hash = array();
+ exec("/usr/bin/openssl x509 -hash -noout -in /tmp/cert.pem", $cert_hash);
+ file_put_contents(SQUID_LOCALBASE . "/share/certs/" . $cert_hash[0] . ".0", $crt, LOCK_EX);
+ $crt = "";
+ $cert = 0;
+ }
+ }
+ }
}
-/* setup cache */
+/*
+ * Squid cache setup
+ */
+
+ /* Create Squid disk cache directories */
function squid_dash_z($cache_action = 'none') {
global $config;
- // We need cache created on package install
+ // We need cache configured after initial package install
+ if (!is_array($config['installedpackages']['squidcache']['config'])) {
+ log_error("[squid] 'Local Cache' not configured, disk cache will be disabled.");
+ log_error("[squid] Please, configure and save 'Local Cache' settings before enabling Squid proxy.");
+ return;
+ }
+
if (is_array($config['installedpackages']['squidcache'])) {
$cachesettings = $config['installedpackages']['squidcache']['config'][0];
} else {
@@ -147,18 +243,18 @@ function squid_dash_z($cache_action = 'none') {
if ($cachesettings['harddisk_cache_system'] == "null") {
if (is_dir($cachedir)) {
if (substr($cachedir, 0, 11) === "/var/squid/") {
- log_error("Deleting Squid cache dir {$cachedir} since 'Hard Disk Cache System' is set to null.");
+ log_error("[squid] Deleting cache dir '{$cachedir}' since 'Hard Disk Cache System' is set to null...");
// cannot nuke disk cache while Squid is running
squid_stop_monitor();
if (is_service_running('squid')) {
stop_service("squid");
}
- rename($cachedir, "{$cachedir}.old");
+ @rename($cachedir, "{$cachedir}.old");
mwexec_bg("/bin/rm -rf {$cachedir}.old");
squid_restart_services();
} else {
- log_error("'Hard Disk Cache System' is set to null.");
- log_error("Will NOT delete Squid cache dir '{$cachedir}' since it is not located under /var/squid. Delete manually if required.");
+ log_error("[squid] 'Hard Disk Cache System' is set to null.");
+ log_error("[squid] Will NOT delete cache dir '{$cachedir}' since it is not located under /var/squid. Delete manually if required.");
}
}
return;
@@ -166,7 +262,7 @@ function squid_dash_z($cache_action = 'none') {
// Re-create the cachedir if clean is forced by cronjob/manually,
// or if the cachedir changed, or level1_subdirs don't exist or the number of level1_subdirs changed
- if ($cache_action == "clean" || ((!is_dir($cachedir)) || (!is_dir($cachedir . '/00'))) || ($numdirs !== $currentdirs)) {
+ if ($cache_action == "clean" || !is_dir($cachedir) || !is_dir($cachedir . '/00') || $numdirs != $currentdirs) {
// cannot nuke disk cache while Squid is running
squid_stop_monitor();
if (is_service_running('squid')) {
@@ -174,10 +270,10 @@ function squid_dash_z($cache_action = 'none') {
}
if (is_dir($cachedir)) {
if (substr($cachedir, 0, 11) === "/var/squid/") {
- rename($cachedir, "{$cachedir}.old");
+ @rename($cachedir, "{$cachedir}.old");
mwexec_bg("/bin/rm -rf {$cachedir}.old");
} else {
- log_error("Will NOT delete Squid cache dir '{$cachedir}' since it is not located under /var/squid. Delete manually if required.");
+ log_error("[squid] Will NOT delete cache dir '{$cachedir}' since it is not located under /var/squid. Delete manually if required.");
}
}
squid_create_cachedir();
@@ -185,6 +281,7 @@ function squid_dash_z($cache_action = 'none') {
}
}
+/* Helper function for squid_dash_z() */
function squid_create_cachedir() {
global $config;
if (is_array($config['installedpackages']['squidcache'])) {
@@ -195,17 +292,17 @@ function squid_create_cachedir() {
$cachedir = ($cachesettings['harddisk_cache_location'] ? $cachesettings['harddisk_cache_location'] : '/var/squid/cache');
if (!is_dir($cachedir)) {
- log_error("Creating Squid cache dir {$cachedir}");
+ log_error("[squid] Creating cache dir '{$cachedir}' ...");
safe_mkdir($cachedir, 0755);
@chown($cachedir, SQUID_UID);
@chgrp($cachedir, SQUID_GID);
}
if (!is_dir($cachedir . '/00')) {
- log_error("Creating Squid cache subdirs in $cachedir");
+ log_error("[squid] Creating Squid cache subdirs in {$cachedir} ...");
+ mwexec(SQUID_BASE. "/sbin/squid -z -f " . SQUID_CONFFILE);
// Double check permissions here, should be safe to recurse cache dir if it's small here.
squid_chown_recursive($cachedir, SQUID_UID, SQUID_GID);
- mwexec(SQUID_BASE. "/sbin/squid -z -f " . SQUID_CONFFILE);
}
if (file_exists("/var/squid/cache/swap.state")) {
@@ -215,20 +312,315 @@ function squid_create_cachedir() {
}
}
-function squid_is_valid_acl($acl) {
- global $valid_acls;
- if (!is_array($valid_acls)) {
+/*
+ * rc scripts, services and cronjobs
+ */
+
+/* Handle cronjob install/uninstall */
+function squid_install_cron($should_install) {
+ global $config;
+
+ if (platform_booting()) {
return;
}
- return in_array($acl, $valid_acls);
+ parse_config(true);
+ if (is_array($config['installedpackages']['squidcache'])) {
+ $settings = $config['installedpackages']['squidcache']['config'][0];
+ } else {
+ $settings = array();
+ }
+
+ $cron_cmd = ($settings['clear_cache'] == 'on' ? "/usr/local/pkg/swapstate_check.php clean; " : "");
+ $cron_cmd .= SQUID_BASE . "/sbin/squid -k rotate -f " . SQUID_CONFFILE;
+ install_cron_job("{$cron_cmd}", $should_install, "0", "0", "*", "*", "*", "root");
+
+ $swapstate_cmd = "/usr/local/pkg/swapstate_check.php clean; ";
+ if (($should_install) && (squid_enabled())) {
+ if ($settings['clear_cache'] == 'on' ) {
+ install_cron_job("{$swapstate_cmd}", true, "*/360");
+ } else {
+ install_cron_job("{$swapstate_cmd}", false);
+ }
+ } else {
+ install_cron_job("{$swapstate_cmd}", false);
+ }
}
+/* Create /usr/local/etc/rc.d/squid.sh rc script */
+function squid_write_rcfile() {
+ /* Declare a variable for the SQUID_CONFFILE constant. */
+ /* Then the variable can be referenced easily in the heredoc text that generates the rc file. */
+ $squid_conffile_var = SQUID_CONFFILE;
+ $squid_base = SQUID_BASE;
+ $rc = array();
+ $rc['file'] = 'squid.sh';
+ $rc['start'] = <<< EOD
+#/sbin/sysctl net.inet.ip.portrange.reservedhigh=0
+if [ -z "`/bin/ps auxw | /usr/bin/grep "[s]quid " | /usr/bin/awk '{print $2}'`" ]; then
+ {$squid_base}/sbin/squid -f {$squid_conffile_var}
+fi
+
+EOD;
+
+ $rc['stop'] = <<< EOD
+{$squid_base}/sbin/squid -k shutdown -f {$squid_conffile_var}
+# Just to be sure...
+sleep 5
+if [ -n "`/bin/ps auxw | /usr/bin/grep "[s]quid " | /usr/bin/awk '{print $2}'`" ]; then
+ {$squid_base}/sbin/squid -k kill -f {$squid_conffile_var}
+fi
+
+if [ -x /usr/bin/ipcs ]; then
+# http://man.chinaunix.net/newsoft/squid/Squid_FAQ/FAQ-22.html#ss22.8
+/usr/bin/ipcs | /usr/bin/grep '^[mq]' | /usr/bin/awk '{printf "ipcrm -%s %s\\n", $1, $2}' | /bin/sh
+fi
+
+/usr/bin/killall -9 squid 2>/dev/null
+/usr/bin/killall pinger 2>/dev/null
+
+EOD;
+
+ conf_mount_rw();
+ write_rcfile($rc);
+ conf_mount_ro();
+}
+
+/* Start sqp_monitor.sh watchdog script */
+function squid_start_monitor() {
+ if (squid_enabled()) {
+ if (!exec("/bin/ps auxw | /usr/bin/grep '[s]qpmon'")) {
+ log_error("[squid] Starting a proxy monitor script");
+ mwexec_bg("/usr/local/etc/rc.d/sqp_monitor.sh start");
+ }
+ sleep(1);
+ } else {
+ log_error("[squid] Squid is disabled. Not starting a proxy monitor script");
+ }
+}
+
+/* Stop sqp_monitor.sh watchdog script */
+function squid_stop_monitor() {
+ /* kill any running proxy alarm scripts */
+ if (exec("/bin/ps auxw | /usr/bin/grep '[s]qpmon'")) {
+ log_error("[squid] Stopping any running proxy monitors");
+ mwexec("/usr/local/etc/rc.d/sqp_monitor.sh stop");
+ }
+ sleep(1);
+}
+
+/* Start and/or stop services according to Squid configuration */
+function squid_restart_services() {
+ global $config;
+
+ // do not (re)start squid services on boot
+ if (platform_booting()) {
+ return;
+ }
+
+ if (squid_enabled()) {
+ /* kill any running proxy alarm scripts */
+ squid_stop_monitor();
+
+ if (!is_service_running('squid')) {
+ log_error("[squid] Starting service...");
+ mwexec(SQUID_BASE . "/sbin/squid -f " . SQUID_CONFFILE);
+ } else {
+ log_error("[squid] Reloading for configuration sync...");
+ mwexec(SQUID_BASE . "/sbin/squid -k reconfigure -f " . SQUID_CONFFILE);
+ }
+ // sleep for a couple seconds to give squid a chance to fire up fully.
+ for ($i = 0; $i < 10; $i++) {
+ if (!is_service_running('squid')) {
+ sleep(1);
+ }
+ }
+ /* restart proxy alarm scripts */
+ squid_start_monitor();
+
+ } else {
+ /* Squid is disabled - kill any running proxy alarm scripts and stop Squid services */
+ squid_stop_monitor();
+ if (is_service_running('squid')) {
+ log_error("[squid] Stopping service...");
+ stop_service("squid");
+ }
+ }
+}
+
+
+/*
+ * Squid package install/uninstall
+ */
+
function squid_install_command() {
global $config, $g;
- update_status("Checking if there is configuration to migrate... One moment please...");
+ update_output_window("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.");
+ update_output_window("Checking if there is configuration to migrate... One moment please...");
+
+ /* Set storage system for nanobsd */
+ if (!is_array($config['installedpackages']['squidcache'])) {
+ $config['installedpackages']['squidcache'] = array();
+ }
+ if ($g['platform'] == "nanobsd") {
+ $config['installedpackages']['squidcache']['config'][0]['harddisk_cache_system'] = 'null';
+ }
+
+ // migrate configuration from old versions
+ squid_upgrade_config();
+
+ /* make sure pinger is executable and suid root */
+ // XXX: Bug #5114
+ if (file_exists(SQUID_LOCALBASE . "/libexec/squid/pinger")) {
+ chgrp(SQUID_LOCALBASE . "/libexec/squid/pinger", SQUID_GID);
+ }
+
+ // another PBI hack
+ if (SQUID_BASE != '/usr/local' && file_exists('/usr/local/bin/check_ip.php') && !file_exists(SQUID_BASE . '/bin/check_ip.php')) {
+ symlink("/usr/local/bin/check_ip.php", SQUID_BASE . "/bin/check_ip.php");
+ }
+
+ // create squid rcfile
+ squid_write_rcfile();
+
+ // create squid monitor rcfile
+ write_rcfile(array(
+ "file" => "sqp_monitor.sh",
+ "start" => "/usr/local/pkg/sqpmon.sh &",
+ "stop" => "/bin/ps awux | /usr/bin/grep \"sqpmon\" | /usr/bin/grep -v \"grep\" | /usr/bin/grep -v \"php\" | /usr/bin/awk '{ print $2 }' | /usr/bin/xargs kill")
+ );
+
+ // antivirus intergration
+ squid_antivirus_install_command();
+
+ foreach (array(SQUID_CONFBASE, SQUID_ACLDIR, SQUID_SSL_DB) as $dir) {
+ safe_mkdir($dir, 0755);
+ squid_chown_recursive($dir, SQUID_UID, SQUID_GID);
+ }
+
+ if (!file_exists(SQUID_CONFBASE . '/mime.conf') && file_exists(SQUID_CONFBASE . '/mime.conf.default')) {
+ copy(SQUID_CONFBASE . '/mime.conf.default', SQUID_CONFBASE . '/mime.conf');
+ }
+
+ // remove unwanted PBI rc script
+ unlink_if_exists("/usr/local/etc/rc.d/squid");
+
+}
+
+function squid_deinstall_command() {
+ global $config, $g, $keep;
+
+ /* remove cronjobs */
+ squid_install_cron(false);
+
+ /* kill all running services */
+ update_output_window("Stopping and removing services...");
+ mwexec('/usr/local/etc/rc.d/sqp_monitor.sh stop');
+ mwexec("/bin/ps awux | /usr/bin/grep '[s]quid' | /usr/bin/awk '{ print $2 }' | /usr/bin/xargs kill");
+ mwexec("/bin/ps awux | /usr/bin/grep '[d]nsserver' | /usr/bin/awk '{ print $2 }' | /usr/bin/xargs kill");
+ mwexec("/bin/ps awux | /usr/bin/grep '[u]nlinkd' | /usr/bin/awk '{ print $2 }' | /usr/bin/xargs kill");
+
+ /* delete rc scripts */
+ unlink_if_exists('/usr/local/etc/rc.d/sqp_monitor.sh');
+
+ /* clean up created directories if 'Keep Settings/Data' is disabled */
+ if (is_array($config['installedpackages']['squidcache'])) {
+ $cachesettings = $config['installedpackages']['squidcache']['config'][0];
+ } else {
+ $cachesettings = array();
+ }
+ $cachedir = ($cachesettings['harddisk_cache_location'] ? $cachesettings['harddisk_cache_location'] : '/var/squid/cache');
+ if (is_array($config['installedpackages']['squid'])) {
+ $squidsettings = $config['installedpackages']['squid']['config'][0];
+ } else {
+ $squidsettings = array();
+ }
+ $logdir = ($squidsettings['log_dir'] ? $squidsettings['log_dir'] : '/var/squid/logs');
+ $keep = ($squidsettings['keep_squid_data'] ? true : false);
+
+ if (!$keep) {
+ update_output_window("Removing cache and logs ... One moment please...");
+ update_output_window("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.");
+ if (is_dir("{$cachedir}")) {
+ if (substr($cachedir, 0, 11) === "/var/squid/") {
+ mwexec_bg("/bin/rm -rf {$cachedir}");
+ } else {
+ log_error("[squid] Will NOT delete Squid cache dir '{$cachedir}' since it is not located under /var/squid. Delete manually if required.");
+ }
+ }
+ if (is_dir("{$logdir}")) {
+ if (substr($logdir, 0, 11) === "/var/squid/") {
+ mwexec("/bin/rm -rf {$logdir}");
+ } else {
+ log_error("[squid] Will NOT delete Squid log dir '{$logdir}' since it is not located under /var/squid. Delete manually if required.");
+ }
+ }
+ update_output_window("Removing remaining Squid directories ... One moment please...");
+ $dirs = array("/var/run/squid", "/var/squid");
+ foreach ($dirs as $dir) {
+ if (is_dir("{$dir}")) {
+ mwexec("/bin/rm -rf {$dir}");
+ }
+ }
+ }
+
+ // remove antivirus integration features
+ squid_antivirus_deinstall_command();
+
+ update_output_window("Reloading filter...");
+ filter_configure();
+
+ /* Remove package settings from config if 'Keep Settings/Data' is disabled */
+ if (!$keep) {
+ log_error("[squid] Removing all Squid settings since 'Keep Settings/Data' is disabled...");
+ if (is_array($config['installedpackages']['squid'])) {
+ unset($config['installedpackages']['squid']);
+ }
+ if (is_array($config['installedpackages']['squidantivirus'])) {
+ unset($config['installedpackages']['squidantivirus']);
+ }
+ if (is_array($config['installedpackages']['squidauth'])) {
+ unset($config['installedpackages']['squidauth']);
+ }
+ if (is_array($config['installedpackages']['squidcache'])) {
+ unset($config['installedpackages']['squidcache']);
+ }
+ if (is_array($config['installedpackages']['squidnac'])) {
+ unset($config['installedpackages']['squidnac']);
+ }
+ if (is_array($config['installedpackages']['squidreverse'])) {
+ unset($config['installedpackages']['squidreverse']);
+ }
+ if (is_array($config['installedpackages']['squidreversegeneral'])) {
+ unset($config['installedpackages']['squidreversegeneral']);
+ }
+ if (is_array($config['installedpackages']['squidreversepeer'])) {
+ unset($config['installedpackages']['squidreversepeer']);
+ }
+ if (is_array($config['installedpackages']['squidreverseredir'])) {
+ unset($config['installedpackages']['squidreverseredir']);
+ }
+ if (is_array($config['installedpackages']['squidsync'])) {
+ unset($config['installedpackages']['squidsync']);
+ }
+ if (is_array($config['installedpackages']['squidtraffic'])) {
+ unset($config['installedpackages']['squidtraffic']);
+ }
+ if (is_array($config['installedpackages']['squidremote'])) {
+ unset($config['installedpackages']['squidremote']);
+ }
+ if (is_array($config['installedpackages']['squidusers'])) {
+ unset($config['installedpackages']['squidusers']);
+ }
+ }
+ update_output_window("Squid3 has been uninstalled.");
+}
+
+/* Migrate configuration from god knows which Squid package versions */
+/* None of these ever existed with Squid 3.4 package and this cruft should be most likely just removed */
+function squid_upgrade_config() {
/* migrate existing csv config fields */
if (is_array($config['installedpackages']['squidauth']['config'])) {
$settingsauth = $config['installedpackages']['squidauth']['config'][0];
@@ -243,15 +635,6 @@ function squid_install_command() {
$settingsgen = $config['installedpackages']['squid']['config'][0];
}
- if (SQUID_BASE != '/usr/local' && file_exists('/usr/local/bin/check_ip.php') && !file_exists(SQUID_BASE . '/bin/check_ip.php')) {
- symlink("/usr/local/bin/check_ip.php", SQUID_BASE . "/bin/check_ip.php");
- }
-
- /* Set storage system */
- if ($g['platform'] == "nanobsd") {
- $config['installedpackages']['squidcache']['config'][0]['harddisk_cache_system'] = 'null';
- }
-
/* migrate auth settings */
if (!empty($settingsauth['no_auth_hosts']) && strstr($settingsauth['no_auth_hosts'], ",")) {
$settingsauth['no_auth_hosts'] = base64_encode(implode("\n", explode(",", $settingsauth['no_auth_hosts'])));
@@ -341,7 +724,7 @@ function squid_install_command() {
if (!is_array($config['installedpackages']['squidreverseuri'])) {
foreach (explode("\n", sq_text_area_decode($old_reverse_settings['reverse_acl'])) as $acls) {
foreach (explode(";", $acls) as $acl) {
- array_push(${'peer_'.$acl[0]},$acl[1]);
+ array_push(${'peer_'.$acl[0]}, $acl[1]);
}
}
foreach (explode("\n", sq_text_area_decode($old_reverse_settings['reverse_uri'])) as $uris) {
@@ -359,180 +742,25 @@ function squid_install_command() {
}
}
}
-
- update_status("Writing configuration... One moment please...");
- write_config();
-
- /* make sure pinger is executable and suid root */
- // XXX: Bug #5114
- if (file_exists(SQUID_LOCALBASE . "/libexec/squid/pinger")) {
- chgrp(SQUID_LOCALBASE . "/libexec/squid/pinger", SQUID_GID);
- }
-
- // create squid rcfile
- squid_write_rcfile();
-
- // XXX: Is it really necessary? mode is set to 0755 in squid.xml
- if (file_exists("/usr/local/pkg/swapstate_check.php")) {
- @chmod("/usr/local/pkg/swapstate_check.php", 0755);
- }
-
- // create squid monitor rcfile
- write_rcfile(array(
- "file" => "sqp_monitor.sh",
- "start" => "/usr/local/pkg/sqpmon.sh &",
- "stop" => "/bin/ps awux | /usr/bin/grep \"sqpmon\" | /usr/bin/grep -v \"grep\" | /usr/bin/grep -v \"php\" | /usr/bin/awk '{ print $2 }' | /usr/bin/xargs kill")
- );
- // create c-icap rcfile
- squid_write_cicap_rcfile();
-
- // make a backup of default c-icap config file on install; also see squid_resync_antivirus() function below
- if (!file_exists(SQUID_LOCALBASE . "/etc/c-icap/c-icap.conf.default")) {
- if (file_exists(SQUID_LOCALBASE . "/etc/c-icap/c-icap.conf.sample")) {
- copy(SQUID_LOCALBASE . "/etc/c-icap/c-icap.conf.sample", SQUID_LOCALBASE . "/etc/c-icap/c-icap.conf.default");
- }
- }
-
- foreach (array(SQUID_CONFBASE, SQUID_ACLDIR, SQUID_SSL_DB) as $dir) {
- safe_mkdir($dir, 0755);
- squid_chown_recursive($dir, SQUID_UID, SQUID_GID);
- }
-
- 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() {
- global $config, $g;
-
- /* remove cronjobs */
- squid_install_cron(false);
- squid_install_freshclam_cron(false);
-
- update_status("Stopping services...");
- /* kill all running services */
- mwexec('/usr/local/etc/rc.d/sqp_monitor.sh stop');
- if (is_process_running("c-icap")) {
- mwexec('/bin/echo -n "stop" > /var/run/c-icap/c-icap.ctl');
- }
- mwexec("/bin/ps awux | /usr/bin/grep '[c]lamd' | /usr/bin/awk '{ print $2 }' | /usr/bin/xargs kill");
- mwexec("/bin/ps awux | /usr/bin/grep '[f]reshclam' | /usr/bin/awk '{ print $2 }' | /usr/bin/xargs kill");
- mwexec("/bin/ps awux | /usr/bin/grep '[s]quid' | /usr/bin/awk '{ print $2 }' | /usr/bin/xargs kill");
- mwexec("/bin/ps awux | /usr/bin/grep '[d]nsserver' | /usr/bin/awk '{ print $2 }' | /usr/bin/xargs kill");
- mwexec("/bin/ps awux | /usr/bin/grep '[u]nlinkd' | /usr/bin/awk '{ print $2 }' | /usr/bin/xargs kill");
- /* delete rc scripts */
- unlink_if_exists('/usr/local/etc/rc.d/sqp_monitor.sh');
- unlink_if_exists('/usr/local/etc/rc.d/c-icap');
- unlink_if_exists("/usr/local/etc/rc.d/c-icap.sh");
- unlink_if_exists('/usr/local/etc/rc.d/clamav-clamd');
- unlink_if_exists('/usr/local/etc/rc.d/clamav-freshclam');
-
- /* clean up created directories */
- update_status("Removing cache and logs ... One moment please...");
- update_output_window("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.");
- if (is_array($config['installedpackages']['squidcache'])) {
- $cachesettings = $config['installedpackages']['squidcache']['config'][0];
- } else {
- $cachesettings = array();
- }
- $cachedir = ($cachesettings['harddisk_cache_location'] ? $cachesettings['harddisk_cache_location'] : '/var/squid/cache');
- if (is_array($config['installedpackages']['squid'])) {
- $squidsettings = $config['installedpackages']['squid']['config'][0];
- } else {
- $squidsettings = array();
- }
- $logdir = ($squidsettings['log_dir'] ? $squidsettings['log_dir'] : '/var/squid/logs');
- // XXX: Is it ok to remove cache and logs? It's going to happen every time package is updated
- if (is_dir("{$cachedir}")) {
- if (substr($cachedir, 0, 11) === "/var/squid/") {
- mwexec_bg("/bin/rm -rf {$cachedir}");
- } else {
- log_error("Will NOT delete Squid cache dir '{$cachedir}' since it is not located under /var/squid. Delete manually if required.");
- }
- }
- if (is_dir("{$logdir}")) {
- if (substr($logdir, 0, 11) === "/var/squid/") {
- mwexec("/bin/rm -rf {$logdir}");
- } else {
- log_error("Will NOT delete Squid log dir '{$logdir}' since it is not located under /var/squid. Delete manually if required.");
- }
- }
- $dirs = array("/var/run/c-icap", "/var/log/c-icap", "/var/log/clamav", "/var/run/clamav", "/var/db/clamav", "/var/run/squid", "/var/squid");
- foreach ($dirs as $dir) {
- if (is_dir("{$dir}")) {
- mwexec("/bin/rm -rf {$dir}");
- }
- }
-
- /* clean up created PBI symlinks */
- update_status("Finishing package cleanup.");
- if (SQUID_LOCALBASE != '/usr/local') {
- $ln_icap = array('bin/c-icap', 'bin/c-icap-client', 'c-icap-config', 'c-icap-libicapapi-config', 'c-icap-stretch', 'lib/c_icap', 'share/c_icap', 'etc/c-icap');
- foreach ($ln_icap as $ln) {
- if (is_link("/usr/local/{$ln}")) {
- unlink("/usr/local/{$ln}");
- }
- }
- if (is_link("/usr/local/lib/libicapapi.so.3")) {
- unlink("/usr/local/lib/libicapapi.so.3");
- }
- }
-
- /* check if clamav/c_icap is enabled in rc.conf.local */
- if (file_exists("/etc/rc.conf.local")) {
- update_status("Removing antivirus services from /etc/rc.conf.local...");
- $sample_file = file_get_contents("/etc/rc.conf.local");
- $rcconf_local_m[0] = "@c_icap_enable(.*)\n@";
- $rcconf_local_m[1] = "@clamav_clamd_enable(.*)\n@";
- $rcconf_local_r[0] = "";
- $rcconf_local_r[1] = "";
- file_put_contents("/etc/rc.conf.local", preg_replace($rcconf_local_m, $rcconf_local_r, $sample_file), LOCK_EX);
+ /* unset broken antivirus settings */
+ if (is_array($config['installedpackages']['squidantivirus'])) {
+ unset($config['installedpackages']['squidantivirus']['config'][0]['squidclamav']);
+ unset($config['installedpackages']['squidantivirus']['config'][0]['c-icap_conf']);
+ unset($config['installedpackages']['squidantivirus']['config'][0]['c-icap_magic']);
+ unset($config['installedpackages']['squidantivirus']['config'][0]['freshclam_conf']);
}
- update_status("Reloading filter...");
- filter_configure();
+ update_output_window("Writing configuration... One moment please...");
+ write_config();
}
-function squid_validate_antivirus($post, &$input_errors) {
- global $config;
- /* Manual ClamAV database update */
- if ($post['submit'] == 'Update AV') {
- squid_update_clamav();
- return;
- }
-
- if ($post['enable'] != "on") {
- return;
- }
-
- if ($post['squidclamav'] && preg_match("/(\S+proxy.domain\S+)/", $post['squidclamav'], $a_match)) {
- $input_errors[] = "SquidClamav warnings redirect points to sample config domain ({$a_match[1]})";
- $input_errors[] = "Change redirect info on 'squidclamav.conf' field to pfSense GUI or an external host.";
- }
- if ($post['c-icap_conf']) {
- if (!preg_match("/squid_clamav/", $post['c-icap_conf'])) {
- $input_errors[] = "c-icap Squidclamav service definition is not present.";
- $input_errors[] = "Add 'Service squid_clamav squidclamav.so'(without quotes) to 'c-icap.conf' field in order to get it working.";
- }
- if (preg_match("/(Manager:Apassword\S+)/", $post['c-icap_conf'], $c_match)) {
- $input_errors[] = "Remove ldap configuration'{$c_match[1]}' from 'c-icap.conf' field.";
- }
- }
-
- if ($post['clamav_dbservers']) {
- foreach (explode(";", $post['clamav_dbservers']) as $dbserver) {
- $dbserver = trim($dbserver);
- if (!empty($dbserver) && !is_ipaddr($dbserver) && !is_hostname($dbserver)) {
- $input_errors[] = "'Optional ClamAV Database Update Servers' entry '$dbserver' is not a valid IP address or hostname.";
- }
- }
- }
-}
+/*
+ * Squid input validation
+ */
+/* Proxy Server: General Settings input validation */
function squid_validate_general($post, &$input_errors) {
global $config;
@@ -542,6 +770,11 @@ function squid_validate_general($post, &$input_errors) {
$settings = array();
}
+ // force users to configure cache
+ if (!is_array($config['installedpackages']['squidcache']['config'])) {
+ $input_errors[] = 'Please, configure and save \'Local Cache\' settings first.';
+ }
+
$port = ($settings['proxy_port'] ? $settings['proxy_port'] : 3128);
$port = $post['proxy_port'] ? $post['proxy_port'] : $port;
@@ -613,6 +846,7 @@ function squid_validate_general($post, &$input_errors) {
}
}
+/* Proxy Server: Remote Proxy Settings input validation */
function squid_validate_upstream($post, &$input_errors) {
if ($post['enabled'] != 'on') {
return;
@@ -639,6 +873,7 @@ function squid_validate_upstream($post, &$input_errors) {
}
}
+/* Proxy Server: Cache Management input validation */
function squid_validate_cache($post, &$input_errors) {
$num_fields = array(
'harddisk_cache_size' => 'Hard disk cache size',
@@ -694,6 +929,7 @@ function squid_validate_cache($post, &$input_errors) {
}
}
+/* Proxy Server: Access Control input validation */
function squid_validate_nac($post, &$input_errors) {
$allowed_subnets = explode("\n", $post['allowed_subnets']);
foreach ($allowed_subnets as $subnet) {
@@ -745,6 +981,7 @@ function squid_validate_nac($post, &$input_errors) {
}
}
+/* Proxy server: Traffic Management input validation */
function squid_validate_traffic($post, &$input_errors) {
$num_fields = array(
'max_download_size' => 'Maximum download size',
@@ -782,75 +1019,7 @@ function squid_validate_traffic($post, &$input_errors) {
}
}
-function squid_validate_reverse($post, &$input_errors) {
- global $config;
-
- if (!empty($post['reverse_ip'])) {
- $reverse_ip = explode(";", ($post['reverse_ip']));
- foreach ($reverse_ip as $reip) {
- if (!is_ipaddr(trim($reip))) {
- $input_errors[] = "You must enter a valid IP address in the 'User-defined reverse-proxy IPs' field. '$reip' is invalid.";
- }
- }
- }
-
- $fqdn = trim($post['reverse_external_fqdn']);
- if (!empty($fqdn) && !is_domain($fqdn)) {
- $input_errors[] = "'External FQDN' field must contain a valid domain name.";
- }
-
- $port = trim($post['reverse_http_port']);
- preg_match("/(\d+)/", shell_exec("/sbin/sysctl net.inet.ip.portrange.reservedhigh"), $portrange);
- if (!empty($port) && !is_port($port)) {
- $input_errors[] = "'Reverse HTTP port' must contain a valid port number.";
- }
- if (!empty($port) && is_port($port) && $port <= $portrange[1]) {
- $input_errors[] = "'Reverse HTTP port' must contain a port number higher than net.inet.ip.portrange.reservedhigh sysctl value({$portrange[1]}).";
- $input_errors[] = "To listen on low ports, change portrange.reservedhigh sysctl value to 0 in system tunable options and restart Squid daemon.";
- }
- $port = trim($post['reverse_https_port']);
- if (!empty($port) && !is_port($port)) {
- $input_errors[] = "'Reverse HTTPS port' must contain a valid port number.";
- }
- if (!empty($port) && is_port($port) && $port <= $portrange[1]) {
- $input_errors[] = "'Reverse HTTPS port' must contain a port number higher than net.inet.ip.portrange.reservedhigh sysctl value({$portrange[1]}).";
- $input_errors[] = "To listen on low ports, change portrange.reservedhigh sysctl value to 0 in system tunable options and restart Squid daemon.";
- }
- if ($post['reverse_ssl_cert'] == 'none') {
- $input_errors[] = 'A valid certificate for the external interface must be selected';
- }
-
- if (($post['reverse_https'] != 'on') && ($post['reverse_owa'] == 'on')) {
- $input_errors[] = "You have to enable reverse HTTPS before enabling OWA support.";
- }
-
- if (!empty($post['reverse_owa_ip'])) {
- $reverse_owa_ip = explode(";", ($post['reverse_owa_ip']));
- foreach ($reverse_owa_ip as $reowaip) {
- if (!is_ipaddr(trim($reowaip))) {
- $input_errors[] = "You must enter a valid IP address in the 'CAS-Array / OWA frontend IP address' field. '$reowaip' is invalid.";
- }
- }
- }
-
- $contents = $post['reverse_cache_peer'];
- if (!empty($contents)) {
- $defs = explode("\r\n", ($contents));
- foreach ($defs as $def) {
- $cfg = explode(";", ($def));
- if (!is_ipaddr($cfg[1])) {
- $input_errors[] = "Please choose a valid IP in the cache peer configuration.";
- }
- if (!is_port($cfg[2])) {
- $input_errors[] = "Please choose a valid port in the cache peer configuration.";
- }
- if (($cfg[3] != 'HTTPS') && ($cfg[3] != 'HTTP')) {
- $input_errors[] = "Please choose HTTP or HTTPS in the cache peer configuration.";
- }
- }
- }
-}
-
+/* Proxy Server: Authentication input validation */
function squid_validate_auth($post, &$input_errors) {
$num_fields = array(
array('auth_processes', 'Authentication processes', 1),
@@ -912,102 +1081,7 @@ function squid_validate_auth($post, &$input_errors) {
}
}
-function squid_install_cron($should_install) {
- global $config;
-
- if (platform_booting()) {
- return;
- }
-
- parse_config(true);
- if (is_array($config['installedpackages']['squidcache'])) {
- $settings = $config['installedpackages']['squidcache']['config'][0];
- } else {
- $settings = array();
- }
-
- $cron_cmd = ($settings['clear_cache'] == 'on' ? "/usr/local/pkg/swapstate_check.php clean; " : "");
- $cron_cmd .= SQUID_BASE . "/sbin/squid -k rotate -f " . SQUID_CONFFILE;
- install_cron_job("{$cron_cmd}", $should_install, "0", "0", "*", "*", "*", "root");
-
- $swapstate_cmd = "/usr/local/pkg/swapstate_check.php clean; ";
- if ($should_install) {
- if ($settings['clear_cache'] == 'on' ) {
- install_cron_job("{$swapstate_cmd}", true, "*/360");
- } else {
- install_cron_job("{$swapstate_cmd}", false);
- }
- } else {
- install_cron_job("{$swapstate_cmd}", false);
- }
-}
-
-function squid_install_freshclam_cron($should_install) {
- global $config;
-
- if (platform_booting()) {
- return;
- }
-
- if (is_array($config['installedpackages']['squidantivirus'])) {
- $antivirus_config = $config['installedpackages']['squidantivirus']['config'][0];
- } else {
- $antivirus_config = array();
- }
-
- $freshclam_cmd = (SQUID_BASE . "/bin/freshclam --config-file=" . SQUID_BASE . "/etc/freshclam.conf");
- if ($should_install) {
- if ($antivirus_config['clamav_update'] != "0") {
- $minutes = ($antivirus_config['clamav_update'] * 60);
- install_cron_job("{$freshclam_cmd}", true, "*/{$minutes}", "*", "*", "*", "*", "clamav");
- } else {
- install_cron_job("{$freshclam_cmd}", false);
- }
- } else {
- install_cron_job("{$freshclam_cmd}", false);
- }
-}
-
-function squid_check_ca_hashes() {
- global $config, $g;
-
- // check certificates
- $cert_count = 0;
- if (is_dir(SQUID_LOCALBASE . '/share/certs')) {
- if ($handle = opendir(SQUID_LOCALBASE . '/share/certs')) {
- while (false !== ($file = readdir($handle))) {
- if (preg_match ("/\d+.0/",$file)) {
- $cert_count++;
- }
- }
- closedir($handle);
- }
- }
- if ($cert_count < 10) {
- conf_mount_rw();
- // create ca-root hashes from ca-root-nss package
- log_error("Creating root certificate bundle hashes from the Mozilla Project");
- $cas = file(SQUID_LOCALBASE . '/share/certs/ca-root-nss.crt');
- $cert = 0;
- foreach ($cas as $ca) {
- if (preg_match("/--BEGIN CERTIFICATE--/", $ca)) {
- $cert = 1;
- }
- if ($cert == 1) {
- $crt .= $ca;
- }
- if (preg_match("/-END CERTIFICATE-/", $ca)) {
- file_put_contents("/tmp/cert.pem", $crt, LOCK_EX);
- $cert_hash = array();
- exec("/usr/bin/openssl x509 -hash -noout -in /tmp/cert.pem", $cert_hash);
- file_put_contents(SQUID_LOCALBASE . "/share/certs/" . $cert_hash[0] . ".0", $crt, LOCK_EX);
- $crt = "";
- $cert = 0;
- }
- }
- }
-}
-
+/* Proxy Server: General Settings configuration handler */
function squid_resync_general() {
global $g, $config, $valid_acls;
@@ -1098,7 +1172,7 @@ function squid_resync_general() {
$iface_ip = squid_get_real_interface_address($iface);
if ($iface_ip[0]) {
$real_ifaces[] = $iface_ip;
- if (in_array($iface,$ssl_ifaces)) {
+ if (in_array($iface, $ssl_ifaces)) {
$conf .= "http_port {$iface_ip[0]}:{$port} {$ssl_interception}\n";
} else {
$conf .= "http_port {$iface_ip[0]}:{$port}\n";
@@ -1129,7 +1203,7 @@ function squid_resync_general() {
$logdir = ($settings['log_dir'] ? $settings['log_dir'] : '/var/squid/logs');
if (!is_dir($logdir)) {
- log_error("Creating Squid log dir $logdir");
+ log_error("[squid] Creating Squid log dir '{$logdir}' ...");
safe_mkdir($logdir, 0755);
squid_chown_recursive($logdir, SQUID_UID, SQUID_GID);
}
@@ -1220,6 +1294,7 @@ EOD;
return $conf;
}
+/* Proxy Server: Cache Management configuration handler */
function squid_resync_cache() {
global $config, $g;
@@ -1242,8 +1317,11 @@ function squid_resync_cache() {
$offline_mode = ($settings['enable_offline'] == 'on' ? 'on' : 'off');
$conf = '';
if (!isset($settings['harddisk_cache_system'])) {
- if ($g['platform'] == "nanobsd" || !is_array ($config['installedpackages']['squidcache']['config'])) {
+ if ($g['platform'] == "nanobsd") {
$disk_cache_system = 'null';
+ } elseif (!is_array($config['installedpackages']['squidcache']['config'])) {
+ log_error("[squid] 'Local Cache' not configured, disk cache will be disabled.");
+ log_error("[squid] Please, configure and save 'Local Cache' settings before enabling Squid proxy.");
} else {
$disk_cache_system = 'ufs';
}
@@ -1358,6 +1436,7 @@ EOD;
return $conf.$refresh_conf;
}
+/* Proxy Server: Remote Proxy Settings configuration handler */
function squid_resync_upstream() {
global $config;
@@ -1399,20 +1478,7 @@ function squid_resync_upstream() {
return $conf;
}
-function squid_resync_redirector() {
- global $config;
-
- // XXX: What port provide squirm binary? It's not present
- $httpav_enabled = ($config['installedpackages']['clamav']['config'][0]['scan_http'] == 'on');
- $redirector = "/usr/local/bin/squirm";
- if (($httpav_enabled) && is_executable($redirector)) {
- $conf = "url_rewrite_program /usr/local/bin/squirm\n";
- } else {
- $conf = "# No redirector configured\n";
- }
- return $conf;
-}
-
+/* Proxy Server: Access Control configuration handler */
function squid_resync_nac() {
global $config, $valid_acls;
@@ -1509,272 +1575,7 @@ EOD;
return $conf;
}
-function squid_resync_antivirus() {
- global $config;
-
- if (is_array($config['installedpackages']['squidantivirus'])) {
- $antivirus_config = $config['installedpackages']['squidantivirus']['config'][0];
- } else {
- $antivirus_config = array();
- }
-
- if ($antivirus_config['enable'] == "on") {
- switch ($antivirus_config['client_info']) {
- case "both":
- default:
- $icap_send_client_ip = "on";
- $icap_send_client_username = "on";
- break;
- case "ip":
- $icap_send_client_ip = "on";
- $icap_send_client_username = "off";
- break;
- case "username":
- $icap_send_client_ip = "off";
- $icap_send_client_username = "on";
- break;
- case "none":
- $icap_send_client_ip = "off";
- $icap_send_client_username = "off";
- break;
- }
-
- $conf = <<< EOF
-icap_enable on
-icap_send_client_ip {$icap_send_client_ip}
-icap_send_client_username {$icap_send_client_username}
-icap_client_username_encode off
-icap_client_username_header X-Authenticated-User
-icap_preview_enable on
-icap_preview_size 1024
-
-icap_service service_avi_req reqmod_precache icap://[::1]:1344/squid_clamav bypass=off
-adaptation_access service_avi_req allow all
-icap_service service_avi_resp respmod_precache icap://[::1]:1344/squid_clamav bypass=on
-adaptation_access service_avi_resp allow all
-
-EOF;
-
- // check if clamav is enabled in rc.conf.local
- // XXX: This whole thing sucks and should be redone to install/enable services in pfSense way
- if (file_exists("/etc/rc.conf.local")) {
- $rc_old_file = file("/etc/rc.conf.local");
- foreach ($rc_old_file as $rc_line) {
- if (preg_match("/^clamav_clamd_enable/", $rc_line, $matches)) {
- $rc_file .= $matches[1] . '="YES"' . "\n";
- ${$matches[1]} = "ok";
- } else {
- $rc_file .= $rc_line;
- }
- }
- }
- if (!isset($clamav_clamd_enable)) {
- $rc_file .= 'clamav_clamd_enable="YES"' . "\n";
- }
- file_put_contents("/etc/rc.conf.local", $rc_file, LOCK_EX);
- squid_check_clamav_user('clamav');
- // patch sample files to pfsense dirs
- // squidclamav.conf
- if (file_exists(SQUID_LOCALBASE . "/etc/c-icap/squidclamav.conf.default")) {
- $sample_file = file_get_contents(SQUID_LOCALBASE . "/etc/c-icap/squidclamav.conf.default");
- $clamav_m[0] = "@/var/run/clamav/clamd.ctl@";
- $clamav_m[1] = "@http\://proxy.domain.dom/cgi-bin/clwarn.cgi@";
- $clamav_r[0] = "/var/run/clamav/clamd.sock";
- $clamav_r[1] = "{$config['system']['webgui']['protocol']}://{$config['system']['hostname']}.{$config['system']['domain']}/squid_clwarn.php";
- if ($antivirus_config['clamav_safebrowsing'] == "on") {
- $clamav_m[2] = "@safebrowsing\s0@";
- $clamav_r[2] = "safebrowsing 1";
- }
- file_put_contents(SQUID_LOCALBASE . "/etc/c-icap/squidclamav.conf.sample", preg_replace($clamav_m, $clamav_r, $sample_file), LOCK_EX);
- }
- // c-icap.conf
- // make a backup of default c-icap.conf.sample first
- // unlike with other config files, the file distributed in package is called c-icap.conf.sample, not c-icap.conf.default
- if (!file_exists(SQUID_LOCALBASE . "/etc/c-icap/c-icap.conf.default")) {
- copy(SQUID_LOCALBASE . "/etc/c-icap/c-icap.conf.sample", SQUID_LOCALBASE . "/etc/c-icap/c-icap.conf.default");
- }
- if (file_exists(SQUID_LOCALBASE . "/etc/c-icap/c-icap.conf.default")) {
- $sample_file = file_get_contents(SQUID_LOCALBASE . "/etc/c-icap/c-icap.conf.default");
- if (!preg_match("/squid_clamav/", $sample_file)) {
- $sample_file .= "\nService squid_clamav squidclamav.so\n";
- }
- $cicap_m[0] = "@Manager:Apassword\S+@";
- $cicap_r[0] = "";
- // XXX: Bug #4615
- if (is_array($config['installedpackages']['squid'])) {
- $squidsettings = $config['installedpackages']['squid']['config'][0];
- } else {
- $squidsettings = array();
- }
- $logdir = ($squidsettings['log_dir'] ? $squidsettings['log_dir'] : '/var/squid/logs');
- $cicap_m[1] = "@DebugLevel\s1@";
- $cicap_r[1] = "DebugLevel 0";
- $cicap_m[2] = "@AccessLog /var/log/c-icap/access.log@";
- $cicap_r[2] = "AccessLog $logdir/c-icap-access.log";
- $cicap_m[3] = "@ServerLog /var/log/c-icap/server.log@";
- $cicap_r[3] = "ServerLog $logdir/c-icap-server.log";
- file_put_contents(SQUID_LOCALBASE . "/etc/c-icap/c-icap.conf.sample", preg_replace($cicap_m, $cicap_r, $sample_file), LOCK_EX);
- }
- // freshclam.conf
- // make a backup of default freshclam.conf.sample first
- if (!file_exists(SQUID_LOCALBASE . "/etc/freshclam.conf.default")) {
- copy(SQUID_LOCALBASE . "/etc/freshclam.conf.sample", SQUID_LOCALBASE . "/etc/freshclam.conf.default");
- }
- if (file_exists(SQUID_LOCALBASE . "/etc/freshclam.conf.default")) {
- $sample_file = file_get_contents(SQUID_LOCALBASE . "/etc/freshclam.conf.default");
- $freshclam_m[0] = "@#Example@";
- $freshclam_r[0] = "";
- $clamav_mirrors = "";
- if ($antivirus_config['clamav_dbregion'] != "") {
- $clamav_mirrors .= "DatabaseMirror db.{$antivirus_config['clamav_dbregion']}.clamav.net\n";
- }
- if ($antivirus_config['clamav_dbservers'] != "") {
- foreach (explode(";", $antivirus_config['clamav_dbservers']) as $dbserver) {
- $clamav_mirrors .= "DatabaseMirror {$dbserver}\n";
- }
- }
- if ($clamav_mirrors != "") {
- $freshclam_m[1] = "@#DatabaseMirror db.XY.clamav.net@";
- $freshclam_r[1] = "{$clamav_mirrors}";
- }
- if ($antivirus_config['clamav_safebrowsing'] == "on") {
- $freshclam_m[2] = "@#SafeBrowsing yes@";
- $freshclam_r[2] = "SafeBrowsing yes";
- }
- file_put_contents(SQUID_LOCALBASE . "/etc/freshclam.conf.sample", preg_replace($freshclam_m, $freshclam_r, $sample_file), LOCK_EX);
- }
- // freshclam cronjob
- squid_install_freshclam_cron(true);
-
- // check squidclamav files until PBIs are gone (https://redmine.pfsense.org/issues/4197)
- $ln_icap = array('bin/c-icap', 'bin/c-icap-client', 'c-icap-config', 'c-icap-libicapapi-config', 'c-icap-stretch', 'lib/c_icap', 'share/c_icap', 'etc/c-icap');
- foreach ($ln_icap as $ln) {
- if (SQUID_LOCALBASE != '/usr/local' && !file_exists("/usr/local/{$ln}") && file_exists(SQUID_LOCALBASE . "/{$ln}")) {
- symlink(SQUID_LOCALBASE . "/{$ln}", "/usr/local/{$ln}");
- }
- }
- if (SQUID_LOCALBASE != '/usr/local' && !file_exists("/usr/local/lib/libicapapi.so.3") && file_exists(SQUID_LOCALBASE . "/lib/libicapapi.so.3.0.5")) {
- symlink(SQUID_LOCALBASE . "/lib/libicapapi.so.3.0.5", "/usr/local/lib/libicapapi.so.3");
- }
-
- $loadsample = 0;
- if ($antivirus_config['squidclamav'] == "" && file_exists(SQUID_LOCALBASE . "/etc/c-icap/squidclamav.conf.sample")) {
- $config['installedpackages']['squidantivirus']['config'][0]['squidclamav'] = base64_encode(str_replace("\r", "", file_get_contents(SQUID_LOCALBASE . "/etc/c-icap/squidclamav.conf.sample")));
- $loadsample++;
- }
- if ($antivirus_config['c-icap_conf'] == "" && file_exists(SQUID_LOCALBASE . "/etc/c-icap/c-icap.conf.sample")) {
- $config['installedpackages']['squidantivirus']['config'][0]['c-icap_conf'] = base64_encode(str_replace("\r", "", file_get_contents(SQUID_LOCALBASE . "/etc/c-icap/c-icap.conf.sample")));
- $loadsample++;
- }
- if ($antivirus_config['c-icap_magic'] == "" && file_exists(SQUID_LOCALBASE . "/etc/c-icap/c-icap.magic.sample")) {
- $config['installedpackages']['squidantivirus']['config'][0]['c-icap_magic'] = base64_encode(str_replace("\r", "", file_get_contents(SQUID_LOCALBASE . "/etc/c-icap/c-icap.magic.sample")));
- $loadsample++;
- }
- if ($antivirus_config['freshclam_conf'] == "" && file_exists(SQUID_LOCALBASE . "/etc/freshclam.conf.sample")) {
- $config['installedpackages']['squidantivirus']['config'][0]['freshclam_conf'] = base64_encode(str_replace("\r", "", file_get_contents(SQUID_LOCALBASE . "/etc/freshclam.conf.sample")));
- $loadsample++;
- }
- if ($loadsample > 0) {
- write_config();
- $antivirus_config = $config['installedpackages']['squidantivirus']['config'][0];
- }
- // check dirs
- $dirs = array(
- "/var/run/c-icap" => "clamav",
- "/var/log/c-icap" => "clamav",
- "/var/log/clamav" => "clamav",
- "/var/run/clamav" => "clamav",
- "/var/db/clamav" => "clamav"
- );
- foreach ($dirs as $dir_path => $dir_user) {
- safe_mkdir($dir_path, 0755);
- squid_chown_recursive($dir_path, $dir_user, "wheel");
- }
-
- $rcd_files = scandir(SQUID_LOCALBASE."/etc/rc.d");
- foreach ($rcd_files as $rcd_file) {
- if (SQUID_LOCALBASE != '/usr/local' && !file_exists("/usr/local/etc/rc.d/{$rcd_file}")) {
- symlink(SQUID_LOCALBASE . "/etc/rc.d/{$rcd_file}", "/usr/local/etc/rc.d/{$rcd_file}");
- }
- }
-
- // write advanced clamav/icap config files
- file_put_contents(SQUID_LOCALBASE . "/etc/c-icap/squidclamav.conf", base64_decode($antivirus_config['squidclamav']), LOCK_EX);
- file_put_contents(SQUID_LOCALBASE . "/etc/c-icap/c-icap.conf", base64_decode($antivirus_config['c-icap_conf']), LOCK_EX);
- file_put_contents(SQUID_LOCALBASE . "/etc/c-icap/c-icap.magic", base64_decode($antivirus_config['c-icap_magic']), LOCK_EX);
- file_put_contents(SQUID_LOCALBASE . "/etc/freshclam.conf", base64_decode($antivirus_config['freshclam_conf']), LOCK_EX);
-
- // Check clamav database
- if (count(glob("/var/db/clamav/*d")) == 0) {
- log_error("Squid - Missing /var/db/clamav/*.cvd or *.cld files. Running freshclam in background.");
- mwexec_bg(SQUID_BASE . "/bin/freshclam --config-file=" . SQUID_BASE . "/etc/freshclam.conf");
- } elseif (($antivirus_config['clamav_safebrowsing'] == "on") && (!is_file("/var/db/clamav/safebrowsing.cvd"))) {
- log_error("Squid - Google Safe Browsing is enabled but missing safebrowsing.cvd definitions. Running freshclam in background.");
- mwexec_bg(SQUID_BASE . "/bin/freshclam --config-file=" . SQUID_BASE . "/etc/freshclam.conf");
- }
-
- // check antivirus daemons
- // check icap
- $c_icap_rcfile = "/usr/local/etc/rc.d/c-icap.sh";
- if (!file_exists($c_icap_rcfile)) {
- squid_write_cicap_rcfile();
- }
- if (is_process_running("c-icap")) {
- mwexec_bg('/bin/echo -n "reconfigure" > /var/run/c-icap/c-icap.ctl');
- } else {
- mwexec_bg("{$c_icap_rcfile} start");
- }
- // check clamav/freshclam
- $rc_files = array("clamav-freshclam", "clamav-clamd");
- $clamm[0] = "@/usr/local/(bin|sbin)@";
- $clamm[1] = "@/local/(bin|sbin)@";
- $clamm[2] = "@/usr/local/etc@";
- $clamm[3] = "@enable:=NO@";
- $clamr[0] = SQUID_BASE . "/bin";
- $clamr[1] = "/bin";
- $clamr[2] = SQUID_LOCALBASE . "/etc";
- $clamr[3] = "enable:=YES";
- foreach ($rc_files as $rc_file) {
- $clamav_rcfile = "/usr/local/etc/rc.d/{$rc_file}";
- if (file_exists($clamav_rcfile)) {
- $sample_file = file_get_contents($clamav_rcfile);
- file_put_contents($clamav_rcfile, preg_replace($clamm, $clamr, $sample_file), LOCK_EX);
- }
- }
- if (is_process_running("clamd")) {
- mwexec_bg("/usr/local/etc/rc.d/clamav-clamd reload");
- } else {
- mwexec_bg("/usr/local/etc/rc.d/clamav-clamd start");
- }
- } else {
- // stop AV services and disable all C-ICAP/AV features
- log_error("Squid antivirus features disabled.");
- if (is_process_running("clamd")) {
- log_error("Stopping ClamAV...");
- mwexec("/bin/ps awux | /usr/bin/grep '[c]lamd' | /usr/bin/awk '{ print $2 }' | /usr/bin/xargs kill");
- }
- if (is_process_running("c-icap")) {
- log_error("Stopping C-ICAP...");
- mwexec_bg("/usr/local/etc/rc.d/c-icap.sh stop");
- }
- // freshclam cronjob
- log_error("Removing freshclam cronjob...");
- squid_install_freshclam_cron(false);
-
- // check if clamav is enabled in rc.conf.local
- // XXX: This whole thing sucks and should be redone to install/enable services in pfSense way
- if (file_exists("/etc/rc.conf.local")) {
- log_error("Removing antivirus services from /etc/rc.conf.local...");
- $sample_file = file_get_contents("/etc/rc.conf.local");
- $rcconf_local_m[0] = "@clamav_clamd_enable(.*)\n@";
- $rcconf_local_r[0] = "";
- file_put_contents("/etc/rc.conf.local", preg_replace($rcconf_local_m, $rcconf_local_r, $sample_file), LOCK_EX);
- }
- }
-
- return $conf;
-}
-
+/* Proxy server: Traffic Management configuration handler */
function squid_resync_traffic() {
global $config, $valid_acls;
@@ -1871,19 +1672,7 @@ EOD;
return $conf;
}
-function squid_get_server_certs() {
- global $config;
- $cert_arr = array();
- $cert_arr[] = array('refid' => 'none', 'descr' => 'none');
- foreach ($config['cert'] as $cert) {
- $cert_arr[] = array('refid' => $cert['refid'], 'descr' => $cert['descr']);
- }
- return $cert_arr;
-}
-
-// squid reverse
-include('/usr/local/pkg/squid_reverse.inc');
-
+/* Proxy Server: Authentication configuration handler */
function squid_resync_auth() {
global $config, $valid_acls;
$write_config = 0;
@@ -2106,6 +1895,7 @@ EOD;
return $conf;
}
+/* Proxy server: Local users configuration handler */
function squid_resync_users() {
global $config;
@@ -2121,6 +1911,7 @@ function squid_resync_users() {
chmod(SQUID_PASSWD, 0600);
}
+/* Proxy server: NT Domain configuration handler */
function squid_resync_msnt() {
global $config;
@@ -2138,6 +1929,7 @@ function squid_resync_msnt() {
chmod(SQUID_CONFBASE . "/msntauth.conf", 0600);
}
+/* Wrapper function to sync whole Squid configuration */
function squid_resync($via_rpc = "no") {
global $config;
@@ -2150,7 +1942,7 @@ function squid_resync($via_rpc = "no") {
}
}
- log_error("[Squid] - Squid_resync function call pr:" . is_process_running('squid') . " bp:" . isset($boot_process) . " rpc:" . $via_rpc);
+ log_error("[squid] - squid_resync function call pr:" . is_process_running('squid') . " bp:" . isset($boot_process) . " rpc:" . $via_rpc);
if (is_process_running('squid') && isset($boot_process) && $via_rpc == "no") {
return;
@@ -2163,7 +1955,6 @@ function squid_resync($via_rpc = "no") {
}
$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";
@@ -2195,223 +1986,9 @@ function squid_resync($via_rpc = "no") {
conf_mount_ro();
}
-function squid_stop_monitor() {
- /* kill any running proxy alarm scripts */
- if (exec("/bin/ps auxw | /usr/bin/grep '[s]qpmon'")) {
- log_error("Stopping any running proxy monitors");
- mwexec("/usr/local/etc/rc.d/sqp_monitor.sh stop");
- }
- sleep(1);
-}
-
-function squid_start_monitor() {
- if (!exec("/bin/ps auxw | /usr/bin/grep '[s]qpmon'")) {
- log_error("Starting a proxy monitor script");
- mwexec_bg("/usr/local/etc/rc.d/sqp_monitor.sh start");
- }
- sleep(1);
-}
-
-function squid_restart_services() {
- global $config;
- // reconfigure and (re)start service as needed if enabled, otherwise stop them
- // do not (re)start squid services on boot
- if (platform_booting()) {
- return;
- }
- $squid_enabled = false;
- if (is_array($config['installedpackages']['squid']['config'])) {
- // check if Squid is enabled
- if ($config['installedpackages']['squid']['config'][0]['active_interface'] != "") {
- $squid_enabled = true;
- }
- } elseif (is_array($config['installedpackages']['squidreversegeneral']['config'])) {
- // check if squidreverse is enabled
- if ($config['installedpackages']['squidreversegeneral']['config'][0]['reverse_interface'] != "") {
- $squid_enabled = true;
- }
- }
-
- if ($squid_enabled) {
- /* kill any running proxy alarm scripts */
- squid_stop_monitor();
-
- if (!is_service_running('squid')) {
- log_error("Starting Squid");
- mwexec(SQUID_BASE . "/sbin/squid -f " . SQUID_CONFFILE);
- } else {
- log_error("Reloading Squid for configuration sync");
- mwexec(SQUID_BASE . "/sbin/squid -k reconfigure -f " . SQUID_CONFFILE);
- }
- // sleep for a couple seconds to give squid a chance to fire up fully.
- for ($i = 0; $i < 10; $i++) {
- if (!is_service_running('squid')) {
- sleep(1);
- }
- }
- /* restart proxy alarm scripts */
- squid_start_monitor();
-
- } else {
- /* Squid is disabled - kill any running proxy alarm scripts and stop Squid services */
- squid_stop_monitor();
- if (is_service_running('squid')) {
- log_error("Stopping Squid");
- stop_service("squid");
- }
- }
-}
-
-function squid_print_javascript_auth() {
- global $config;
- $transparent_proxy = ($config['installedpackages']['squid']['config'][0]['transparent_proxy'] == 'on');
-
- // No authentication for transparent proxy
- if ($transparent_proxy and preg_match("/(local|ldap|radius|msnt|ntlm)/",$config['installedpackages']['squidauth']['config'][0]['auth_method'])) {
- $javascript = <<< EOD
-<script type="text/javascript">
-<!--
-function on_auth_method_changed() {
- document.iform.auth_method.disabled = 1;
- document.iform.auth_server.disabled = 1;
- document.iform.auth_ntdomain.disabled = 1;
- document.iform.auth_server_port.disabled = 1;
- document.iform.ldap_user.disabled = 1;
- document.iform.ldap_version.disabled = 1;
- document.iform.ldap_userattribute.disabled = 1;
- document.iform.ldap_filter.disabled = 1;
- document.iform.ldap_pass.disabled = 1;
- document.iform.ldap_basedomain.disabled = 1;
- document.iform.radius_secret.disabled = 1;
- document.iform.msnt_secondary.disabled = 1;
- document.iform.auth_prompt.disabled = 1;
- document.iform.auth_processes.disabled = 1;
- document.iform.auth_ttl.disabled = 1;
- document.iform.unrestricted_auth.disabled = 1;
- document.iform.no_auth_hosts.disabled = 1;
-}
--->
-</script>
-
-EOD;
- } else {
- $javascript = <<< EOD
-<script type="text/javascript">
-<!--
-function on_auth_method_changed() {
- var field = document.iform.auth_method;
- var auth_method = field.options[field.selectedIndex].value;
-
- if (auth_method == 'none') {
- document.iform.auth_server.disabled = 1;
- document.iform.auth_server_port.disabled = 1;
- document.iform.auth_ntdomain.disabled = 1;
- document.iform.ldap_user.disabled = 1;
- document.iform.ldap_version.disabled = 1;
- document.iform.ldap_userattribute.disabled = 1;
- document.iform.ldap_filter.disabled = 1;
- document.iform.ldap_pass.disabled = 1;
- document.iform.ldap_basedomain.disabled = 1;
- document.iform.radius_secret.disabled = 1;
- document.iform.msnt_secondary.disabled = 1;
- document.iform.auth_prompt.disabled = 1;
- document.iform.auth_processes.disabled = 1;
- document.iform.auth_ttl.disabled = 1;
- document.iform.unrestricted_auth.disabled = 1;
- document.iform.no_auth_hosts.disabled = 1;
- } else {
- document.iform.auth_prompt.disabled = 0;
- document.iform.auth_processes.disabled = 0;
- document.iform.auth_ttl.disabled = 0;
- document.iform.unrestricted_auth.disabled = 0;
- document.iform.no_auth_hosts.disabled = 0;
- }
-
- switch (auth_method) {
- case 'local':
- document.iform.auth_server.disabled = 1;
- document.iform.auth_server_port.disabled = 1;
- document.iform.auth_ntdomain.disabled = 1;
- document.iform.ldap_user.disabled = 1;
- document.iform.ldap_pass.disabled = 1;
- document.iform.ldap_version.disabled = 1;
- document.iform.ldap_userattribute.disabled = 1;
- document.iform.ldap_filter.disabled = 1;
- document.iform.ldap_basedomain.disabled = 1;
- document.iform.radius_secret.disabled = 1;
- document.iform.msnt_secondary.disabled = 1;
- break;
- case 'ldap':
- document.iform.auth_server.disabled = 0;
- document.iform.auth_server_port.disabled = 0;
- document.iform.ldap_user.disabled = 0;
- document.iform.ldap_pass.disabled = 0;
- document.iform.ldap_version.disabled = 0;
- document.iform.ldap_userattribute.disabled = 0;
- document.iform.ldap_filter.disabled = 0;
- document.iform.ldap_basedomain.disabled = 0;
- document.iform.radius_secret.disabled = 1;
- document.iform.msnt_secondary.disabled = 1;
- document.iform.auth_ntdomain.disabled = 1;
- break;
- case 'radius':
- document.iform.auth_server.disabled = 0;
- document.iform.auth_server_port.disabled = 0;
- document.iform.ldap_user.disabled = 1;
- document.iform.ldap_pass.disabled = 1;
- document.iform.ldap_version.disabled = 1;
- document.iform.ldap_userattribute.disabled = 1;
- document.iform.ldap_filter.disabled = 1;
- document.iform.ldap_basedomain.disabled = 1;
- document.iform.radius_secret.disabled = 0;
- document.iform.msnt_secondary.disabled = 1;
- document.iform.auth_ntdomain.disabled = 1;
- break;
- case 'msnt':
- document.iform.auth_server.disabled = 0;
- document.iform.auth_server_port.disabled = 1;
- document.iform.auth_ntdomain.disabled = 0;
- document.iform.ldap_user.disabled = 1;
- document.iform.ldap_pass.disabled = 1;
- document.iform.ldap_version.disabled = 1;
- document.iform.ldap_userattribute.disabled = 1;
- document.iform.ldap_filter.disabled = 1;
- document.iform.ldap_basedomain.disabled = 1;
- document.iform.radius_secret.disabled = 1;
- document.iform.msnt_secondary.disabled = 0;
- break;
- case 'cp':
- document.iform.auth_server.disabled = 1;
- document.iform.auth_server_port.disabled = 1;
- document.iform.auth_ntdomain.disabled = 1;
- document.iform.ldap_user.disabled = 1;
- document.iform.ldap_version.disabled = 1;
- document.iform.ldap_userattribute.disabled = 1;
- document.iform.ldap_filter.disabled = 1;
- document.iform.ldap_pass.disabled = 1;
- document.iform.ldap_basedomain.disabled = 1;
- document.iform.radius_secret.disabled = 1;
- document.iform.msnt_secondary.disabled = 1;
- document.iform.auth_prompt.disabled = 1;
- document.iform.auth_processes.disabled = 0;
- document.iform.auth_ttl.disabled = 0;
- document.iform.unrestricted_auth.disabled = 1;
- document.iform.no_auth_hosts.disabled = 1;
- break;
- }
-}
--->
-</script>
-
-EOD;
- }
-
- print($javascript);
-}
-
-function squid_print_javascript_auth2() {
- print("<script type=\"text/javascript\">on_auth_method_changed()</script>\n");
-}
+/*
+ * Squid firewall rules configuration
+ */
function squid_generate_rules($type) {
global $config, $pfs_version;
@@ -2422,7 +1999,7 @@ function squid_generate_rules($type) {
$port = ($settings['proxy_port'] ? $settings['proxy_port'] : 3128);
$cp_inc = file($cp_file);
$new_cp_inc = "";
- $found_rule=0;
+ $found_rule = 0;
foreach ($cp_inc as $line) {
$new_line = $line;
//remove applied squid patch
@@ -2444,13 +2021,20 @@ function squid_generate_rules($type) {
if ($found_rule > 0) {
file_put_contents($cp_file, $new_cp_inc, LOCK_EX);
}
+
+ // do not install any firewall rules if Squid is disabled
+ if (!squid_enabled()) {
+ log_error("[squid] Installed but disabled. Not installing '{$type}' rules.");
+ return;
+ }
+
// normal squid rule check
if (($squid_conf['transparent_proxy'] != 'on') || ($squid_conf['allow_interface'] != 'on')) {
return;
}
if (!is_service_running('squid')) {
- log_error("Squid is installed but not started. Not installing \"{$type}\" rules.");
+ log_error("[squid] Installed but not started. Not installing '{$type}' rules.");
return;
}
// Read assigned interfaces
@@ -2460,13 +2044,13 @@ function squid_generate_rules($type) {
$transparent_ifaces = explode(",", $squid_conf['transparent_active_interface']);
$transparent_ifaces = array_map('convert_friendly_interface_to_real_interface_name', $transparent_ifaces);
} else {
- $transparent_ifaces=array();
+ $transparent_ifaces = array();
}
if ($squid_conf['ssl_proxy'] == "on") {
$ssl_ifaces = explode(",", $squid_conf['ssl_active_interface']);
$ssl_ifaces = array_map('convert_friendly_interface_to_real_interface_name', $ssl_ifaces);
} else {
- $ssl_ifaces=array();
+ $ssl_ifaces = array();
}
$port = ($squid_conf['proxy_port'] ? $squid_conf['proxy_port'] : 3128);
@@ -2595,73 +2179,11 @@ function squid_generate_rules($type) {
return $rules;
}
-function squid_write_rcfile() {
- /* Declare a variable for the SQUID_CONFFILE constant. */
- /* Then the variable can be referenced easily in the heredoc text that generates the rc file. */
- $squid_conffile_var = SQUID_CONFFILE;
- $squid_base = SQUID_BASE;
- $rc = array();
- $rc['file'] = 'squid.sh';
- $rc['start'] = <<< EOD
-#/sbin/sysctl net.inet.ip.portrange.reservedhigh=0
-if [ -z "`/bin/ps auxw | /usr/bin/grep "[s]quid " | /usr/bin/awk '{print $2}'`" ]; then
- {$squid_base}/sbin/squid -f {$squid_conffile_var}
-fi
-
-EOD;
-
- $rc['stop'] = <<< EOD
-{$squid_base}/sbin/squid -k shutdown -f {$squid_conffile_var}
-# Just to be sure...
-sleep 5
-if [ -n "`/bin/ps auxw | /usr/bin/grep "[s]quid " | /usr/bin/awk '{print $2}'`" ]; then
- {$squid_base}/sbin/squid -k kill -f {$squid_conffile_var}
-fi
-
-if [ -x /usr/bin/ipcs ]; then
-# http://man.chinaunix.net/newsoft/squid/Squid_FAQ/FAQ-22.html#ss22.8
-/usr/bin/ipcs | /usr/bin/grep '^[mq]' | /usr/bin/awk '{printf "ipcrm -%s %s\\n", $1, $2}' | /bin/sh
-fi
-
-/usr/bin/killall -9 squid 2>/dev/null
-/usr/bin/killall pinger 2>/dev/null
-
-EOD;
- $rc['restart'] = <<< EOD
-if [ -z "`ps auxw | /usr/bin/grep "[s]quid " | /usr/bin/awk '{print $2}'`" ]; then
- {$squid_base}/sbin/squid -f {$squid_conffile_var}
- else
- {$squid_base}/sbin/squid -k reconfigure -f {$squid_conffile_var}
- fi
-
-EOD;
- conf_mount_rw();
- write_rcfile($rc);
- // force delete the PBI initscript that keeps creeping back
- unlink_if_exists("/usr/local/etc/rc.d/squid");
- conf_mount_ro();
-}
-
-function squid_write_cicap_rcfile() {
- $c_icap_rcfile = "c-icap.sh";
- $cicap_libdir = SQUID_LOCALBASE . "/lib";
- $cicap_bin = SQUID_LOCALBASE . "/bin/c-icap";
- $cicap_conf = SQUID_LOCALBASE . "/etc/c-icap/c-icap.conf";
- $cicap_start_cmd = "LD_LIBRARY_PATH={$cicap_libdir} {$cicap_bin} -f {$cicap_conf}";
- $cicap_stop_cmd = '/bin/echo -n "stop" > /var/run/c-icap/c-icap.ctl';
- conf_mount_rw();
- write_rcfile(array(
- "file" => "{$c_icap_rcfile}",
- "start" => "{$cicap_start_cmd}",
- "stop" => "{$cicap_stop_cmd}"
- )
- );
- // force delete the PBI initscript that keeps creeping back
- unlink_if_exists("/usr/local/etc/rc.d/c-icap");
- conf_mount_ro();
-}
+/*
+ * Squid XMLRPC sync
+ */
-/* Uses XMLRPC to synchronize the changes to a remote node */
+/* XMLRPC sync configuration */
function squid_sync_on_changes() {
global $config, $g;
if (is_array($config['installedpackages']['squidsync']['config'])) {
@@ -2710,19 +2232,12 @@ function squid_sync_on_changes() {
}
}
}
-/* Do the actual XMLRPC sync */
+
+/* Perform the actual XMLRPC sync */
function squid_do_xmlrpc_sync($sync_to_ip, $username, $password, $synctimeout) {
global $config, $g;
- if (!$username) {
- return;
- }
-
- if (!$password) {
- return;
- }
-
- if (!$sync_to_ip) {
+ if (!$username || !$password || !$sync_to_ip) {
return;
}
@@ -2730,7 +2245,6 @@ function squid_do_xmlrpc_sync($sync_to_ip, $username, $password, $synctimeout) {
$synctimeout = 250;
}
-
$xmlrpc_sync_neighbor = $sync_to_ip;
if ($config['system']['webgui']['protocol'] != "") {
$synchronizetoip = $config['system']['webgui']['protocol'];
@@ -2739,10 +2253,7 @@ function squid_do_xmlrpc_sync($sync_to_ip, $username, $password, $synctimeout) {
$port = $config['system']['webgui']['port'];
/* If port is empty let's rely on the protocol selection */
if ($port == "") {
- if ($config['system']['webgui']['protocol'] == "http")
- $port = "80";
- else
- $port = "443";
+ $port = $config['system']['webgui']['protocol'] == "http" ? "80" : "443";
}
$synchronizetoip .= $sync_to_ip;
@@ -2767,7 +2278,7 @@ function squid_do_xmlrpc_sync($sync_to_ip, $username, $password, $synctimeout) {
/* Set a few variables needed for sync */
$url = $synchronizetoip;
- log_error("[squid] Beginning Squid XMLRPC sync to {$url}:{$port}.");
+ log_error("[squid] Beginning XMLRPC sync to {$url}:{$port}.");
$method = 'pfsense.merge_installedpackages_section_xmlrpc';
$msg = new XML_RPC_Message($method, $params);
$cli = new XML_RPC_Client('/xmlrpc.php', $url, $port);
@@ -2778,13 +2289,13 @@ function squid_do_xmlrpc_sync($sync_to_ip, $username, $password, $synctimeout) {
/* Send our XMLRPC message and timeout after defined sync timeout value*/
$resp = $cli->send($msg, $synctimeout);
if (!$resp) {
- $error = "A communication error occurred while attempting Squid XMLRPC sync with {$url}:{$port}.";
+ $error = "[squid] Communication error occurred while attempting XMLRPC sync with {$url}:{$port}.";
log_error($error);
file_notice("sync_settings", $error, "Squid Settings Sync", "");
} elseif ($resp->faultCode()) {
$cli->setDebug(1);
$resp = $cli->send($msg, $synctimeout);
- $error = "An error code was received while attempting Squid XMLRPC sync with {$url}:{$port} - Code " . $resp->faultCode() . ": " . $resp->faultString();
+ $error = "[squid] An error code was received while attempting XMLRPC sync with {$url}:{$port} - Code " . $resp->faultCode() . ": " . $resp->faultString();
log_error($error);
file_notice("sync_settings", $error, "Squid Settings Sync", "");
} else {
@@ -2807,17 +2318,17 @@ function squid_do_xmlrpc_sync($sync_to_ip, $username, $password, $synctimeout) {
$cli->setCredentials($username, $password);
$resp = $cli->send($msg, $synctimeout);
if (!$resp) {
- $error = "A communication error occurred while attempting Squid XMLRPC sync with {$url}:{$port} (pfsense.exec_php).";
+ $error = "[squid] Communication error occurred while attempting XMLRPC sync with {$url}:{$port} (pfsense.exec_php).";
log_error($error);
file_notice("sync_settings", $error, "Squid Settings Sync", "");
} elseif ($resp->faultCode()) {
$cli->setDebug(1);
$resp = $cli->send($msg, $synctimeout);
- $error = "[Squid] An error code was received while attempting Squid XMLRPC sync with {$url}:{$port} - Code " . $resp->faultCode() . ": " . $resp->faultString();
+ $error = "[squid] An error code was received while attempting XMLRPC sync with {$url}:{$port} - Code " . $resp->faultCode() . ": " . $resp->faultString();
log_error($error);
file_notice("sync_settings", $error, "Squid Settings Sync", "");
} else {
- log_error("Squid XMLRPC reload data success with {$url}:{$port} (pfsense.exec_php).");
+ log_error("[squid] XMLRPC reload data success with {$url}:{$port} (pfsense.exec_php).");
}
}
diff --git a/config/squid3/34/squid.xml b/config/squid3/34/squid.xml
index dda924f8..ccaca843 100644
--- a/config/squid3/34/squid.xml
+++ b/config/squid3/34/squid.xml
@@ -42,7 +42,7 @@
]]>
</copyright>
<name>squid</name>
- <version>0.3.7</version>
+ <version>0.3.9</version>
<title>Proxy Server: General Settings</title>
<include_file>/usr/local/pkg/squid.inc</include_file>
<menu>
@@ -65,7 +65,7 @@
</service>
<service>
<name>clamd</name>
- <rcfile>clamav-clamd</rcfile>
+ <rcfile>clamd.sh</rcfile>
<executable>clamd</executable>
<description>ClamAV Antivirus</description>
</service>
@@ -125,6 +125,14 @@
</additional_files_needed>
<additional_files_needed>
<prefix>/usr/local/pkg/</prefix>
+ <item>https://packages.pfsense.org/packages/config/squid3/34/squid_antivirus.inc</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <item>https://packages.pfsense.org/packages/config/squid3/34/squid_js.inc</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
<item>https://packages.pfsense.org/packages/config/squid3/34/squid_reverse.inc</item>
</additional_files_needed>
<additional_files_needed>
@@ -155,10 +163,6 @@
</additional_files_needed>
<additional_files_needed>
<prefix>/usr/local/pkg/</prefix>
- <item>https://packages.pfsense.org/packages/config/squid3/34/squid_reverse.xml</item>
- </additional_files_needed>
- <additional_files_needed>
- <prefix>/usr/local/pkg/</prefix>
<item>https://packages.pfsense.org/packages/config/squid3/34/squid_reverse_general.xml</item>
</additional_files_needed>
<additional_files_needed>
@@ -237,6 +241,29 @@
<type>listtopic</type>
</field>
<field>
+ <fielddescr>Enable Squid Proxy</fielddescr>
+ <fieldname>enable_squid</fieldname>
+ <description>
+ <![CDATA[
+ Check to enable the Squid proxy.<br/>
+ Note: If unchecked, <strong>all</strong> Squid services will be disabled and stopped.<br/>
+ ]]>
+ </description>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <fielddescr>Keep Settings/Data</fielddescr>
+ <fieldname>keep_squid_data</fieldname>
+ <description>
+ <![CDATA[
+ If enabled, the settings, logs, cache, AV defs and other data will be preserved across package reinstalls.<br/>
+ <strong><span class="errmsg">Note:</span> If disabled, all settings and data will be wiped on package uninstall/reinstall/upgrade.</strong>
+ ]]>
+ </description>
+ <type>checkbox</type>
+ <default_value>on</default_value>
+ </field>
+ <field>
<fielddescr>Proxy Interface(s)</fielddescr>
<fieldname>active_interface</fieldname>
<description>
@@ -496,23 +523,23 @@
<type>listtopic</type>
</field>
<field>
- <fielddescr>Enable Logging</fielddescr>
+ <fielddescr>Enable Access Logging</fielddescr>
<fieldname>log_enabled</fieldname>
<description>
<![CDATA[
- This will enable the access log.
+ This will enable the <strong>access</strong> log.
<strong>Warning:</strong> Do not switch this on if you don't have much disk space left.
]]>
</description>
<type>checkbox</type>
- <enablefields>log_dir,log_rotate</enablefields>
+ <enablefields>log_rotate</enablefields>
</field>
<field>
<fielddescr>Log Store Directory</fielddescr>
<fieldname>log_dir</fieldname>
<description>
<![CDATA[
- The directory where the log will be stored.<br/>
+ The directory where the logs will be stored. This is also used for logs other than the Access Log above.<br/>
Default: /var/squid/logs<br/>
<strong>Note: Do NOT include the trailing / when setting a custom location.</strong>
]]>
@@ -724,12 +751,7 @@
squid_resync();
</custom_php_resync_config_command>
<custom_php_install_command>
- <![CDATA[
- update_output_window("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_command();
- unlink_if_exists("/usr/local/etc/rc.d/squid");
- unlink_if_exists("/usr/local/etc/rc.d/c-icap");
- ]]>
</custom_php_install_command>
<custom_php_deinstall_command>
squid_deinstall_command();
diff --git a/config/squid3/34/squid_antivirus.inc b/config/squid3/34/squid_antivirus.inc
new file mode 100644
index 00000000..e047db93
--- /dev/null
+++ b/config/squid3/34/squid_antivirus.inc
@@ -0,0 +1,797 @@
+<?php
+/*
+ squid_antivirus.inc
+ part of pfSense (https://www.pfSense.org/)
+ Copyright (C) 2015 ESF, LLC
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+/* Functions for Squid C-ICAP/ClamAV integration */
+require_once('globals.inc');
+require_once('config.inc');
+/* This file is currently only being included in squid.inc and not used separately */
+// require_once('squid.inc');
+
+/*
+ * Utility functions
+ */
+
+/* clamav user account hadling (only needed for PBI/pfSense <2.3) */
+function squid_check_clamav_user($user) {
+ if (SQUID_BASE == '/usr/local') {
+ return;
+ }
+
+ $_gc = exec("/usr/sbin/pw usershow {$user}", $sq_ex_output, $sq_ex_return);
+ $user_arg = ($sq_ex_return == 0 ? "mod" : "add");
+ $_gc = exec("/usr/sbin/pw user{$user_arg} {$user} -G wheel -u 9595 -s /sbin/nologin", $sq_ex_output, $sq_ex_return);
+ if ($sq_ex_return != 0) {
+ log_error("[squid] Could not change clamav user settings. " . serialize($sq_ex_output));
+ }
+}
+
+/* Antivirus definitions updates via cron */
+function squid_install_freshclam_cron($should_install) {
+ global $config;
+
+ if (platform_booting()) {
+ return;
+ }
+
+ if (is_array($config['installedpackages']['squidantivirus'])) {
+ $antivirus_config = $config['installedpackages']['squidantivirus']['config'][0];
+ } else {
+ $antivirus_config = array();
+ }
+
+ $freshclam_cmd = (SQUID_BASE . "/bin/freshclam --config-file=" . SQUID_BASE . "/etc/freshclam.conf");
+ if (($should_install) && (squid_enabled())) {
+ if ($antivirus_config['clamav_update'] != "0") {
+ log_error("[squid] Adding freshclam cronjob.");
+ $minutes = ($antivirus_config['clamav_update'] * 60);
+ install_cron_job("{$freshclam_cmd}", true, "*/{$minutes}", "*", "*", "*", "*", "clamav");
+ } else {
+ log_error("[squid] Removing freshclam cronjob.");
+ install_cron_job("{$freshclam_cmd}", false);
+ }
+ } else {
+ log_error("[squid] Removing freshclam cronjob.");
+ install_cron_job("{$freshclam_cmd}", false);
+ }
+}
+
+/* Manually update ClamAV virus definitions via the GUI button */
+function squid_update_clamav() {
+ log_error("[squid] Updating ClamAV definitions now... This will take a while. Check /var/log/clamav/freshclam.log for progress information.");
+ mwexec_bg(SQUID_BASE . "/bin/freshclam --config-file=" . SQUID_BASE . "/etc/freshclam.conf");
+}
+
+/*
+ * Squid package install/uninstall
+ */
+
+/* Run on Squid package install */
+function squid_antivirus_install_command() {
+ // antivirus rc scripts
+ squid_write_cicap_rcfile();
+ squid_write_clamd_rcfile();
+
+ // antivirus config files
+ squid_antivirus_install_config_files();
+
+ // check squidclamav files until PBIs are gone (https://redmine.pfsense.org/issues/4197)
+ $ln_icap = array('bin/c-icap', 'bin/c-icap-client', 'c-icap-config', 'c-icap-libicapapi-config', 'c-icap-stretch', 'lib/c_icap', 'share/c_icap', 'etc/c-icap');
+ foreach ($ln_icap as $ln) {
+ if (SQUID_LOCALBASE != '/usr/local' && !file_exists("/usr/local/{$ln}") && file_exists(SQUID_LOCALBASE . "/{$ln}")) {
+ symlink(SQUID_LOCALBASE . "/{$ln}", "/usr/local/{$ln}");
+ }
+ }
+ if (SQUID_LOCALBASE != '/usr/local' && !file_exists("/usr/local/lib/libicapapi.so.3") && file_exists(SQUID_LOCALBASE . "/lib/libicapapi.so.3.0.5")) {
+ symlink(SQUID_LOCALBASE . "/lib/libicapapi.so.3.0.5", "/usr/local/lib/libicapapi.so.3");
+ }
+
+ // check dirs
+ $dirs = array(
+ "/var/run/c-icap" => "clamav",
+ "/var/log/c-icap" => "clamav",
+ "/var/log/clamav" => "clamav",
+ "/var/run/clamav" => "clamav",
+ "/var/db/clamav" => "clamav"
+ );
+ foreach ($dirs as $dir_path => $dir_user) {
+ safe_mkdir($dir_path, 0755);
+ squid_chown_recursive($dir_path, $dir_user, "wheel");
+ }
+
+ // remove unwanted PBI rc scripts
+ unlink_if_exists("/usr/local/etc/rc.d/c-icap");
+ unlink_if_exists("/usr/local/etc/rc.d/clamav-clamd");
+ unlink_if_exists("/usr/local/etc/rc.d/clamav-freshclam");
+}
+
+/* Run on Squid package uninstall */
+function squid_antivirus_deinstall_command() {
+ /* kill all running services */
+ if (is_process_running("c-icap")) {
+ mwexec('/bin/echo -n "stop" > /var/run/c-icap/c-icap.ctl');
+ }
+ mwexec("/bin/ps awux | /usr/bin/grep '[c]lamd' | /usr/bin/awk '{ print $2 }' | /usr/bin/xargs kill");
+ mwexec("/bin/ps awux | /usr/bin/grep '[f]reshclam' | /usr/bin/awk '{ print $2 }' | /usr/bin/xargs kill");
+
+ /* remove cronjobs */
+ squid_install_freshclam_cron(false);
+
+ /* delete rc scripts */
+ unlink_if_exists('/usr/local/etc/rc.d/squid.sh');
+ unlink_if_exists("/usr/local/etc/rc.d/c-icap.sh");
+ unlink_if_exists('/usr/local/etc/rc.d/clamd.sh');
+
+ /* clean up created PBI symlinks */
+ update_output_window("Finishing package cleanup.");
+ if (SQUID_LOCALBASE != '/usr/local') {
+ $ln_icap = array('bin/c-icap', 'bin/c-icap-client', 'c-icap-config', 'c-icap-libicapapi-config', 'c-icap-stretch', 'lib/c_icap', 'share/c_icap', 'etc/c-icap');
+ foreach ($ln_icap as $ln) {
+ if (is_link("/usr/local/{$ln}")) {
+ unlink("/usr/local/{$ln}");
+ }
+ }
+ if (is_link("/usr/local/lib/libicapapi.so.3")) {
+ unlink("/usr/local/lib/libicapapi.so.3");
+ }
+ }
+
+ /* clean up created directories if 'Keep Settings/Data' is disabled */
+ if (is_array($config['installedpackages']['squid'])) {
+ $squidsettings = $config['installedpackages']['squid']['config'][0];
+ } else {
+ $squidsettings = array();
+ }
+ $keep = ($squidsettings['keep_squid_data'] ? true : false);
+
+ if (!$keep) {
+ update_output_window("Removing antivirus definitions and logs ... One moment please...");
+ $dirs = array("/var/run/c-icap", "/var/log/c-icap", "/var/log/clamav", "/var/run/clamav", "/var/db/clamav");
+ foreach ($dirs as $dir) {
+ if (is_dir("{$dir}")) {
+ mwexec("/bin/rm -rf {$dir}");
+ }
+ }
+ }
+
+ /* check if clamav/c_icap is enabled in rc.conf.local */
+ // XXX: This hasn't been used since 0.3.7; to be removed in future
+ if (file_exists("/etc/rc.conf.local")) {
+ update_output_window("Removing antivirus services from /etc/rc.conf.local...");
+ $sample_file = file_get_contents("/etc/rc.conf.local");
+ $rcconf_local_m[0] = "@c_icap_enable(.*)\n@";
+ $rcconf_local_m[1] = "@clamav_clamd_enable(.*)\n@";
+ $rcconf_local_r[0] = "";
+ $rcconf_local_r[1] = "";
+ file_put_contents("/etc/rc.conf.local", preg_replace($rcconf_local_m, $rcconf_local_r, $sample_file), LOCK_EX);
+ }
+}
+
+/*
+ * Antivirus features configuration
+ *
+ * <file>.conf is the actual configuration file used for services.
+ * <file>.conf.pfsense is a template file patched for pfSense; should be never altered beyond initial install.
+ * <file>.conf.{sample,default} are templates distributed directly with PBI/package;
+ * If <file>.conf.default does not exist, a backup copy is made from another distributed files before patching it for pfSense.
+ *
+ * Configuration via the GUI options:
+ * <file>.conf is always (re)generated from the <file>.conf.pfsense on package resync,
+ * with additional patches depending on the GUI configuration options configured by user.
+ * Directly editing files via 'Advanced Features' is disabled in the GUI.
+ *
+ * Manual Configuration
+ * When the user enables 'Manual Configuration' for the first time, the config.xml settings are
+ * serialized from <file>.conf.pfsense template patched for pfSense. After this initial configuration,
+ * <file>.conf is always (re)generated from config.xml as long as 'Manual Configuration' is enabled in settings.
+ * In this case, any additional configuration made in the Antivirus GUI outside of 'Advanced Features'
+ * is unset on saving settings; after that, those options are disabled in the GUI and have no effect any more.
+ */
+
+/* Proxy Server: Antivirus configuration handler */
+function squid_resync_antivirus() {
+ global $config;
+
+ if (is_array($config['installedpackages']['squidantivirus'])) {
+ $antivirus_config = $config['installedpackages']['squidantivirus']['config'][0];
+ } else {
+ $antivirus_config = array();
+ }
+
+ // squid.conf antivirus integration
+ if (squid_enabled() && ($antivirus_config['enable'] == "on")) {
+ switch ($antivirus_config['client_info']) {
+ case "both":
+ default:
+ $icap_send_client_ip = "on";
+ $icap_send_client_username = "on";
+ break;
+ case "ip":
+ $icap_send_client_ip = "on";
+ $icap_send_client_username = "off";
+ break;
+ case "username":
+ $icap_send_client_ip = "off";
+ $icap_send_client_username = "on";
+ break;
+ case "none":
+ $icap_send_client_ip = "off";
+ $icap_send_client_username = "off";
+ break;
+ }
+
+ $conf = <<< EOF
+icap_enable on
+icap_send_client_ip {$icap_send_client_ip}
+icap_send_client_username {$icap_send_client_username}
+icap_client_username_encode off
+icap_client_username_header X-Authenticated-User
+icap_preview_enable on
+icap_preview_size 1024
+
+icap_service service_avi_req reqmod_precache icap://[::1]:1344/squid_clamav bypass=off
+adaptation_access service_avi_req allow all
+icap_service service_avi_resp respmod_precache icap://[::1]:1344/squid_clamav bypass=on
+adaptation_access service_avi_resp allow all
+
+EOF;
+
+ // check clamav user
+ squid_check_clamav_user('clamav');
+
+ if ($antivirus_config['enable_advanced'] == "enabled") {
+ // User is managing raw configuration, so we unset the configuration options set via GUI
+ squid_antivirus_toggle_raw_config(true);
+ // Generate the raw configuration if missing
+ $rawopts = array("raw_squidclamav_conf", "raw_cicap_conf", "raw_cicap_magic", "raw_freshclam_conf", "raw_clamd_conf");
+ foreach ($rawopts as $rawopt) {
+ if ($antivirus_config[$rawopt] == "") {
+ squid_antivirus_get_raw_config();
+ }
+ }
+ // Create configuration files
+ squid_antivirus_put_raw_config($config['installedpackages']['squidantivirus']['config'][0]);
+ } else {
+ // unset raw configuration options
+ squid_antivirus_toggle_raw_config(false);
+
+ // patch sample files to pfsense dirs
+ // squidclamav.conf
+ $cf = SQUID_LOCALBASE . "/etc/c-icap/squidclamav.conf";
+ if (file_exists("{$cf}.pfsense")) {
+ $sample_file = file_get_contents("{$cf}.pfsense");
+ if ($antivirus_config['clamav_safebrowsing'] == "on") {
+ $squidclamav_m[0] = "@safebrowsing\s0@";
+ $squidclamav_r[0] = "safebrowsing 1";
+ }
+ if ($antivirus_config['clamav_url'] != "") {
+ $squidclamav_m[1] = "@redirect http@";
+ $squidclamav_r[1] = "{$antivirus_config['clamav_url']}";
+ }
+ file_put_contents("{$cf}", preg_replace($squidclamav_m, $squidclamav_r, $sample_file), LOCK_EX);
+ } else {
+ log_error("[squid] Template not found; could not generate '{$cf}' file!");
+ }
+
+ // c-icap.conf
+ $cf = SQUID_LOCALBASE . "/etc/c-icap/c-icap.conf";
+ if (file_exists("{$cf}.pfsense")) {
+ $sample_file = file_get_contents("{$cf}.pfsense");
+ if (!preg_match("/squid_clamav/", $sample_file)) {
+ $sample_file .= "\nService squid_clamav squidclamav.so\n";
+ }
+ // XXX: Bug #4615
+ if (is_array($config['installedpackages']['squid'])) {
+ $squidsettings = $config['installedpackages']['squid']['config'][0];
+ } else {
+ $squidsettings = array();
+ }
+ $logdir = ($squidsettings['log_dir'] ? $squidsettings['log_dir'] : '/var/squid/logs');
+ $cicap_m[0] = "@DebugLevel\s1@";
+ $cicap_r[0] = "DebugLevel 0";
+ $cicap_m[1] = "@AccessLog /var/squid/logs/c-icap-access.log@";
+ $cicap_r[1] = "AccessLog {$logdir}/c-icap-access.log";
+ $cicap_m[2] = "@ServerLog /var/squid/logs/c-icap-server.log@";
+ $cicap_r[2] = "ServerLog {$logdir}/c-icap-server.log";
+ file_put_contents("{$cf}", preg_replace($cicap_m, $cicap_r, $sample_file), LOCK_EX);
+ } else {
+ log_error("[squid] Template not found; could not generate '{$cf}' file!");
+ }
+
+ // c-icap.magic
+ // just make a copy of pfSense template, nothing configurable via GUI options here
+ $cf = SQUID_LOCALBASE . "/etc/c-icap/c-icap.magic";
+ if (file_exists("{$cf}.pfsense")) {
+ copy("{$cf}.pfsense", "{$cf}");
+ } else {
+ log_error("[squid] Template not found; could not generate '{$cf}' file!");
+ }
+
+ // freshclam.conf
+ $cf = SQUID_LOCALBASE . "/etc/freshclam.conf";
+ if (file_exists("{$cf}.pfsense")) {
+ $sample_file = file_get_contents("{$cf}.pfsense");
+ $clamav_mirrors = "";
+ if ($antivirus_config['clamav_dbregion'] != "") {
+ $clamav_mirrors .= "DatabaseMirror db.{$antivirus_config['clamav_dbregion']}.clamav.net\n";
+ }
+ if ($antivirus_config['clamav_dbservers'] != "") {
+ foreach (explode(";", $antivirus_config['clamav_dbservers']) as $dbserver) {
+ $clamav_mirrors .= "DatabaseMirror {$dbserver}\n";
+ }
+ }
+ if ($clamav_mirrors != "") {
+ $freshclam_m[0] = "@#DatabaseMirror db.XY.clamav.net@";
+ $freshclam_r[0] = "{$clamav_mirrors}";
+ }
+ if ($antivirus_config['clamav_safebrowsing'] == "on") {
+ $freshclam_m[1] = "@#SafeBrowsing yes@";
+ $freshclam_r[1] = "SafeBrowsing yes";
+ }
+ file_put_contents("{$cf}", preg_replace($freshclam_m, $freshclam_r, $sample_file), LOCK_EX);
+ } else {
+ log_error("[squid] Template not found; could not generate '{$cf}' file!");
+ }
+
+ // clamd.conf
+ // just make a copy of pfSense template, nothing configurable via GUI options here
+ $cf = SQUID_LOCALBASE . "/etc/clamd.conf";
+ if (file_exists("{$cf}.pfsense")) {
+ copy("{$cf}.pfsense", "{$cf}");
+ } else {
+ log_error("[squid] Template not found; could not generate '{$cf}' file!");
+ }
+ unset($cf);
+ }
+
+ // freshclam cronjob
+ squid_install_freshclam_cron(true);
+
+ }
+ // this will (re)start or stop/disable services as needed
+ // depending on whether Squid proxy and/or antivirus features are enabled
+ squid_restart_antivirus();
+
+ return $conf;
+}
+
+/* Patch paths and settings in configuration files template for pfSense-specific values on install */
+function squid_antivirus_install_config_files() {
+ global $config;
+ if (is_array($config['installedpackages']['squid'])) {
+ $squidsettings = $config['installedpackages']['squid']['config'][0];
+ } else {
+ $squidsettings = array();
+ }
+ // squidclamav.conf
+ // there is no squidclamav.conf.sample packaged, use squidclamav.conf if really needed
+ $cf = SQUID_LOCALBASE . "/etc/c-icap/squidclamav.conf";
+ if (!file_exists("{$cf}.default")) {
+ copy("{$cf}", "{$cf}.default");
+ }
+ if (file_exists("{$cf}.default")) {
+ $sample_file = file_get_contents("{$cf}.default");
+ $squidclamav_m[0] = "@# SquidClamav default configuration file@";
+ $squidclamav_r[0] = "#This file was automatically generated by pfSense";
+ $squidclamav_m[1] = "@/var/run/clamav/clamd.ctl@";
+ $squidclamav_r[1] = "/var/run/clamav/clamd.sock";
+ $squidclamav_m[2] = "@http\://proxy.domain.dom/cgi-bin/clwarn.cgi@";
+ $squidclamav_r[2] = "{$config['system']['webgui']['protocol']}://{$config['system']['hostname']}.{$config['system']['domain']}/squid_clwarn.php";
+ file_put_contents("{$cf}.pfsense", preg_replace($squidclamav_m, $squidclamav_r, $sample_file), LOCK_EX);
+ } else {
+ log_error("[squid] Could not patch '{$cf}' template file!");
+ }
+
+ // c-icap.conf
+ // there is no c-icap.conf.sample packaged, use c-icap.conf if really needed
+ $cf = SQUID_LOCALBASE . "/etc/c-icap/c-icap.conf";
+ if (!file_exists("{$cf}.default")) {
+ copy("{$cf}", "{$cf}.default");
+ }
+ if (file_exists("{$cf}.default")) {
+ $sample_file = file_get_contents("{$cf}.default");
+ if (!preg_match("/squid_clamav/", $sample_file)) {
+ $sample_file .= "\nService squid_clamav squidclamav.so\n";
+ }
+ $cicap_m[0] = "@# This file contains the default settings for c-icap@";
+ $cicap_r[0] = "#This file was automatically generated by pfSense";
+ $cicap_m[1] = "@DebugLevel\s1@";
+ $cicap_r[1] = "DebugLevel 0";
+ $cicap_m[2] = "@AccessLog /var/log/c-icap/access.log@";
+ $cicap_r[2] = "AccessLog /var/squid/logs/c-icap-access.log";
+ $cicap_m[3] = "@ServerLog /var/log/c-icap/server.log@";
+ $cicap_r[3] = "ServerLog /var/squid/logs/c-icap-server.log";
+ file_put_contents("{$cf}.pfsense", preg_replace($cicap_m, $cicap_r, $sample_file), LOCK_EX);
+ } else {
+ log_error("[squid] Could not patch '{$cf}' template file!");
+ }
+
+ // c-icap.magic
+ // just make a backup and pfSense template copies of default c-icap.magic, we are not patching anything here
+ $cf = SQUID_LOCALBASE . "/etc/c-icap/c-icap.magic";
+ if (!file_exists("{$cf}.default")) {
+ copy("{$cf}.sample", "{$cf}.default");
+ }
+ if (!file_exists("{$cf}.pfsense")) {
+ copy("{$cf}.sample", "{$cf}.pfsense");
+ }
+
+ // clamd.conf
+ // make a backup of default clamd.conf.sample first
+ $cf = SQUID_LOCALBASE . "/etc/clamd.conf";
+ if (!file_exists("{$cf}.default")) {
+ copy("{$cf}.sample", "{$cf}.default");
+ }
+ if (file_exists("{$cf}.default")) {
+ $sample_file = file_get_contents("{$cf}.default");
+ $clamd_m[0] = "@## Example config file for the Clam AV daemon@";
+ $clamd_r[0] = "#This file was automatically generated by pfSense";
+ $clamd_m[1] = "@# Comment or remove the line below.@";
+ $clamd_r[1] = "";
+ $clamd_m[2] = "@#Example@";
+ $clamd_r[2] = "";
+ file_put_contents("{$cf}.pfsense", preg_replace($clamd_m, $clamd_r, $sample_file), LOCK_EX);
+ } else {
+ log_error("[squid] Could not patch '{$cf}' template file!");
+ }
+
+ // freshclam.conf
+ // make a backup of default freshclam.conf.sample first
+ $cf = SQUID_LOCALBASE . "/etc/freshclam.conf";
+ if (!file_exists("{$cf}.default")) {
+ copy("{$cf}.sample", "{$cf}.default");
+ }
+ if (file_exists("{$cf}.default")) {
+ $sample_file = file_get_contents("{$cf}.default");
+ $freshclam_m[0] = "@## Example config file for freshclam@";
+ $freshclam_r[0] = "#This file was automatically generated by pfSense";
+ $freshclam_m[1] = "@# Comment or remove the line below.@";
+ $freshclam_r[1] = "";
+ $freshclam_m[2] = "@#Example@";
+ $freshclam_r[2] = "";
+ file_put_contents("{$cf}.pfsense", preg_replace($freshclam_m, $freshclam_r, $sample_file), LOCK_EX);
+ } else {
+ log_error("[squid] - could not patch '{$cf}' template file!");
+ }
+ unset($cf);
+}
+
+/* Get the raw pfSense template files for manual configuration and serialize them to config.xml */
+function squid_antivirus_get_raw_config() {
+ global $config;
+ $loaded = false;
+ $rawfiles = array("squidclamav.conf", "c-icap.conf", "c-icap.magic", "freshclam.conf", "clamd.conf");
+
+ foreach ($rawfiles as $rawfile) {
+ switch ($rawfile) {
+ case 'squidclamav.conf':
+ $confdir = "/c-icap";
+ $confopt = "raw_squidclamav_conf";
+ break;
+ case 'c-icap.conf':
+ $confdir = "/c-icap";
+ $confopt = "raw_cicap_conf";
+ break;
+ case 'c-icap.magic':
+ $confdir = "/c-icap";
+ $confopt = "raw_cicap_magic";
+ break;
+ case 'freshclam.conf':
+ $confdir = "";
+ $confopt = "raw_freshclam_conf";
+ break;
+ case 'clamd.conf':
+ $confdir = "";
+ $confopt = "raw_clamd_conf";
+ break;
+ default:
+ $confdir = "";
+ $confopt = "";
+ break;
+ }
+ // get the config from the files if not set (yet) in config.xml
+ if ($confopt) {
+ $conffile = SQUID_LOCALBASE . "/etc" . "{$confdir}" . "/{$rawfile}.pfsense";
+ if (file_exists($conffile)) {
+ if ($config['installedpackages']['squidantivirus']['config'][0][$confopt] == "") {
+ $config['installedpackages']['squidantivirus']['config'][0][$confopt] = base64_encode(str_replace("\r", "", file_get_contents("{$conffile}")));
+ log_error("[squid] Successfully loaded '{$conffile}' configuration file");
+ $loaded = true;
+ }
+ // Just a fallback attempt if people do things in weird order on a completely fresh install perhaps; should not be ever needed
+ } else {
+ squid_antivirus_install_config_files();
+ if (file_exists($conffile)) {
+ $config['installedpackages']['squidantivirus']['config'][0][$confopt] = base64_encode(str_replace("\r", "", file_get_contents("{$conffile}")));
+ log_error("[squid] Successfully loaded '{$conffile}' configuration file");
+ $loaded = true;
+ } else {
+ log_error("[squid] '{$conffile}' template does not exist; could not load advanced {$rawfile} configuration!");
+ }
+ }
+ }
+ }
+ if ($loaded) {
+ write_config("Squid - Loaded raw configuration files", false);
+ log_error("[squid] Successfully loaded raw configuration files");
+ }
+}
+
+/* Toggle the raw config state */
+function squid_antivirus_toggle_raw_config($state) {
+ global $config;
+ if ($state) {
+ // manual configuration enabled
+ $opts = array("clamav_url", "clamav_safebrowsing", "clamav_update", "clamav_dbregion", "clamav_dbservers");
+ foreach ($opts as $opt) {
+ if (isset($config['installedpackages']['squidantivirus']['config'][0][$opt])) {
+ unset($config['installedpackages']['squidantivirus']['config'][0][$opt]);
+ log_error("[squid] Loaded '{$opt}' raw configuration file...");
+ }
+ }
+ log_error("[squid] Loading raw configuration files...");
+ squid_antivirus_get_raw_config();
+ } else {
+ // manual configuration disabled
+ $opts = array("raw_squidclamav_conf", "raw_cicap_conf", "raw_cicap_magic", "raw_freshclam_conf", "raw_clamd_conf");
+ foreach ($opts as $opt) {
+ if (isset($config['installedpackages']['squidantivirus']['config'][0][$opt])) {
+ unset($config['installedpackages']['squidantivirus']['config'][0][$opt]);
+ log_error("[squid] Unloaded '{$opt}' raw configuration.");
+ }
+ }
+ $config['installedpackages']['squidantivirus']['config'][0]['enable_advanced'] = "disabled";
+ }
+}
+
+/* Write the raw config files to disk from config.xml configuration */
+function squid_antivirus_put_raw_config($rawfiles) {
+ if (is_array($rawfiles)) {
+ foreach ($rawfiles as $rawfile => $rawconfig) {
+ switch ($rawfile) {
+ case 'raw_squidclamav_conf':
+ $confdir = "/c-icap";
+ $conffile = "/squidclamav.conf";
+ break;
+ case 'raw_cicap_conf':
+ $confdir = "/c-icap";
+ $conffile = "/c-icap.conf";
+ break;
+ case 'raw_cicap_magic':
+ $confdir = "/c-icap";
+ $conffile = "/c-icap.magic";
+ break;
+ case 'raw_freshclam_conf':
+ $confdir = "";
+ $conffile = "freshclam.conf";
+ break;
+ case 'raw_clamd_conf':
+ $confdir = "";
+ $conffile = "clamd.conf";
+ break;
+ default:
+ $confdir = "";
+ $conffile = "";
+ break;
+ }
+ if ($conffile && $rawconfig) {
+ squid_antivirus_write_conffile($confdir, $conffile, $rawconfig);
+ }
+ }
+ }
+}
+
+/* Helper function for squid_antivirus_put_raw_config() */
+function squid_antivirus_write_conffile($dir, $file, $text) {
+ if ($file && $text) {
+ file_put_contents(SQUID_LOCALBASE . "/etc" . "{$dir}" . "/{$file}", preg_replace("/\r\n/", "\n", base64_decode($text)), LOCK_EX);
+ log_error("[squid] Saved '{$file}' configuration file.");
+ }
+}
+
+/*
+ * rc scripts and services
+ */
+
+/* Create clamd.sh rc script */
+function squid_write_clamd_rcfile() {
+ $squid_base = SQUID_BASE;
+ $rc = array();
+ $rc['file'] = 'clamd.sh';
+ $rc['start'] = <<< EOD
+
+if [ ! -f /var/db/clamav/main.cvd -a ! -f /var/db/clamav/main.cld ]; then
+ echo "Missing /var/db/clamav/*.cvd or *.cld files. You must run freshclam first"
+ exit 1
+fi
+
+{$squid_base}/bin/clamd --config-file="{$squid_base}/local/etc/clamd.conf"
+
+EOD;
+
+ $rc['stop'] = <<< EOD
+
+/usr/bin/killall clamd 2>/dev/null
+# Just to be sure...
+sleep 5
+if [ -n "`/bin/ps auxw | /usr/bin/grep "[c]lamd" | /usr/bin/awk '{print $2}'`" ]; then
+ /usr/bin/killall -9 clamd 2>/dev/null
+fi
+
+EOD;
+
+ conf_mount_rw();
+ write_rcfile($rc);
+ conf_mount_ro();
+}
+
+/* Create c-icap.sh rc script */
+function squid_write_cicap_rcfile() {
+ $c_icap_rcfile = "c-icap.sh";
+ $cicap_libdir = SQUID_LOCALBASE . "/lib";
+ $cicap_bin = SQUID_LOCALBASE . "/bin/c-icap";
+ $cicap_conf = SQUID_LOCALBASE . "/etc/c-icap/c-icap.conf";
+ $cicap_start_cmd = "LD_LIBRARY_PATH={$cicap_libdir} {$cicap_bin} -f {$cicap_conf}";
+ $cicap_stop_cmd = '/bin/echo -n "stop" > /var/run/c-icap/c-icap.ctl';
+ conf_mount_rw();
+ write_rcfile(array(
+ "file" => "{$c_icap_rcfile}",
+ "start" => "{$cicap_start_cmd}",
+ "stop" => "{$cicap_stop_cmd}"
+ )
+ );
+ conf_mount_ro();
+}
+
+/* (Re)start antivirus services if AV features are enabled; otherwise stop and disable them */
+function squid_restart_antivirus() {
+ global $config;
+ if (is_array($config['installedpackages']['squidantivirus'])) {
+ $antivirus_config = $config['installedpackages']['squidantivirus']['config'][0];
+ } else {
+ $antivirus_config = array();
+ }
+
+ // reconfigure and (re)start service as needed if enabled, otherwise stop them
+ // do not (re)start antivirus services on boot
+ if (platform_booting()) {
+ return;
+ }
+
+ if (squid_enabled() && ($antivirus_config['enable'] == "on")) {
+ // Check clamav database
+ if (count(glob("/var/db/clamav/*d")) == 0) {
+ log_error("[squid] Missing /var/db/clamav/*.cvd or *.cld files. Running freshclam in background.");
+ mwexec_bg(SQUID_BASE . "/bin/freshclam --config-file=" . SQUID_BASE . "/etc/freshclam.conf");
+ } elseif ($antivirus_config['clamav_safebrowsing'] == "on" && !is_file("/var/db/clamav/safebrowsing.cvd")) {
+ log_error("[squid] Google Safe Browsing is enabled but missing safebrowsing.cvd definitions. Running freshclam in background.");
+ mwexec_bg(SQUID_BASE . "/bin/freshclam --config-file=" . SQUID_BASE . "/etc/freshclam.conf");
+ } elseif ($antivirus_config['clamav_safebrowsing'] != "on" && is_file("/var/db/clamav/safebrowsing.cvd")) {
+ log_error("[squid] Google Safe Browsing is disabled. Removing safebrowsing.cvd definitions.");
+ mwexec("/bin/rm -f /var/db/clamav/safebrowsing.cvd");
+ }
+
+ // start/reload clamav
+ $clamd_rcfile = "/usr/local/etc/rc.d/clamd.sh";
+ if (!file_exists($clamd_rcfile)) {
+ squid_write_clamd_rcfile();
+ }
+ if (is_process_running("clamd")) {
+ log_error("[squid] Reloading ClamAV...");
+ $reload_cmd = SQUID_BASE . "/bin/clamdscan --reload";
+ mwexec_bg("{$reload_cmd}");
+ } else {
+ log_error("[squid] Starting ClamAV...");
+ mwexec_bg("{$clamd_rcfile} start");
+ }
+
+ // check c-icap rcfile
+ $c_icap_rcfile = "/usr/local/etc/rc.d/c-icap.sh";
+ if (!file_exists($c_icap_rcfile)) {
+ squid_write_cicap_rcfile();
+ }
+ if (is_process_running("c-icap")) {
+ mwexec_bg('/bin/echo -n "reconfigure" > /var/run/c-icap/c-icap.ctl');
+ } else {
+ mwexec_bg("{$c_icap_rcfile} start");
+ }
+ } else {
+ // stop AV services and disable all C-ICAP/AV features
+ log_error("[squid] Antivirus features disabled.");
+ if (is_process_running("clamd")) {
+ log_error("[squid] Stopping and disabling ClamAV...");
+ mwexec("/usr/bin/killall clamd");
+ }
+ unlink_if_exists("/usr/local/etc/rc.d/clamd.sh");
+
+ // freshclam cronjob
+ squid_install_freshclam_cron(false);
+
+ // check c-icap rcfile
+ if (is_process_running("c-icap")) {
+ log_error("[squid] Stopping and disabling C-ICAP...");
+ mwexec('/bin/echo -n "stop" > /var/run/c-icap/c-icap.ctl');
+ }
+ unlink_if_exists("/usr/local/etc/rc.d/c-icap.sh");
+ }
+}
+
+/*
+ * Input validation
+ */
+
+/* Proxy server: Antivirus input validation */
+/* Also handles manual AV updates and switching 'Manual Configuration' on/off */
+function squid_validate_antivirus($post, &$input_errors) {
+ global $config;
+ if (is_array($config['installedpackages']['squidantivirus'])) {
+ $antivirus_config = $config['installedpackages']['squidantivirus']['config'][0];
+ } else {
+ $antivirus_config = array();
+ }
+
+ /* Manual ClamAV database update */
+ if ($post['update_av'] == 'Update AV') {
+ squid_update_clamav();
+ return;
+ }
+
+ /* Load the raw config files if manual configuration is enabled */
+ if ($post['load_advanced'] == 'Load Advanced') {
+ $config['installedpackages']['squidantivirus']['config'][0]['enable_advanced'] = "enabled";
+ squid_antivirus_toggle_raw_config(true);
+ return;
+ }
+
+ if ($post['raw_squidclamav_conf'] && preg_match("/(\S+proxy.domain\S+)/", $post['raw_squidclamav_conf'], $a_match)) {
+ $input_errors[] = "SquidClamav warnings redirect points to sample config domain ({$a_match[1]})";
+ $input_errors[] = "Change redirect info on 'squidclamav.conf' field to pfSense GUI or an external host.";
+ }
+ if ($post['raw_cicap_conf']) {
+ if (!preg_match("/squid_clamav/", $post['raw_cicap_conf'])) {
+ $input_errors[] = "c-icap Squidclamav service definition is not present.";
+ $input_errors[] = "Add 'Service squid_clamav squidclamav.so'(without quotes) to 'c-icap.conf' field in order to get it working.";
+ }
+ }
+
+ if ($post['clamav_dbservers']) {
+ foreach (explode(";", $post['clamav_dbservers']) as $dbserver) {
+ $dbserver = trim($dbserver);
+ if (!empty($dbserver) && !is_ipaddr($dbserver) && !is_hostname($dbserver)) {
+ $input_errors[] = "'Optional ClamAV Database Update Servers' entry '$dbserver' is not a valid IP address or hostname.";
+ }
+ }
+ }
+
+ if ($post['clamav_url']) {
+ if (!filter_var($post['clamav_url'], FILTER_VALIDATE_URL)) {
+ $input_errors[] = "'Redirect URL' is not a valid URL.";
+ }
+ }
+}
+
+?>
diff --git a/config/squid3/34/squid_antivirus.xml b/config/squid3/34/squid_antivirus.xml
index a257891d..e7d046f0 100755
--- a/config/squid3/34/squid_antivirus.xml
+++ b/config/squid3/34/squid_antivirus.xml
@@ -42,7 +42,7 @@
]]>
</copyright>
<name>squidantivirus</name>
- <version>0.3.7</version>
+ <version>0.3.9</version>
<title>Proxy server: Antivirus</title>
<include_file>/usr/local/pkg/squid.inc</include_file>
<tabs>
@@ -88,6 +88,7 @@
<url>/pkg_edit.php?xml=squid_sync.xml</url>
</tab>
</tabs>
+ <advanced_options>enabled</advanced_options>
<fields>
<field>
<name>ClamAV Anti-Virus Integration Using C-ICAP</name>
@@ -117,6 +118,40 @@
</options>
</field>
<field>
+ <fielddescr>Enable Manual Configuration</fielddescr>
+ <fieldname>enable_advanced</fieldname>
+ <description>
+ <![CDATA[
+ When enabled, the options below no longer have any effect.<br/>
+ You must edit the configuration files directly in the 'Advanced Features'.<br/>
+ <strong><span class="errmsg">Warning:</span> Only enable this if you know what are you doing.</strong><br/><br/>
+ After enabling manual configuration, click <input name='load_advanced' id='load_advanced' type='submit' value='Load Advanced' /> button once to load default configuration files.
+ To disable manual configuration again, select 'disabled' and click 'Save' button.
+ ]]>
+ </description>
+ <type>select</type>
+ <options>
+ <option><value>disabled</value><name>disabled</name></option>
+ <option><value>enabled</value><name>enabled</name></option>
+ </options>
+ <default_value>disabled</default_value>
+ <onchange>on_antivirus_advanced_config_changed()</onchange>
+ </field>
+ <field>
+ <fielddescr>Redirect URL</fielddescr>
+ <fieldname>clamav_url</fieldname>
+ <description>
+ <![CDATA[
+ When a virus is found then redirect the user to this URL.<br />
+ Leave empty to use the default Squid/pfSense WebGUI URL.<br/>
+ <strong>Example:</strong> http://proxy.example.com/blocked.html
+ ]]>
+ </description>
+ <type>input</type>
+ <cols>60</cols>
+
+ </field>
+ <field>
<fielddescr>Google Safe Browsing</fielddescr>
<fieldname>clamav_safebrowsing</fieldname>
<description>
@@ -136,7 +171,7 @@
<![CDATA[
Optionally, you can schedule ClamAV definitions updates via cron.<br/>
Select the desired frequency here.<br/><br/>
- <input name='submit' type='submit' value='Update AV' />
+ <input name='update_av' id='update_av' type='submit' value='Update AV' />
Click the button to update AV databases now.<br/>
<strong>Note: This will take a while.</strong> Check /var/log/clamav/freshclam.log for progress information.
]]>
@@ -195,53 +230,99 @@
</description>
<type>input</type>
<cols>60</cols>
- <rows>5</rows>
- </field>
- <field>
- <name>Advanced Options</name>
- <type>listtopic</type>
</field>
<field>
<fielddescr>squidclamav.conf</fielddescr>
- <fieldname>squidclamav</fieldname>
- <description>squidclamav.conf file. Leave empty to load sample file. Edit only if you know what are you doing.</description>
+ <fieldname>raw_squidclamav_conf</fieldname>
+ <description>squidclamav.conf file. Edit only if you know what are you doing.</description>
<type>textarea</type>
<encoding>base64</encoding>
<cols>85</cols>
<rows>15</rows>
+ <advancedfield/>
</field>
<field>
<fielddescr>c-icap.conf</fielddescr>
- <fieldname>c-icap_conf</fieldname>
- <description>c-icap.conf file. Leave empty to load sample file. Edit only if you know what are you doing.</description>
+ <fieldname>raw_cicap_conf</fieldname>
+ <description>c-icap.conf file. Edit only if you know what are you doing.</description>
<type>textarea</type>
<encoding>base64</encoding>
<cols>85</cols>
<rows>15</rows>
+ <advancedfield/>
</field>
<field>
<fielddescr>c-icap.magic</fielddescr>
- <fieldname>c-icap_magic</fieldname>
- <description>c-icap.conf file. Leave empty to load sample file. Edit only if you know what are you doing.</description>
+ <fieldname>raw_cicap_magic</fieldname>
+ <description>c-icap.conf file. Edit only if you know what are you doing.</description>
<type>textarea</type>
<encoding>base64</encoding>
<cols>85</cols>
<rows>15</rows>
+ <advancedfield/>
</field>
<field>
<fielddescr>freshclam.conf</fielddescr>
- <fieldname>freshclam_conf</fieldname>
- <description>freshclam.conf file. Leave empty to load sample file. Edit only if you know what are you doing.</description>
+ <fieldname>raw_freshclam_conf</fieldname>
+ <description>freshclam.conf file. Edit only if you know what are you doing.</description>
+ <type>textarea</type>
+ <encoding>base64</encoding>
+ <cols>85</cols>
+ <rows>15</rows>
+ <advancedfield/>
+ </field>
+ <field>
+ <fielddescr>clamd.conf</fielddescr>
+ <fieldname>raw_clamd_conf</fieldname>
+ <description>clamd.conf file. Edit only if you know what are you doing.</description>
<type>textarea</type>
<encoding>base64</encoding>
<cols>85</cols>
<rows>15</rows>
+ <advancedfield/>
</field>
</fields>
+ <custom_php_after_head_command>
+ squid_print_antivirus_advanced_config();
+ </custom_php_after_head_command>
+ <custom_php_before_form_command>
+ <![CDATA[
+ squid_print_antivirus_advanced_config2();
+ if ($_POST['enable_advanced'] == "enabled") {
+ $opts = array("clamav_url", "clamav_safebrowsing", "clamav_update", "clamav_dbregion", "clamav_dbservers");
+ foreach ($opts as $opt) {
+ if (isset($_POST[$opt])) {
+ unset($_POST[$opt]);
+ }
+ }
+ } else {
+ $opts = array("raw_squidclamav_conf", "raw_cicap_conf", "raw_cicap_magic", "raw_freshclam_conf", "raw_clamd_conf");
+ foreach ($opts as $opt) {
+ if (isset($_POST[$opt])) {
+ unset($_POST[$opt]);
+ }
+ }
+ }
+ ]]>
+ </custom_php_before_form_command>
+ <custom_php_after_form_command>
+ squid_print_antivirus_advanced_config2();
+ </custom_php_after_form_command>
<custom_php_validation_command>
squid_validate_antivirus($_POST, $input_errors);
</custom_php_validation_command>
<custom_php_resync_config_command>
+ <![CDATA[
+ if ($_POST['load_advanced'] == "Load Advanced" ) {
+ return;
+ }
+ if ($_POST['update_av'] == 'Update AV') {
+ return;
+ }
+ if ($_POST['enable_advanced'] == "enabled" ) {
+ squid_antivirus_put_raw_config($_POST);
+ }
squid_resync();
+ ]]>
</custom_php_resync_config_command>
</packagegui>
diff --git a/config/squid3/34/squid_auth.xml b/config/squid3/34/squid_auth.xml
index e2bae945..58a0bf12 100755
--- a/config/squid3/34/squid_auth.xml
+++ b/config/squid3/34/squid_auth.xml
@@ -127,7 +127,7 @@
]]>
</description>
<type>input</type>
- <size>60</size>
+ <size>5</size>
</field>
<field>
<fielddescr>Authentication Prompt</fielddescr>
@@ -135,6 +135,7 @@
<description>This string will be displayed at the top of the authentication request window.</description>
<type>input</type>
<default_value>Please enter your credentials to access the proxy</default_value>
+ <size>60</size>
</field>
<field>
<fielddescr>Authentication Processes</fielddescr>
diff --git a/config/squid3/34/squid_cache.xml b/config/squid3/34/squid_cache.xml
index 2045005c..20f62376 100755
--- a/config/squid3/34/squid_cache.xml
+++ b/config/squid3/34/squid_cache.xml
@@ -168,7 +168,6 @@
]]>
</description>
<type>checkbox</type>
- <required/>
</field>
<field>
<fielddescr>External Cache Managers</fielddescr>
diff --git a/config/squid3/34/squid_js.inc b/config/squid3/34/squid_js.inc
new file mode 100644
index 00000000..781b6710
--- /dev/null
+++ b/config/squid3/34/squid_js.inc
@@ -0,0 +1,273 @@
+<?php
+/*
+ squid_js.inc
+ part of pfSense (https://www.pfSense.org/)
+ Copyright (C) 2015 ESF, LLC
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+/*
+ * Squid javascript helpers for GUI fields status manipulation
+ */
+require_once('globals.inc');
+require_once('config.inc');
+
+/*
+ * Enable/disable and blank out various parts of the Authentication tab
+ * depending on selected 'Authentication Method' value
+ */
+function squid_print_javascript_auth() {
+ global $config;
+ if (is_array($config['installedpackages']['squid'])) {
+ $squidsettings = $config['installedpackages']['squid']['config'][0];
+ } else {
+ $squidsettings = array();
+ }
+ if (is_array($config['installedpackages']['squidauth']['config'])) {
+ $settingsauth = $config['installedpackages']['squidauth']['config'][0];
+ } else {
+ $settingsauth = array();
+ }
+ $transparent_proxy = ($squidsettings['transparent_proxy'] == 'on');
+ $auth_method = $settingsauth['auth_method'];
+
+ // No authentication for transparent proxy
+ if ($transparent_proxy and preg_match("/(local|ldap|radius|msnt|ntlm)/", $auth_method)) {
+ $javascript = <<< EOD
+<script type="text/javascript">
+//<![CDATA[
+function on_auth_method_changed() {
+ document.iform.auth_method.disabled = 1;
+ document.iform.auth_server.disabled = 1;
+ document.iform.auth_ntdomain.disabled = 1;
+ document.iform.auth_server_port.disabled = 1;
+ document.iform.ldap_user.disabled = 1;
+ document.iform.ldap_version.disabled = 1;
+ document.iform.ldap_userattribute.disabled = 1;
+ document.iform.ldap_filter.disabled = 1;
+ document.iform.ldap_pass.disabled = 1;
+ document.iform.ldap_basedomain.disabled = 1;
+ document.iform.radius_secret.disabled = 1;
+ document.iform.msnt_secondary.disabled = 1;
+ document.iform.auth_prompt.disabled = 1;
+ document.iform.auth_processes.disabled = 1;
+ document.iform.auth_ttl.disabled = 1;
+ document.iform.unrestricted_auth.disabled = 1;
+ document.iform.no_auth_hosts.disabled = 1;
+}
+//]]>
+</script>
+
+EOD;
+
+ } else {
+
+ $javascript = <<< EOD
+<script type="text/javascript">
+//<![CDATA[
+function on_auth_method_changed() {
+ var field = document.iform.auth_method;
+ var auth_method = field.options[field.selectedIndex].value;
+
+ if (auth_method == 'none') {
+ document.iform.auth_server.disabled = 1;
+ document.iform.auth_server_port.disabled = 1;
+ document.iform.auth_ntdomain.disabled = 1;
+ document.iform.ldap_user.disabled = 1;
+ document.iform.ldap_version.disabled = 1;
+ document.iform.ldap_userattribute.disabled = 1;
+ document.iform.ldap_filter.disabled = 1;
+ document.iform.ldap_pass.disabled = 1;
+ document.iform.ldap_basedomain.disabled = 1;
+ document.iform.radius_secret.disabled = 1;
+ document.iform.msnt_secondary.disabled = 1;
+ document.iform.auth_prompt.disabled = 1;
+ document.iform.auth_processes.disabled = 1;
+ document.iform.auth_ttl.disabled = 1;
+ document.iform.unrestricted_auth.disabled = 1;
+ document.iform.no_auth_hosts.disabled = 1;
+ } else {
+ document.iform.auth_prompt.disabled = 0;
+ document.iform.auth_processes.disabled = 0;
+ document.iform.auth_ttl.disabled = 0;
+ document.iform.unrestricted_auth.disabled = 0;
+ document.iform.no_auth_hosts.disabled = 0;
+ }
+
+ switch (auth_method) {
+ case 'local':
+ document.iform.auth_server.disabled = 1;
+ document.iform.auth_server_port.disabled = 1;
+ document.iform.auth_ntdomain.disabled = 1;
+ document.iform.ldap_user.disabled = 1;
+ document.iform.ldap_pass.disabled = 1;
+ document.iform.ldap_version.disabled = 1;
+ document.iform.ldap_userattribute.disabled = 1;
+ document.iform.ldap_filter.disabled = 1;
+ document.iform.ldap_basedomain.disabled = 1;
+ document.iform.radius_secret.disabled = 1;
+ document.iform.msnt_secondary.disabled = 1;
+ break;
+ case 'ldap':
+ document.iform.auth_server.disabled = 0;
+ document.iform.auth_server_port.disabled = 0;
+ document.iform.ldap_user.disabled = 0;
+ document.iform.ldap_pass.disabled = 0;
+ document.iform.ldap_version.disabled = 0;
+ document.iform.ldap_userattribute.disabled = 0;
+ document.iform.ldap_filter.disabled = 0;
+ document.iform.ldap_basedomain.disabled = 0;
+ document.iform.radius_secret.disabled = 1;
+ document.iform.msnt_secondary.disabled = 1;
+ document.iform.auth_ntdomain.disabled = 1;
+ break;
+ case 'radius':
+ document.iform.auth_server.disabled = 0;
+ document.iform.auth_server_port.disabled = 0;
+ document.iform.ldap_user.disabled = 1;
+ document.iform.ldap_pass.disabled = 1;
+ document.iform.ldap_version.disabled = 1;
+ document.iform.ldap_userattribute.disabled = 1;
+ document.iform.ldap_filter.disabled = 1;
+ document.iform.ldap_basedomain.disabled = 1;
+ document.iform.radius_secret.disabled = 0;
+ document.iform.msnt_secondary.disabled = 1;
+ document.iform.auth_ntdomain.disabled = 1;
+ break;
+ case 'msnt':
+ document.iform.auth_server.disabled = 0;
+ document.iform.auth_server_port.disabled = 1;
+ document.iform.auth_ntdomain.disabled = 0;
+ document.iform.ldap_user.disabled = 1;
+ document.iform.ldap_pass.disabled = 1;
+ document.iform.ldap_version.disabled = 1;
+ document.iform.ldap_userattribute.disabled = 1;
+ document.iform.ldap_filter.disabled = 1;
+ document.iform.ldap_basedomain.disabled = 1;
+ document.iform.radius_secret.disabled = 1;
+ document.iform.msnt_secondary.disabled = 0;
+ break;
+ case 'cp':
+ document.iform.auth_server.disabled = 1;
+ document.iform.auth_server_port.disabled = 1;
+ document.iform.auth_ntdomain.disabled = 1;
+ document.iform.ldap_user.disabled = 1;
+ document.iform.ldap_version.disabled = 1;
+ document.iform.ldap_userattribute.disabled = 1;
+ document.iform.ldap_filter.disabled = 1;
+ document.iform.ldap_pass.disabled = 1;
+ document.iform.ldap_basedomain.disabled = 1;
+ document.iform.radius_secret.disabled = 1;
+ document.iform.msnt_secondary.disabled = 1;
+ document.iform.auth_prompt.disabled = 1;
+ document.iform.auth_processes.disabled = 0;
+ document.iform.auth_ttl.disabled = 0;
+ document.iform.unrestricted_auth.disabled = 1;
+ document.iform.no_auth_hosts.disabled = 1;
+ break;
+ }
+}
+//]]>
+</script>
+
+EOD;
+
+ }
+ print($javascript);
+}
+
+/* onchange toggle helper for squid_print_javascript_auth() function */
+function squid_print_javascript_auth2() {
+ print("<script type=\"text/javascript\">on_auth_method_changed()</script>\n");
+}
+
+/*
+ * Enable/disable and blank out various parts of the Antivirus tab
+ * depending on selected 'Enable Manual Configuration' value
+ */
+function squid_print_antivirus_advanced_config() {
+ $javascript = <<< EOD
+<script type="text/javascript">
+//<![CDATA[
+function on_antivirus_advanced_config_changed() {
+ var field = document.iform.enable_advanced;
+ var enable_advanced = field.options[field.selectedIndex].value;
+
+ if (enable_advanced === 'disabled') {
+ document.iform['clamav_url'].disabled = 0;
+ document.iform['clamav_safebrowsing'].disabled = 0;
+ document.iform['clamav_update'].disabled = 0;
+ document.iform['clamav_dbregion'].disabled = 0;
+ document.iform['clamav_dbservers'].disabled = 0;
+ document.iform['clamav_dbservers'].disabled = 0;
+ document.iform['clamav_dbservers'].disabled = 0;
+ document.getElementById("load_advanced").disabled = 1;
+ document.iform['raw_squidclamav_conf'].disabled = 1;
+ document.iform['raw_squidclamav_conf'].value = '';
+ document.iform['raw_cicap_conf'].disabled = 1;
+ document.iform['raw_cicap_conf'].value = '';
+ document.iform['raw_cicap_magic'].disabled = 1;
+ document.iform['raw_cicap_magic'].value = '';
+ document.iform['raw_freshclam_conf'].disabled = 1;
+ document.iform['raw_freshclam_conf'].value = '';
+ document.iform['raw_clamd_conf'].disabled = 1;
+ document.iform['raw_clamd_conf'].value = '';
+ } else {
+ document.iform['clamav_url'].disabled = 1;
+ document.iform['clamav_safebrowsing'].disabled = 1;
+ document.getElementById('clamav_safebrowsing').checked = 0;
+ document.iform['clamav_update'].disabled = 1;
+ document.getElementById("clamav_update").value = '';
+ document.iform['clamav_dbregion'].disabled = 1;
+ document.getElementById("clamav_dbregion").value = '';
+ document.iform['clamav_dbservers'].disabled = 1;
+ document.iform['clamav_dbservers'].value = '';
+ document.getElementById("load_advanced").disabled = 0;
+ document.iform['raw_squidclamav_conf'].disabled = 0;
+ document.iform['raw_cicap_conf'].disabled = 0;
+ document.iform['raw_cicap_magic'].disabled = 0;
+ document.iform['raw_freshclam_conf'].disabled = 0;
+ document.iform['raw_clamd_conf'].disabled = 0;
+
+ }
+
+ if (document.getElementById("enable").checked == 0) {
+ document.getElementById("update_av").disabled = 1;
+ } else {
+ document.getElementById("update_av").disabled = 0;
+ }
+}
+//]]>
+</script>
+
+EOD;
+ print($javascript);
+
+}
+
+/* onchange toggle helper for squid_print_antivirus_advanced_config() function */
+function squid_print_antivirus_advanced_config2() {
+ print("<script type=\"text/javascript\">on_antivirus_advanced_config_changed()</script>\n");
+}
+
+?>
diff --git a/config/squid3/34/squid_reverse.inc b/config/squid3/34/squid_reverse.inc
index 32c3fa65..d69d6a01 100755
--- a/config/squid3/34/squid_reverse.inc
+++ b/config/squid3/34/squid_reverse.inc
@@ -33,6 +33,7 @@ require_once('certs.inc');
/* This file is currently only being included in squid.inc and not used separately */
// require_once('squid.inc');
+/* Reverse Proxy Server configuration handler */
function squid_resync_reverse() {
global $config;
@@ -262,4 +263,74 @@ function squid_resync_reverse() {
return $conf;
}
+/* Reverse Proxy Server input validation */
+function squid_validate_reverse($post, &$input_errors) {
+ global $config;
+
+ if (!empty($post['reverse_ip'])) {
+ $reverse_ip = explode(";", ($post['reverse_ip']));
+ foreach ($reverse_ip as $reip) {
+ if (!is_ipaddr(trim($reip))) {
+ $input_errors[] = "You must enter a valid IP address in the 'User-defined reverse-proxy IPs' field. '$reip' is invalid.";
+ }
+ }
+ }
+
+ $fqdn = trim($post['reverse_external_fqdn']);
+ if (!empty($fqdn) && !is_domain($fqdn)) {
+ $input_errors[] = "'External FQDN' field must contain a valid domain name.";
+ }
+
+ $port = trim($post['reverse_http_port']);
+ preg_match("/(\d+)/", shell_exec("/sbin/sysctl net.inet.ip.portrange.reservedhigh"), $portrange);
+ if (!empty($port) && !is_port($port)) {
+ $input_errors[] = "'Reverse HTTP port' must contain a valid port number.";
+ }
+ if (!empty($port) && is_port($port) && $port <= $portrange[1]) {
+ $input_errors[] = "'Reverse HTTP port' must contain a port number higher than net.inet.ip.portrange.reservedhigh sysctl value({$portrange[1]}).";
+ $input_errors[] = "To listen on low ports, change portrange.reservedhigh sysctl value to 0 in system tunable options and restart Squid daemon.";
+ }
+ $port = trim($post['reverse_https_port']);
+ if (!empty($port) && !is_port($port)) {
+ $input_errors[] = "'Reverse HTTPS port' must contain a valid port number.";
+ }
+ if (!empty($port) && is_port($port) && $port <= $portrange[1]) {
+ $input_errors[] = "'Reverse HTTPS port' must contain a port number higher than net.inet.ip.portrange.reservedhigh sysctl value({$portrange[1]}).";
+ $input_errors[] = "To listen on low ports, change portrange.reservedhigh sysctl value to 0 in system tunable options and restart Squid daemon.";
+ }
+ if ($post['reverse_ssl_cert'] == 'none') {
+ $input_errors[] = 'A valid certificate for the external interface must be selected';
+ }
+
+ if (($post['reverse_https'] != 'on') && ($post['reverse_owa'] == 'on')) {
+ $input_errors[] = "You have to enable reverse HTTPS before enabling OWA support.";
+ }
+
+ if (!empty($post['reverse_owa_ip'])) {
+ $reverse_owa_ip = explode(";", ($post['reverse_owa_ip']));
+ foreach ($reverse_owa_ip as $reowaip) {
+ if (!is_ipaddr(trim($reowaip))) {
+ $input_errors[] = "You must enter a valid IP address in the 'CAS-Array / OWA frontend IP address' field. '$reowaip' is invalid.";
+ }
+ }
+ }
+
+ $contents = $post['reverse_cache_peer'];
+ if (!empty($contents)) {
+ $defs = explode("\r\n", ($contents));
+ foreach ($defs as $def) {
+ $cfg = explode(";", ($def));
+ if (!is_ipaddr($cfg[1])) {
+ $input_errors[] = "Please choose a valid IP in the cache peer configuration.";
+ }
+ if (!is_port($cfg[2])) {
+ $input_errors[] = "Please choose a valid port in the cache peer configuration.";
+ }
+ if (($cfg[3] != 'HTTPS') && ($cfg[3] != 'HTTP')) {
+ $input_errors[] = "Please choose HTTP or HTTPS in the cache peer configuration.";
+ }
+ }
+ }
+}
+
?>
diff --git a/config/squid3/34/squid_reverse.xml b/config/squid3/34/squid_reverse.xml
deleted file mode 100755
index 3617debc..00000000
--- a/config/squid3/34/squid_reverse.xml
+++ /dev/null
@@ -1,451 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE packagegui SYSTEM "../schema/packages.dtd">
-<?xml-stylesheet type="text/xsl" href="../xsl/package.xsl"?>
-<packagegui>
- <copyright>
-<![CDATA[
-/* $Id$ */
-/* ====================================================================================== */
-/*
- squid_reverse.xml
- part of pfSense (https://www.pfSense.org/)
- Copyright (C) 2012-2014 Marcello Coutinho
- Copyright (C) 2015 ESF, LLC
- All rights reserved.
-*/
-/* ====================================================================================== */
-/*
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-
- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-*/
-/* ====================================================================================== */
- ]]>
- </copyright>
- <name>squidreverse</name>
- <version>0.3.5</version>
- <title>Proxy Server: Reverse Proxy</title>
- <include_file>/usr/local/pkg/squid.inc</include_file>
- <tabs>
- <tab>
- <text>General</text>
- <url>/pkg_edit.php?xml=squid.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>Upstream</text>
- <url>/pkg_edit.php?xml=squid_upstream.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>Cache</text>
- <url>/pkg_edit.php?xml=squid_cache.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>ACLs</text>
- <url>/pkg_edit.php?xml=squid_nac.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>Traffic Mgmt</text>
- <url>/pkg_edit.php?xml=squid_traffic.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>Reverse</text>
- <url>/pkg_edit.php?xml=squid_reverse.xml&amp;id=0</url>
- <active/>
- </tab>
- <tab>
- <text>Authentication</text>
- <url>/pkg_edit.php?xml=squid_auth.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>Users</text>
- <url>/pkg.php?xml=squid_users.xml</url>
- </tab>
- <tab>
- <text>Real Time</text>
- <url>/squid_monitor.php</url>
- </tab>
- <tab>
- <text>Sync</text>
- <url>/pkg_edit.php?xml=squid_sync.xml</url>
- </tab>
- </tabs>
- <fields>
- <field>
- <name>Squid Reverse Proxy General Settings</name>
- <type>listtopic</type>
- </field>
- <field>
- <fielddescr>Reverse Proxy Interface</fielddescr>
- <fieldname>reverse_interface</fieldname>
- <description>
- <![CDATA[
- The interface(s) the reverse-proxy server will bind to.<br/>
- Use CTRL + click to select multiple interfaces.
- ]]>
- </description>
- <type>interfaces_selection</type>
- <required/>
- <default_value>wan</default_value>
- <multiple/>
- </field>
- <field>
- <fielddescr>User Defined Reverse Proxy IPs</fielddescr>
- <fieldname>reverse_ip</fieldname>
- <description>
- <![CDATA[
- Squid will additionally bind to these user-defined IPs for reverse proxy operation. Useful for virtual IPs such as CARP.<br/>
- <strong>Note: Separate entries by semi-colons (;)</strong>
- ]]>
- </description>
- <type>input</type>
- <size>70</size>
- </field>
- <field>
- <fielddescr>External FQDN</fielddescr>
- <fieldname>reverse_external_fqdn</fieldname>
- <description>The external fully qualified domain name of the WAN IP address.</description>
- <type>input</type>
- <required/>
- <size>70</size>
- </field>
- <field>
- <fielddescr>Reset TCP Connections on Unauthorized Requests</fielddescr>
- <fieldname>deny_info_tcp_reset</fieldname>
- <description>If checked, the reverse proxy will reset the TCP connection if the request is unauthorized.</description>
- <type>checkbox</type>
- <default_value>on</default_value>
- </field>
- <field>
- <name>Squid Reverse HTTP Settings</name>
- <type>listtopic</type>
- </field>
- <field>
- <fielddescr>Enable HTTP Reverse Mode</fielddescr>
- <fieldname>reverse_http</fieldname>
- <description>
- <![CDATA[
- If checked, the proxy server will act in HTTP reverse mode.<br/>
- <strong>Note: You must add a proper firewall rule with destination 'WAN Address'.</strong>
- ]]>
- </description>
- <type>checkbox</type>
- <enablefields>reverse_http_port,reverse_http_defsite</enablefields>
- <required/>
- <default_value>off</default_value>
- </field>
- <field>
- <fielddescr>Reverse HTTP Port</fielddescr>
- <fieldname>reverse_http_port</fieldname>
- <description>
- <![CDATA[
- This is the port the HTTP reverse proxy will listen on. Default value will be used if left empty.<br/>
- Default: 80
- ]]>
- </description>
- <type>input</type>
- <size>5</size>
- <default_value>80</default_value>
- </field>
- <field>
- <fielddescr>Reverse HTTP Default Site</fielddescr>
- <fieldname>reverse_http_defsite</fieldname>
- <description>
- <![CDATA[
- This is the HTTP reverse proxy default site.<br/>
- Note: Leave empty to use 'External FQDN' value specified above.
- ]]>
- </description>
- <type>input</type>
- <size>60</size>
- </field>
- <field>
- <name>Squid Reverse HTTPS Settings</name>
- <type>listtopic</type>
- </field>
- <field>
- <fielddescr>Enable HTTPS Reverse Proxy</fielddescr>
- <fieldname>reverse_https</fieldname>
- <description>
- <![CDATA[
- If checked, the proxy server will act in HTTPS reverse mode.<br/>
- <strong>Note: You must add a proper firewall rule with destination 'WAN Address'.</strong>
- ]]>
- </description>
- <type>checkbox</type>
- <enablefields>reverse_https_port,reverse_https_defsite,reverse_ssl_cert,reverse_int_ca,reverse_ignore_ssl_valid,reverse_owa,reverse_owa_ip,reverse_owa_webservice,reverse_owa_activesync,reverse_owa_rpchttp,reverse_owa_mapihttp,reverse_owa_autodiscover,reverse_ssl_chain</enablefields>
- <required/>
- <default_value>off</default_value>
- </field>
- <field>
- <fielddescr>Reverse HTTPS Port</fielddescr>
- <fieldname>reverse_https_port</fieldname>
- <description>
- <![CDATA[
- This is the port the HTTPS reverse proxy will listen on. Default value will be used if left empty.<br/>
- Default: 443
- ]]>
- </description>
- <type>input</type>
- <size>5</size>
- <default_value>443</default_value>
- </field>
- <field>
- <fielddescr>Reverse HTTPS Default Site</fielddescr>
- <fieldname>reverse_https_defsite</fieldname>
- <description>
- <![CDATA[
- This is the HTTPS reverse proxy default site.<br/>
- Note: Leave empty to use 'External FQDN' value specified above.
- ]]>
- </description>
- <type>input</type>
- <size>60</size>
- </field>
- <field>
- <fielddescr>Reverse SSL Certificate</fielddescr>
- <fieldname>reverse_ssl_cert</fieldname>
- <description>Choose the SSL Server Certificate here.</description>
- <type>select_source</type>
- <source>$config['cert']</source>
- <source_name>descr</source_name>
- <source_value>refid</source_value>
- </field>
- <field>
- <fielddescr>Intermediate CA Certificate (If Needed)</fielddescr>
- <fieldname>reverse_int_ca</fieldname>
- <description>
- <![CDATA[
- Paste a signed certificate in X.509 <strong>PEM format</strong> here.
- ]]>
- </description>
- <type>textarea</type>
- <cols>75</cols>
- <rows>5</rows>
- <encoding>base64</encoding>
- </field>
- <field>
- <fielddescr>Ignore Internal Certificate Validation</fielddescr>
- <fieldname>reverse_ignore_ssl_valid</fieldname>
- <description>If checked, internal certificate validation will be ignored.</description>
- <type>checkbox</type>
- <default_value>on</default_value>
- </field>
- <field>
- <name>OWA Reverse Proxy General Settings</name>
- <type>listtopic</type>
- </field>
- <field>
- <fielddescr>Enable OWA Reverse Proxy</fielddescr>
- <fieldname>reverse_owa</fieldname>
- <description>If checked, Squid will act as an accelerator/SSL offloader for Outlook Web App.</description>
- <type>checkbox</type>
- <enablefields>reverse_owa_ip,reverse_owa_activesync,reverse_owa_rpchttp,reverse_owa_mapihttp,reverse_owa_webservice,reverse_owa_autodiscover</enablefields>
- </field>
- <field>
- <fielddescr>CAS-Array / OWA Frontend IP Address</fielddescr>
- <fieldname>reverse_owa_ip</fieldname>
- <description>
- <![CDATA[
- These are the internal IPs of the CAS-Array (OWA frontend servers).<br/>
- <strong>Note: Separate entries by semi-colons (;)</strong>
- ]]>
- </description>
- <type>input</type>
- <size>70</size>
- </field>
- <field>
- <fielddescr>Enable ActiveSync</fielddescr>
- <fieldname>reverse_owa_activesync</fieldname>
- <description>If checked, ActiveSync will be enabled.</description>
- <type>checkbox</type>
- </field>
- <field>
- <fielddescr>Enable Outlook Anywhere</fielddescr>
- <fieldname>reverse_owa_rpchttp</fieldname>
- <description>If checked, RPC over HTTP will be enabled.</description>
- <type>checkbox</type>
- </field>
- <field>
- <fielddescr>Enable MAPI HTTP</fielddescr>
- <fieldname>reverse_owa_mapihttp</fieldname>
- <description>
- <![CDATA[
- If checked, MAPI over HTTP will be enabled.<br/>
- <strong>This feature is only available with at least Microsoft Exchange 2013 SP1</strong>
- ]]>
- </description>
- <type>checkbox</type>
- </field>
- <field>
- <fielddescr>Enable Exchange WebServices</fielddescr>
- <fieldname>reverse_owa_webservice</fieldname>
- <description>
- <![CDATA[
- If checked, Exchange WebServices will be enabled.<br/>
- <strong>There are potential DoS side effects to its use. Please avoid unless really required.</strong>
- ]]>
- </description>
- <type>checkbox</type>
- </field>
- <field>
- <fielddescr>Enable AutoDiscover</fielddescr>
- <fieldname>reverse_owa_autodiscover</fieldname>
- <description>
- <![CDATA[
- If checked, AutoDiscover will be enabled.<br/>
- <strong>You also should set up the autodiscover DNS record to point to you WAN IP.</strong>
- ]]>
- </description>
- <type>checkbox</type>
- </field>
- <field>
- <name>Squid Reverse Mappings</name>
- <type>listtopic</type>
- </field>
- <field>
- <fielddescr>
- <![CDATA[
- Peer Definitions<br/>
- Publishing Hosts
- ]]>
- </fielddescr>
- <fieldname>reverse_cache_peer</fieldname>
- <description>
- <![CDATA[
- Enter each peer definition on a new line. Directives have to be separated by a semicolon(;).<br/><br/>
- Syntax: [peer alias];[internal ip address];[port];[HTTP/HTTPS]<br/>
- Example: HOST1;192.168.0.1;80;HTTP<br/>
- <strong><span class="errmsg">WARNING:</span> Wrong syntax usage will result in Squid not starting!</strong>
- ]]>
- </description>
- <type>textarea</type>
- <cols>60</cols>
- <rows>10</rows>
- <encoding>base64</encoding>
- </field>
- <field>
- <fielddescr>
- <![CDATA[
- URI Definitions<br/>
- Published URIs
- ]]>
- </fielddescr>
- <fieldname>reverse_uri</fieldname>
- <description>
- <![CDATA[
- Enter each reverse ACL definition on a separate line. Directives have to be separated by a semicolon(;)<br/><br/>
- Syntax: [group the uri belongs to];[URI to publish](;[vhost fqdn])<br/>
- Example: URI1;public;server.example.com<br/><br/>
- Notes:<br/>
- - A group can contain multiple URIs<br/>
- - If [vhost fqdn] is ommited, 'External FQDN' is used<br/>
- - You also can specify http:// or https://<br/><br/>
- <strong><span class="errmsg">WARNING:</span> Wrong syntax usage will result in Squid not starting!</strong>
- ]]>
- </description>
- <type>textarea</type>
- <cols>60</cols>
- <rows>10</rows>
- <encoding>base64</encoding>
- </field>
- <field>
- <fielddescr>
- <![CDATA[
- ACL Definitions<br/>
- Published URIs
- ]]>
- </fielddescr>
- <fieldname>reverse_acl</fieldname>
- <description>
- <![CDATA[
- Enter each reverse ACL definition on a new line. Directives have to be separated by a semicolon(;)<br/>
- Syntax: [peer alias];[uri group alias]<br/>
- Example: HOST1;URI1<br/>
- <strong><span class="errmsg">WARNING:</span> Wrong syntax usage will result in Squid not starting!</strong>
- ]]>
- </description>
- <type>textarea</type>
- <cols>60</cols>
- <rows>10</rows>
- <encoding>base64</encoding>
- </field>
- <!--
- <field>
- <fielddescr>Internal Hosts</fielddescr>
- <type>rowhelper</type>
- <rowhelper>
- <rowhelperfield>
- <fielddescr>IP Address</fielddescr>
- <fieldname>reverse_cache_peer_ip</fieldname>
- <type>input</type>
- <size>15</size>
- </rowhelperfield>
- <rowhelperfield>
- <fielddescr>Protocol</fielddescr>
- <fieldname>reverse_cache_peer_proto</fieldname>
- <type>select</type>
- <options>
- <option><name>HTTP</name><value>HTTP</value></option>
- <option><name>HTTPS</name><value>HTTPS</value></option>
- </options>
- </rowhelperfield>
- <rowhelperfield>
- <fielddescr>Port</fielddescr>
- <fieldname>reverse_cache_peer_port</fieldname>
- <type>input</type>
- <size>5</size>
- </rowhelperfield>
- <rowhelperfield>
- <fielddescr>Peer Name</fielddescr>
- <fieldname>reverse_cache_peer_name</fieldname>
- <type>input</type>
- <size>25</size>
- </rowhelperfield>
- </rowhelper>
- </field>
- <field>
- <fielddescr>Published URI</fielddescr>
- <type>rowhelper</type>
- <rowhelper>
- <rowhelperfield>
- <fielddescr>URI</fielddescr>
- <fieldname>reverse_cache_peer_uri</fieldname>
- <type>input</type>
- <size>50</size>
- </rowhelperfield>
- <rowhelperfield>
- <fielddescr>Peer Name</fielddescr>
- <fieldname>reverse_cache_peer</fieldname>
- <type>input</type>
- <size>25</size>
- </rowhelperfield>
- </rowhelper>
- </field>
- -->
- </fields>
- <custom_php_validation_command>
- squid_validate_reverse($_POST, $input_errors);
- </custom_php_validation_command>
- <custom_php_resync_config_command>
- squid_resync();
- </custom_php_resync_config_command>
-</packagegui>
diff --git a/config/squid3/34/squid_reverse_general.xml b/config/squid3/34/squid_reverse_general.xml
index 19c504f1..90babcd0 100755
--- a/config/squid3/34/squid_reverse_general.xml
+++ b/config/squid3/34/squid_reverse_general.xml
@@ -42,7 +42,7 @@
]]>
</copyright>
<name>squidreversegeneral</name>
- <version>0.3.5</version>
+ <version>0.3.8</version>
<title>Reverse Proxy Server: General</title>
<include_file>/usr/local/pkg/squid.inc</include_file>
<tabs>
@@ -303,7 +303,12 @@
</field>
</fields>
<custom_php_validation_command>
+ <![CDATA[
+ if (!empty($_POST) && !squid_enabled()) {
+ $input_errors[] = "Squid is disabled. You must enable Squid proxy under Services - Squid Proxy Server - General.";
+ }
squid_validate_reverse($_POST, $input_errors);
+ ]]>
</custom_php_validation_command>
<custom_php_resync_config_command>
squid_resync();
diff --git a/config/squid3/34/squid_traffic.xml b/config/squid3/34/squid_traffic.xml
index ac86770f..bd01bbb7 100755
--- a/config/squid3/34/squid_traffic.xml
+++ b/config/squid3/34/squid_traffic.xml
@@ -217,6 +217,7 @@
<fieldname>quick_abort_max</fieldname>
<description>If the transfer has more than x KB remaining, it will abort the retrieval.</description>
<type>input</type>
+ <size>10</size>
<default_value>0</default_value>
</field>
<field>
diff --git a/config/squid3/34/squid_users.xml b/config/squid3/34/squid_users.xml
index f67db48e..c47395b9 100755
--- a/config/squid3/34/squid_users.xml
+++ b/config/squid3/34/squid_users.xml
@@ -111,6 +111,7 @@
<description>Enter the username here.</description>
<type>input</type>
<required/>
+ <size>20</size>
</field>
<field>
<fielddescr>Password</fielddescr>
@@ -118,12 +119,14 @@
<description>Enter the password here.</description>
<type>password</type>
<required/>
+ <size>20</size>
</field>
<field>
<fielddescr>Description</fielddescr>
<fieldname>description</fieldname>
<description>You may enter a description here for your reference (not parsed).</description>
<type>input</type>
+ <size>60</size>
</field>
</fields>
<custom_php_resync_config_command>