Joe Maimon wrote:

<snip>



From the maillog:

dsn=4.0.0, stat=Deferred: 451 4.7.1 Please try again later


Any ideas, anyone?
(The latest tarball had issues during the make, so I could not get it
installed)



In my case this is directly due to large emails. Also that above message means that clamd is no longer listening to clamav-milter.

<snip>

Long answer, stuff that I found

1) clamav-milter does not respect the options in clamav.conf for StreamMaxLength. clamd is the program which does. It respects it by.....
2) clamd does not scan anything if the stream is larger than StreamMaxLength - sizeof(buff). In my book thats a bug. It should read up to the max.


It might be wiser to

a) make clamav-milter respect MaxStreamLength and also make clamd actualy go up to StreamMaxLength
b) scan whatever we got prior to exceeding StreamMaxLength, which is probaly easier to do once you do (a) than current behavior.


I have been playing with making a patch to do this.

Disclaimer: I am a clamav newbie, someone else probaly has a much better handle on this.

Joe


Anyone care to try these? fresh from the oven. barely tested.

Joe
--- clamav-0.70-rc/clamav-milter/clamav-milter.c        Mon Mar 15 15:03:13 2004
+++ clamav-0.70-rc-jm/clamav-milter/clamav-milter.c     Tue Mar 30 18:29:39 2004
@@ -566,6 +566,7 @@
        char    *filename;      /* Where to store the message in quarantine */
        u_char  *body;          /* body of the message if Sflag is set */
        size_t  bodyLen;        /* number of bytes in body */
+       size_t  nWritten;       /* number of bytes we have written */
        header_list_t headers;  /* Message headers */
 };
 
@@ -1914,17 +1915,14 @@
 clamfi_body(SMFICTX *ctx, u_char *bodyp, size_t len)
 {
        struct privdata *privdata = (struct privdata *)smfi_getpriv(ctx);
+       struct cfgstruct *cpt = NULL;   
+       size_t sendlen = 0;
 
        if(logVerbose)
                syslog(LOG_DEBUG, "clamfi_envbody: %u bytes", len);
 #ifdef CL_DEBUG
        printf("clamfi_envbody: %u bytes\n", len);
 #endif
-
-       if(clamfi_send(privdata, len, (char *)bodyp) < 0) {
-               clamfi_cleanup(ctx);
-               return cl_error;
-       }
        if(Sflag) {
                if(privdata->body) {
                        assert(privdata->bodyLen > 0);
@@ -1938,6 +1936,41 @@
                        privdata->bodyLen = len;
                }
        }
+
+       if((!quarantine_dir) 
+               && (cpt = cfgopt(copt, "StreamMaxLength")) 
+               && cpt->numarg < (len + privdata->nWritten)
+          ){
+               sendlen = (cpt->numarg - privdata->nWritten);
+               if(use_syslog && privdata->nWritten != cpt->numarg){
+                       char buf[1024]; 
+                       strncpy(buf,privdata->from,sizeof(buf));
+                       syslog(LOG_INFO,"Stream from %s size exceeded max of %u , 
already wrote %u, will write %u more instead of len %u",
+                                       buf,
+                                       cpt->numarg,
+                                       privdata->nWritten,
+                                       sendlen,
+                                       len); 
+               }
+       }
+       else {
+               sendlen = len;
+       }
+
+       if(!sendlen)
+               return SMFIS_CONTINUE;
+
+
+       if(sendlen && (clamfi_send(privdata, sendlen, (char *)bodyp) < 0)) {
+               clamfi_cleanup(ctx);
+               return cl_error;
+       }else
+       {
+               if(sendlen)
+                       privdata->nWritten += sendlen;
+       }               
+
+
        return SMFIS_CONTINUE;
 }
 
@@ -2389,6 +2422,7 @@
                printf("clamfi_send: len=%u bufsiz=%u\n", len, sizeof(output));
 #endif
 
+       errno = 0;
        while(len > 0) {
                const int nbytes = (quarantine_dir) ?
                        write(privdata->dataSocket, ptr, len) :
@@ -2400,7 +2434,8 @@
                        perror("send");
                        checkClamd();
                        if(use_syslog)
-                               syslog(LOG_ERR, "write failure to clamd");
+                               syslog(LOG_ERR, "write failure to clamd, nbytes: %d, 
quarantine_dir: %s, error: %s", 
+                                               nbytes, quarantine_dir, 
strerror(errno) );
 
                        return -1;
                }
--- clamav-0.70-rc/clamd/scanner.c      Mon Mar 15 15:03:12 2004
+++ clamav-0.70-rc-jm/clamd/scanner.c   Tue Mar 30 18:28:29 2004
@@ -186,7 +186,7 @@
 
 int scanstream(int odesc, unsigned long int *scanned, const struct cl_node *root, 
const struct cl_limits *limits, int options, const struct cfgstruct *copt)
 {
-       int ret, portscan = CL_DEFAULT_MAXPORTSCAN, sockfd, port, acceptd, tmpd, 
bread, retval;
+       int ret, portscan = CL_DEFAULT_MAXPORTSCAN, sockfd, port, acceptd, tmpd, 
bread, btread, retval;
        long int size = 0, maxsize = 0;
        short bound = 0;
        const char *virname;
@@ -260,22 +260,18 @@
        if((cpt = cfgopt(copt, "StreamMaxLength")))
            maxsize = cpt->numarg;
 
+       btread = sizeof(buff);
        while((retval = poll_fd(acceptd, CL_DEFAULT_SCANTIMEOUT)) == 1) {
-           bread = read(acceptd, buff, sizeof(buff));
+           bread = read(acceptd, buff, btread);
            if (bread <= 0) {
                break;
            }
            size += bread;
 
-           if(maxsize && (size + sizeof(buff)) > maxsize) {
-               shutdown(sockfd, 2);
-               close(sockfd);
-               close(acceptd);
-               mdprintf(odesc, "Size exceeded ERROR\n");
-               logg("^ScanStream: Size exceeded (stopped at %d, max: %d)\n", size, 
maxsize);
-               if(tmp)
-                   fclose(tmp);
-               return -1;
+           btread = ( (maxsize && ( size + btread > maxsize)) ? (maxsize - size) : 
btread);
+           if(btread == 0) {
+               logg("^ScanStream: Size limit reached (max: %d)\n",  maxsize);
+               break;
            }
 
            if(write(tmpd, buff, bread) < 0) {

Reply via email to