Пример #1
0
int
msgmod_change_header(void *ctx, int argc, var_t *args[])
{
	char *headerf;
	char *headerv;
	long index = 1;

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

	headerf = args[0]->v_data;
	headerv = args[1]->v_data;

	if (argc == 3)
	{
		index = atol(args[2]->v_data);
	}

	if (smfi_chgheader(ctx, headerf, index, headerv) != MI_SUCCESS)
	{
		log_error("msgmod_change_header: smfi_chgheader failed");
		return -1;
	}

	log_debug("msgmod_change_header: %s: %s (%d)", headerf, headerv,
		index);

	return 0;
}
Пример #2
0
static void add_x_header(SMFICTX *ctx, char *st, unsigned int scanned, unsigned int status) {
    if(addxvirus == 1) { /* Replace/Yes */
	while(scanned)
	    if(smfi_chgheader(ctx, (char *)"X-Virus-Scanned", scanned--, NULL) != MI_SUCCESS)
		logg("^Failed to remove existing X-Virus-Scanned header\n");
	while(status)
	    if(smfi_chgheader(ctx, (char *)"X-Virus-Status", status--, NULL) != MI_SUCCESS)
		logg("^Failed to remove existing X-Virus-Status header\n");
	if(smfi_addheader(ctx, (char *)"X-Virus-Scanned", xvirushdr) != MI_SUCCESS)
	    logg("^Failed to add X-Virus-Scanned header\n");
	if(smfi_addheader(ctx, (char *)"X-Virus-Status", st) != MI_SUCCESS)
	    logg("^Failed to add X-Virus-Status header\n");
    } else { /* Add */
	if(smfi_insheader(ctx, 1, (char *)"X-Virus-Scanned", xvirushdr) != MI_SUCCESS)
	    logg("^Failed to insert X-Virus-Scanned header\n");
	if(smfi_insheader(ctx, 1, (char *)"X-Virus-Status", st) != MI_SUCCESS)
	    logg("^Failed to insert X-Virus-Status header\n");
    }
}
Пример #3
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));
}
Пример #4
0
	/*}}}*/
}	priv_t;
static char *
xfree (char *s) /*{{{*/
{
	if (s)
		free (s);
	return NULL;
}/*}}}*/
static bool_t
xcopy (char **buf, const char *str) /*{{{*/
{
	if (*buf)
		free (*buf);
	*buf = str ? strdup (str) : NULL;
	return (! str) || *buf ? true : false;
}/*}}}*/
static void
priv_clear (priv_t *p) /*{{{*/
{
	if (p) {
		p -> x_agn = 0;
		p -> from = xfree (p -> from);
		p -> receiver = charc_free_all (p -> receiver);
		p -> prev = NULL;
		p -> info = xfree (p -> info);
	}
}/*}}}*/
static priv_t *
priv_free (priv_t *p) /*{{{*/
{
	if (p) {
		priv_clear (p);
		if (p -> lg)
			log_free (p -> lg);
		if (p -> cfg)
			cfg_free (p -> cfg);
		free (p);
	}
	return NULL;
}/*}}}*/
static priv_t *
priv_alloc (void) /*{{{*/
{
	priv_t	*p;
	
	if (p = (priv_t *) malloc (sizeof (priv_t)))
		if (p -> cfg = cfg_alloc (cfgfile)) {
			p -> is_local = false;
			p -> x_agn = 0;
			p -> from = NULL;
			p -> receiver = NULL;
			p -> prev = NULL;
			p -> info = NULL;
			if (! (p -> lg = log_alloc (NULL, program, loglevel)))
				p = priv_free (p);
		} else {
			free (p);
			p = NULL;
		}
	return p;
}/*}}}*/
static bool_t
priv_setfrom (priv_t *p, const char *from) /*{{{*/
{
	return xcopy (& p -> from, from);
}/*}}}*/
static bool_t
priv_setto (priv_t *p, const char *to) /*{{{*/
{
	charc_t	*r;
	
	if (r = charc_alloc (to)) {
		if (p -> prev)
			p -> prev -> next = r;
		else
			p -> receiver = r;
		p -> prev = r;
	}
	return r ? true : false;
}/*}}}*/
static bool_t
priv_addinfo (priv_t *p, const char *info) /*{{{*/
{
	char	*temp;

	if ((! p -> info) || (! p -> info[0]))
		return xcopy (& p -> info, info);
	if (temp = malloc (strlen (p -> info) + strlen (info) + 2)) {
		sprintf (temp, "%s,%s", p -> info, info);
		free (p -> info);
		p -> info = temp;
		return true;
	}
	return false;
}/*}}}*/
static bool_t
priv_addinfopair (priv_t *p, const char *var, const char *val) /*{{{*/
{
	bool_t	rc;
	char	*scratch, *ptr;
	
	if (scratch = malloc (strlen (var) + strlen (val) + 2)) {
		for (ptr = scratch; *var; *ptr++ = *var++)
			;
		*ptr++ = '=';
		for (;*val; ++val)
			*ptr++ = *val == ',' ? '_' : *val;
		*ptr = '\0';
		rc = priv_addinfo (p, scratch);
		free (scratch);
	} else
		rc = false;
	return rc;
}/*}}}*/

static sfsistat
handle_connect (SMFICTX *ctx, char  *hostname, _SOCK_ADDR *hostaddr) /*{{{*/
{
	priv_t	*p;

	if (! (p = priv_alloc ()))
		return SMFIS_TEMPFAIL;
	if (hostaddr -> sa_family == AF_INET) {
		struct sockaddr_in	*iaddr = (struct sockaddr_in *) hostaddr;

		if (ntohl (iaddr -> sin_addr.s_addr) == INADDR_LOOPBACK)
			p -> is_local = true;
	}
# ifdef		AF_INET6
	else if (hostaddr -> sa_family == AF_INET6) {
		struct sockaddr_in6	*i6addr = (struct sockaddr_in6 *) hostaddr;
		static struct in6_addr	loopback = IN6ADDR_LOOPBACK_INIT;
		
		if (memcmp (& i6addr -> sin6_addr, & loopback, sizeof (i6addr -> sin6_addr)) == 0)
			p -> is_local = true;
	}
# endif		/* AF_INET6 */
	smfi_setpriv (ctx, p);
	return SMFIS_CONTINUE;
}/*}}}*/
static sfsistat
handle_from (SMFICTX *ctx, char **argv) /*{{{*/
{
	priv_t	*p = (priv_t *) smfi_getpriv (ctx);
	
	if (! p)
		return SMFIS_TEMPFAIL;
	priv_clear (p);
	if (! priv_setfrom (p, argv[0]))
		return SMFIS_TEMPFAIL;
	priv_addinfopair (p, "from", argv[0]);
	return SMFIS_CONTINUE;
}/*}}}*/
static sfsistat
handle_to (SMFICTX *ctx, char **argv) /*{{{*/
{
	priv_t	*p = (priv_t *) smfi_getpriv (ctx);
	char	*chk, *opt;
	bool_t	reject, tempfail;
	
	if (! p)
		return SMFIS_TEMPFAIL;
	if (p -> is_local)
		return SMFIS_CONTINUE;
	if (! (chk = cfg_valid_address (p -> cfg, argv[0]))) {
		log_out (p -> lg, LV_ERROR, "Unable to setup initial data for `%s'", argv[0]);
		return SMFIS_TEMPFAIL;
	}
	if (opt = strchr (chk, ':'))
		*opt++ = '\0';
	reject = false;
	tempfail = false;
	if (! strcmp (chk, ID_REJECT))
		reject = true;
	else if (! strcmp (chk, ID_TEMPFAIL))
		tempfail = true;
	else if ((! strcmp (chk, ID_ACCEPT)) && opt)
		priv_addinfo (p, opt);
	priv_addinfopair (p, "to", argv[0]);
	free (chk);
	if (reject) {
		log_out (p -> lg, LV_INFO, "Receiver `%s' is rejected", argv[0]);
		smfi_setreply (ctx, (char *) "550", (char *) "5.1.1", (char *) "No such user");
		return SMFIS_REJECT;
	}
	if (tempfail) {
		log_out (p -> lg, LV_INFO, "Receiver `%s' is temp. disbaled", argv[0]);
		smfi_setreply (ctx, (char *) "400", (char *) "4.0.0", (char *) "Please try again later");
		return SMFIS_TEMPFAIL;
	}
	if (! priv_setto (p, argv[0]))
		return SMFIS_TEMPFAIL;
	return SMFIS_CONTINUE;
}/*}}}*/
static sfsistat
handle_header (SMFICTX *ctx, char *field, char *value) /*{{{*/
{
	priv_t	*p = (priv_t *) smfi_getpriv (ctx);

	if (! p)
		return SMFIS_TEMPFAIL;
	if (p -> is_local)
		return SMFIS_CONTINUE;
	if (! strcasecmp (field, X_LOOP)) {
		log_out (p -> lg, LV_WARNING, "Mail from `%s' has already loop marker set, rejected", p -> from);
		smfi_setreply (ctx, (char *) "500", (char *) "5.4.6", (char *) "Loop detected");
		return SMFIS_REJECT;
	}
	if (! strcasecmp (field, X_AGN))
		p -> x_agn++;
	return SMFIS_CONTINUE;
}/*}}}*/
static sfsistat
handle_eom (SMFICTX *ctx) /*{{{*/
{
	priv_t	*p = (priv_t *) smfi_getpriv (ctx);
	int	n;
	
	if (! p)
		return SMFIS_TEMPFAIL;
	for (n = 0; n < p -> x_agn; ++n)
		smfi_chgheader (ctx, (char *) X_AGN, 0, NULL);
	if (! p -> is_local) {
		if (p -> info)
			smfi_addheader (ctx, (char *) X_AGN, p -> info);
		smfi_addheader (ctx, (char *) X_LOOP, (char *) LOOP_SET);
	}
	return SMFIS_CONTINUE;
}/*}}}*/
Пример #5
0
int
msgmod_delete_header(void *ctx, int argc, var_t *args[])
{
	char *headerf;

	if (argc != 1)
	{
		log_error("msgmod_delete_header: bad argument count");
		return -1;
	}

	headerf = args[0]->v_data;

	if (smfi_chgheader(ctx, headerf, 1, NULL) != MI_SUCCESS)
	{
		log_error("msgmod_delete_header: smfi_chgheader failed");
		return -1;
	}

	log_debug("msgmod_delete_header: %s (1)", headerf);

	return 0;
}