diff options
Diffstat (limited to 'config/havp')
-rw-r--r-- | config/havp/havp.inc | 1436 | ||||
-rw-r--r-- | config/havp/havp.xml | 251 | ||||
-rw-r--r-- | config/havp/havp_avset.xml | 105 | ||||
-rw-r--r-- | config/havp/havp_fscan.xml | 72 |
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> 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> 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> 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&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&id=0</url> <active/> </tab> + <tab> + <text>Files Scanner</text> + <url>/pkg_edit.php?xml=havp_fscan.xml&id=0</url> + </tab> + <tab> + <text>Settings</text> + <url>/pkg_edit.php?xml=havp_avset.xml&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: <br> + <b> standard </b> - client(s) bind to the 'proxy port' on selected interface(s); <br> + <b> parent for squid </b> - configure HAVP as parent for Squid proxy;<br> + <b> transparent </b> - 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); <br> + <b> internal </b> - HAVP listen internal interface (127.0.0.1) on 'proxy port', use you own traffic forwarding rules.<br> + </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. + <br>Enable this if you use your own parent proxy after HAVP, so it will see the original client IP. + <br>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. + <br> 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> - <input name='submit' type='submit' value='Update_AV'> - 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(&$pkg); + </custom_php_command_before_form> <custom_php_validation_command> - havp_validate_settings($_POST, &$input_errors); + havp_validate_settings($_POST, &$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&id=0</url> + </tab> + <tab> + <text>Files Scanner</text> + <url>/pkg_edit.php?xml=havp_fscan.xml&id=0</url> + </tab> + <tab> + <text>Settings</text> + <url>/pkg_edit.php?xml=havp_avset.xml&id=0</url> + <active/> + </tab> + </tabs> + + <fields> + <field> + <fielddescr>AV base update</fielddescr> + <fieldname>havpavupdate</fieldname> + <description> + <input name='submit' type='submit' value='Update_AV'> + 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(&$pkg); + </custom_php_command_before_form> + <custom_php_validation_command> + havp_validate_settings($_POST, &$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&id=0</url> + </tab> + <tab> + <text>Files Scanner</text> + <url>/pkg_edit.php?xml=havp_fscan.xml&id=0</url> + <active/> + </tab> + <tab> + <text>Settings</text> + <url>/pkg_edit.php?xml=havp_avset.xml&id=0</url> + </tab> + </tabs> + + <fields> + <field> + <fielddescr>Scan file path</fielddescr> + <fieldname>scanfilepath</fieldname> + <description> + Enter file path or catalog for scanning. <br> + </description> + <type>input</type> + <size>90</size> + </field> +<!-- + <field> + <fielddescr>Files scan task</fielddescr> + <fieldname>havpavupdate</fieldname> + <description> + <input name='submit' type='submit' value='Update_AV'> + 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(&$pkg); + </custom_php_command_before_form> + <custom_php_validation_command> + havp_validate_settings($_POST, &$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 |