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