summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2017-01-30 15:37:50 +0000
committerJeremy Harris <jgh146exb@wizmail.org>2017-01-30 15:37:50 +0000
commitb6040544759110aa97f93e9ba0dd8232cd5e5188 (patch)
tree434104aa65999ada411681a92dd83db0b368761e
parent9e7e0f6a60dea9e21aac8b4ea5f8725bdc52a743 (diff)
downloadexim4-b6040544759110aa97f93e9ba0dd8232cd5e5188.tar.gz
Restrict address-parsing to a maximum of five layers of nested angle-brackets,
under main-option strip_excess_angle_brackets
-rw-r--r--doc/doc-txt/ChangeLog4
-rw-r--r--src/src/parse.c24
2 files changed, 18 insertions, 10 deletions
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index a4c11e58d..bc9b19f19 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -69,6 +69,10 @@ JH/14 Bug 2000: Reject messages recieved with CHUNKING but with malformed line
endings, at least on the first header line. Try to canonify any that get
past that check, despite the cost.
+JH/15 Angle-bracket nesting (an error inserted by broken sendmails) levels are
+ now limited to an arbitrary five deep, while parsing addresses with the
+ strip_excess_angle_brackets option enabled.
+
Exim version 4.88
-----------------
diff --git a/src/src/parse.c b/src/src/parse.c
index 3f0823a1e..b2771b5b8 100644
--- a/src/src/parse.c
+++ b/src/src/parse.c
@@ -661,7 +661,7 @@ if (*s != '@' && *s != '<')
while (*s != '<' && (!parse_allow_group || *s != ':'))
{
s = read_local_part(s, t, errorptr, FALSE);
- if (*errorptr != NULL)
+ if (*errorptr)
{
*errorptr = string_sprintf("%s (expected word or \"<\")", *errorptr);
goto PARSE_FAILED;
@@ -686,8 +686,8 @@ processing it. Note that this is "if" rather than "else if" because it's also
used after reading a preceding phrase.
There are a lot of broken sendmails out there that put additional pairs of <>
-round <route-addr>s. If strip_excess_angle_brackets is set, allow any number of
-them, as long as they match. */
+round <route-addr>s. If strip_excess_angle_brackets is set, allow a limited
+number of them, as long as they match. */
if (*s == '<')
{
@@ -696,8 +696,11 @@ if (*s == '<')
int bracket_count = 1;
s++;
- if (strip_excess_angle_brackets)
- while (*s == '<') { bracket_count++; s++; }
+ if (strip_excess_angle_brackets) while (*s == '<')
+ {
+ if(bracket_count++ > 5) FAILED(US"angle-brackets nested too deep");
+ s++;
+ }
t = yield;
startptr = s;
@@ -711,7 +714,7 @@ if (*s == '<')
if (*s == '@')
{
s = read_route(s, t, errorptr);
- if (*errorptr != NULL) goto PARSE_FAILED;
+ if (*errorptr) goto PARSE_FAILED;
*t = 0; /* Ensure route is ignored - probably overkill */
source_routed = TRUE;
}
@@ -729,7 +732,7 @@ if (*s == '<')
else
{
s = read_addr_spec(s, t, '>', errorptr, &domainptr);
- if (*errorptr != NULL) goto PARSE_FAILED;
+ if (*errorptr) goto PARSE_FAILED;
*domain = domainptr - yield;
if (source_routed && *domain == 0)
FAILED(US"domain missing in source-routed address");
@@ -739,9 +742,10 @@ if (*s == '<')
if (*errorptr != NULL) goto PARSE_FAILED;
while (bracket_count-- > 0) if (*s++ != '>')
{
- *errorptr = (s[-1] == 0)? US"'>' missing at end of address" :
- string_sprintf("malformed address: %.32s may not follow %.*s",
- s-1, s - (uschar *)mailbox - 1, mailbox);
+ *errorptr = s[-1] == 0
+ ? US"'>' missing at end of address"
+ : string_sprintf("malformed address: %.32s may not follow %.*s",
+ s-1, s - (uschar *)mailbox - 1, mailbox);
goto PARSE_FAILED;
}