diff --git a/README.md b/README.md
index 7a367cebd..09cc30d14 100644
--- a/README.md
+++ b/README.md
@@ -53,6 +53,7 @@ sysutils/smart -- SMART tools
sysutils/vmware -- VMware tools
sysutils/xen -- Xen guest utilities
security/acme-client -- Let's Encrypt client
+security/clamav -- Antivirus engine for detecting malicious threats
security/intrusion-detection-content-pt-open -- IDS PT Research ruleset (only for non-commercial use)
security/tinc -- Tinc VPN
www/web-proxy-sso -- Add SSO Active Directory to use in Proxy
diff --git a/security/clamav/Makefile b/security/clamav/Makefile
new file mode 100644
index 000000000..16e48923d
--- /dev/null
+++ b/security/clamav/Makefile
@@ -0,0 +1,8 @@
+PLUGIN_NAME= clamav
+PLUGIN_VERSION= 0.2
+PLUGIN_COMMENT= Antivirus engine for detecting malicious threats
+PLUGIN_DEPENDS= clamav
+PLUGIN_MAINTAINER= m.muenz@gmail.com
+PLUGIN_DEVEL= yes
+
+.include "../../Mk/plugins.mk"
diff --git a/security/clamav/pkg-descr b/security/clamav/pkg-descr
new file mode 100644
index 000000000..4fe5a529d
--- /dev/null
+++ b/security/clamav/pkg-descr
@@ -0,0 +1,8 @@
+ClamAV(r) is an open source (GPL) anti-virus engine used in a
+variety of situations including email scanning, web scanning,
+and end point security. It provides a number of utilities
+including a flexible and scalable multi-threaded daemon,
+a command line scanner and an advanced tool for automatic
+database updates.
+
+WWW: https://www.clamav.net/
diff --git a/security/clamav/src/etc/inc/plugins.inc.d/clamav.inc b/security/clamav/src/etc/inc/plugins.inc.d/clamav.inc
new file mode 100644
index 000000000..15c7357f6
--- /dev/null
+++ b/security/clamav/src/etc/inc/plugins.inc.d/clamav.inc
@@ -0,0 +1,62 @@
+ gettext('ClamAV Daemon'),
+ 'configd' => array(
+ 'restart' => array('clamav restart'),
+ 'start' => array('clamav start'),
+ 'stop' => array('clamav stop'),
+ ),
+ 'name' => 'clamd',
+ 'pidfile' => '/var/run/clamav/clamd.pid'
+ );
+ }
+
+ if (isset($config['OPNsense']['clamav']['freshclam']['enabled']) && $config['OPNsense']['clamav']['freshclam']['enabled'] == 1) {
+ $services[] = array(
+ 'description' => gettext('freshclam daemon'),
+ 'configd' => array(
+ 'restart' => array('clamav restart'),
+ 'start' => array('clamav start'),
+ 'stop' => array('clamav stop'),
+ ),
+ 'name' => 'freshclam',
+ 'pidfile' => '/var/run/clamav/freshclam.pid'
+ );
+ }
+
+ return $services;
+}
diff --git a/security/clamav/src/opnsense/mvc/app/controllers/OPNsense/ClamAV/Api/GeneralController.php b/security/clamav/src/opnsense/mvc/app/controllers/OPNsense/ClamAV/Api/GeneralController.php
new file mode 100644
index 000000000..704c29577
--- /dev/null
+++ b/security/clamav/src/opnsense/mvc/app/controllers/OPNsense/ClamAV/Api/GeneralController.php
@@ -0,0 +1,77 @@
+request->isGet()) {
+ $mdlGeneral = new General();
+ $result['general'] = $mdlGeneral->getNodes();
+ }
+ return $result;
+ }
+
+ public function setAction()
+ {
+ $result = array("result"=>"failed");
+ if ($this->request->isPost()) {
+ // load model and update with provided data
+ $mdlGeneral = new General();
+ $mdlGeneral->setNodes($this->request->getPost("general"));
+
+ // perform validation
+ $valMsgs = $mdlGeneral->performValidation();
+ foreach ($valMsgs as $field => $msg) {
+ if (!array_key_exists("validations", $result)) {
+ $result["validations"] = array();
+ }
+ $result["validations"]["general.".$msg->getField()] = $msg->getMessage();
+ }
+
+ // serialize model to config and save
+ if ($valMsgs->count() == 0) {
+ $mdlGeneral->serializeToConfig();
+ Config::getInstance()->save();
+ $result["result"] = "saved";
+ }
+ }
+ return $result;
+ }
+}
diff --git a/security/clamav/src/opnsense/mvc/app/controllers/OPNsense/ClamAV/Api/ServiceController.php b/security/clamav/src/opnsense/mvc/app/controllers/OPNsense/ClamAV/Api/ServiceController.php
new file mode 100644
index 000000000..6d3c648b0
--- /dev/null
+++ b/security/clamav/src/opnsense/mvc/app/controllers/OPNsense/ClamAV/Api/ServiceController.php
@@ -0,0 +1,166 @@
+request->isPost()) {
+ $backend = new Backend();
+ $command = 'clamav freshclam';
+ if ($this->request->hasPost('action')) {
+ $command .= ' go';
+ }
+ $response = trim($backend->configdRun($command));
+ return array('status' => $response);
+ } else {
+ return array('status' => 'error');
+ }
+ }
+ /**
+ * start clamav service (in background)
+ * @return array
+ */
+ public function startAction()
+ {
+ if ($this->request->isPost()) {
+ $backend = new Backend();
+ $response = $backend->configdRun("clamav start", true);
+ return array("response" => $response);
+ } else {
+ return array("response" => array());
+ }
+ }
+
+ /**
+ * stop clamav service
+ * @return array
+ */
+ public function stopAction()
+ {
+ if ($this->request->isPost()) {
+ $backend = new Backend();
+ $response = $backend->configdRun("clamav stop");
+ return array("response" => $response);
+ } else {
+ return array("response" => array());
+ }
+ }
+
+ /**
+ * restart clamav service
+ * @return array
+ */
+ public function restartAction()
+ {
+ if ($this->request->isPost()) {
+ $backend = new Backend();
+ $response = $backend->configdRun("clamav restart");
+ return array("response" => $response);
+ } else {
+ return array("response" => array());
+ }
+ }
+
+ /**
+ * retrieve status of clamav
+ * @return array
+ * @throws \Exception
+ */
+ public function statusAction()
+ {
+ $backend = new Backend();
+ $mdlGeneral = new General();
+ $response = $backend->configdRun("clamav status");
+
+ if (strpos($response, "not running") > 0) {
+ if ($mdlGeneral->enabled->__toString() == 1) {
+ $status = "stopped";
+ } else {
+ $status = "disabled";
+ }
+ } elseif (strpos($response, "is running") > 0) {
+ $status = "running";
+ } elseif ($mdlGeneral->enabled->__toString() == 0) {
+ $status = "disabled";
+ } else {
+ $status = "unkown";
+ }
+
+
+ return array("status" => $status);
+ }
+
+ /**
+ * reconfigure clamav, generate config and reload
+ */
+ public function reconfigureAction()
+ {
+ if ($this->request->isPost()) {
+ // close session for long running action
+ $this->sessionClose();
+
+ $mdlGeneral = new General();
+ $backend = new Backend();
+
+ $runStatus = $this->statusAction();
+
+ // stop clamav if it is running or not
+ $this->stopAction();
+
+ // generate template
+ $backend->configdRun('template reload OPNsense/ClamAV');
+
+ // (res)start daemon
+ if ($mdlGeneral->enabled->__toString() == 1) {
+ $this->startAction();
+ }
+
+ return array("status" => "ok");
+ } else {
+ return array("status" => "failed");
+ }
+ }
+}
diff --git a/security/clamav/src/opnsense/mvc/app/controllers/OPNsense/ClamAV/GeneralController.php b/security/clamav/src/opnsense/mvc/app/controllers/OPNsense/ClamAV/GeneralController.php
new file mode 100644
index 000000000..a0df9a70c
--- /dev/null
+++ b/security/clamav/src/opnsense/mvc/app/controllers/OPNsense/ClamAV/GeneralController.php
@@ -0,0 +1,39 @@
+view->title = gettext("ClamAV settings");
+ $this->view->generalForm = $this->getForm("general");
+ $this->view->pick('OPNsense/ClamAV/general');
+ }
+}
diff --git a/security/clamav/src/opnsense/mvc/app/controllers/OPNsense/ClamAV/forms/general.xml b/security/clamav/src/opnsense/mvc/app/controllers/OPNsense/ClamAV/forms/general.xml
new file mode 100644
index 000000000..747d2e5ac
--- /dev/null
+++ b/security/clamav/src/opnsense/mvc/app/controllers/OPNsense/ClamAV/forms/general.xml
@@ -0,0 +1,180 @@
+
diff --git a/security/clamav/src/opnsense/mvc/app/models/OPNsense/ClamAV/ACL/ACL.xml b/security/clamav/src/opnsense/mvc/app/models/OPNsense/ClamAV/ACL/ACL.xml
new file mode 100644
index 000000000..1edb10b18
--- /dev/null
+++ b/security/clamav/src/opnsense/mvc/app/models/OPNsense/ClamAV/ACL/ACL.xml
@@ -0,0 +1,9 @@
+
+
+ Services: ClamAV
+
+ ui/clamav/*
+ api/clamav/*
+
+
+
diff --git a/security/clamav/src/opnsense/mvc/app/models/OPNsense/ClamAV/General.php b/security/clamav/src/opnsense/mvc/app/models/OPNsense/ClamAV/General.php
new file mode 100644
index 000000000..2c02998f1
--- /dev/null
+++ b/security/clamav/src/opnsense/mvc/app/models/OPNsense/ClamAV/General.php
@@ -0,0 +1,35 @@
+
+ //OPNsense/clamav/general
+ ClamAV configuration
+ 1.0.0
+
+
+ 0
+ Y
+
+
+ 0
+ Y
+
+
+ 0
+ Y
+
+
+ 10
+ N
+
+
+ 100
+ N
+
+
+ 30
+ N
+
+
+ 20
+ N
+
+
+ 0
+ N
+
+
+ 0
+ N
+
+
+ 0
+ N
+
+
+ 1
+ N
+
+
+ 1
+ N
+
+
+ 0
+ N
+
+
+ 1
+ N
+
+
+ 0
+ N
+
+
+ 1
+ N
+
+
+ 1
+ N
+
+
+ 1
+ N
+
+
+ 1
+ N
+
+
+ 1
+ N
+
+
+ 1
+ N
+
+
+ 1
+ N
+
+
+ 0
+ N
+
+
+ 100M
+ N
+
+
+ 25M
+ N
+
+
+ 16
+ N
+
+
+ 10000
+ N
+
+
+ 0
+ N
+
+
+ database.clamav.net
+ Y
+
+
+ 60
+ Y
+
+
+
diff --git a/security/clamav/src/opnsense/mvc/app/models/OPNsense/ClamAV/Menu/Menu.xml b/security/clamav/src/opnsense/mvc/app/models/OPNsense/ClamAV/Menu/Menu.xml
new file mode 100644
index 000000000..f5e43ec53
--- /dev/null
+++ b/security/clamav/src/opnsense/mvc/app/models/OPNsense/ClamAV/Menu/Menu.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/security/clamav/src/opnsense/mvc/app/views/OPNsense/ClamAV/general.volt b/security/clamav/src/opnsense/mvc/app/views/OPNsense/ClamAV/general.volt
new file mode 100644
index 000000000..5b5aeb2f9
--- /dev/null
+++ b/security/clamav/src/opnsense/mvc/app/views/OPNsense/ClamAV/general.volt
@@ -0,0 +1,102 @@
+{#
+
+OPNsense® is Copyright © 2014 – 2017 by Deciso B.V.
+This file is Copyright © 2017 by Michael Muenz
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+#}
+
+
+
{{ lang._('Download signatures') }}
+
{{ lang._('No signature database found, please download before use. The download will take several minutes and this message will disappear when it has been completed. If you have memory file system enabled where /var is mounted into RAM you have to download this file with every reboot.')}}
+
+
+
+
+
+ {{ partial("layout_partials/base_form",['fields':generalForm,'id':'frm_general_settings'])}}
+
+
+ {{ lang._('Save') }}
+
+
+
+
+
+
diff --git a/security/clamav/src/opnsense/scripts/OPNsense/ClamAV/freshclam.sh b/security/clamav/src/opnsense/scripts/OPNsense/ClamAV/freshclam.sh
new file mode 100755
index 000000000..e54851c70
--- /dev/null
+++ b/security/clamav/src/opnsense/scripts/OPNsense/ClamAV/freshclam.sh
@@ -0,0 +1,43 @@
+#!/bin/sh
+
+# Copyright (c) 2017 Franco Fichtner
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+PIDFILE="/var/run/clamav/freshclam-init.pid"
+DBFILE="/var/db/clamav/main.cvd"
+COMMAND="${1}"
+
+if [ -f ${DBFILE} ]; then
+ echo "done"
+elif pgrep -qF ${PIDFILE} 2> /dev/null; then
+ echo "running"
+elif [ -z "${COMMAND}" ]; then
+ echo "missing"
+else
+ daemon -f -p ${PIDFILE} freshclam --quiet
+ echo "starting"
+fi
+
+exit 0
diff --git a/security/clamav/src/opnsense/scripts/OPNsense/ClamAV/setup.sh b/security/clamav/src/opnsense/scripts/OPNsense/ClamAV/setup.sh
new file mode 100644
index 000000000..e8c24bb19
--- /dev/null
+++ b/security/clamav/src/opnsense/scripts/OPNsense/ClamAV/setup.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+mkdir -p /var/run/clamav
+chown -R clamav:clamav /var/run/clamav
+chmod 750 /var/run/clamav
+
+mkdir -p /var/db/clamav
+chown -R clamav:clamav /var/db/clamav
+chmod 750 /var/db/clamav
+
+mkdir -p /var/log/clamav
+chown -R clamav:clamav /var/log/clamav
+chmod 750 /var/log/clamav
diff --git a/security/clamav/src/opnsense/service/conf/actions.d/actions_clamav.conf b/security/clamav/src/opnsense/service/conf/actions.d/actions_clamav.conf
new file mode 100644
index 000000000..8e185dfe3
--- /dev/null
+++ b/security/clamav/src/opnsense/service/conf/actions.d/actions_clamav.conf
@@ -0,0 +1,35 @@
+[start]
+command:/usr/local/opnsense/scripts/OPNsense/ClamAV/setup.sh;/usr/local/etc/rc.d/clamav-freshclam start;/usr/local/etc/rc.d/clamav-clamd start
+parameters:
+type:script
+message:starting ClamAV
+
+[stop]
+command:/usr/local/etc/rc.d/clamav-freshclam stop;/usr/local/etc/rc.d/clamav-clamd stop; exit 0
+parameters:
+type:script
+message:stopping ClamAV
+
+[restart]
+command:/usr/local/opnsense/scripts/OPNsense/ClamAV/setup.sh;/usr/local/etc/rc.d/clamav-freshclam restart;/usr/local/etc/rc.d/clamav-clamd restart
+parameters:
+type:script
+message:restarting ClamAV
+
+[reconfigure]
+command:/usr/local/opnsense/scripts/OPNsense/ClamAV/setup.sh;/usr/local/etc/rc.d/clamav-freshclam restart;/usr/local/etc/rc.d/clamav-clamd restart
+parameters:
+type:script
+message:reconfigure ClamAV
+
+[status]
+command:/usr/local/etc/rc.d/clamav-freshclam status;/usr/local/etc/rc.d/clamav-clamd status;exit 0
+parameters:
+type:script_output
+message:request ClamAV status
+
+[freshclam]
+command:/usr/local/opnsense/scripts/OPNsense/ClamAV/freshclam.sh
+parameters:%s
+type:script_output
+message:Check or install signatures
diff --git a/security/clamav/src/opnsense/service/templates/OPNsense/ClamAV/+TARGETS b/security/clamav/src/opnsense/service/templates/OPNsense/ClamAV/+TARGETS
new file mode 100644
index 000000000..8fd952c65
--- /dev/null
+++ b/security/clamav/src/opnsense/service/templates/OPNsense/ClamAV/+TARGETS
@@ -0,0 +1,4 @@
+clamav_clamd:/etc/rc.conf.d/clamav_clamd
+clamav_freshclam:/etc/rc.conf.d/clamav_freshclam
+clamd.conf:/usr/local/etc/clamd.conf
+freshclam.conf:/usr/local/etc/freshclam.conf
diff --git a/security/clamav/src/opnsense/service/templates/OPNsense/ClamAV/clamav_clamd b/security/clamav/src/opnsense/service/templates/OPNsense/ClamAV/clamav_clamd
new file mode 100644
index 000000000..f80cf3395
--- /dev/null
+++ b/security/clamav/src/opnsense/service/templates/OPNsense/ClamAV/clamav_clamd
@@ -0,0 +1,6 @@
+{% if helpers.exists('OPNsense.clamav.general.enabled') and OPNsense.clamav.general.enabled == '1' %}
+clamav_clamd_opnsense_bootup_run="/usr/local/opnsense/scripts/OPNsense/ClamAV/setup.sh"
+clamav_clamd_enable="YES"
+{% else %}
+clamav_clamd_enable="NO"
+{% endif %}
diff --git a/security/clamav/src/opnsense/service/templates/OPNsense/ClamAV/clamav_freshclam b/security/clamav/src/opnsense/service/templates/OPNsense/ClamAV/clamav_freshclam
new file mode 100644
index 000000000..5a2db5b5e
--- /dev/null
+++ b/security/clamav/src/opnsense/service/templates/OPNsense/ClamAV/clamav_freshclam
@@ -0,0 +1,6 @@
+{% if helpers.exists('OPNsense.clamav.general.fc_enabled') and OPNsense.clamav.general.fc_enabled == '1' %}
+clamav_freshclam_opnsense_bootup_run="/usr/local/opnsense/scripts/OPNsense/ClamAV/setup.sh"
+clamav_freshclam_enable="YES"
+{% else %}
+clamav_freshclam_enable="NO"
+{% endif %}
diff --git a/security/clamav/src/opnsense/service/templates/OPNsense/ClamAV/clamd.conf b/security/clamav/src/opnsense/service/templates/OPNsense/ClamAV/clamd.conf
new file mode 100644
index 000000000..c2ae4805d
--- /dev/null
+++ b/security/clamav/src/opnsense/service/templates/OPNsense/ClamAV/clamd.conf
@@ -0,0 +1,84 @@
+{% if helpers.exists('OPNsense.clamav.general.enabled') and OPNsense.clamav.general.enabled == '1' %}
+LogFile /var/log/clamav/clamd.log
+LogTime yes
+PidFile /var/run/clamav/clamd.pid
+DatabaseDirectory /var/db/clamav
+LocalSocket /var/run/clamav/clamd.sock
+FixStaleSocket yes
+{% if helpers.exists('OPNsense.clamav.general.enabletcp') and OPNsense.clamav.general.enabletcp == '1' %}
+TCPSocket 3310
+TCPAddr 127.0.0.1
+{% endif %}
+{% if helpers.exists('OPNsense.clamav.general.maxthreads') and OPNsense.clamav.general.maxthreads != '' %}
+MaxThreads {{ OPNsense.clamav.general.maxthreads }}
+{% endif %}
+{% if helpers.exists('OPNsense.clamav.general.maxqueue') and OPNsense.clamav.general.maxqueue != '' %}
+MaxQueue {{ OPNsense.clamav.general.maxqueue }}
+{% endif %}
+{% if helpers.exists('OPNsense.clamav.general.idletimeout') and OPNsense.clamav.general.idletimeout != '' %}
+IdleTimeout {{ OPNsense.clamav.general.idletimeout }}
+{% endif %}
+{% if helpers.exists('OPNsense.clamav.general.maxdirrecursion') and OPNsense.clamav.general.maxdirrecursion != '' %}
+MaxDirectoryRecursion {{ OPNsense.clamav.general.maxdirrecursion }}
+{% endif %}
+{% if helpers.exists('OPNsense.clamav.general.followdirsym') and OPNsense.clamav.general.followdirsym == '1' %}
+FollowDirectorySymlinks yes
+{% endif %}
+{% if helpers.exists('OPNsense.clamav.general.followfilesym') and OPNsense.clamav.general.followfilesym == '1' %}
+FollowFileSymlinks yes
+{% endif %}
+User clamav
+AllowSupplementaryGroups yes
+{% if helpers.exists('OPNsense.clamav.general.scanpe') and OPNsense.clamav.general.scanpe == '1' %}
+ScanPE yes
+{% endif %}
+{% if helpers.exists('OPNsense.clamav.general.scanelf') and OPNsense.clamav.general.scanelf == '1' %}
+ScanELF yes
+{% endif %}
+{% if helpers.exists('OPNsense.clamav.general.detectbroken') and OPNsense.clamav.general.detectbroken == '1' %}
+DetectBrokenExecutables yes
+{% endif %}
+{% if helpers.exists('OPNsense.clamav.general.scanole2') and OPNsense.clamav.general.scanole2 == '1' %}
+ScanOLE2 yes
+{% endif %}
+{% if helpers.exists('OPNsense.clamav.general.ole2blockmarcros') and OPNsense.clamav.general.ole2blockmarcros == '1' %}
+OLE2BlockMacros yes
+{% endif %}
+{% if helpers.exists('OPNsense.clamav.general.scanpdf') and OPNsense.clamav.general.scanpdf == '1' %}
+ScanPDF yes
+{% endif %}
+{% if helpers.exists('OPNsense.clamav.general.scanswf') and OPNsense.clamav.general.scanswf == '1' %}
+ScanSWF yes
+{% endif %}
+{% if helpers.exists('OPNsense.clamav.general.scanxmldocs') and OPNsense.clamav.general.scanxmldocs == '1' %}
+ScanXMLDOCS yes
+{% endif %}
+{% if helpers.exists('OPNsense.clamav.general.scanhwp3') and OPNsense.clamav.general.scanhwp3 == '1' %}
+ScanHWP3 yes
+{% endif %}
+{% if helpers.exists('OPNsense.clamav.general.scanmailfiles') and OPNsense.clamav.general.scanmailfiles == '1' %}
+ScanMail yes
+{% endif %}
+{% if helpers.exists('OPNsense.clamav.general.scanhtml') and OPNsense.clamav.general.scanhtml == '1' %}
+ScanHTML yes
+{% endif %}
+{% if helpers.exists('OPNsense.clamav.general.scanarchive') and OPNsense.clamav.general.scanarchive == '1' %}
+ScanArchive yes
+{% endif %}
+{% if helpers.exists('OPNsense.clamav.general.arcblockenc') and OPNsense.clamav.general.arcblockenc == '1' %}
+ArchiveBlockEncrypted yes
+{% endif %}
+{% if helpers.exists('OPNsense.clamav.general.maxscansize') and OPNsense.clamav.general.maxscansize != '' %}
+MaxScanSize {{ OPNsense.clamav.general.maxscansize }}
+{% endif %}
+{% if helpers.exists('OPNsense.clamav.general.maxfilesize') and OPNsense.clamav.general.maxfilesize != '' %}
+MaxFileSize {{ OPNsense.clamav.general.maxfilesize }}
+{% endif %}
+{% if helpers.exists('OPNsense.clamav.general.maxrecursion') and OPNsense.clamav.general.maxrecursion != '' %}
+MaxRecursion {{ OPNsense.clamav.general.maxrecursion }}
+{% endif %}
+{% if helpers.exists('OPNsense.clamav.general.maxfiles') and OPNsense.clamav.general.maxfiles != '' %}
+MaxFiles {{ OPNsense.clamav.general.maxfiles }}
+{% endif %}
+
+{% endif %}
diff --git a/security/clamav/src/opnsense/service/templates/OPNsense/ClamAV/freshclam.conf b/security/clamav/src/opnsense/service/templates/OPNsense/ClamAV/freshclam.conf
new file mode 100644
index 000000000..3765f24a8
--- /dev/null
+++ b/security/clamav/src/opnsense/service/templates/OPNsense/ClamAV/freshclam.conf
@@ -0,0 +1,28 @@
+{% if helpers.exists('OPNsense.clamav.general.fc_enabled') and OPNsense.clamav.general.fc_enabled == '1' %}
+
+
+DatabaseDirectory /var/db/clamav
+UpdateLogFile /var/log/clamav/freshclam.log
+
+LogTime yes
+{% if helpers.exists('OPNsense.clamav.general.fc_logverbose') and OPNsense.clamav.general.fc_logverbose == '1' %}
+LogVerbose yes
+{% endif %}
+
+PidFile /var/run/clamav/freshclam.pid
+DatabaseOwner clamav
+AllowSupplementaryGroups yes
+
+{% if helpers.exists('OPNsense.clamav.general.fc_databasemirror') and OPNsense.clamav.general.fc_databasemirror != '' %}
+DatabaseMirror {{ OPNsense.clamav.general.fc_databasemirror }}
+{% endif %}
+NotifyClamd /usr/local/etc/clamd.conf
+{% if helpers.exists('OPNsense.clamav.general.fc_timeout') and OPNsense.clamav.general.fc_timeout != '' %}
+ConnectTimeout {{ OPNsense.clamav.general.fc_timeout }}
+{% endif %}
+
+{% else %}
+{% if helpers.exists('OPNsense.clamav.general.fc_databasemirror') and OPNsense.clamav.general.fc_databasemirror != '' %}
+DatabaseMirror {{ OPNsense.clamav.general.fc_databasemirror }}
+{% endif %}
+{% endif %}