aboutsummaryrefslogtreecommitdiffstats
path: root/config/havp
diff options
context:
space:
mode:
authorserg dvoriancev <dv_serg@mail.ru>2009-05-01 22:59:43 +0400
committerserg dvoriancev <dv_serg@mail.ru>2009-05-01 22:59:43 +0400
commitedd26d4525fd346b0493e255235aca5706c96428 (patch)
tree7c40a8d1fe8f2b0738f98b2d533f584d25b77b9f /config/havp
parent6911a4803dcf5a8eea3c0f3d1b000a80be4b97cd (diff)
downloadpfsense-packages-edd26d4525fd346b0493e255235aca5706c96428.tar.gz
pfsense-packages-edd26d4525fd346b0493e255235aca5706c96428.tar.bz2
pfsense-packages-edd26d4525fd346b0493e255235aca5706c96428.zip
havp update new version ; squidGuard fix small bug
Diffstat (limited to 'config/havp')
-rw-r--r--config/havp/havp.inc1436
-rw-r--r--config/havp/havp.xml251
-rw-r--r--config/havp/havp_avset.xml105
-rw-r--r--config/havp/havp_fscan.xml72
4 files changed, 1420 insertions, 444 deletions
diff --git a/config/havp/havp.inc b/config/havp/havp.inc
index 85427eb2..e51f0a9b 100644
--- a/config/havp/havp.inc
+++ b/config/havp/havp.inc
@@ -2,7 +2,7 @@
/*
havp.inc
Part of pfSense package
- Copyright (C) 2008 Serg Dvorianceev
+ Copyright (C) 2009 Serg Dvorianceev
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -27,197 +27,501 @@
POSSIBILITY OF SUCH DAMAGE.
*/
-/* ! НАVP v.0.88 !*/
+/* ! for HAVP v.0.88 ! */
+/* ! Real virus collection for tests http://www.nvkz.kuzbass.net/as/ ! */
require_once('globals.inc');
require_once('config.inc');
require_once('util.inc');
+require_once('system.inc');
require_once('pfsense-utils.inc');
require_once('pkg-utils.inc');
require_once('filter.inc');
require_once('service-utils.inc');
+# ------------------------------------------------------------------------------
+# globals
+# ------------------------------------------------------------------------------
+# Debug / uncomment next for debug /
+define('HV_DEBUG', 'false');
+# use Clamd daemon (another - use libclam)
+define('HV_USE_CLAMD', 'true');
+define('HV_CLAMD_TCPSOCKET', 'true');
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# RAM Disk - use as 'tmp' dir for more quick work
+# note: this options allow RAM Disk allocation
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# set 'true' for enable RAM Disk
+define('HV_USE_TMPRAMDISK', 'true');
+# set 'false' for disable RAM Disk on VM (if you have troubles on VM)
+define('HV_VM_TMPRAMDISK', 'true');
+
+# ------------------------------------------------------------------------------
+# forms
+# ------------------------------------------------------------------------------
+define('HVFORM_HAVP', 'havp');
+define('HVFORM_FSCAN', 'havpfscan');
+define('HVFORM_AVSET', 'havpavset');
+
+# ------------------------------------------------------------------------------
# defines
-define('HV_USER', 'havp');
-define('HV_AV_USER', 'havp');
-
-define('HV_WORKDIR', '/usr/local/etc/havp');
-define('HV_CONFIGFILE', '/havp.config');
-define('HV_WHITELISTFILE', '/whitelist');
-define('HV_BLACKLISTFILE', '/blacklist');
-
-define('HV_PIDFILE', '/var/run/havp.pid');
-define('HV_LOGDIR', '/var/log/havp');
-define('HV_AVLOGDIR', '/var/log/clamav');
-define('HV_ACCESSLOG', '/access.log');
-define('HV_LOG', '/havp.log');
-define('HV_TEMPDIR', '/var/tmp');
-define('HV_HAVPTEMPDIR', '/var/tmp/havp');
-define('HV_SCANTEMPFILE', '/havp/havp-XXXXXX');
-define('HV_DEFAULTPORT', '3125');
-define('HV_DEFAULTADDR', '127.0.0.1');
-define('HV_TEMPLATEPATH', '/usr/local/share/examples/havp/templates');
-define('HV_CRONNAME_AVUPD','havp_av_update');
-define('HV_CRONCMD_AVUPD', '/usr/local/etc/rc.d/clamav-freshclam start');
-define('HV_CRONKEY_AVUPD', '/clamav-freshclam');
-define('HV_AVUPD_SCRIPT', '/usr/local/etc/rc.d/havp_avupdate.sh');
-define('HV_FRESHCLAM_CONFIGFILE', '/usr/local/etc/freshclam.conf');
+# ------------------------------------------------------------------------------
+# havp
+define('HVDEF_ADDR', '127.0.0.1');
+define('HVDEF_PROXYPORT', '8080');
+define('HVDEF_MAXSCANSIZE', '5000000'); # [bytes] ! do not enter 0 or big size !
+define('HVDEF_MAXARCSCANSIZE', '5000000'); # [bytes] ! do not enter 0 or big size !
+define('HVDEF_PID_FILE', '/var/run/havp.pid');
+define('HVDEF_WORK_DIR', '/usr/local/etc/havp');
+define('HVDEF_LOG_DIR', '/var/log/havp');
+define('HVDEF_AVLOG_DIR', '/var/log/clamav');
+define('HVDEF_TEMP_DIR', '/var/tmp');
+define('HVDEF_HAVPTEMP_DIR', HVDEF_TEMP_DIR . '/havp');
+define('HVDEF_RAMTEMP_DIR', HVDEF_TEMP_DIR . '/havpRAM');
+define('HVDEF_SCANTEMPFILE', '/havp-XXXXXX');
+define('HVDEF_TEMPLATES', '/usr/local/share/examples/havp/templates');
+define('HVDEF_TEMPLATES_EX', HVDEF_TEMPLATES . '_ex');
+define('HVDEF_FRESHCLAM_CONF', '/usr/local/etc/freshclam.conf');
+define('HVDEF_FILTER_RULES', '/tmp/rules.havp');
+define('HVDEF_HAVP_CONFIG', HVDEF_WORK_DIR . '/havp.config');
+define('HVDEF_HAVP_XMLCONF', HVDEF_WORK_DIR . '/havp_conf.xml');
+define('HVDEF_HAVP_WHITELIST', HVDEF_WORK_DIR . '/whitelist');
+define('HVDEF_HAVP_BLACKLIST', HVDEF_WORK_DIR . '/blacklist');
+define('HVDEF_HAVP_ACCESSLOG', HVDEF_LOG_DIR . '/access.log');
+define('HVDEF_HAVP_ERRORLOG', HVDEF_LOG_DIR . '/havp.log');
+define('HVDEF_HAVP_MINSRV', '10');
+define('HVDEF_HAVP_MAXSRV', '100');
+# Clam
+define('HVDEF_CLAM_RUNDIR', '/var/run/clamav');
+define('HVDEF_CLAM_SOCKET', HVDEF_CLAM_RUNDIR.'/clamd.sock');
+define('HVDEF_CLAM_PID', HVDEF_CLAM_RUNDIR.'/clamd.pid');
+define('HVDEF_CLAM_WORKDIR', '/usr/local/etc');
+define('HVDEF_CLAM_CONFIG', '/usr/local/etc/clamd.conf');
+define('HVDEF_CLAM_TCPSOCKET', '3310');
+# script's
+define('HVDEF_SCRIPT_DIR', '/usr/local/etc/rc.d');
+define('HVDEF_AVCRON_SCRIPT', '/clamav-freshclam');
+define('HVDEF_FILTER_RESYNC_SCRIPT', '/usr/local/pkg/pf/havp_filter_resync.sh');
+define('HVDEF_HAVP_STARTUP_SCRIPT', HVDEF_SCRIPT_DIR . '/havp.sh');
+define('HVDEF_CLAM_STARTUP_SCRIPT', HVDEF_SCRIPT_DIR . '/clamd.sh');
+define('HVDEF_AVUPD_SCRIPT', HVDEF_SCRIPT_DIR . '/havp_avupdate');
+# cron
+define('HVDEF_CLAM_UPD_CRONNAME', 'havp_clam_update');
+define('HVDEF_CLAM_UPD_CRONCMD', HVDEF_SCRIPT_DIR . HVDEF_AVCRON_SCRIPT . " start");
+define('HVDEF_CLAM_UPD_CRONKEY', HVDEF_AVCRON_SCRIPT);
+# user
+define('HVDEF_USER', 'havp');
+define('HVDEF_GROUP', 'havp');
+define('HVDEF_AVUSER', HVDEF_USER);
+# fields
+define('HV_SCANTEMPFILE', 'hv_scan_tempfile');
+# ------------------------------------------------------------------------------
# XML fields
-define('XML_HAVPENABLE', 'enable');
-define('XML_HAVPLANG', 'havplang');
-define('XML_PARENTPROXY', 'parentproxy');
-define('XML_WHITELIST', 'whitelist');
-define('XML_BLACKLIST', 'blacklist');
-define('XML_PROXYIFACE', 'proxyiface');
-define('XML_PROXYPORT', 'proxyport');
-define('XML_USEEXTIFACE', 'listenextinterface');
-define('XML_XFORWARDEDFOR', 'xforwardedfor');
-define('XML_FAILSCANERROR', 'failscanerror');
-define('XML_LANGUAGE', 'lang');
-define('XML_SCANIMG', 'scanimg');
-define('XML_SCANARC', 'scanarc');
-define('XML_SCANMAXSIZE', 'scanmaxsize');
-define('XML_MAXDOWNLOADSIZE', 'maxdownloadsize');
-define('XML_SYSLOG', 'syslog');
-define('XML_HAVPUPDATE', 'havpavupdate');
-# define('','');
-
-function havp_install(){
+# ------------------------------------------------------------------------------
+define('F_ENABLE', 'enable');
+define('F_PROXYMODE', 'proxymode');
+define('F_PROXYINTERFACE', 'proxyinterface');
+define('F_PROXYBINDIFACE', 'proxybindiface'); # internal var
+define('F_PROXYPORT', 'proxyport');
+define('F_PARENTPROXY', 'parentproxy');
+define('F_LANGUAGE', 'lang');
+define('F_MAXDOWNLOADSIZE', 'maxdownloadsize');
+define('F_RANGE', 'range');
+define('F_WHITELIST', 'whitelist');
+define('F_BLACKLIST', 'blacklist');
+define('F_ENABLEFORWARDEDIP', 'enableforwardedip');
+define('F_ENABLEXFORWARDEDFOR', 'enablexforwardedfor');
+define('F_ENABLERAMDISK', 'enableramdisk');
+# scanner
+define('F_FAILSCANERROR', 'failscanerror');
+define('F_SCANMAXSIZE', 'scanmaxsize');
+define('F_SCANIMG', 'scanimg');
+define('F_SCANARC', 'scanarc');
+define('F_SCANARCMAXSIZE', 'scanarcmaxsize');
+# antivirus options
+define('F_HAVPUPDATE', 'havpavupdate');
+define('F_DBREGION', 'dbregion');
+define('F_AVUPDATESERVER', 'avupdateserver');
+# log
+define('F_SYSLOG', 'syslog');
+define('F_LOG', 'log');
+define('F_AVSETSYSLOG', 'avsetsyslog');
+define('F_AVSETLOG', 'avsetlog');
+#
+define('F_TEMPLATEPATH', 'templatepath'); # internal var
+# file scanner [HVFORM_FSCAN]
+define('F_SCANFILEPATH', 'scanfilepath');
+# пока непонятно что это и что с ним делать
+define('F_DISABLEXFORWARD', 'disablexforward'); # + forwarded ip
+define('F_FORWARDEDIP', 'forwardedip');
+
+# ------------------------------------------------------------------------------
+# global config
+# ------------------------------------------------------------------------------
+$havp_config = array();
+$havp_config[HV_SCANTEMPFILE] = HVDEF_HAVPTEMP_DIR . HVDEF_SCANTEMPFILE;
+
+# ------------------------------------------------------------------------------
+# Initialization
+# ------------------------------------------------------------------------------
+havp_convert_pfxml_xml();
+
+# ==============================================================================
+# Installation and config
+# ==============================================================================
+function havp_install()
+{
havp_check_system();
}
-
-function havp_deinstall() {
- havp_setup_cron(HV_CRONNAME_AVUPD,"", "");
- mwexec("rm -rf " . HV_AVUPD_SCRIPT);
- mwexec("rm -rf " . HV_PIDFILE);
+# ------------------------------------------------------------------------------
+function havp_deinstall()
+{
+ havp_setup_cron(HVDEF_CLAM_UPD_CRONNAME,"", "");
+ mwexec("rm -rf " . HVDEF_HAVP_STARTUP_SCRIPT);
+ mwexec("rm -rf " . HVDEF_CLAM_STARTUP_SCRIPT);
+ mwexec("rm -rf " . HVDEF_AVUPD_SCRIPT);
+ mwexec("rm -rf " . HVDEF_FILTER_RESYNC_SCRIPT);
+ mwexec("rm -rf " . HVDEF_PID_FILE);
+ mwexec("rm -rf " . HVDEF_CLAM_PID);
+ mwexec("rm -rf " . HVDEF_CLAM_SOCKET);
+}
+# ==============================================================================
+# Events
+# ==============================================================================
+# before form
+# ------------------------------------------------------------------------------
+function havp_before_form($pkg)
+{
+}
+# ------------------------------------------------------------------------------
+function havp_fscan_before_form($pkg)
+{
+ if(is_array($pkg['fields']['field'])) {
+ foreach($pkg['fields']['field'] as $key => $field) {
+ if ($field['fieldname'] === F_SCANFILEPATH) {
+ $pkg['fields']['field'][$key]['description'] .= havp_fscan_html();
+ break;
+ }
+ }
+ }
}
+# ------------------------------------------------------------------------------
+# validation
+# ------------------------------------------------------------------------------
+function havp_validate_settings($post, $input_errors)
+{
+ $submit = isset($_GET['submit']) ? $_GET['submit'] : $_POST['submit'];
-function havp_resync() {
- global $config;
- $pfconf = $config['installedpackages']['havp']['config'][0];
+ # manual update AV database
+ if ($submit === 'Update_AV') {
+ havp_update_AV();
+ }
+ # Scan file or dir
+ elseif($submit === 'Start_scan') {
+ if (file_exists($post[F_SCANFILEPATH]))
+ start_antivirus_scanner($post[F_SCANFILEPATH]);
+ else $input_errors[] = "File or path not exists '{$post[F_SCANFILEPATH]}'.";
+ }
+ else {
+ # port validate
+ $prxport = trim($post[F_PROXYPORT]);
+ if (!empty($prxport) && !is_port($prxport))
+ $input_errors[] = 'You must enter a valid port number in the \'Proxy port\' field';
+
+ # parent proxy validate
+ $parent = trim($post[F_PARENT]);
+
+ # max download size validate
+ $maxval = trim($post[F_MAXDOWNLOADSIZE]);
+ if (!empty($maxval) && !is_numericint($maxval)) # is_port - validate value
+ $input_errors[] = 'You must enter a valid numeric value in \'Max download size\' field.';
+
+ # scan max file size validate
+ $maxval = trim($post[F_SCANMAXSIZE]);
+ if (!empty($maxval) && !is_numericint($maxval)) # is_port - validate value
+ $input_errors[] = 'You must enter a valid numeric value in \'Scan max file size\' field.';
+
+ # whitelist validate
+ $lst = explode("\n", str_replace(" ", "\n", $post[F_WHITELIST]));
+ foreach ($lst as $dm) {
+ $dm = trim($dm);
+ if ($dm && check_bw_domain($dm) === false)
+ $input_errors[] = "Invalid whitelist element '$dm'.";
+ }
+
+ # blacklist validate
+ $lst = explode("\n", str_replace(" ", "\n", $post[F_BLACKLIST]));
+ foreach ($lst as $dm) {
+ $dm = trim($dm);
+ if ($dm && check_bw_domain($dm) === false)
+ $input_errors[] = "Invalid blacklist element '$dm'.";
+ }
+ }
+
+}
+# ------------------------------------------------------------------------------
+# resync
+# ------------------------------------------------------------------------------
+function havp_resync()
+{
+ global $havp_config;
+ havp_convert_pfxml_xml();
havp_check_system();
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# whitelist and blacklist
- # also white-listed:
- $whitelist = havp_whitelist_def() . "\n" . str_replace(" ", "\n", base64_decode($pfconf[XML_WHITELIST]));
- $blacklist = str_replace(" ", "\n", base64_decode($pfconf[XML_BLACKLIST]));
- # stupid havp parser - error on 0x0D:
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ # also white-listed by default:
+ $whitelist = havp_whitelist_def() . "\n" . str_replace(" ", "\n", base64_decode($havp_config[F_WHITELIST]));
+ $blacklist = str_replace(" ", "\n", base64_decode($havp_config[F_BLACKLIST]));
+ # fix: stupid havp parser - error on 0x0D:
$whitelist = str_replace("\r", "", $whitelist);
$blacklist = str_replace("\r", "", $blacklist);
- file_put_contents(HV_WORKDIR . HV_WHITELISTFILE, $whitelist);
- file_put_contents(HV_WORKDIR . HV_BLACKLISTFILE, $blacklist);
+ file_put_contents(HVDEF_HAVP_WHITELIST, $whitelist);
+ file_put_contents(HVDEF_HAVP_BLACKLIST, $blacklist);
- # config havp
- file_put_contents(HV_WORKDIR . HV_CONFIGFILE, havp_config());
- set_file_access(HV_WORKDIR, HV_USER, '0755');
+ # reconfigure clamd
+ havp_reconfigure_clamd();
- # config freshclam
- file_put_contents(HV_FRESHCLAM_CONFIGFILE, havp_config_freshclam());
- set_file_access(HV_FRESHCLAM_CONFIGFILE, HV_AV_USER, '0664');
+ # config havp
+ file_put_contents (HVDEF_HAVP_CONFIG, havp_config_havp());
+ havp_set_file_access(HVDEF_WORK_DIR, HVDEF_USER, '0755');
- # cron task
- $on = false;
- $opt = array("0", "*", "*", "*", "*", "root", "/usr/bin/nice -n20 " . HV_AVUPD_SCRIPT);
- switch($pfconf['havpavupdate']) {
- case 'none': $on = false; break;
- case 'hv_01h': $on = true; $opt[1]= "*/1"; break;
- case 'hv_02h': $on = true; $opt[1]= "*/2"; break;
- case 'hv_03h': $on = true; $opt[1]= "*/3"; break;
- case 'hv_04h': $on = true; $opt[1]= "*/4"; break;
- case 'hv_06h': $on = true; $opt[1]= "*/6"; break;
- case 'hv_08h': $on = true; $opt[1]= "*/8"; break;
- case 'hv_12h': $on = true; $opt[1]= "*/12"; break;
- case 'hv_24h': $on = true; $opt[1]= "0"; break;
- default: break;
- }
- havp_setup_cron(HV_CRONNAME_AVUPD, $opt, $on);
+ if ($havp_config[F_ENABLE] === 'true') {
+ mwexec_bg(HVDEF_HAVP_STARTUP_SCRIPT . " restart");
+ log_error("Starting HAVP");
+ }
+ else {
+ mwexec_bg(HVDEF_HAVP_STARTUP_SCRIPT . " stop");
+ log_error("Stopping HAVP");
+ }
- mwexec("killall havp");
- mwexec("killall havp");
- mwexec("/usr/local/sbin/havp -c /usr/local/etc/havp" . HV_CONFIGFILE);
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ # reconfigure squid
+ havp_configure_squid();
-mountRAMdisk();
+ # reconfigure AV parts
+ havp_reconfigure_freshclam();
+ havp_reconfigure_cron();
+ # configure system filter
+ filter_configure();
}
-
-function havp_check_system() {
+# ------------------------------------------------------------------------------
+function havp_avset_resync()
+{
+ havp_convert_pfxml_xml();
+ havp_check_system();
+ # reconfigure
+ havp_reconfigure_freshclam();
+ havp_reconfigure_cron();
+}
+# ==============================================================================
+# check system
+# ==============================================================================
+function havp_check_system()
+{
+ global $havp_config;
# workdir permissions
- set_file_access(HV_WORKDIR, HV_USER, '');
+ havp_set_file_access(HVDEF_WORK_DIR, HVDEF_USER, '');
- # tempdir
- if (!file_exists(HV_HAVPTEMPDIR)) mwexec("mkdir -p " . HV_HAVPTEMPDIR);
- set_file_access(HV_HAVPTEMPDIR, HV_USER, '');
+ # havp tempdir
+ if (!file_exists(HVDEF_HAVPTEMP_DIR))
+ mwexec("mkdir -p " . HVDEF_HAVPTEMP_DIR);
+ havp_set_file_access(HVDEF_HAVPTEMP_DIR, HVDEF_USER, '');
+
+ # RAM tempdir
+ if (!file_exists(HVDEF_RAMTEMP_DIR))
+ mwexec("mkdir -p " . HVDEF_RAMTEMP_DIR);
+ havp_set_file_access(HVDEF_RAMTEMP_DIR, HVDEF_USER, '');
# template permissions
- set_file_access(HV_TEMPLATEPATH, HV_USER, '');
+ havp_set_file_access(HVDEF_TEMPLATES, HVDEF_USER, '');
+ havp_set_file_access(HVDEF_TEMPLATES_EX, HVDEF_USER, '');
# log files exists ?
- if (!file_exists(HV_LOGDIR . HV_ACCESSLOG)) file_put_contents(HV_LOGDIR . HV_ACCESSLOG, '');
- if (!file_exists(HV_LOGDIR . HV_LOG)) file_put_contents(HV_LOGDIR . HV_LOG, '');
+ if (!file_exists(HVDEF_HAVP_ACCESSLOG)) file_put_contents(HVDEF_HAVP_ACCESSLOG, '');
+ if (!file_exists(HVDEF_HAVP_ERRORLOG)) file_put_contents(HVDEF_HAVP_ERRORLOG, '');
# log dir permissions
- set_file_access(HV_LOGDIR, HV_USER, '0764');
+ havp_set_file_access(HVDEF_LOG_DIR, HVDEF_USER, '0764');
# pid file
- if (!file_exists(HV_PIDFILE)) file_put_contents(HV_PIDFILE, '');
- set_file_access(HV_PIDFILE, HV_USER, '0664');
+ if (!file_exists(HVDEF_PID_FILE)) file_put_contents(HVDEF_PID_FILE, '');
+ havp_set_file_access(HVDEF_PID_FILE, HVDEF_USER, '0664');
# freshclam config permissions
- if (!file_exists(HV_FRESHCLAM_CONFIGFILE)) file_put_contents(HV_FRESHCLAM_CONFIGFILE, '');
- set_file_access(HV_FRESHCLAM_CONFIGFILE, HV_AV_USER, '0664');
+ if (!file_exists(HVDEF_FRESHCLAM_CONF)) file_put_contents(HVDEF_FRESHCLAM_CONF, '');
+ havp_set_file_access(HVDEF_FRESHCLAM_CONF, HVDEF_AVUSER, '0664');
# log files exists ?
- if (!file_exists(HV_AVLOGDIR . '/clamd.log')) file_put_contents(HV_AVLOGDIR . '/clamd.log', '');
- if (!file_exists(HV_AVLOGDIR . '/freshclam.log')) file_put_contents(HV_AVLOGDIR . '/freshclam.log', '');
+ if (!file_exists(HVDEF_AVLOG_DIR . '/clamd.log')) file_put_contents(HVDEF_AVLOG_DIR . '/clamd.log', '');
+ if (!file_exists(HVDEF_AVLOG_DIR . '/freshclam.log')) file_put_contents(HVDEF_AVLOG_DIR . '/freshclam.log', '');
# log dir permissions
- set_file_access(HV_AVLOGDIR, HV_USER, '0777');
+ havp_set_file_access(HVDEF_AVLOG_DIR, HVDEF_USER, '0777');
# checking dir's and permissions
# "DatabaseDirectory /var/db/clamav";
# "UpdateLogFile /var/log/clamav/freshclam.log";
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ # ClamAV
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ # catalog for Pid and Socket files
+ if (!file_exists(HVDEF_CLAM_RUNDIR))
+ mwexec("mkdir -p " . HVDEF_CLAM_RUNDIR);
+ havp_set_file_access(HVDEF_CLAM_RUNDIR, HVDEF_USER, '0774');
+
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# AV update script
- file_put_contents(HV_AVUPD_SCRIPT, havp_AVupdate_script());
- set_file_access(HV_AVUPD_SCRIPT, HV_AV_USER, '0755');
-}
+ file_put_contents(HVDEF_AVUPD_SCRIPT, havp_AVupdate_script());
+ havp_set_file_access(HVDEF_AVUPD_SCRIPT, HVDEF_AVUSER, '0755');
-function havp_validate_settings($post, $input_errors) {
- $submit = isset($_GET['submit']) ? $_GET['submit'] : $_POST['submit'];
+ # startup script's (havp and clamd)
+ havp_startup_script();
+ hv_clamd_startup_script();
- # manual update AV database
- if ($submit === 'Update_AV')
- havp_update_AV();
- else {
- $prxport = trim($post[XML_PROXYPORT]);
- if (!empty($prxport) && !is_port($prxport))
- $input_errors[] = 'You must enter a valid port number in the \'Proxy port\' field';
+ # havp filter script
+ if (1 /*!file_exists(HVDEF_FILTER_RESYNC_SCRIPT)*/) {
+ file_put_contents(HVDEF_FILTER_RESYNC_SCRIPT, havp_filter_resync_script());
+ havp_set_file_access(HVDEF_FILTER_RESYNC_SCRIPT, HVDEF_AVUSER, '0755');
+ }
- # check whitelist
- $lst = explode("\n", str_replace(" ", "\n", $post[XML_WHITELIST]));
- foreach ($lst as $dm) {
- $dm = trim($dm);
- if ($dm && check_bw_domain($dm) === false)
- $input_errors[] = "Invalid whitelist element '$dm'.";
- }
+ # mount RAMDisk
+ mountRAMdisk(true);
+}
+# ==============================================================================
+# Reconfigure package parts
+# ==============================================================================
+function havp_reconfigure_clamd()
+{
+ file_put_contents (HVDEF_CLAM_CONFIG, havp_config_clam());
+ havp_set_file_access(HVDEF_CLAM_CONFIG, HVDEF_USER, '0664');
+}
+# ------------------------------------------------------------------------------
+function havp_reconfigure_freshclam()
+{
+ # config freshclam
+ file_put_contents (HVDEF_FRESHCLAM_CONF, havp_config_freshclam());
+ havp_set_file_access(HVDEF_FRESHCLAM_CONF, HVDEF_USER, '0664');
+}
+# ------------------------------------------------------------------------------
+function havp_reconfigure_cron()
+{
+ global $havp_config;
- # check blacklist
- $lst = explode("\n", str_replace(" ", "\n", $post[XML_BLACKLIST]));
- foreach ($lst as $dm) {
- $dm = trim($dm);
- if ($dm && check_bw_domain($dm) === false)
- $input_errors[] = "Invalid blacklist element '$dm'.";
+ # cron task
+ $on = false;
+ $optval = array("", "*/1", "*/2", "*/3", "*/4", "*/6", "*/8", "*/12", "0");
+ $opt = array("0", "*", "*", "*", "*", "root", "/usr/bin/nice -n20 " . HVDEF_AVUPD_SCRIPT);
+ $opt[1] = $optval[$havp_config[F_HAVPUPDATE]];
+ $on = ($opt[1] !== "");
+
+ havp_setup_cron(HVDEF_CLAM_UPD_CRONNAME, $opt, $on);
+}
+# ------------------------------------------------------------------------------
+# Convert conf to XML
+# ------------------------------------------------------------------------------
+function havp_convert_pfxml_xml()
+{
+ global $config, $havp_config;
+
+ $pfconf = $config['installedpackages'][HVFORM_HAVP]['config'][0];
+
+ # === GUI Fields ===
+ $havp_config[F_ENABLE] = ( $pfconf[F_ENABLE] === 'on' ? 'true' : 'false' );
+
+ # proxy
+ $havp_config[F_PROXYMODE] = ( !empty($pfconf[F_PROXYMODE]) ? $pfconf[F_PROXYMODE] : 'standard' );
+# ToDo: add check squid transparent
+ $havp_config[F_PROXYINTERFACE] = $pfconf[F_PROXYINTERFACE];
+ $havp_config[F_PROXYPORT] = ( !empty($pfconf[F_PROXYPORT]) ? $pfconf[F_PROXYPORT] : HVDEF_PROXYPORT );
+# ToDo: add check squid proxy port
+
+ # parent proxy
+ # [F_PARENTPROXY] = "proxy_ip:port"
+ $pfconf[F_PARENTPROXY] = trim($pfconf[F_PARENTPROXY]);
+ if (!empty($pfconf[F_PARENTPROXY])) {
+ $parent = explode(":", trim($pfconf[F_PARENTPROXY]));
+ $havp_config[F_PARENTPROXY] = array( 'ip' => $parent[0], 'port' => $parent[1] );
+ }
+ else $havp_config[F_PARENTPROXY] = '';
+
+ # language
+ $havp_config[F_LANGUAGE] = trim($pfconf[F_LANGUAGE]);
+
+ # proxy settings
+ $havp_config[F_ENABLEFORWARDEDIP] = ( $pfconf[F_ENABLEFORWARDEDIP] === 'on' ? 'true' : 'false' );
+ $havp_config[F_ENABLEXFORWARDEDFOR] = ( $pfconf[F_ENABLEXFORWARDEDFOR] === 'on' ? 'true' : 'false' );
+ $havp_config[F_MAXDOWNLOADSIZE] = ( is_numeric($pfconf[F_MAXDOWNLOADSIZE]) ? $pfconf[F_MAXDOWNLOADSIZE] : 0 );
+ $havp_config[F_RANGE] = ( $pfconf[F_RANGE] === 'on' ? 'true' : 'false' );
+ $havp_config[F_ENABLERAMDISK] = ( $pfconf[F_ENABLERAMDISK] === 'on' ? 'true' : 'false' );
+
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ # Temp RAMDisk
+ # use RAMDisk if only capacity > calculated [MAXSCANSIZE * 50 connections]
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ # before config manage Temp Dir = RAMDisk|Hard Disk
+ $havp_config[HV_SCANTEMPFILE] = HVDEF_HAVPTEMP_DIR . HVDEF_SCANTEMPFILE;
+ if ($havp_config[F_ENABLERAMDISK] === 'true') {
+ $sys_capacity = get_memory();
+ $mem_capacity = intval($sys_capacity[0]) / 4; # [Mb]
+ $calculated = 50 * $havp_config[F_SCANMAXSIZE] / (1024 * 1024); # [Mb]
+
+ # this is restriction need for balancing between pfSense and HAVP work speed
+ # we can not allocate memory at the expense of other services of the pfSense
+ if ($mem_capacity > $calculated) {
+ # re-define temp file to RAM Disk
+ $havp_config[HV_SCANTEMPFILE] = HVDEF_RAMTEMP_DIR . HVDEF_SCANTEMPFILE;
}
+ else
+ log_error("havp: RAMDisk not used. Diagnostic: system {$sys_capacity[0]}Mb, avialable {$mem_capacity}Mb, calculated {$calculated}Mb. Try reducing 'MAXSCANSIZE' value.");
}
-
+ # scanner
+ $havp_config[F_FAILSCANERROR] = ( $pfconf[F_FAILSCANERROR] === 'on' ? 'true' : 'false' );
+ $havp_config[F_SCANMAXSIZE] = ( is_numeric($pfconf[F_SCANMAXSIZE]) ? $pfconf[F_SCANMAXSIZE] : HVDEF_MAXSCANSIZE ) * 1024; # KB -> Byte
+ $havp_config[F_SCANIMG] = ( $pfconf[F_SCANIMG] === 'on' ? 'true' : 'false' );
+ $havp_config[F_SCANARC] = ( $pfconf[F_SCANARC] === 'on' ? 'true' : 'false' );
+ $havp_config[F_SCANARCMAXSIZE] = ( is_numeric($pfconf[F_SCANARCMAXSIZE]) ? $pfconf[F_SCANARCMAXSIZE] : HVDEF_MAXARCSCANSIZE );
+ # log
+ $havp_config[F_SYSLOG] = ( $pfconf[F_SYSLOG] === 'on' ? 'true' : 'false' );
+ $havp_config[F_LOG] = ( $pfconf[F_LOG] === 'on' ? 'true' : 'false' );
+ $havp_config[F_AVSETSYSLOG] = ( $pfconf[F_AVSETSYSLOG] === 'on' ? 'true' : 'false' );
+ $havp_config[F_AVSETLOG] = ( $pfconf[F_AVSETLOG] === 'on' ? 'true' : 'false' );
+ #
+ # === Internal variables ===
+ # proxy
+ $havp_config[F_PROXYBINDIFACE] = 'localhost';
+ # language template files path
+ $havp_config[F_TEMPLATEPATH] = ( file_exists(HVDEF_TEMPLATES_EX) ? HVDEF_TEMPLATES_EX : HVDEF_TEMPLATES );
+ $havp_config[F_TEMPLATEPATH] .= ( !empty($havp_config[F_LANGUAGE]) ? "/{$havp_config[F_LANGUAGE]}" : "/en" );
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ # HVFORM_AVSET - av settings
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ $pf_avset_conf = $config['installedpackages'][HVFORM_AVSET]['config'][0];
+ $havp_config[F_HAVPUPDATE] = $pf_avset_conf[F_HAVPUPDATE];
+ $havp_config[F_DBREGION] = $pf_avset_conf[F_DBREGION];
+ $havp_config[F_AVUPDATESERVER] = $pf_avset_conf[F_AVUPDATESERVER];
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ # store havp config cache
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ $cfg_xml = dump_xml_config($havp_config, 'havp');
+ file_put_contents(HVDEF_HAVP_XMLCONF, $cfg_xml);
+
+ return $havp_config;
}
+# ------------------------------------------------------------------------------
+# config
+# ------------------------------------------------------------------------------
+# HAVP config
+function havp_config_havp()
+{
+ global $havp_config;
-function havp_config() {
- global $config;
- $pfconf = $config['installedpackages']['havp']['config'][0];
$conf = array();
-
$conf[] =
"# ============================================================
# HAVP config file
@@ -226,138 +530,203 @@ function havp_config() {
# email: dv_serg@mail.ru
# ============================================================
";
-
- $conf[] = "USER " . HV_USER;
- $conf[] = "GROUP " . HV_USER;
- $conf[] = "DAEMON true";
- $conf[] = "PIDFILE " . HV_PIDFILE;
- $conf[] = "\n# For single user home use, 8 should be minimum.";
+ $conf[] = "USER " . HVDEF_USER;
+ $conf[] = "GROUP " . HVDEF_GROUP;
+ $conf[] = "DAEMON true";
+ $conf[] = "PIDFILE " . HVDEF_PID_FILE;
+ $conf[] = "\n# For small home use, 8 should be minimum.";
$conf[] = "# For 500 users corporate use, start at 40.";
- $conf[] = "SERVERNUMBER 3";
- $conf[] = "MAXSERVERS 100";
-
+ $conf[] = "SERVERNUMBER " . HVDEF_HAVP_MINSRV;
+ $conf[] = "MAXSERVERS " . HVDEF_HAVP_MAXSRV;
# log
$conf[] = "\n# log ";
- $conf[] = "ACCESSLOG " . HV_LOGDIR . HV_ACCESSLOG;
- $conf[] = "ERRORLOG " . HV_LOGDIR . HV_LOG;
+ $conf[] = "ACCESSLOG " . HVDEF_HAVP_ACCESSLOG;
+ $conf[] = "ERRORLOG " . HVDEF_HAVP_ERRORLOG;
# syslog
- $syslog = ($pfconf[XML_SYSLOG] === 'on') ? 'true' : 'false';
$conf[] = "\n# syslog";
- $conf[] = "USESYSLOG $syslog"; # use syslog?
- $conf[] = "SYSLOGNAME havp";
+ $conf[] = "USESYSLOG {$havp_config[F_SYSLOG]}";
+ $conf[] = "SYSLOGNAME havp";
$conf[] = "SYSLOGFACILITY daemon";
- $conf[] = "SYSLOGLEVEL info";
+ $conf[] = "SYSLOGLEVEL " . (HV_DEBUG === 'true' ? "debug" : "info"); # err | warning | info | debug
#
$conf[] = "\n# Level of HAVP logging\n# 0 = Only serious errors and information\n# 1 = Less interesting information is included";
- $conf[] = "LOG_OKS true"; # true - for debug, false - for work
- $conf[] = "LOGLEVEL 1"; # 0 - work level, 1 - debug level
-
+ $conf[] = "LOG_OKS " . ( HV_DEBUG === 'true' ? "true" : "false" ); # true - for debug, false - for work
+ $conf[] = "LOGLEVEL " . ( HV_DEBUG === 'true' ? "1" : "0" ); # 0 - work level, 1 - debug level
# temp
$conf[] = "\n# temp ";
- $conf[] = "SCANTEMPFILE " . HV_TEMPDIR . HV_SCANTEMPFILE;
- $conf[] = "TEMPDIR " . HV_TEMPDIR;
-
+ $conf[] = "SCANTEMPFILE " . $havp_config[HV_SCANTEMPFILE];
+ $conf[] = "TEMPDIR " . HVDEF_TEMP_DIR;
+ #
$conf[] = "\n#";
- $conf[] = "DBRELOAD 180";
- $conf[] = "TRANSPARENT false";
- $conf[] = "FORWARDED_IP false";
-
- # X-FORWARD
- $conf[] = "\n# X-FORWARD: proxy can include system's IP address or name in the HTTP requests it forwards";
- $v = ($pfconf[XML_XFORWARDEDFOR] === 'on') ? "true" : "false";
- $conf[] = "X_FORWARDED_FOR $v";
-
+ $conf[] = "DBRELOAD 180";
+ $conf[] = "TRANSPARENT " . ( $havp_config[F_PROXYMODE] === 'transparent' ? "true" : "false" );
+ # X-FORWARD, X-FORWARDED-FOR options
+ $conf[] = "\n# if HAVP is used as parent proxy by some other proxy, this allows to write the real users IP to log, instead of proxy IP.";
+ $conf[] = "FORWARDED_IP " . $havp_config[F_ENABLEFORWARDEDIP];
+ $conf[] = "X_FORWARDED_FOR " . $havp_config[F_ENABLEXFORWARDEDFOR];
# parent proxy = [proxy:port]
- if (!empty($pfconf[XML_PARENTPROXY])) {
- $prxy = str_replace(" ", ":", $pfconf[XML_PARENTPROXY]);
- $prxy = explode(":", $prxy);
+ if (!empty($havp_config[F_PARENTPROXY])) {
$conf[] = "\n# parent proxy ";
- $conf[] = "PARENTPROXY {$prxy[0]}";
- $conf[] = "PARENTPORT {$prxy[1]}";
+ $conf[] = "PARENTPROXY {$havp_config[F_PARENTPROXY]['ip']}";
+ $conf[] = "PARENTPORT {$havp_config[F_PARENTPROXY]['port']}";
}
-
# proxy listening on
$conf[] = "\n# havp is listening on ";
- $pxyport = HV_DEFAULTPORT;
- $pxyaddr = HV_DEFAULTADDR;
- if (!empty($pfconf[XML_PROXYPORT])) $pxyport = $pfconf[XML_PROXYPORT];
- if ($pfconf[XML_USEEXTIFACE] === 'on' && !empty($pfconf[XML_PROXYIFACE])) {
- $pxyaddr = get_real_interface_address($pfconf[XML_PROXYIFACE]);
- $pxyaddr = $pxyaddr[0];
- }
- $conf[] = "PORT $pxyport";
- $conf[] = "BIND_ADDRESS $pxyaddr";
-
+ $conf[] = "PORT {$havp_config[F_PROXYPORT]}";
+ # bind to ip address
+ $bind_iface = get_real_interface_address($havp_config[F_PROXYBINDIFACE]);
+ $conf[] = "BIND_ADDRESS {$bind_iface[0]}";
# template files language
$conf[] = "\n# Path to template files ";
- if (!empty($pfconf[XML_LANGUAGE]))
- $conf[] = "TEMPLATEPATH " . HV_TEMPLATEPATH . "/" . trim($pfconf[XML_LANGUAGE]);
- else $conf[] = "TEMPLATEPATH " . HV_TEMPLATEPATH . "/en";
-
+ $conf[] = "TEMPLATEPATH {$havp_config[F_TEMPLATEPATH]}";
+ #
$conf[] = "\n# whitelist and blacklist";
$conf[] = "WHITELISTFIRST true";
- $conf[] = "WHITELIST /usr/local/etc/havp" . HV_WHITELISTFILE;
- $conf[] = "BLACKLIST /usr/local/etc/havp" . HV_BLACKLISTFILE;
-
+ $conf[] = "WHITELIST " . HVDEF_HAVP_WHITELIST;
+ $conf[] = "BLACKLIST " . HVDEF_HAVP_BLACKLIST;
# failscanerror - pass/block files if scanner error
$conf[] = "\n# block file if error scanning";
- $v = ($pfconf[XML_FAILSCANERROR] === 'on') ? "true" : "false";
- $conf[] = "FAILSCANERROR $v";
-
+ $conf[] = "FAILSCANERROR {$havp_config[F_FAILSCANERROR]}";
+ #
$conf[] = "\n# scanner ";
$conf[] = "SCANNERTIMEOUT 10";
- $conf[] = "RANGE false";
-
+ $conf[] = "RANGE {$havp_config[F_SCANIMG]}";
+ #
$conf[] = "\n# stream";
$conf[] = "STREAMUSERAGENT Player Winamp iTunes QuickTime Audio RMA/ MAD/ Foobar2000 XMMS";
$conf[] = "STREAMSCANSIZE 20000";
-
- # scan image
- $v = ($pfconf[XML_SCANIMG] === 'on') ? "true" : "false";
- $conf[] = "SCANIMAGES $v";
-
- $val = (!empty($pfconf[XML_SCANMAXSIZE]) && is_numeric($pfconf[XML_SCANMAXSIZE])) ? $pfconf[XML_SCANMAXSIZE] : 0;
- $conf[] = "MAXSCANSIZE $v";
-
- $conf[] = "# KEEPBACKBUFFER 200000";
- $conf[] = "# KEEPBACKTIME 5";
-
+ # scan options
+ $conf[] = "SCANIMAGES {$havp_config[F_SCANIMG]}";
+ $conf[] = "MAXSCANSIZE {$havp_config[F_SCANMAXSIZE]}";
+ #
+ $conf[] = "KEEPBACKBUFFER 200000";
+ $conf[] = "KEEPBACKTIME 5";
+ #
$conf[] = "# After Trickling Time (seconds), some bytes are sent to browser to keep the connection alive";
- $conf[] = "TRICKLING 30";
-
+ $conf[] = "TRICKLING 5";
+ #
$conf[] = "# Downloads larger than MAXDOWNLOADSIZE will be blocked.";
- $val = (!empty($pfconf[XML_DOWNLOADMAXSIZE]) && is_numeric($pfconf[XML_DOWNLOADMAXSIZE])) ? $pfconf[XML_DOWNLOADMAXSIZE] : 0;
- $conf[] = "MAXDOWNLOADSIZE $val";
-
+ $conf[] = "MAXDOWNLOADSIZE {$havp_config[F_MAXDOWNLOADSIZE]}";
+ #
$conf[] = "\n# ClamAV Library Scanner (libclamav) ";
- $conf[] = "ENABLECLAMLIB true";
- $conf[] = "# Should we block encrypted archives?";
- $conf[] = "# CLAMBLOCKENCRYPTED false";
- $conf[] = "# Should we block files that go over maximum archive limits?";
- $conf[] = "# CLAMBLOCKMAX false";
- $conf[] = "# Scanning limits inside archives (filesize = MB):";
- $conf[] = "# CLAMMAXFILES 1000";
- $conf[] = "# CLAMMAXFILESIZE 10";
- $conf[] = "# CLAMMAXRECURSION 8";
- $conf[] = "# CLAMMAXRATIO 250";
-
+ $conf[] = "ENABLECLAMLIB " . (HV_USE_CLAMD !== 'true' ? "true" : "false");
+ # use clamd, if configured
+ if (HV_USE_CLAMD === 'true') {
+ $conf[] = "\n# Clamd scanner (Clam daemon)";
+ $conf[] = "ENABLECLAMD true";
+ # clamd socket
+ if (HV_CLAMD_TCPSOCKET === 'true') {
+ $conf[] = "CLAMDSERVER 127.0.0.1";
+ $conf[] = "CLAMDPORT " . HVDEF_CLAM_TCPSOCKET;
+ }
+ else $conf[] = "CLAMDSOCKET " . HVDEF_CLAM_SOCKET;
+ }
$conf[] = "";
return implode("\n", $conf);
}
+# ------------------------------------------------------------------------------
+# Clamd config
+# ------------------------------------------------------------------------------
+function havp_config_clam()
+{
+ global $havp_config;
+ $conf = array();
+ $conf[] =
+"# ==============================================================================
+# CLAMD config file
+# This file generated automaticly with HAVP configurator (part of pfSense)
+# (C)2008 Serg Dvoriancev
+# email: dv_serg@mail.ru
+# ==============================================================================
+";
+ $conf[] = "# log";
+ $conf[] = "LogFile /var/log/clamav/clamd.log";
+ $conf[] = "LogFileUnlock yes";
+ $conf[] = "LogFileMaxSize 1M";
+ $conf[] = "LogTime yes";
+ $conf[] = "LogClean no";
+ $conf[] = "LogSyslog yes"; # todo - настройки Гуя
+ $conf[] = "LogFacility LOG_LOCAL6";
+ $conf[] = "LogVerbose no";
+ #
+ $conf[] = "\n# sysdirs";
+ $conf[] = "PidFile " . HVDEF_CLAM_PID;
+ $conf[] = "TemporaryDirectory " . HVDEF_TEMP_DIR;
+ $conf[] = "DatabaseDirectory /var/db/clamav";
+ #
+ $conf[] = "\n# socket";
+ $conf[] = "LocalSocket " . HVDEF_CLAM_SOCKET;
+ $conf[] = "FixStaleSocket yes";
+ #
+ if (HV_CLAMD_TCPSOCKET === 'true') {
+ $conf[] = "TCPAddr 127.0.0.1";
+ $conf[] = "TCPSocket " . HVDEF_CLAM_TCPSOCKET;
+ }
+ $conf[] = "MaxConnectionQueueLength 30";
+ #
+ $conf[] = "\n# daemon";
+ $conf[] = "MaxThreads 100";
+ #
+ $conf[] = "\n# scanner";
+ $conf[] = "MaxDirectoryRecursion 255";
+ $conf[] = "FollowDirectorySymlinks no"; # not need scan symbol links dirs
+ $conf[] = "FollowFileSymlinks yes";
+ $conf[] = "# perform a database check.(sec) [3600 sec = 60 min]";
+ $conf[] = "SelfCheck 3600";
+ $conf[] = "# detect possibly unwanted applications.";
+ $conf[] = "DetectPUA yes";
+ $conf[] = "AlgorithmicDetection yes";
+ $conf[] = "# executable";
+ $conf[] = "ScanPE yes";
+ $conf[] = "ScanELF yes";
+ $conf[] = "DetectBrokenExecutables yes";
+ $conf[] = "# documents";
+ $conf[] = "ScanOLE2 yes";
+ $conf[] = "ScanPDF yes";
+ $conf[] = "# email";
+ $conf[] = "ScanMail yes";
+ $conf[] = "MailFollowURLs no";
+ $conf[] = "PhishingSignatures yes";
+ $conf[] = "PhishingScanURLs yes";
+ $conf[] = "PhishingAlwaysBlockSSLMismatch no";
+ $conf[] = "PhishingAlwaysBlockCloak no";
+ $conf[] = "# html";
+ $conf[] = "ScanHTML yes";
+ $conf[] = "# archives";
+ $conf[] = "ScanArchive yes";
+ $conf[] = "ArchiveLimitMemoryUsage no";
+ $conf[] = "ArchiveBlockEncrypted no";
+ $conf[] = "# limits";
+ $conf[] = "MaxScanSize 50M";
+ $conf[] = "MaxFileSize 30M";
+ $conf[] = "MaxRecursion 255";
+ $conf[] = "MaxFiles 10000";
+ #
+ $conf[] = "\n# system";
+ $conf[] = "User root"; # . HVDEF_USER; # mast have full access to files for scan
+ $conf[] = "AllowSupplementaryGroups yes";
+ $conf[] = "Debug " . (HV_DEBUG === 'true' ? "yes" : "no");
+ #
+ $conf[] = "";
+ return implode("\n", $conf);
+}
+# ------------------------------------------------------------------------------
+# FreshClamAV config
+# ------------------------------------------------------------------------------
function havp_config_freshclam()
{
- global $config;
- $pfconf = $config['installedpackages']['havp']['config'][0];
+ global $havp_config;
+ $pfconf = $havp_config;
$conf = array();
$conf[] =
-"# ============================================================
+"# ==============================================================================
# freshclam(HAVP) config file
# This file generated automaticly with HAVP configurator (part of pfSense)
# (C)2008 Serg Dvoriancev
# email: dv_serg@mail.ru
-# ============================================================
+# ==============================================================================
";
$conf[] = "DatabaseDirectory /var/db/clamav";
# --
@@ -366,31 +735,38 @@ function havp_config_freshclam()
# --
# $conf[] = "UpdateLogFile /var/log/clamav/freshclam.log";
- if ($pfconf[XML_SYSLOG] === 'on') {
+ # log
+ $conf[] = "UpdateLogFile /var/tmp/freshclam.log";
+ $conf[] = "LogFileMaxSize 10M";
+ $conf[] = "LogTime yes";
+ $conf[] = "LogVerbose yes";
+
+ # Syslog
+ if ($pfconf[F_AVSETSYSLOG] === 'true') {
$conf[] = "\n# syslog";
- $conf[] = "LogSyslog yes";
- $conf[] = "LogFacility LOG_LOCAL6"; # LOG_LOCAL6 | LOG_MAIL
+ $conf[] = "LogSyslog yes";
+ $conf[] = "LogFacility LOG_LOCAL6"; # LOG_LOCAL6 | LOG_MAIL
}
$conf[] = "\n# pid";
$conf[] = "PidFile /var/run/clamav/freshclam.pid";
$conf[] = "\n# db";
- $conf[] = "DatabaseOwner clamav";
+ $conf[] = "DatabaseOwner clamav";
$conf[] = "AllowSupplementaryGroups yes";
- $conf[] = "DNSDatabaseInfo current.cvd.clamav.net";
+ $conf[] = "DNSDatabaseInfo current.cvd.clamav.net";
- $avsrv = $pfconf['avupdateserver'];
+ $avsrv = $pfconf[F_AVUPDATESERVER];
$avsrv = explode(" ", trim($avsrv));
foreach ($avsrv as $asr)
if (!empty($asr))
- $conf[] = "DatabaseMirror $asr";
+ $conf[] = "DatabaseMirror $asr";
# regional mirror
- if (!empty($pfconf['dbregion'])) {
+ if (!empty($pfconf[F_DBREGION])) {
$conf[] = '# regional db';
- switch($pfconf['dbregion']) {
+ switch($pfconf[F_DBREGION]) {
case 'au': $conf[] = "DatabaseMirror clamav.mirror.ayudahosting.com.au"; break; # australia
case 'ca': $conf[] = "DatabaseMirror clamav.mirror.rafal.ca"; break; # canada
case 'cn': $conf[] = "DatabaseMirror 4most2.clamav.ialfa.net"; break; # china
@@ -408,26 +784,58 @@ function havp_config_freshclam()
}
}
-# $conf[] = "DatabaseMirror db.ru.clamav.net";
-# $conf[] = "DatabaseMirror db.us.clamav.net";
+ $conf[] = "DatabaseMirror db.at.clamav.net";
+ $conf[] = "DatabaseMirror db.au.clamav.net";
+ $conf[] = "DatabaseMirror db.ba.clamav.net";
+ $conf[] = "DatabaseMirror db.be.clamav.net";
+ $conf[] = "DatabaseMirror db.ca.clamav.net";
+ $conf[] = "DatabaseMirror db.ch.clamav.net";
+ $conf[] = "DatabaseMirror db.cn.clamav.net";
+ $conf[] = "DatabaseMirror db.cr.clamav.net";
+ $conf[] = "DatabaseMirror db.cy.clamav.net";
+ $conf[] = "DatabaseMirror db.cz.clamav.net";
+ $conf[] = "DatabaseMirror db.de.clamav.net";
+ $conf[] = "DatabaseMirror db.dk.clamav.net";
+ $conf[] = "DatabaseMirror db.ec.clamav.net";
+ $conf[] = "DatabaseMirror db.ee.clamav.net";
+ $conf[] = "DatabaseMirror db.es.clamav.net";
+ $conf[] = "DatabaseMirror db.fi.clamav.net";
+ $conf[] = "DatabaseMirror db.fr.clamav.net";
+ $conf[] = "DatabaseMirror db.gr.clamav.net";
+ $conf[] = "DatabaseMirror db.hk.clamav.net";
+ $conf[] = "DatabaseMirror db.hu.clamav.net";
+ $conf[] = "DatabaseMirror db.id.clamav.net";
+ $conf[] = "DatabaseMirror db.ie.clamav.net";
+ $conf[] = "DatabaseMirror db.it.clamav.net";
+ $conf[] = "DatabaseMirror db.jp.clamav.net";
+ $conf[] = "DatabaseMirror db.kr.clamav.net";
+ $conf[] = "DatabaseMirror db.li.clamav.net";
+ $conf[] = "DatabaseMirror db.lt.clamav.net";
+ $conf[] = "DatabaseMirror db.lv.clamav.net";
+ $conf[] = "DatabaseMirror db.mt.clamav.net";
+ $conf[] = "DatabaseMirror db.my.clamav.net";
+ $conf[] = "DatabaseMirror db.ml.clamav.net";
+ $conf[] = "DatabaseMirror db.no.clamav.net";
+ $conf[] = "DatabaseMirror db.pl.clamav.net";
+ $conf[] = "DatabaseMirror db.pt.clamav.net";
+ $conf[] = "DatabaseMirror db.ro.clamav.net";
+ $conf[] = "DatabaseMirror db.ru.clamav.net";
+ $conf[] = "DatabaseMirror db.se.clamav.net";
+ $conf[] = "DatabaseMirror db.sk.clamav.net";
+ $conf[] = "DatabaseMirror db.th.clamav.net";
+ $conf[] = "DatabaseMirror db.tr.clamav.net";
+ $conf[] = "DatabaseMirror db.tw.clamav.net";
+ $conf[] = "DatabaseMirror db.ua.clamav.net";
+ $conf[] = "DatabaseMirror db.uk.clamav.net";
+ $conf[] = "DatabaseMirror db.za.clamav.net";
$conf[] = "\n# DO NOT TOUCH the following line ";
$conf[] = "DatabaseMirror database.clamav.net";
$conf[] = "\n# Number of database checks per day. Default: 12 (every two hours)";
$chks = 0;
- switch($pfconf['havpavupdate']) {
- case 'none': $chks = 0; break;
- case 'hv_01h': $chks = 24; break;
- case 'hv_02h': $chks = 12; break;
- case 'hv_03h': $chks = 8; break;
- case 'hv_04h': $chks = 6; break;
- case 'hv_06h': $chks = 4; break;
- case 'hv_08h': $chks = 3; break;
- case 'hv_12h': $chks = 2; break;
- case 'hv_24h': $chks = 1; break;
- }
$conf[] = "Checks $chks";
+ $conf[] = "Debug " . (HV_DEBUG === 'true' ? "yes" : "no");
# $conf[] = "# Proxy settings"; # future
#HTTPProxyServer myproxy.com
@@ -447,13 +855,46 @@ function havp_config_freshclam()
# Enable debug messages in libclamav.
# Default: disabled
-#Debug
+#Debug yes
$conf[] = "";
return implode("\n", $conf);
}
+# ------------------------------------------------------------------------------
+# configure squid
+function havp_configure_squid()
+{
+ global $config, $havp_config;
+ $new_opt = array();
+ $on_configure = ($havp_config[F_PROXYMODE] === 'squid' ? true : false);
+
+ if (!isset($config['installedpackages']['squid']['config'][0]['custom_options'])) return;
+
+ if ($on_configure === true)
+ $new_opt[] = "cache_peer 127.0.0.1 parent {$havp_config[F_PROXYPORT]} 0 name=havp proxy-only no-query no-digest no-netdb-exchange default";
-function havp_whitelist_def() {
+ # copy options, but not 'cache_peer' option
+ $cust_opt = explode(";", $config['installedpackages']['squid']['config'][0]['custom_options']);
+ foreach($cust_opt as $key => $val)
+ if (strpos($val, "cache_peer 127.0.0.1 parent") === false) $new_opt[] = $val;
+
+ $new_opt = implode(";", $new_opt);
+ if (/*is_package_installed('squid') && */file_exists('/usr/local/pkg/squid.inc')) {
+ # squid config update
+ $config['installedpackages']['squid']['config'][0]['custom_options'] = $new_opt;
+
+ # disable upstream proxy
+ if ($on_configure === true)
+ $config['installedpackages']['squidupstream']['config'][0]['proxy_forwarding'] = '';
+
+ write_config('Update redirector options to squid config.');
+ require_once('squid.inc');
+ squid_resync();
+ }
+}
+# ------------------------------------------------------------------------------
+function havp_whitelist_def()
+{
$whitelist = array();
$whitelist[] = "*sourceforge.net/*clamav-*";
@@ -465,45 +906,25 @@ function havp_whitelist_def() {
return implode("\n", $whitelist);
}
-
-# RAM disk
-# Mem - RAM
-# 128M - 16M
-# 256M - 32M
-# 512M - 64M
-# 1G - 128M
-#
-function mountRAMdisk()
+# ==============================================================================
+# Utils
+# ==============================================================================
+function havp_set_file_access($dir, $owner, $mod)
{
-# disabled for VMware
-# return;
-
- # detach and free all resources used by /dev/md10:
- mwexec("umount /var/tmp/havp");
- mwexec("mdconfig -d -u 10");
-
- # create and mount a 8MByte swap backed file system on /var/tmp/havp by /dev/md10:
- mwexec("mdconfig -a -t swap -s 1M -u 10");
- mwexec("newfs -U /dev/md10");
- mwexec("mount /dev/md10 /var/tmp/havp");
- mwexec("chmod 1777 /var/tmp/havp");
-}
-
-# ------------------------------------------------------------------------------
-function set_file_access($dir, $owner, $mod) {
mwexec("chgrp -R -v $owner $dir");
mwexec("chown -R -v $owner $dir");
if (!empty($mod)) {
mwexec( "chmod -R -v $mod $dir");
}
}
-
-# Src from squid.inc
-# Copyright (C) 2006 Scott Ullrich
-# Copyright (C) 2006 Fernando Lemos
-function get_real_interface_address($iface) {
+# ------------------------------------------------------------------------------
+# Src from squid.inc Copyright (C) 2006 Scott Ullrich, Fernando Lemos
+function get_real_interface_address($iface)
+{
global $config;
+ if ($iface === 'localhost') return array('127.0.0.1', '');
+
$iface = convert_friendly_interface_to_real_interface_name($iface);
$line = trim(shell_exec("ifconfig $iface | grep inet | grep -v inet6"));
list($dummy, $ip, $dummy2, $netmask) = explode(" ", $line);
@@ -511,16 +932,6 @@ function get_real_interface_address($iface) {
return array($ip, long2ip(hexdec($netmask)));
}
#-------------------------------------------------------------------------------
-
-function havp_update_AV() {
- # AV update script
- if (file_exists(HV_AVUPD_SCRIPT)) {
- file_put_contents(HV_AVUPD_SCRIPT, havp_AVupdate_script());
- set_file_access(HV_AVUPD_SCRIPT, HV_AV_USER, '0755');
- }
- mwexec(HV_AVUPD_SCRIPT);
-}
-
# *** check black/white list domain ***
# Lines can hold URLs with wildcards with following rules:
# Line must cointain Domain/Path
@@ -534,8 +945,9 @@ function havp_update_AV() {
# (4) */*.gif (All .gif are whitelisted)
# (5) www.server-side.de/novirus*
# (6) www.server-side.de/*novirus*
-
-function check_bw_domain($_dm) {
+#-------------------------------------------------------------------------------
+function check_bw_domain($_dm)
+{
$domain = "";
$path = "";
$pos = strpos($_dm, "/");
@@ -550,56 +962,20 @@ function check_bw_domain($_dm) {
}
$fmt = "[a-zA-Z0-9_-]";
-
# Domains can have a wildcard at begin '*xxx.xxx' - *my.domain.com
if (!eregi("^(\*)|((\*){0,1}($fmt\.){0,}$fmt{1,})$", $domain)) return false;
-
# Path can have a wildcard at begin and end '*xxx*'
if ($path && !eregi("^(\*){0,1}(.[^\*][^=]){0,}(\*){0,1}$", $path)) return false;
-
return true;
}
-
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-function havp_AVupdate_script() {
-
-# *** AV update script ***
-
-$scr = <<<EOD
-#!/bin/sh
-# AV update script
-# This file was automatically generated
-# by the pfSense service handler.
-/usr/local/bin/freshclam
-wait
-/usr/local/bin/sigtool --unpack-current daily.cvd
-/usr/local/bin/sigtool --unpack-current main.cvd
-wait
-EOD;
-
-# --- AV update script ---
-
- return $scr;
-}
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-# === UNDER CONSTRUCTION ===
-
-# $day: 1, 2, .., 31, *, mon, tue, wed, thu, fri, sat, sun ; every day : [$day]
-# $mon: 1, 2, .., 12, * ; every mon: [$mon] [15]-[01]-[2001]
-# $time = 'hh:mm': '12:00' - at 12:00; '*:*' - at any time; '/hh:/mm' - every hh every /mm
-# havp_crontask('my_task', '15', '/1', '15:30', 'root' 'start_cmd', true);
-function havp_crontask($task_name, $day, $mon, $time, $who, $cmd, $enabled)
-{
-
-}
-
-# / === UNDER CONSTRUCTION ===
-
+# ------------------------------------------------------------------------------
+# cron
+# ------------------------------------------------------------------------------
# $options: [0]='minute', [1]='hour', [2]='mday', [3]='month', [4]='wday', [5]='who', [6]='command'
#
-function havp_setup_cron($task_name, $options, $on_off) {
+function havp_setup_cron($task_name, $options, $on_off)
+{
global $config;
$cron_item = array();
@@ -617,16 +993,13 @@ function havp_setup_cron($task_name, $options, $on_off) {
}
# unset old cron task with $task_name
- if ($task_name !== "") {
+ if (!empty($task_name)) {
$flag_cron_upd = false;
-
# delete old cron task if exists
foreach($config['cron']['item'] as $key => $val) {
if ($config['cron']['item'][$key]['task_name'] === $task_name) {
unset($config['cron']['item'][$key]);
$flag_cron_upd = true;
-
- # log ! cron task deleted !
break;
}
}
@@ -635,22 +1008,409 @@ function havp_setup_cron($task_name, $options, $on_off) {
if (($on_off === true) and !empty($cron_item)) {
$config['cron']['item'][] = $cron_item;
$flag_cron_upd = true;
-
- # log ! cron task installed !
}
# write config and configure cron only if cron task modified
if ($flag_cron_upd === true) {
write_config("Installed cron task '$task_name' for 'havp' package");
configure_cron();
- # log ! cron stored !
}
}
else {
# ! error $name !
-
- # if error - break function
return;
}
}
+# ------------------------------------------------------------------------------
+# filter rules
+# ------------------------------------------------------------------------------
+function havp_generate_rules($type = 'filter')
+{
+ # 'nat' 'filter'
+ global $config, $havp_config;
+ $rules = array();
+
+ # nothing if havp not running
+ if (!is_service_running('havp')) {
+ if (HV_DEBUG === 'true')
+ log_error("havp: Havp is installed but not started. Filter rules not created.");
+ return;
+ }
+
+ $proxymode = $havp_config[F_PROXYMODE];
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ # HAVP always listen 127.0.0.1:port
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ # Proxy mode:
+ # Standard - Filter: Rdr ifaces:port => 127.0.0.1:port
+ # Parent for Squid - Filter: No
+ # Transparent - Filter: Rdr ifaces:port => 127.0.0.1:port;
+ # Rdr Any Http => 127.0.0.1:port + Allow Http traffic via iface
+ # If Squid transparent, then as Standard.
+ # Internal - Filter: No
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ $proxybindiface = 'lo0'; # 127.0.0.1
+ $ifaces = array_map('convert_friendly_interface_to_real_interface_name', explode(',', $havp_config[F_PROXYINTERFACE]));
+ $proxyport = ( $havp_config[F_PROXYPORT] ? $havp_config[F_PROXYPORT] : HVDEF_PROXYPORT );
+
+ # squid already transparent
+ $squid_transparent_proxy = ($config['installedpackages']['squid']['config'][0]['transparent_proxy'] == 'on');
+ if (($proxymode === 'transparent') && $squid_transparent_proxy) {
+ $proxymode = 'standard';
+ log_error("Havp: Squid is already configured as transparent proxy. Use 'Standard' proxy mode.");
+ }
+
+ # nat
+ if ($type === 'nat') {
+ $rules[] = "# havp proxy ifaces redirect";
+ foreach($ifaces as $iface) {
+ switch($proxymode) {
+ case 'transparent':
+ # rdr any http => localhost:port
+ $rules[] = "rdr on $iface proto tcp from any to !($iface) port 80 -> $proxybindiface port $proxyport";
+ case 'standard':
+ case 'squid':
+ # rdr iface:port => localhost:port
+ $rules[] = "rdr on $iface proto tcp from any to ($iface) port $proxyport -> $proxybindiface port $proxyport";
+ break;
+ # no more rdr
+ case 'internal':
+ default: break;
+ }
+ }
+ }
+ # filter
+ else {
+ $rules[] = "# havp proxy ifaces rules";
+ foreach($ifaces as $iface) {
+ switch($proxymode) {
+ case 'transparent':
+ # pass http on iface
+ $rules[] = "pass in quick on $iface proto tcp from any to !($iface) port 80 flags S/SA keep state";
+ break;
+ # no more rules
+ case 'standard':
+ case 'squid':
+ case 'internal':
+ default: break;
+ }
+ }
+ }
+
+ return implode("\n", $rules);
+}
+# ------------------------------------------------------------------------------
+function havp_filter_update_3()
+{
+ $rules_file = '/tmp/rules.debug';
+ if (file_exists($rules_file)) {
+ $newrules = array();
+ $rules = file_get_contents($rules_file);
+ $rules = explode("\n", $rules);
+
+ foreach($rules as $val) {
+ $newrules[] = $val;
+ # rdr
+ if (trim($val) === "rdr-anchor \"miniupnpd\"") {
+ $newrules[] = "# havp rdr";
+ $newrules[] = havp_generate_rules('nat');
+ $newrules[] = "";
+ }
+ # rules
+ elseif(trim($val) === "anchor \"miniupnpd\"") {
+ $newrules[] = "# havp rules";
+ $newrules[] = havp_generate_rules('filter');
+ $newrules[] = "";
+ }
+ $rules = implode("\n", $newrules);
+ }
+ file_put_contents($rules_file, $rules);
+ mwexec("pfctl -f $rules_file");
+ }
+}
+# ------------------------------------------------------------------------------
+function havp_update_AV()
+{
+ # AV update script
+ if (file_exists(HVDEF_AVUPD_SCRIPT)) {
+ file_put_contents(HVDEF_AVUPD_SCRIPT, havp_AVupdate_script());
+ havp_set_file_access(HVDEF_AVUPD_SCRIPT, HVDEF_AVUSER, '0755');
+ }
+ mwexec(HVDEF_AVUPD_SCRIPT);
+}
+# ==============================================================================
+# Scripts
+# ==============================================================================
+# AV update script
+function havp_AVupdate_script()
+{
+
+return <<<EOD
+#!/bin/sh
+# AV update script
+# This file was automatically generated
+# by the pfSense service handler.
+/usr/local/bin/freshclam
+wait
+/usr/local/bin/sigtool --unpack-current daily.cvd
+/usr/local/bin/sigtool --unpack-current main.cvd
+wait
+EOD;
+
+}
+# ------------------------------------------------------------------------------
+# HAVP service startup script
+function havp_startup_script()
+{
+ global $havp_config;
+ $pid = HVDEF_PID_FILE;
+
+ # rc script
+ $rc = array();
+ $rc['file'] = basename(HVDEF_HAVP_STARTUP_SCRIPT);
+
+ $s[] = "# start";
+ $s[] = "\tif [ -z \"`ps auxw | grep \"[h]avp -c\"|awk '{print $2}'`\" ];then";
+ if (HV_USE_CLAMD === 'true') {
+ $s[] = "\t\t# start clamd before (to be sure)";
+ $s[] = "\t\t/usr/local/etc/rc.d/clamd.sh start";
+ $s[] = "\t\twait";
+ }
+ $s[] = "\t\t/usr/local/sbin/havp -c " . HVDEF_HAVP_CONFIG . " 2>/dev/null";
+ $s[] = "\t\tsleep 2";
+ $s[] = "\tfi";
+ $s[] = "";
+ $rc['start'] = implode("\n", $s);
+ unset($s);
+
+ $s[] = "# stop";
+ $s[] = "\t killall -9 havp 2>/dev/null";
+ $s[] = "\t killall -9 havp 2>/dev/null";
+ $s[] = "\t sleep 2";
+ $s[] = "";
+ $rc['stop'] = implode("\n", $s);
+ unset($s);
+
+ write_rcfile($rc);
+}
+# ------------------------------------------------------------------------------
+# clamd service startup script
+function hv_clamd_startup_script()
+{
+ global $havp_config;
+ $pid = HVDEF_CLAM_PID;
+
+ # rc script
+ $rc = array();
+ $rc['file'] = basename(HVDEF_CLAM_STARTUP_SCRIPT);
+
+ $s[] = "# start";
+ $s[] = "\tif [ -z \"`ps auxw | grep \"[c]lamd -c\"|awk '{print $2}'`\" ];then";
+ $s[] = "\t\t/usr/local/sbin/clamd -c " . HVDEF_CLAM_CONFIG . " 2>/dev/null";
+ $s[] = "\t\twait";
+ $s[] = "\tfi";
+ $s[] = "";
+ $rc['start'] = implode("\n", $s);
+ unset($s);
+
+ $s[] = "#stop";
+ $s[] = "\t killall -9 clamd 2>/dev/null";
+ $s[] = "\t killall -9 clamd 2>/dev/null";
+ $s[] = "\t wait";
+ $s[] = "";
+ $rc['stop'] = implode("\n", $s);
+ unset($s);
+
+ write_rcfile($rc);
+}
+# ------------------------------------------------------------------------------
+# HAVP filter resync script
+function havp_filter_resync_script()
+{
+
+return <<<EOD
+#!/usr/local/bin/php -f
+<?php
+# havp filter hook
+if (/*is_package_installed('havp') &&*/ file_exists('/usr/local/pkg/havp.inc')) {
+ require_once('havp.inc');
+ havp_filter_update_3();
+}
+?>
+EOD;
+
+}
+
+# ==============================================================================
+# RAM Disk
+# ==============================================================================
+function mountRAMdisk($free_and_mount = true)
+{
+ global $havp_config;
+ $mnt_point = HVDEF_RAMTEMP_DIR;
+ $mnt_flag_file = "$mnt_point/.mnt";
+
+ # RAM Disk disabled
+ if (HV_USE_TMPRAMDISK !== 'true') {
+ umountRAMDisk();
+ return;
+ }
+
+ # RAM Disk on VM disabled
+ if ((HV_VM_TMPRAMDISK !== 'true') && VMWare_detect()) {
+ umountRAMDisk();
+ log_error("havp: RAMDisk on VM disabled.");
+ return;
+ }
+
+ # free RAMDisk only
+ if ($free_and_mount !== true) {
+ umountRAMDisk();
+ return;
+ }
+
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ # Temp RAMDisk
+ # note: use 1/4 of system memory capacity
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ $ramdisk_capacity = get_memory();
+ $ramdisk_capacity = intval($ramdisk_capacity[0]) / 4; # [Mb]
+
+ # check RAMDisk for exists and capacity
+ if (file_exists($mnt_flag_file)) {
+ $old_ramdisk_size = trim(file_get_contents($mnt_flag_file));
+ # RAMDisk exists - not need create new
+ if (intval($ramdisk_size) === intval($old_ramdisk_size)) return;
+ }
+
+ # umount old RAMDisk
+ umountRAMDisk();
+
+ # create and mount a swap backed file system on /var/tmp/havp by /dev/md10:
+ mwexec("mdconfig -a -t swap -s {$ramdisk_capacity}M -u 10");
+ mwexec("newfs -U /dev/md10");
+ mwexec("mount /dev/md10 $mnt_point");
+ mwexec("chmod 1777 $mnt_point");
+
+ # create flag file
+ file_put_contents($mnt_flag_file, "$ramdisk_capacity");
+ # syslog
+ if (HV_DEBUG === 'true')
+ log_error("havp: Create RAMDisk {$ramdisk_capacity}Mb.");
+}
+# ------------------------------------------------------------------------------
+function umountRAMDisk()
+{
+ global $havp_config;
+
+ # detach and free all resources used by /dev/md10:
+ mwexec("umount -f " . HVDEF_RAMTEMP_DIR);
+ mwexec("mdconfig -d -u 10");
+}
+
+# ==============================================================================
+# Utilites
+# ==============================================================================
+function VMWare_detect()
+{
+ global $g;
+ $fc = '';
+
+ if (file_exists("{$g['varlog_path']}/dmesg.boot") !== false)
+ $fc = file_get_contents("{$g['varlog_path']}/dmesg.boot");
+
+ return (strpos($fc, "<VMware Virtual") !== false);
+}
+# ------------------------------------------------------------------------------
+function start_antivirus_scanner($filename)
+{
+ $param = array();
+# $param[] = "-v"; # verbose
+ if (HV_DEBUG === 'true')
+ $param[] = "--debug"; # debug option
+ else $param[] = "--quiet"; # output only errors
+ $param[] = "--stdout"; # Write to stdout instead of stderr
+# $param[] = "--no-summary"; # Disable summary at end of scanning
+ $param[] = "-i"; # Only print infected files
+ $param[] = "--tempdir=" . HVDEF_TEMP_DIR; # Create temporary files in DIRECTORY
+# $param[] = "-d FILE/DIR"; # Load virus database from FILE or load all .cvd and .db[2] files from DIR
+ $param[] = "-l /var/log/clamscan.log"; # Save scan report to FILE
+ $param[] = "-r"; # Scan subdirectories recursively
+ $param[] = "--remove"; # Remove infected files. Be careful!
+# $param[] = "--move=DIRECTORY"; # Move infected files into DIRECTORY
+# $param[] = "--exclude=PATT"; # Don't scan file names containing PATT
+# $param[] = "--exclude-dir=PATT"; # Don't scan directories containing PATT
+# $param[] = "--include=PATT"; # Only scan file names containing PATT
+# $param[] = "--include-dir=PATT"; # Only scan directories containing PATT
+ $param[] = "--detect-pua"; # Detect Possibly Unwanted Applications
+ $param[] = "--detect-broken"; # Try to detect broken executable files
+ $param[] = "--max-filesize=10000000"; # Files larger than this will be skipped and assumed clean
+ $param[] = "--max-scansize=5000000"; # The maximum amount of data to scan for each container file (*)
+ $param[] = "--max-files=10000"; # The maximum number of files to scan for each container file (*)
+ $param[] = "--max-recursion=255"; # Maximum archive recursion level for container file (*)
+ $param[] = "--max-dir-recursion=255"; # Maximum directory recursion level
+# $param[] = "--unzip[=FULLPATH]"; # Enable support for .zip files
+# $param[] = "--unrar[=FULLPATH]"; # Enable support for .rar files
+# $param[] = "--arj[=FULLPATH]"; # Enable support for .arj files
+# $param[] = "--unzoo[=FULLPATH]"; # Enable support for .zoo files
+# $param[] = "--lha[=FULLPATH]"; # Enable support for .lha files
+# $param[] = "--jar[=FULLPATH]"; # Enable support for .jar files
+# $param[] = "--tar[=FULLPATH]"; # Enable support for .tar files
+# $param[] = "--deb[=FULLPATH to ar]"; # Enable support for .deb files
+# $param[] = "--tgz[=FULLPATH]"; # Enable support for .tar.gz, .tgz files
+
+ $param = implode(" ", $param);
+ if (HV_USE_CLAMD === 'true')
+ $param = "clamdscan $param $filename"; # use clamd daemon (more quickly)
+ else $param = "clamscan $param $filename";
+
+ # debug clamscan cmd
+ if (HV_DEBUG === 'true') file_put_contents("/tmp/clamscan.cmd", $param);
+
+ if (file_exists($filename)) {
+ log_error("Antivirus: Starting file '$filename' scanner. Log file is '/var/log/clamscan.log'. Wait 5-10 minutes.");
+
+ # put to log scanning file
+ $cont="Starting scan file {$filename}\n";
+ file_put_contents("/var/log/clamscan.log", $cont);
+
+ mwexec_bg("$param");
+ }
+ else log_error("Antivirus: Can't starting file scanner. File '$filename' not exists.");
+}
+
+# ------------------------------------------------------------------------------
+# HTML
+# ------------------------------------------------------------------------------
+function havp_fscan_html()
+{
+ global $g;
+
+ return <<<EOD
+<hr>
+<span onClick="document.getElementById('scanfilepath').value = '/var/squid';" style="cursor: pointer;">
+ <img src='./themes/{$g['theme']}/images/icons/icon_pass.gif' title='Click here'>
+ <font size='-1'><u>&nbsp;Squid cache path (scan you squid cache now).</u></font>
+ </img>
+</span>
+<br>
+<span onClick="document.getElementById('scanfilepath').value = '/var/db';" style="cursor: pointer;">
+ <img src='./themes/{$g['theme']}/images/icons/icon_pass.gif' title='Click here'>
+ <font size='-1'><u>&nbsp;Common DB path.</u></font>
+ </img>
+</span>
+<br>
+<span onClick="document.getElementById('scanfilepath').value = '/tmp';" style="cursor: pointer;">
+ <img src='./themes/{$g['theme']}/images/icons/icon_pass.gif' title='Click here'>
+ <font size='-1'><u>&nbsp;Temp path.</u></font>
+ </img>
+</span>
+<hr>
+<input name='submit' type='submit' value='Start_scan'><br>
+Press button for start antivirus scanner now. After 5-10 minutes look log file '/var/log/clamscan.log'
+(Diagnostics: Execute Shell command: <b>'cat /var/log/clamscan.log'</b>)
+EOD;
+}
+
?>
diff --git a/config/havp/havp.xml b/config/havp/havp.xml
index a70b09bc..f2e07c91 100644
--- a/config/havp/havp.xml
+++ b/config/havp/havp.xml
@@ -1,30 +1,58 @@
<?xml version="1.0" encoding="utf-8" ?>
<packagegui>
<name>havp</name>
- <title>Services: Antivirus proxy server (havp + clamav) -> Settings</title>
+ <title>Antivirus: HTTP proxy (havp + clamav)</title>
<category>Status</category>
- <version>1.7.1</version>
- <include_file>havp.inc</include_file>
+ <version>0.88_03</version>
+ <include_file>/usr/local/pkg/havp.inc</include_file>
<!-- Installation -->
<menu>
- <name>HTTP Antivirus</name>
- <tooltiptext>Proxy server antivirus</tooltiptext>
+ <name>Antivirus</name>
+ <tooltiptext>Antivirus service</tooltiptext>
<section>Services</section>
<url>/pkg_edit.php?xml=havp.xml&amp;id=0</url>
</menu>
+ <service>
+ <name>havp</name>
+ <rcfile>havp.sh</rcfile>
+ <executable>havp</executable>
+ <description>Antivirus HTTP proxy Service</description>
+ </service>
+
<additional_files_needed>
<item>http://www.pfsense.com/packages/config/havp/havp.inc</item>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>0755</chmod>
+ </additional_files_needed>
+ <additional_files_needed>
+ <item>http://www.pfsense.com/packages/config/havp/havp_fscan.xml</item>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>0755</chmod>
+ </additional_files_needed>
+ <additional_files_needed>
+ <item>http://www.pfsense.com/packages/config/havp/havp_avset.xml</item>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>0755</chmod>
</additional_files_needed>
<tabs>
<tab>
- <text>Settings</text>
+ <text>HTTP proxy</text>
<url>/pkg_edit.php?xml=havp.xml&amp;id=0</url>
<active/>
</tab>
+ <tab>
+ <text>Files Scanner</text>
+ <url>/pkg_edit.php?xml=havp_fscan.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Settings</text>
+ <url>/pkg_edit.php?xml=havp_avset.xml&amp;id=0</url>
+ </tab>
</tabs>
+
<fields>
<field>
<fielddescr>Enable</fielddescr>
@@ -33,39 +61,73 @@
<type>checkbox</type>
</field>
<field>
- <fielddescr>Use external interface</fielddescr>
- <fieldname>listenextinterface</fieldname>
- <description>Select this for use external interface, otherwise the proxy will use the internal interface '127.0.0.1'. Cascade you other proxy to the HAVP as 'parent proxy' via '127.0.0.1' ip.</description>
- <type>checkbox</type>
- <enablefields>proxyiface</enablefields>
+ <fielddescr>Proxy mode</fielddescr>
+ <fieldname>proxymode</fieldname>
+ <description>
+ Select interface mode: &lt;br&gt;
+ &lt;b&gt; standard &lt;/b&gt; - client(s) bind to the 'proxy port' on selected interface(s); &lt;br&gt;
+ &lt;b&gt; parent for squid &lt;/b&gt; - configure HAVP as parent for Squid proxy;&lt;br&gt;
+ &lt;b&gt; transparent &lt;/b&gt; - all 'http' requests on interface(s) will be translated to the HAVP proxy server without any client(s) additional configuration necessary (worked as 'parent for squid' with 'transparent' Squid proxy); &lt;br&gt;
+ &lt;b&gt; internal &lt;/b&gt; - HAVP listen internal interface (127.0.0.1) on 'proxy port', use you own traffic forwarding rules.&lt;br&gt;
+ </description>
+ <type>select</type>
+ <default_value>standard</default_value>
+ <options>
+ <option><value>standard</value><name>Standard</name></option>
+ <option><value>squid</value><name>Parent for Squid</name></option>
+ <option><value>transparent</value><name>Transparent</name></option>
+ <option><value>internal</value><name>Internal</name></option>
+ </options>
</field>
+
<field>
- <fielddescr>Proxy interface</fielddescr>
- <fieldname>proxyiface</fieldname>
- <description>The interface(s) the proxy server will bind to.</description>
+ <fielddescr>Proxy interface(s)</fielddescr>
+ <fieldname>proxyinterface</fieldname>
+ <description>The interface(s) for client connections to the proxy. Use 'Ctrl' + L.Click for multiple selection.</description>
<type>interfaces_selection</type>
<required/>
- <default_value>lan</default_value>
+ <multiple/>
+ <value>lan</value>
</field>
<field>
<fielddescr>Proxy port</fielddescr>
<fieldname>proxyport</fieldname>
- <description>This is the port the proxy server will listen on.</description>
+ <description>
+ This is the port the proxy server will listen on (for example: 8080). This port must be different from Squid proxy.
+ </description>
<type>input</type>
<size>10</size>
<required/>
- <default_value>3128</default_value>
+ <value>3125</value>
</field>
<field>
<fielddescr>Parent proxy</fielddescr>
<fieldname>parentproxy</fieldname>
<description>
- Enter the parent proxy as PROXY:PORT format or leave empty.
+ Enter the parent (upstream) proxy settings as PROXY:PORT format or leave empty.
</description>
<type>input</type>
<size>90</size>
</field>
<field>
+ <fielddescr>Enable X-Forwarded-For</fielddescr>
+ <fieldname>enablexforwardedfor</fieldname>
+ <description>
+ If client sent this header, FORWARDED_IP setting defines the value, then it is passed on. You might want to keep this disabled for security reasons.
+ &lt;br&gt;Enable this if you use your own parent proxy after HAVP, so it will see the original client IP.
+ &lt;br&gt;Disabling this also disables Via: header generation.
+ </description>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <fielddescr>Enable Forwarded IP</fielddescr>
+ <fieldname>enableforwardedip</fieldname>
+ <description>
+ If HAVP is used as parent proxy by some other proxy, this allows to write the real users IP to log, instead of proxy IP.
+ </description>
+ <type>checkbox</type>
+ </field>
+ <field>
<fielddescr>Language</fielddescr>
<fieldname>lang</fieldname>
<description>Select the language in which the proxy server will display error messages to users.</description>
@@ -84,17 +146,21 @@
</options>
</field>
<field>
- <fielddescr>Max download size</fielddescr>
+ <fielddescr>Max download size, Bytes</fielddescr>
<fieldname>maxdownloadsize</fieldname>
- <description>Enter value or leave empty. Value in bytes. Downloads larger than 'Max download size' will be blocked. Only if not Whitelisted!</description>
+ <description>Enter value (in Bytes) or leave empty. Downloads larger, than 'Max download size' will be blocked. Only if not Whitelisted!</description>
<type>input</type>
<size>10</size>
<default_value></default_value>
</field>
<field>
- <fielddescr>Disable X-Forward</fielddescr>
- <fieldname>xforwardedfor</fieldname>
- <description>If not set, proxy will include your system's IP address or name in the HTTP requests it forwards.</description>
+ <fielddescr>HTTP Range requests</fielddescr>
+ <fieldname>range</fieldname>
+ <description>
+ Set this for allow HTTP Range requests, and broken downloads can be resumed.
+ Allowing HTTP Range is a security risk, because partial HTTP requests may not be properly scanned.
+ Whitelisted sites are allowed to use Range in any case.
+ </description>
<type>checkbox</type>
</field>
@@ -129,101 +195,70 @@
</field>
<field>
+ <fielddescr>Enable RAM Disk</fielddescr>
+ <fieldname>enableramdisk</fieldname>
+ <description>
+ This option allow use RAM Disk for HAVP temp files for more quick traffic scan.
+ Ram Disc size depend from 'ScanMax file size and avialable memory.
+ This option can be ignored in VMVare or on 'low system memory'.
+ ( RAM Disk size calculated as [1/4 avialable system memory] > [Scan max file size] * 100 )
+ </description>
+ <type>checkbox</type>
+ </field>
+ <field>
<fielddescr>Scan max file size</fielddescr>
<fieldname>scanmaxsize</fieldname>
<description>
- Enter here value in bytes (5, 10, 15, 20) or leave empty.
+ Select this value for limit maximum file size or leave '---(5M)'.
Files larger than this limit won't be scanned.
- Empty or 0 also disables the limit.
+ Small values increace scan speed and maximum new connections per second and allow RAM Disk use.
+ &lt;br&gt;
NOTE: Setting limit is a security risk, because some archives like
ZIP need all the data to be scanned properly! Use this only if you
- can't afford temporary space for big files. Also scanner settings
- will affect how many files will be scanned inside an archive etc.
+ can't afford temporary space for big files.
</description>
- <type>input</type>
- <size>10</size>
+ <type>select</type>
+ <value>0</value>
+ <options>
+ <option><value> 5000</value><name>--- (5M)</name></option>
+ <option><value> 1</value><name> 1 K</name></option>
+ <option><value> 2</value><name> 2 K</name></option>
+ <option><value> 3</value><name> 3 K</name></option>
+ <option><value> 5</value><name> 5 K</name></option>
+ <option><value> 7</value><name> 7 K</name></option>
+ <option><value> 10</value><name> 10 K</name></option>
+ <option><value> 20</value><name> 20 K</name></option>
+ <option><value> 30</value><name> 30 K</name></option>
+ <option><value> 50</value><name> 50 K</name></option>
+ <option><value> 70</value><name> 70 K</name></option>
+ <option><value> 100</value><name> 100 K</name></option>
+ <option><value> 200</value><name> 200 K</name></option>
+ <option><value> 300</value><name> 300 K</name></option>
+ <option><value> 500</value><name> 500 K</name></option>
+ <option><value> 700</value><name> 700 K</name></option>
+ <option><value> 1000</value><name> 1000 K</name></option>
+ <option><value> 1500</value><name> 1500 K</name></option>
+ <option><value> 2000</value><name> 2000 K</name></option>
+ <option><value> 2500</value><name> 2500 K</name></option>
+ <option><value> 3000</value><name> 3000 K</name></option>
+ <option><value> 3500</value><name> 3500 K</name></option>
+ <option><value> 4000</value><name> 4000 K</name></option>
+ <option><value> 4500</value><name> 4500 K</name></option>
+ <option><value> 5000</value><name> 5000 K</name></option>
+ <option><value> 5500</value><name> 5500 K</name></option>
+ <option><value> 6000</value><name> 6000 K</name></option>
+ <option><value> 7000</value><name> 7000 K</name></option>
+ <option><value> 8000</value><name> 8000 K</name></option>
+ <option><value> 9000</value><name> 9000 K</name></option>
+ <option><value>10000</value><name>10 000 K</name></option>
+ </options>
</field>
-
<field>
<fielddescr>Scan images</fielddescr>
<fieldname>scanimg</fieldname>
<description>Check this for scan image files.</description>
<type>checkbox</type>
</field>
-
- <field>
- <fielddescr>Scan archives</fielddescr>
- <fieldname>scanarc</fieldname>
- <description>Check this for scan within archives and compressed files.</description>
- <type>checkbox</type>
- </field>
-
- <field>
- <fielddescr>Scan archive max file size</fielddescr>
- <fieldname>scanarcmaxsize</fieldname>
- <value>10M</value>
- <description>
- Enter here value in megabytes (15M) or leave empty.
- Files in archives larger than this limit won't be scanned.
- Value of 0 also disables the limit.
- </description>
- <type>input</type>
- <size>10</size>
- </field>
-
- <field>
- <fielddescr>AV bases update</fielddescr>
- <fieldname>havpavupdate</fieldname>
- <description>
- &lt;input name='submit' type='submit' value='Update_AV'&gt;
- Press button for update AV database now.
- </description>
- <type>select</type>
- <value>hv_none</value>
- <options>
- <option><name>none</name><value>hv_none</value></option>
- <option><name>every 1 hours</name><value>hv_01h</value></option>
- <option><name>every 2 hours</name><value>hv_02h</value></option>
- <option><name>every 3 hours</name><value>hv_03h</value></option>
- <option><name>every 4 hours</name><value>hv_04h</value></option>
- <option><name>every 6 hours</name><value>hv_06h</value></option>
- <option><name>every 8 hours</name><value>hv_08h</value></option>
- <option><name>every 12 hours</name><value>hv_12h</value></option>
- <option><name>every 24 hours</name><value>hv_24h</value></option>
- </options>
- </field>
- <field>
- <fielddescr>Regional AV database update mirror</fielddescr>
- <fieldname>dbregion</fieldname>
- <description>Select regional database mirror.</description>
- <type>select</type>
- <value></value>
- <options>
- <option><value></value><name>-----</name></option>
- <option><value>au</value><name>Australia</name></option>
- <option><value>eu</value><name>Europe</name></option>
- <option><value>ca</value><name>Canada</name></option>
- <option><value>cn</value><name>China</name></option>
- <option><value>id</value><name>Indonesia</name></option>
- <option><value>jp</value><name>Japan</name></option>
- <option><value>kr</value><name>Korea</name></option>
- <option><value>ml</value><name>Malaysia</name></option>
- <option><value>ru</value><name>Russian</name></option>
- <option><value>sa</value><name>South africa</name></option>
- <option><value>tw</value><name>Taiwan</name></option>
- <option><value>uk</value><name>United Kingdom</name></option>
- <option><value>us</value><name>United States</name></option>
- </options>
- </field>
- <field>
- <fielddescr>Optional AV database update servers</fielddescr>
- <fieldname>avupdateserver</fieldname>
- <description>Enter here space separated AV update servers, or leave empty.</description>
- <type>textarea</type>
- <cols>60</cols>
- <rows>5</rows>
- </field>
-
<field>
<fielddescr>Syslog</fielddescr>
<fieldname>syslog</fieldname>
@@ -237,11 +272,15 @@
<type>checkbox</type>
</field>
</fields>
+
+ <custom_php_command_before_form>
+ havp_before_form(&amp;$pkg);
+ </custom_php_command_before_form>
<custom_php_validation_command>
- havp_validate_settings($_POST, &amp;$input_errors);
+ havp_validate_settings($_POST, &amp;$input_errors);
</custom_php_validation_command>
<custom_php_resync_config_command>
- havp_resync();
+ havp_resync();
</custom_php_resync_config_command>
<custom_php_install_command>
</custom_php_install_command>
diff --git a/config/havp/havp_avset.xml b/config/havp/havp_avset.xml
new file mode 100644
index 00000000..2ba7a5cb
--- /dev/null
+++ b/config/havp/havp_avset.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<packagegui>
+ <name>havpavset</name>
+ <title>Antivirus: Settings</title>
+ <category>Status</category>
+ <version>0.88_03</version>
+ <include_file>/usr/local/pkg/havp.inc</include_file>
+
+ <tabs>
+ <tab>
+ <text>HTTP Proxy</text>
+ <url>/pkg_edit.php?xml=havp.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Files Scanner</text>
+ <url>/pkg_edit.php?xml=havp_fscan.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Settings</text>
+ <url>/pkg_edit.php?xml=havp_avset.xml&amp;id=0</url>
+ <active/>
+ </tab>
+ </tabs>
+
+ <fields>
+ <field>
+ <fielddescr>AV base update</fielddescr>
+ <fieldname>havpavupdate</fieldname>
+ <description>
+ &lt;input name='submit' type='submit' value='Update_AV'&gt;
+ Press button for update AV database now.
+ </description>
+ <type>select</type>
+ <value>hv_none</value>
+ <options>
+ <option><name>none </name><value>0</value></option>
+ <option><name>every 1 hours</name><value>1</value></option>
+ <option><name>every 2 hours</name><value>2</value></option>
+ <option><name>every 3 hours</name><value>3</value></option>
+ <option><name>every 4 hours</name><value>4</value></option>
+ <option><name>every 6 hours</name><value>5</value></option>
+ <option><name>every 8 hours</name><value>6</value></option>
+ <option><name>every 12 hours</name><value>7</value></option>
+ <option><name>every 24 hours</name><value>8</value></option>
+ </options>
+ </field>
+ <field>
+ <fielddescr>Regional AV database update mirror</fielddescr>
+ <fieldname>dbregion</fieldname>
+ <description>Select regional database mirror.</description>
+ <type>select</type>
+ <value></value>
+ <options>
+ <option><value></value><name>-----</name></option>
+ <option><value>au</value><name>Australia</name></option>
+ <option><value>eu</value><name>Europe</name></option>
+ <option><value>ca</value><name>Canada</name></option>
+ <option><value>cn</value><name>China</name></option>
+ <option><value>id</value><name>Indonesia</name></option>
+ <option><value>jp</value><name>Japan</name></option>
+ <option><value>kr</value><name>Korea</name></option>
+ <option><value>ml</value><name>Malaysia</name></option>
+ <option><value>ru</value><name>Russian</name></option>
+ <option><value>sa</value><name>South africa</name></option>
+ <option><value>tw</value><name>Taiwan</name></option>
+ <option><value>uk</value><name>United Kingdom</name></option>
+ <option><value>us</value><name>United States</name></option>
+ </options>
+ </field>
+ <field>
+ <fielddescr>Optional AV database update servers</fielddescr>
+ <fieldname>avupdateserver</fieldname>
+ <description>Enter here space separated AV update servers, or leave empty.</description>
+ <type>textarea</type>
+ <cols>60</cols>
+ <rows>5</rows>
+ </field>
+ <field>
+ <fielddescr>Syslog</fielddescr>
+ <fieldname>avsetsyslog</fieldname>
+ <description>Check this for enable Syslog.</description>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <fielddescr>Log</fielddescr>
+ <fieldname>avsetlog</fieldname>
+ <description>Check this for enable log.</description>
+ <type>checkbox</type>
+ </field>
+ </fields>
+
+ <custom_php_command_before_form>
+ havp_before_form(&amp;$pkg);
+ </custom_php_command_before_form>
+ <custom_php_validation_command>
+ havp_validate_settings($_POST, &amp;$input_errors);
+ </custom_php_validation_command>
+ <custom_php_resync_config_command>
+ havp_avset_resync();
+ </custom_php_resync_config_command>
+ <custom_php_install_command>
+ </custom_php_install_command>
+ <custom_php_deinstall_command>
+ </custom_php_deinstall_command>
+</packagegui> \ No newline at end of file
diff --git a/config/havp/havp_fscan.xml b/config/havp/havp_fscan.xml
new file mode 100644
index 00000000..f7548006
--- /dev/null
+++ b/config/havp/havp_fscan.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<packagegui>
+ <name>havpfscan</name>
+ <title>Antivirus: Files scanner</title>
+ <category>Status</category>
+ <version>none</version>
+ <include_file>/usr/local/pkg/havp.inc</include_file>
+
+ <tabs>
+ <tab>
+ <text>HTTP Proxy</text>
+ <url>/pkg_edit.php?xml=havp.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Files Scanner</text>
+ <url>/pkg_edit.php?xml=havp_fscan.xml&amp;id=0</url>
+ <active/>
+ </tab>
+ <tab>
+ <text>Settings</text>
+ <url>/pkg_edit.php?xml=havp_avset.xml&amp;id=0</url>
+ </tab>
+ </tabs>
+
+ <fields>
+ <field>
+ <fielddescr>Scan file path</fielddescr>
+ <fieldname>scanfilepath</fieldname>
+ <description>
+ Enter file path or catalog for scanning. &lt;br&gt;
+ </description>
+ <type>input</type>
+ <size>90</size>
+ </field>
+<!--
+ <field>
+ <fielddescr>Files scan task</fielddescr>
+ <fieldname>havpavupdate</fieldname>
+ <description>
+ &lt;input name='submit' type='submit' value='Update_AV'&gt;
+ Press button for update AV database now.
+ </description>
+ <type>select</type>
+ <value>hv_none</value>
+ <options>
+ <option><name>none</name><value>hv_none</value></option>
+ <option><name>every 1 hours</name><value>hv_01h</value></option>
+ <option><name>every 2 hours</name><value>hv_02h</value></option>
+ <option><name>every 3 hours</name><value>hv_03h</value></option>
+ <option><name>every 4 hours</name><value>hv_04h</value></option>
+ <option><name>every 6 hours</name><value>hv_06h</value></option>
+ <option><name>every 8 hours</name><value>hv_08h</value></option>
+ <option><name>every 12 hours</name><value>hv_12h</value></option>
+ <option><name>every 24 hours</name><value>hv_24h</value></option>
+ </options>
+ </field>
+-->
+ </fields>
+
+ <custom_php_command_before_form>
+ havp_fscan_before_form(&amp;$pkg);
+ </custom_php_command_before_form>
+ <custom_php_validation_command>
+ havp_validate_settings($_POST, &amp;$input_errors);
+ </custom_php_validation_command>
+ <custom_php_resync_config_command>
+ </custom_php_resync_config_command>
+ <custom_php_install_command>
+ </custom_php_install_command>
+ <custom_php_deinstall_command>
+ </custom_php_deinstall_command>
+</packagegui> \ No newline at end of file