Beispiel #1
0
void dupe_action(SMFICTX *ctx, mlfiPriv *priv)
{
	if(ctx != NULL && priv != NULL && priv->pdupercpt != NULL)
	{
		smfi_addrcpt(ctx, priv->pdupercpt);
		free(priv->pdupercpt);
		priv->pdupercpt = NULL;
	}
}
Beispiel #2
0
static sfsistat test_eom(SMFICTX *ctx)
{
    printf("test_eom\n");
#ifdef SMFIR_REPLBODY
    if (body_file) {
	char    buf[BUFSIZ + 2];
	FILE   *fp;
	size_t  len;
	int     count;

	if ((fp = fopen(body_file, "r")) == 0) {
	    perror(body_file);
	} else {
	    printf("replace body with content of %s\n", body_file);
	    for (count = 0; fgets(buf, BUFSIZ, fp) != 0; count++) {
		len = strcspn(buf, "\n");
		buf[len + 0] = '\r';
		buf[len + 1] = '\n';
		if (smfi_replacebody(ctx, buf, len + 2) == MI_FAILURE) {
		    fprintf(stderr, "body replace failure\n");
		    exit(1);
		}
		if (verbose)
		    printf("%.*s\n", (int) len, buf);
	    }
	    if (count == 0)
		perror("fgets");
	    (void) fclose(fp);
	}
    }
#endif
#ifdef SMFIR_CHGFROM
    if (chg_from != 0 && smfi_chgfrom(ctx, chg_from, "whatever") == MI_FAILURE)
	fprintf(stderr, "smfi_chgfrom failed\n");
#endif
#ifdef SMFIR_INSHEADER
    if (ins_hdr && smfi_insheader(ctx, ins_idx, ins_hdr, ins_val) == MI_FAILURE)
	fprintf(stderr, "smfi_insheader failed\n");
#endif
#ifdef SMFIR_CHGHEADER
    if (chg_hdr && smfi_chgheader(ctx, chg_hdr, chg_idx, chg_val) == MI_FAILURE)
	fprintf(stderr, "smfi_chgheader failed\n");
#endif
    {
	int     count;

	for (count = 0; count < rcpt_count; count++)
	    if (smfi_addrcpt(ctx, rcpt_addr[count]) == MI_FAILURE)
		fprintf(stderr, "smfi_addrcpt `%s' failed\n", rcpt_addr[count]);
    }
    return (test_reply(ctx, test_eom_reply));
}
Beispiel #3
0
int
msgmod_add_rcpt(void *ctx, int argc, var_t *args[])
{
	char *rcpt;
	char *esmtp_args = NULL;
	int r;

	if (argc < 1 || argc > 2)
	{
		log_error("msgmod_add_rcpt: bad argument count");
		return -1;
	}

	rcpt = args[0]->v_data;

	if (argc == 2)
	{
		esmtp_args = args[1]->v_data;
		r = smfi_addrcpt_par(ctx, rcpt, esmtp_args);
	}
	else
	{
		r = smfi_addrcpt(ctx, rcpt);
	}

	if (r != MI_SUCCESS)
	{
		log_error("msgmod_add_rcpt: smfi_addrcpt failed");
		return -1;
	}

	log_debug("msgmod_add_rcpt: %s %s", rcpt,
		esmtp_args? esmtp_args: "");

	return 0;
}
Beispiel #4
0
int 
spamdscan(SMFICTX *ctx, struct mlfi_priv *priv, struct config_file *cfg, char **subject, int extra)
{
	int retry, r = -2, hr = 0, to_trace = 0;
	struct timeval t;
	double ts, tf;
	struct spamd_server *selected = NULL;
	char rbuf[BUFSIZ], hdrbuf[BUFSIZ];
	char *prefix = "s", *mid = NULL, *c;
	rspamd_result_t res;
	struct rspamd_metric_result *cur = NULL, *tmp;
	struct rspamd_symbol *cur_symbol, *tmp_symbol;
	enum rspamd_metric_action res_action = METRIC_ACTION_NOACTION;
	struct timespec sleep_ts;
	

	gettimeofday(&t, NULL);
	ts = t.tv_sec + t.tv_usec / 1000000.0;
	retry = cfg->spamd_retry_count;
	sleep_ts.tv_sec = cfg->spamd_retry_timeout / 1000;
	sleep_ts.tv_nsec = (cfg->spamd_retry_timeout % 1000) * 1000000ULL;

	TAILQ_INIT(&res);

	/* try to scan with available servers */
	while (1) {
		if (extra) {
			selected = (struct spamd_server *) get_random_upstream ((void *)cfg->extra_spamd_servers,
					cfg->extra_spamd_servers_num, sizeof (struct spamd_server),
					t.tv_sec, cfg->spamd_error_time, cfg->spamd_dead_time, cfg->spamd_maxerrors);
		}
		else {
			selected = (struct spamd_server *) get_random_upstream ((void *)cfg->spamd_servers,
					cfg->spamd_servers_num, sizeof (struct spamd_server),
					t.tv_sec, cfg->spamd_error_time, cfg->spamd_dead_time, cfg->spamd_maxerrors);
		}
		if (selected == NULL) {
			msg_err ("spamdscan: upstream get error, %s", priv->file);
			return -1;
		}
		
		if (selected->type == SPAMD_SPAMASSASSIN) {
			prefix = "s";
			r = spamdscan_socket (priv->file, selected, cfg, &res);
		}
		else {
			prefix = "rs";
			r = rspamdscan_socket (ctx, priv, selected, cfg, &res, &mid);
		}
		if (r == 0 || r == 1) {
			upstream_ok (&selected->up, t.tv_sec);
			break;
		}
		upstream_fail (&selected->up, t.tv_sec);
		if (r == -2) {
			msg_warn("%spamdscan: unexpected problem, %s, %s", prefix, selected->name, priv->file);
			break;
		}
		if (--retry < 1) {
			msg_warn("%spamdscan: retry limit exceeded, %s, %s", prefix, selected->name, priv->file);
			break;
		}

		msg_warn("%spamdscan: failed to scan, retry, %s, %s", prefix, selected->name, priv->file);
		nanosleep (&sleep_ts, NULL);
	}

	/*
	 * print scanning time, server and result
	 */
	gettimeofday(&t, NULL);
	tf = t.tv_sec + t.tv_usec / 1000000.0;
	
	/* Parse res tailq */
	cur = TAILQ_FIRST(&res);
	while (cur) {
		if (cur->metric_name) {
			if (cfg->extended_spam_headers) {
				hr = snprintf (hdrbuf, sizeof (hdrbuf), "%s: %s [%.2f / %.2f]%c",
						cur->metric_name,
						cur->score > cur->required_score ? "True" : "False",
						cur->score,
						cur->required_score,
						TAILQ_FIRST(&cur->symbols) != NULL ? '\n' : ' ');
			}
			r = snprintf (rbuf, sizeof (rbuf), "spamdscan: scan qid: <%s>, mid: <%s>, %f, %s, metric: %s: [%f / %f], symbols: ",
					priv->mlfi_id,
					(mid != NULL) ? mid : "undef",
					tf - ts,
					selected->name,
					cur->metric_name,
					cur->score,
					cur->required_score);
			free (cur->metric_name);
		}
		else {
			if (cfg->extended_spam_headers) {
				hr = snprintf (hdrbuf, sizeof (hdrbuf), "%s: %s [%.2f / %.2f]%c",
						"default",
						cur->score > cur->required_score ? "True" : "False",
						cur->score,
						cur->required_score,
						TAILQ_FIRST(&cur->symbols) != NULL ? '\n' : ' ');
			}
			r = snprintf (rbuf, sizeof (rbuf), "spamdscan: scan <%s>, %f, %s, metric: default: [%f / %f], symbols: ",
					priv->mlfi_id,
					tf - ts,
					selected->name,
					cur->score,
					cur->required_score);
		
		}
		if (cur->action > res_action) {
			res_action = cur->action;
			if (res_action == METRIC_ACTION_REWRITE_SUBJECT && cur->subject != NULL) {
				/* Copy subject as it would be freed further */
				if (*subject != NULL) {
					free (*subject);
				}
				*subject = strdup (cur->subject);
			}
		}
		/* Write symbols */
		cur_symbol = TAILQ_FIRST(&cur->symbols);
		if (cur_symbol == NULL) {
			r += snprintf (rbuf + r, sizeof (rbuf) - r, "no symbols");
		}
		else {
			while (cur_symbol) {
				if (cur_symbol->symbol) {
					if (TAILQ_NEXT (cur_symbol, entry)) {
						r += snprintf (rbuf + r, sizeof (rbuf) - r, "%s, ", cur_symbol->symbol);
					}
					else {
						r += snprintf (rbuf + r, sizeof (rbuf) - r, "%s", cur_symbol->symbol);
					}
					if (cfg->trace_symbol) {
						c = strchr (cur_symbol->symbol, '(');
						if (c != NULL) {
							*c = '\0';
						}
						if ( !strcmp (cfg->trace_symbol, cur_symbol->symbol)) {
							to_trace ++;
						}
					}
					if (cfg->extended_spam_headers) {
						if (TAILQ_NEXT (cur_symbol, entry)) {
							hr += snprintf (hdrbuf + hr, sizeof (hdrbuf) - hr, " %s\n",
									cur_symbol->symbol);
						}
						else {
							hr += snprintf (hdrbuf + hr, sizeof (hdrbuf) - hr, " %s",
									cur_symbol->symbol);
						}
					}
					free (cur_symbol->symbol);
				}
				tmp_symbol = cur_symbol;
				cur_symbol = TAILQ_NEXT(cur_symbol, entry);
				free (tmp_symbol);
			}
		}
		msg_info ("%s", rbuf);
		if (cur->subject != NULL) {
			free (cur->subject);
		}

		tmp = cur;
		cur = TAILQ_NEXT(cur, entry);

		free (tmp);
		if (cfg->extended_spam_headers) {
			if (extra) {
				smfi_addheader (ctx, "X-Spamd-Extra-Result", hdrbuf);
			}
			else {
				smfi_addheader (ctx, "X-Spamd-Result", hdrbuf);
			}
		}
	}
	/* All other statistic headers */
	if (cfg->extended_spam_headers) {
		if (extra) {
			smfi_addheader (ctx, "X-Spamd-Extra-Server", selected->name);
			snprintf (hdrbuf, sizeof (hdrbuf), "%.2f", tf - ts);
			smfi_addheader (ctx, "X-Spamd-Extra-Scan-Time", hdrbuf);
		}
		else {
			smfi_addheader (ctx, "X-Spamd-Server", selected->name);
			snprintf (hdrbuf, sizeof (hdrbuf), "%.2f", tf - ts);
			smfi_addheader (ctx, "X-Spamd-Scan-Time", hdrbuf);
			smfi_addheader (ctx, "X-Spamd-Queue-ID", priv->mlfi_id);
		}
	}
	/* Trace spam messages to specific addr */
	if (!extra && to_trace && cfg->trace_addr) {
		smfi_addrcpt (ctx, cfg->trace_addr);
		smfi_setpriv (ctx, priv);
	}


	return (r > 0 ? res_action : r);
}