Beispiel #1
0
sfsistat clamfi_body(SMFICTX *ctx, unsigned char *bodyp, size_t len) {
    struct CLAMFI *cf;

    if(!(cf = (struct CLAMFI *)smfi_getpriv(ctx)))
        return SMFIS_CONTINUE; /* whatever */

    if(!cf->gotbody) {
        sfsistat ret = sendchunk(cf, (unsigned char *)"\r\n", 2, ctx);
        if(ret != SMFIS_CONTINUE)
            return ret;
        cf->gotbody = 1;
    }

    return sendchunk(cf, bodyp, len, ctx);
}
Beispiel #2
0
sfsistat clamfi_header(SMFICTX *ctx, char *headerf, char *headerv) {
    struct CLAMFI *cf;
    sfsistat ret;

    if(!(cf = (struct CLAMFI *)smfi_getpriv(ctx)))
	return SMFIS_CONTINUE; /* whatever */

    if(!cf->totsz && cf->all_whitelisted) {
	logg("*Skipping scan (all destinations whitelisted)\n");
	nullify(ctx, cf, CF_NONE);
	free(cf);
	return SMFIS_ACCEPT;
    }

    if(!headerf) return SMFIS_CONTINUE; /* just in case */

    if((loginfected & (LOGINF_FULL | LOGCLN_FULL)) || viraction) {
	if(!cf->msg_subj && !strcasecmp(headerf, "Subject"))
	    cf->msg_subj = strdup(headerv ? headerv : "");
	if(!cf->msg_date && !strcasecmp(headerf, "Date"))
	    cf->msg_date = strdup(headerv ? headerv : "");
	if(!cf->msg_id && !strcasecmp(headerf, "Message-ID"))
	    cf->msg_id = strdup(headerv ? headerv : "");
    }

    if(addxvirus==1) {
	if(!strcasecmp(headerf, "X-Virus-Scanned")) cf->scanned_count++;
	if(!strcasecmp(headerf, "X-Virus-Status")) cf->status_count++;
    }

    if((ret = sendchunk(cf, (unsigned char *)headerf, strlen(headerf), ctx)) != SMFIS_CONTINUE) {
        free(cf);
        return ret;
    }
    if((ret = sendchunk(cf, (unsigned char *)": ", 2, ctx)) != SMFIS_CONTINUE) {
        free(cf);
        return ret;
    }
    if(headerv && (ret = sendchunk(cf, (unsigned char *)headerv, strlen(headerv), ctx)) != SMFIS_CONTINUE) {
        free(cf);
        return ret;
    }
    ret = sendchunk(cf, (unsigned char *)"\r\n", 2, ctx);
    if(ret != SMFIS_CONTINUE)
        free(cf);
    return ret;
}
Beispiel #3
0
static sfsistat sendchunk(struct CLAMFI *cf, unsigned char *bodyp, size_t len, SMFICTX *ctx) {
    if(cf->totsz >= maxfilesize || len == 0)
        return SMFIS_CONTINUE;

    if(!cf->totsz) {
        sfsistat ret;
        if(nc_connect_rand(&cf->main, &cf->alt, &cf->local)) {
            logg("!Failed to initiate streaming/fdpassing\n");
            nullify(ctx, cf, CF_NONE);
            return FailAction;
        }
        cf->totsz = 1; /* do not infloop */
        if((ret = sendchunk(cf, (unsigned char *)"From clamav-milter\n", 19, ctx)) != SMFIS_CONTINUE)
            return ret;
        cf->totsz -= 1;
    }

    if(cf->totsz + len > maxfilesize)
        len = maxfilesize - cf->totsz;

    cf->totsz += len;
    if(cf->local) {
        while(len) {
            int n = write(cf->alt, bodyp, len);

            if (n==-1) {
                logg("!Failed to write temporary file\n");
                nullify(ctx, cf, CF_BOTH);
                return FailAction;
            }
            len -= n;
            bodyp += n;
        }
    } else {
        int sendfailed = 0;

        if(len < CLAMFIBUFSZ - cf->bufsz) {
            memcpy(&cf->buffer[cf->bufsz], bodyp, len);
            cf->bufsz += len;
        } else if(len < CLAMFIBUFSZ) {
            memcpy(&cf->buffer[cf->bufsz], bodyp, CLAMFIBUFSZ - cf->bufsz);
            sendfailed = nc_send(cf->alt, cf->buffer, CLAMFIBUFSZ);
            len -= (CLAMFIBUFSZ - cf->bufsz);
            memcpy(cf->buffer, &bodyp[CLAMFIBUFSZ - cf->bufsz], len);
            cf->bufsz = len;
        } else {
            if(nc_send(cf->alt, cf->buffer, cf->bufsz) || nc_send(cf->alt, bodyp, len))
                sendfailed = 1;
            cf->bufsz = 0;
        }
        if(sendfailed) {
            logg("!Streaming failed\n");
            nullify(ctx, cf, CF_MAIN);
            return FailAction;
        }
    }
    return SMFIS_CONTINUE;
}