need clamav integration?
Valery Zhuchenko
zvn at belkam.com
Mon Aug 15 07:55:06 EDT 2005
Hello!
I just wrote patch which adds online scanning with clamav engine and, if
it founds virus, it removes attachments from message, original message
is moved to quarantine.
This is usefull if user received message before virus db on MTA was updated
Valery.
--------------------------------------------------
diff -ruN cyrus-imapd-2.2.3.orig/configure.in cyrus-imapd-2.2.3/configure.in
--- cyrus-imapd-2.2.3.orig/configure.in 2005-08-15 12:08:05.000000000
+0400
+++ cyrus-imapd-2.2.3/configure.in 2005-08-15 12:14:28.151316888 +0400
@@ -979,6 +979,10 @@
CMU_LIBWRAP
CMU_UCDSNMP
+
+LDFLAGS="$LDFLAGS -lclamav"
+
+
# Figure out what directories we're linking against.
# Lots of fun for the whole family.
# This probably chokes on anything with spaces in it.
diff -ruN cyrus-imapd-2.2.3.orig/imap/mailbox.c
cyrus-imapd-2.2.3/imap/mailbox.c
--- cyrus-imapd-2.2.3.orig/imap/mailbox.c 2004-01-14
05:11:03.000000000 +0300
+++ cyrus-imapd-2.2.3/imap/mailbox.c 2005-08-12 16:14:47.000000000 +0400
@@ -62,6 +62,8 @@
#include <ctype.h>
#include <com_err.h>
+#include <clamav.h>
+
#ifdef HAVE_DIRENT_H
# include <dirent.h>
# define NAMLEN(dirent) strlen((dirent)->d_name)
@@ -299,6 +301,22 @@
char *p = buf;
struct stat sbuf;
+
+static marker = 0;
+static struct cl_node *root = NULL;
+static struct cl_limits limits;
+static int no = 0;
+int ret;
+unsigned long int size = 0;
+long double mb;
+const char *virname;
+char syscall[4096];
+struct stat oldsbuf;
+unsigned char* dummy;
+int cpmsgfd;
+char cpbuf[4096];
+off_t offset = 0;
+
buf[0]='\0';
if (!iscurrentdir) {
@@ -316,6 +334,64 @@
snprintf(p, sizeof(buf) - strlen(buf), "%lu.", uid);
+
+if (!marker) {
+ marker=1;
+
+ if((ret = cl_loaddbdir(cl_retdbdir(), &root, &no))) {
+ syslog(LOG_WARNING,"cl_loaddbdir: %s\n", cl_perror(ret));
+ }
+
+ if((ret = cl_build(root))) {
+ syslog(LOG_WARNING,"Database initialization error: %s\n",
cl_strerror(ret));;
+ cl_free(root);
+ }
+
+ memset(&limits, 0, sizeof(struct cl_limits));
+ limits.maxfiles = 1000; /* max files */
+ limits.maxfilesize = 10 * 1048576; /* maximal archived file size ==
10 Mb
*/
+ limits.maxreclevel = 5; /* maximal recursion level */
+ limits.maxratio = 200; /* maximal compression ratio */
+ limits.archivememlim = 0; /* disable memory limit for bzip2 scanner */
+
+}
+
+msgfd = open(buf, O_RDONLY, 0666);
+if (msgfd == -1) return errno;
+
+if ((ret = cl_scandesc(msgfd, &virname, &size, root, &limits,
CL_SCAN_STDOPT))
== CL_VIRUS) {
+ fstat(msgfd, &oldsbuf);
+
+ sprintf(cpbuf,"/tmp/qurantine");
+ mkdir(cpbuf,S_IRWXU);
+ sprintf(cpbuf,"%s/%s_%s",cpbuf,mailbox->name,buf);
+ cpmsgfd=open(cpbuf,O_WRONLY|O_CREAT,oldsbuf.st_mode);
+// sendfile(cpmsgfd,msgfd,&offset,oldsbuf.st_size);
+ sprintf(syscall,"cp %s %s",buf,cpbuf);
+ system(syscall);
+ close(cpmsgfd);
+ close(msgfd);
+
+ sprintf(syscall,"/usr/local/sbin/altermime --input=%s --removeall
--disclaimer=/tmp/1.txt",buf);
+ syslog(LOG_WARNING, "mailbox_map_message %s %s %s VIRUS detected %s
%s",mailbox->name,mailbox->path,buf,virname,syscall);
+ system(syscall);
+
+ msgfd = open(buf, O_RDWR);
+ if (msgfd == -1) return errno;
+
+ fstat(msgfd, &sbuf);
+
+ dummy=malloc(oldsbuf.st_size-sbuf.st_size);
+ memset(dummy,' ',oldsbuf.st_size-sbuf.st_size);
+ lseek(msgfd,offset,SEEK_END);
+ write(msgfd,dummy,oldsbuf.st_size-sbuf.st_size);
+ free(dummy);
+ close(msgfd);
+}
+else {
+ close(msgfd);
+}
+
msgfd = open(buf, O_RDONLY, 0666);
if (msgfd == -1) return errno;
diff -ruN cyrus-imapd-2.2.3.orig/imap/pop3d.c cyrus-imapd-2.2.3/imap/pop3d.c
--- cyrus-imapd-2.2.3.orig/imap/pop3d.c 2005-08-15 10:57:04.000000000
+0400
+++ cyrus-imapd-2.2.3/imap/pop3d.c 2005-08-15 10:36:08.000000000 +0400
@@ -68,6 +68,8 @@
#include <sasl/sasl.h>
#include <sasl/saslutil.h>
+#include <clamav.h>
+
#include "acl.h"
#include "util.h"
#include "auth.h"
@@ -1461,8 +1463,88 @@
char fnamebuf[MAILBOX_FNAME_LEN];
int thisline = -2;
+
+static marker = 0;
+static struct cl_node *root = NULL;
+static struct cl_limits limits;
+static int no = 0;
+int ret;
+unsigned long int size = 0;
+long double mb;
+const char *virname;
+char syscall[4096];
+struct stat sbuf,oldsbuf;
+unsigned char* dummy;
+int msgfd,cpmsgfd;
+char cpbuf[4096];
+off_t offset = 0;
+
+
mailbox_message_get_fname(popd_mailbox, popd_msg[msg].uid, fnamebuf,
sizeof(fnamebuf));
+
+
+if (!marker) {
+ marker=1;
+
+ if((ret = cl_loaddbdir(cl_retdbdir(), &root, &no))) {
+ syslog(LOG_WARNING,"cl_loaddbdir: %s\n", cl_perror(ret));
+ }
+
+ if((ret = cl_build(root))) {
+ syslog(LOG_WARNING,"Database initialization error: %s\n",
cl_strerror(ret));;
+ cl_free(root);
+ }
+
+ memset(&limits, 0, sizeof(struct cl_limits));
+ limits.maxfiles = 1000; /* max files */
+ limits.maxfilesize = 10 * 1048576; /* maximal archived file size ==
10 Mb
*/
+ limits.maxreclevel = 5; /* maximal recursion level */
+ limits.maxratio = 200; /* maximal compression ratio */
+ limits.archivememlim = 0; /* disable memory limit for bzip2 scanner */
+
+}
+
+msgfd = open(fnamebuf, O_RDONLY, 0666);
+if (msgfd == -1){
+ prot_printf(popd_out, "-ERR [SYS/PERM] Could not read message
file\r\n");
+ return;
+ }
+
+if ((ret = cl_scandesc(msgfd, &virname, &size, root, &limits,
CL_SCAN_STDOPT))
== CL_VIRUS) {
+ fstat(msgfd, &oldsbuf);
+
+ sprintf(cpbuf,"/tmp/qurantine");
+ mkdir(cpbuf,S_IRWXU);
+ sprintf(cpbuf,"%s/%s_%s",cpbuf,popd_mailbox->name,fnamebuf);
+ cpmsgfd=open(cpbuf,O_WRONLY|O_CREAT,oldsbuf.st_mode);
+// sendfile(cpmsgfd,msgfd,&offset,oldsbuf.st_size);
+ sprintf(syscall,"cp %s %s",fnamebuf,cpbuf);
+ system(syscall);
+ close(cpmsgfd);
+ close(msgfd);
+
+ sprintf(syscall,"/usr/local/sbin/altermime --input=%s --removeall
--disclaimer=/tmp/1.txt",fnamebuf);
+ syslog(LOG_WARNING, "blat %s %s %s VIRUS detected %s
%s",popd_mailbox->name,popd_mailbox->path,fnamebuf,virname,syscall);
+ system(syscall);
+
+ msgfd = open(fnamebuf, O_RDWR);
+ if (msgfd == -1) return;
+
+ fstat(msgfd, &sbuf);
+
+ dummy=malloc(oldsbuf.st_size-sbuf.st_size);
+ memset(dummy,' ',oldsbuf.st_size-sbuf.st_size);
+ lseek(msgfd,offset,SEEK_END);
+ write(msgfd,dummy,oldsbuf.st_size-sbuf.st_size);
+ free(dummy);
+ close(msgfd);
+}
+else {
+ close(msgfd);
+}
+
+
msgfile = fopen(fnamebuf, "r");
if (!msgfile) {
prot_printf(popd_out, "-ERR [SYS/PERM] Could not read message
file\r\n");
More information about the Cyrus-devel
mailing list