Skip to content

Commit

Permalink
mod_mailscript: Add RECIPIENT condition.
Browse files Browse the repository at this point in the history
Add and document RECIPIENT condition, which corresponds to the
envelope recipient (RCPT TO address). This should have been
present when the module was initially written, as a counterpart
to the MAILFROM condition, but for some reason was not.

LBBS-54 #close
  • Loading branch information
InterLinked1 committed Sep 14, 2024
1 parent 32228e0 commit efeba84
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 19 deletions.
3 changes: 2 additions & 1 deletion configs/.rules
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@
# Note: Some conditions (e.g. RETVAL, SIZE) accept logical operators (>,>=,==,<,<=). The != operator is NOT supported; instead, use NOT before the condition in combination with ==.

# DIRECTION <IN|OUT> - direction of message. IN=incoming message for a local recipient, OUT=message sent by a local user for delivery (either locally or externally)
# MAILFROM <EQUALS|LIKE> <arg> - envelope MAIL FROM
# MAILFROM <EQUALS|LIKE> <arg> - envelope MAIL FROM (envelope sender)
# RECIPIENT <EQUALS|LIKE> <arg> - envelope RCPT TO (envelope recipient)
# HEADER <header name> <EQUALS|LIKE|EXISTS> <arg> - header in the message. Since certain headers may be duplicated (To:, Cc:, etc.), this is a match on ANY of these headers.
# FILE <file> <EXISTS> - whether a named file exists in the user's maildir. May be used for both incoming and outgoing messages.
# RETVAL (>,>=,==,<,<=) <value> - check return value of last command
Expand Down
45 changes: 28 additions & 17 deletions modules/mod_mailscript.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,27 @@ static int header_match(struct smtp_msg_process *mproc, const char *header, cons
return found;
}

static void str_match(const char *matchtype, const char *a, const char *expr, int *restrict match)
{
if (!strcasecmp(matchtype, "EQUALS")) {
*match = !strcmp(a, expr);
} else if (!strcasecmp(matchtype, "LIKE")) {
regex_t regexbuf;
int errcode;
if ((errcode = regcomp(&regexbuf, expr, REG_EXTENDED | REG_NOSUB))) {
char errbuf[256];
regerror(errcode, &regexbuf, errbuf, sizeof(errbuf));
bbs_warning("Malformed expression %s: %s\n", expr, errbuf);
} else {
bbs_debug(6, "Evaluating regex: '%s' %s\n", expr, a);
*match = regexec(&regexbuf, a, 0, NULL, 0) ? 0 : 1;
regfree(&regexbuf);
}
} else {
bbs_warning("Invalid command match type: %s\n", matchtype);
}
}

static int test_condition(struct smtp_msg_process *mproc, int lineno, int lastretval, const char *usermaildir, char *s)
{
char *next;
Expand Down Expand Up @@ -185,23 +206,13 @@ static int test_condition(struct smtp_msg_process *mproc, int lineno, int lastre
matchtype = strsep(&s, " ");
expr = s;
REQUIRE_ARG(expr);
if (!strcasecmp(matchtype, "EQUALS")) {
match = !strcmp(mproc->from, expr);
} else if (!strcasecmp(matchtype, "LIKE")) {
regex_t regexbuf;
int errcode;
if ((errcode = regcomp(&regexbuf, expr, REG_EXTENDED | REG_NOSUB))) {
char errbuf[256];
regerror(errcode, &regexbuf, errbuf, sizeof(errbuf));
bbs_warning("Malformed expression %s: %s\n", expr, errbuf);
} else {
bbs_debug(6, "Evaluating regex: '%s' %s\n", expr, mproc->from);
match = regexec(&regexbuf, mproc->from, 0, NULL, 0) ? 0 : 1;
regfree(&regexbuf);
}
} else {
bbs_warning("Invalid MAILFROM command match type: %s\n", matchtype);
}
str_match(matchtype, mproc->from, expr, &match);
} else if (!strcasecmp(next, "RECIPIENT")) {
const char *expr, *matchtype;
matchtype = strsep(&s, " ");
expr = s;
REQUIRE_ARG(expr);
str_match(matchtype, mproc->recipient, expr, &match);
} else if (!strcasecmp(next, "HEADER")) {
int found;
const char *expr, *matchtype, *header;
Expand Down
10 changes: 9 additions & 1 deletion modules/mod_smtp_delivery_local.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ static int do_local_delivery(struct smtp_session *smtp, struct smtp_response *re
struct mailbox *mbox;
struct smtp_msg_process mproc;
struct smtp_response tmpresp;
char recip_buf[256];

UNUSED(from);
UNUSED(fromlocal);
Expand Down Expand Up @@ -240,10 +241,17 @@ static int do_local_delivery(struct smtp_session *smtp, struct smtp_response *re
return -1;
}

/* recipient includes <>,
* but the mail filtering engines don't want that,
* and just want to consume the address itself.
* XXX Can be revisited if the use of variables with and without <> is ever made consistent! */
safe_strncpy(recip_buf, recipient, sizeof(recip_buf));
bbs_strterm(recip_buf, '>');

/* SMTP callbacks for incoming messages */
smtp_mproc_init(smtp, &mproc);
mproc.size = (int) datalen;
mproc.recipient = recipient;
mproc.recipient = recip_buf + 1; /* Without <> */
mproc.direction = SMTP_MSG_DIRECTION_IN;
mproc.mbox = mbox;
mproc.userid = 0;
Expand Down

0 comments on commit efeba84

Please sign in to comment.