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; }
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; }
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; }