Example #1
0
void nc_ping_entry(struct CP_ENTRY *cpe) {
    int s = nc_connect_entry(cpe);
    char *reply;

    if(s>=0 && !nc_send(s, "nPING\n", 6) && (reply = nc_recv(s))) {
	cpe->dead = strcmp(reply, "PONG\n")!=0;
	free(reply);
	close(s);
    } else cpe->dead = 1;
    return;
}
Example #2
0
sfsistat clamfi_eom(SMFICTX *ctx) {
    struct CLAMFI *cf;
    char *reply;
    int len, ret;
    unsigned int crcpt;

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

    if(!cf->totsz) {
	/* got no headers and no body */
	logg("*Not scanning an empty message\n");
	ret = CleanAction(ctx);
	nullify(ctx, cf, CF_NONE);
	free(cf);
	return ret;
    }

    if(cf->local) {
	lseek(cf->alt, 0, SEEK_SET);

	if(nc_sendmsg(cf->main, cf->alt) == -1) {
	    logg("!FD send failed\n");
	    nullify(ctx, cf, CF_ALT);
	    free(cf);
	    return FailAction;
	}
    } else {
	uint32_t sendmetoo = 0;
	cf->sendme = htonl(cf->bufsz);
	if((cf->bufsz && nc_send(cf->main, &cf->sendme, cf->bufsz + 4)) || nc_send(cf->main, &sendmetoo, 4))  {
	    logg("!Failed to flush STREAM\n");
	    nullify(ctx, cf, CF_NONE);
	    free(cf);
	    return FailAction;
	}
    }

    reply = nc_recv(cf->main);

    if(cf->local)
	close(cf->alt);

    cf->alt = -1;

    if(!reply) {
	logg("!No reply from clamd\n");
	nullify(ctx, cf, CF_NONE);
	free(cf);
	return FailAction;
    }

    len = strlen(reply);
    if(len>5 && !strcmp(reply + len - 5, ": OK\n")) {
	if(addxvirus) add_x_header(ctx, "Clean", cf->scanned_count, cf->status_count);
	if(loginfected & LOGCLN_FULL) {
	    const char *id = smfi_getsymval(ctx, "{i}");
	    const char *from = smfi_getsymval(ctx, "{mail_addr}");
	    const char *msg_subj = makesanehdr(cf->msg_subj);
	    const char *msg_date = makesanehdr(cf->msg_date);
	    const char *msg_id = makesanehdr(cf->msg_id);
	    if(multircpt && cf->nrecipients) {
		for(crcpt = 0; crcpt < cf->nrecipients; crcpt++)
		    logg("~Clean message %s from <%s> to <%s> with subject '%s' message-id '%s' date '%s'\n", id, from, cf->recipients[crcpt], msg_subj, msg_id, msg_date);
	    } else {
		const char *to = smfi_getsymval(ctx, "{rcpt_addr}");
		logg("~Clean message %s from <%s> to <%s> with subject '%s' message-id '%s' date '%s'\n", id, from, to ? to : HDR_UNAVAIL, msg_subj, msg_id, msg_date);
	    }
	} else if(loginfected & LOGCLN_BASIC) {
	    const char *from = smfi_getsymval(ctx, "{mail_addr}");
	    if(multircpt && cf->nrecipients) {
		for(crcpt = 0; crcpt < cf->nrecipients; crcpt++)
		    logg("~Clean message from <%s> to <%s>\n", from, cf->recipients[crcpt]);
	    } else {
		const char *to = smfi_getsymval(ctx, "{rcpt_addr}");
		logg("~Clean message from <%s> to <%s>\n", from, to ? to : HDR_UNAVAIL);
	    }
	}
	ret = CleanAction(ctx);
    } else if (len>7 && !strcmp(reply + len - 7, " FOUND\n")) {
	cf->virusname = NULL;
	if((loginfected & (LOGINF_BASIC | LOGINF_FULL)) || addxvirus || rejectfmt || viraction) {
	    char *vir;

	    reply[len-7] = '\0';
	    vir = strrchr(reply, ' ');
	    if(vir) {
		unsigned int have_multi = (multircpt != 0 && cf->nrecipients);
		unsigned int lst_rcpt = (have_multi * (cf->nrecipients - 1)) + 1;
		vir++;

		if(rejectfmt)
		    cf->virusname = vir;

		if(addxvirus) {
		    char msg[255];
		    snprintf(msg, sizeof(msg), "Infected (%s)", vir);
		    msg[sizeof(msg)-1] = '\0';
		    add_x_header(ctx, msg, cf->scanned_count, cf->status_count);
		}

		for(crcpt = 0; crcpt < lst_rcpt; crcpt++) {
		    if(loginfected || viraction) {
			const char *from = smfi_getsymval(ctx, "{mail_addr}");
			const char *to = have_multi ? cf->recipients[crcpt] : smfi_getsymval(ctx, "{rcpt_addr}");

			if(!from) from = HDR_UNAVAIL;
			if(!to) to = HDR_UNAVAIL;
			if((loginfected & LOGINF_FULL) || viraction) {
			    const char *id = smfi_getsymval(ctx, "{i}");
			    const char *msg_subj = makesanehdr(cf->msg_subj);
			    const char *msg_date = makesanehdr(cf->msg_date);
			    const char *msg_id = makesanehdr(cf->msg_id);

			    if(!id) id = HDR_UNAVAIL;
			
			    if(loginfected & LOGINF_FULL)
				logg("~Message %s from <%s> to <%s> with subject '%s' message-id '%s' date '%s' infected by %s\n", id, from, to, msg_subj, msg_id, msg_date, vir);

			    if(viraction) {
				char er[256];
				char *e_id = strdup(id);
				char *e_from = strdup(from);
				char *e_to = strdup(to);
				char *e_msg_subj = strdup(msg_subj);
				char *e_msg_date = strdup(msg_date);
				char *e_msg_id = strdup(msg_id);
				pid_t pid;

				logg("*VirusEvent: about to execute '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s'\n", viraction, vir, e_id, e_from, e_to, e_msg_subj, e_msg_id, e_msg_date);

				pthread_mutex_lock(&virusaction_lock);
				pid = fork();
				if(!pid) {
				    char * args[9]; /* avoid element is not computable at load time warns */
				    args[0]= viraction;
				    args[1] = vir;
				    args[2] = e_id;
				    args[3] = e_from;
				    args[4] = e_to;
				    args[5] = e_msg_subj;
				    args[6] = e_msg_id;
				    args[7] = e_msg_date;
				    args[8] = NULL;
				    exit(execvp(viraction, args));
				} else if(pid > 0) {
				    int wret;
				    pthread_mutex_unlock(&virusaction_lock);
				    while((wret = waitpid(pid, &ret, 0)) == -1 && errno == EINTR);
				    if(wret<0)
					logg("!VirusEvent: waitpid() failed: %s\n", cli_strerror(errno, er, sizeof(er)));
				    else {
					if(WIFEXITED(ret))
					    logg("*VirusEvent: child exited with code %d\n", WEXITSTATUS(ret));
					else if(WIFSIGNALED(ret))
					    logg("*VirusEvent: child killed by signal %d\n", WTERMSIG(ret));
					else
					    logg("*VirusEvent: child lost\n");
				    }
				} else {
				    logg("!VirusEvent: fork failed: %s\n", cli_strerror(errno, er, sizeof(er)));
				}
				free(e_id);
				free(e_from);
				free(e_to);
				free(e_msg_subj);
				free(e_msg_date);
				free(e_msg_id);
			    }
			}
			if(loginfected & LOGINF_BASIC)
			    logg("~Message from <%s> to <%s> infected by %s\n", from, to, vir);
		    }
		}
	    }
	}
	ret = InfectedAction(ctx);
    } else {
	logg("!Unknown reply from clamd\n");
	ret = FailAction;
    }

    nullify(ctx, cf, CF_MAIN);
    free(cf);
    free(reply);
    return ret;
}
Example #3
0
sfsistat clamfi_eom(SMFICTX *ctx) {
    struct CLAMFI *cf;
    char *reply;
    int len, ret;

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

    if(!cf->totsz) {
        /* got no headers and no body */
        logg("*Not scanning an empty message\n");
        ret = CleanAction(ctx);
        nullify(ctx, cf, CF_NONE);
        return ret;
    }

    if(cf->local) {
        if(nc_send(cf->main, "nFILDES\n", 8)) {
            logg("!FD scan request failed\n");
            nullify(ctx, cf, CF_ALT);
            return FailAction;
        }

        lseek(cf->alt, 0, SEEK_SET);

        if(nc_sendmsg(cf->main, cf->alt) == -1) {
            logg("!FD send failed\n");
            nullify(ctx, cf, CF_ALT);
            return FailAction;
        }
    } else {
        if(cf->bufsz && nc_send(cf->alt, cf->buffer, cf->bufsz)) {
            logg("!Failed to flush STREAM\n");
            nullify(ctx, cf, CF_MAIN);
            return FailAction;
        }
        close(cf->alt);
    }

    reply = nc_recv(cf->main);

    if(cf->local)
        close(cf->alt);

    cf->alt = -1;

    if(!reply) {
        logg("!No reply from clamd\n");
        nullify(ctx, cf, CF_NONE);
        return FailAction;
    }

    len = strlen(reply);
    if(len>5 && !strcmp(reply + len - 5, ": OK\n")) {
        if(addxvirus) add_x_header(ctx, "Clean", cf->scanned_count, cf->status_count);
        ret = CleanAction(ctx);
    } else if (len>7 && !strcmp(reply + len - 7, " FOUND\n")) {
        cf->virusname = NULL;
        if(loginfected || addxvirus || rejectfmt) {
            char *vir;

            reply[len-7] = '\0';
            vir = strrchr(reply, ' ');
            if(vir) {
                vir++;

                if(rejectfmt)
                    cf->virusname = vir;

                if(addxvirus) {
                    char msg[255];
                    snprintf(msg, sizeof(msg), "Infected (%s)", vir);
                    msg[sizeof(msg)-1] = '\0';
                    add_x_header(ctx, msg, cf->scanned_count, cf->status_count);
                }

                if(loginfected) {
                    const char *from = smfi_getsymval(ctx, "{mail_addr}");
                    const char *to = smfi_getsymval(ctx, "{rcpt_addr}");

                    if(!from) from = HDR_UNAVAIL;
                    if(!to) to = HDR_UNAVAIL;
                    if(loginfected == LOGINF_FULL) {
                        const char *id = smfi_getsymval(ctx, "{i}");
                        const char *msg_subj = makesanehdr(cf->msg_subj);
                        const char *msg_date = makesanehdr(cf->msg_date);
                        const char *msg_id = makesanehdr(cf->msg_id);

                        if(!id) id = HDR_UNAVAIL;
                        logg("~Message %s from <%s> to <%s> with subject '%s' message-id '%s' date '%s' infected by %s\n", id, from, to, msg_subj, msg_id, msg_date, vir);
                    } else logg("~Message from <%s> to <%s> infected by %s\n", from, to, vir);
                }
            }
        }
        ret = InfectedAction(ctx);
    } else {
        logg("!Unknown reply from clamd\n");
        ret = FailAction;
    }

    nullify(ctx, cf, CF_MAIN);

    free(reply);
    return ret;
}