]> git.pld-linux.org Git - packages/exim.git/blob - messageid.patch
78c06319f5a1a26e1c2c5aebace2f81ba86a64e5
[packages/exim.git] / messageid.patch
1 From 889894461aa958da4604299acc161c29e2aa603c Mon Sep 17 00:00:00 2001
2 From: Jeremy Harris <jgh146exb@wizmail.org>
3 Date: Sun, 5 Sep 2021 11:32:09 +0100
4 Subject: [PATCH] Fix validation of domain-literals in Message_ID: headers. 
5  Bug 2805
6
7 ---
8  src/src/parse.c              | 34 +++++++++++++++++++++-------------
9  src/src/receive.c            |  3 ++-
10  5 files changed, 43 insertions(+), 20 deletions(-)
11
12 diff --git a/src/src/parse.c b/src/src/parse.c
13 index 58f8941..42f1234 100644
14 --- a/src/src/parse.c
15 +++ b/src/src/parse.c
16 @@ -224,16 +224,20 @@ If allow_domain_literals is TRUE, a "domain" may also be an IP address enclosed
17  in []. Make sure the output is set to the null string if there is a syntax
18  error as well as if there is no domain at all.
19  
20 +Optionally, msg_id domain literals ( printable-ascii enclosed in [] )
21 +are permitted.
22 +
23  Arguments:
24    s          current character pointer
25    t          where to put the domain
26 +  msg_id_literals     flag for relaxed domain-literal processing
27    errorptr   put error message here on failure (*t will be 0 on exit)
28  
29  Returns:     new character pointer
30  */
31  
32  static const uschar *
33 -read_domain(const uschar *s, uschar *t, uschar **errorptr)
34 +read_domain(const uschar *s, uschar *t, BOOL msg_id_literals, uschar **errorptr)
35  {
36  uschar *tt = t;
37  s = skip_comment(s);
38 @@ -259,7 +263,11 @@ if (*s == '[')
39      t += 5;
40      s += 5;
41      }
42 -  while (*s == '.' || *s == ':' || isxdigit(*s)) *t++ = *s++;
43 +
44 +  if (msg_id_literals)
45 +    while (*s >= 33 && *s <= 90 || *s >= 94 && *s <= 126) *t++ = *s++;
46 +  else
47 +    while (*s == '.' || *s == ':' || isxdigit(*s)) *t++ = *s++;
48  
49    if (*s == ']') *t++ = *s++; else
50      {
51 @@ -267,7 +275,7 @@ if (*s == '[')
52      *tt = 0;
53      }
54  
55 -  if (!allow_domain_literals)
56 +  if (!allow_domain_literals && !msg_id_literals)
57      {
58      *errorptr = US"domain literals not allowed";
59      *tt = 0;
60 @@ -500,7 +508,7 @@ BOOL commas = FALSE;
61  while (*s == '@')
62    {
63    *t++ = '@';
64 -  s = read_domain(s+1, t, errorptr);
65 +  s = read_domain(s+1, t, FALSE, errorptr);
66    if (*t == 0) return s;
67    t += Ustrlen((const uschar *)t);
68    if (*s != ',') break;
69 @@ -559,7 +567,7 @@ if (*errorptr == NULL)
70        t += Ustrlen((const uschar *)t);
71        *t++ = *s++;
72        *domainptr = t;
73 -      s = read_domain(s, t, errorptr);
74 +      s = read_domain(s, t, FALSE, errorptr);
75        }
76  return s;
77  }
78 @@ -649,7 +657,7 @@ if (*s != '@' && *s != '<')
79    {
80    if (*s == 0 || *s == ';')
81      {
82 -    if (*t == 0) FAILED(US"empty address");
83 +    if (!*t) FAILED(US"empty address");
84      endptr = last_comment_position;
85      goto PARSE_SUCCEEDED;              /* Bare local part */
86      }
87 @@ -740,7 +748,7 @@ if (*s == '<')
88      }
89  
90    endptr = s;
91 -  if (*errorptr != NULL) goto PARSE_FAILED;
92 +  if (*errorptr) goto PARSE_FAILED;
93    while (bracket_count-- > 0) if (*s++ != '>')
94      {
95      *errorptr = s[-1] == 0
96 @@ -759,14 +767,14 @@ should be the domain. However, for flexibility we allow for a route-address
97  not enclosed in <> as well, which is indicated by an empty first local
98  part preceding '@'. The source routing is, however, ignored. */
99  
100 -else if (*t == 0)
101 +else if (!*t)
102    {
103    uschar *domainptr = yield;
104    s = read_route(s, t, errorptr);
105 -  if (*errorptr != NULL) goto PARSE_FAILED;
106 +  if (*errorptr) goto PARSE_FAILED;
107    *t = 0;         /* Ensure route is ignored - probably overkill */
108    s = read_addr_spec(s, t, 0, errorptr, &domainptr);
109 -  if (*errorptr != NULL) goto PARSE_FAILED;
110 +  if (*errorptr) goto PARSE_FAILED;
111    *domain = domainptr - yield;
112    endptr = last_comment_position;
113    if (*domain == 0) FAILED(US"domain missing in source-routed address");
114 @@ -779,8 +787,8 @@ else
115    t += Ustrlen((const uschar *)t);
116    *t++ = *s++;
117    *domain = t - yield;
118 -  s = read_domain(s, t, errorptr);
119 -  if (*t == 0) goto PARSE_FAILED;
120 +  s = read_domain(s, t, TRUE, errorptr);
121 +  if (!*t) goto PARSE_FAILED;
122    endptr = last_comment_position;
123    }
124  
125 @@ -789,7 +797,7 @@ through for other cases. Endptr may have been moved over whitespace, so
126  move it back past white space if necessary. */
127  
128  PARSE_SUCCEEDED:
129 -if (*s != 0)
130 +if (*s)
131    {
132    if (f.parse_found_group && *s == ';')
133      {
134 diff --git a/src/src/receive.c b/src/src/receive.c
135 index c2b313c..5471aa7 100644
136 --- a/src/src/receive.c
137 +++ b/src/src/receive.c
138 @@ -1663,7 +1663,6 @@ int  process_info_len = Ustrlen(process_info);
139  int  error_rc = error_handling == ERRORS_SENDER
140         ? errors_sender_rc : EXIT_FAILURE;
141  int  header_size = 256;
142 -int  start, end, domain;
143  int  id_resolution = 0;
144  int  had_zero = 0;
145  int  prevlines_length = 0;
146 @@ -4084,6 +4083,8 @@ if (  LOGGING(msg_id) && msgid_header
147    uschar * old_id;
148    BOOL save_allow_domain_literals = allow_domain_literals;
149    allow_domain_literals = TRUE;
150 +  int start, end, domain;
151 +
152    old_id = parse_extract_address(Ustrchr(msgid_header->text, ':') + 1,
153      &errmsg, &start, &end, &domain, FALSE);
154    allow_domain_literals = save_allow_domain_literals;
155
This page took 0.028356 seconds and 2 git commands to generate.