Blame


1 40cd76f4 2020-08-30 martijn /*
2 40cd76f4 2020-08-30 martijn * Copyright (c) 2020 Martijn van Duren <martijn@openbsd.org>
3 40cd76f4 2020-08-30 martijn *
4 40cd76f4 2020-08-30 martijn * Permission to use, copy, modify, and distribute this software for any
5 40cd76f4 2020-08-30 martijn * purpose with or without fee is hereby granted, provided that the above
6 40cd76f4 2020-08-30 martijn * copyright notice and this permission notice appear in all copies.
7 40cd76f4 2020-08-30 martijn *
8 40cd76f4 2020-08-30 martijn * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 40cd76f4 2020-08-30 martijn * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 40cd76f4 2020-08-30 martijn * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 40cd76f4 2020-08-30 martijn * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 40cd76f4 2020-08-30 martijn * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 40cd76f4 2020-08-30 martijn * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 40cd76f4 2020-08-30 martijn * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 40cd76f4 2020-08-30 martijn */
16 40cd76f4 2020-08-30 martijn
17 40cd76f4 2020-08-30 martijn #include <ctype.h>
18 40cd76f4 2020-08-30 martijn #include <errno.h>
19 40cd76f4 2020-08-30 martijn #include <stddef.h>
20 40cd76f4 2020-08-30 martijn #include <string.h>
21 40cd76f4 2020-08-30 martijn #include <strings.h>
22 40cd76f4 2020-08-30 martijn
23 40cd76f4 2020-08-30 martijn #include "mheader.h"
24 40cd76f4 2020-08-30 martijn
25 60e9f82d 2022-01-27 martijn #include <stdio.h>
26 40cd76f4 2020-08-30 martijn char *
27 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_sp(char *ptr, int optional)
28 40cd76f4 2020-08-30 martijn {
29 40cd76f4 2020-08-30 martijn if (ptr[0] == 0x20)
30 40cd76f4 2020-08-30 martijn return ptr + 1;
31 40cd76f4 2020-08-30 martijn return optional ? ptr : NULL;
32 40cd76f4 2020-08-30 martijn }
33 40cd76f4 2020-08-30 martijn
34 40cd76f4 2020-08-30 martijn char *
35 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_htab(char *ptr, int optional)
36 40cd76f4 2020-08-30 martijn {
37 40cd76f4 2020-08-30 martijn if (ptr[0] == 0x9)
38 40cd76f4 2020-08-30 martijn return ptr + 1;
39 40cd76f4 2020-08-30 martijn return optional ? ptr : NULL;
40 40cd76f4 2020-08-30 martijn }
41 40cd76f4 2020-08-30 martijn
42 40cd76f4 2020-08-30 martijn char *
43 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_wsp(char *ptr, int optional)
44 40cd76f4 2020-08-30 martijn {
45 40cd76f4 2020-08-30 martijn char *start = ptr;
46 40cd76f4 2020-08-30 martijn
47 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_sp(start, 0)) != NULL ||
48 40cd76f4 2020-08-30 martijn (ptr = osmtpd_mheader_skip_htab(start, 0)) != NULL)
49 40cd76f4 2020-08-30 martijn return ptr;
50 40cd76f4 2020-08-30 martijn return optional ? ptr : NULL;
51 40cd76f4 2020-08-30 martijn }
52 40cd76f4 2020-08-30 martijn
53 40cd76f4 2020-08-30 martijn char *
54 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_crlf(char *ptr, int optional)
55 40cd76f4 2020-08-30 martijn {
56 40cd76f4 2020-08-30 martijn if (ptr[0] == 13 && ptr[1] == 10)
57 40cd76f4 2020-08-30 martijn return ptr + 2;
58 40cd76f4 2020-08-30 martijn return optional ? ptr : NULL;
59 40cd76f4 2020-08-30 martijn }
60 40cd76f4 2020-08-30 martijn
61 40cd76f4 2020-08-30 martijn char *
62 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_vchar(char *ptr, int optional)
63 40cd76f4 2020-08-30 martijn {
64 40cd76f4 2020-08-30 martijn if (ptr[0] >= 0x21 && ptr[0] <= 0x7e)
65 40cd76f4 2020-08-30 martijn return ptr + 1;
66 40cd76f4 2020-08-30 martijn return optional ? ptr : NULL;
67 40cd76f4 2020-08-30 martijn }
68 40cd76f4 2020-08-30 martijn
69 40cd76f4 2020-08-30 martijn char *
70 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_lf(char *ptr, int optional)
71 40cd76f4 2020-08-30 martijn {
72 40cd76f4 2020-08-30 martijn if (ptr[0] == 0xa)
73 40cd76f4 2020-08-30 martijn return ptr + 1;
74 40cd76f4 2020-08-30 martijn return optional ? ptr : NULL;
75 40cd76f4 2020-08-30 martijn }
76 40cd76f4 2020-08-30 martijn
77 40cd76f4 2020-08-30 martijn char *
78 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_cr(char *ptr, int optional)
79 40cd76f4 2020-08-30 martijn {
80 40cd76f4 2020-08-30 martijn if (ptr[0] == 0xd)
81 40cd76f4 2020-08-30 martijn return ptr + 1;
82 40cd76f4 2020-08-30 martijn return optional ? ptr : NULL;
83 40cd76f4 2020-08-30 martijn }
84 40cd76f4 2020-08-30 martijn
85 40cd76f4 2020-08-30 martijn char *
86 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_alpha(char *ptr, int optional)
87 40cd76f4 2020-08-30 martijn {
88 40cd76f4 2020-08-30 martijn if ((ptr[0] >= 0x41 && ptr[0] <= 0x5a) ||
89 40cd76f4 2020-08-30 martijn (ptr[0] >= 0x61 && ptr[0] <= 0x7a))
90 40cd76f4 2020-08-30 martijn return ptr + 1;
91 40cd76f4 2020-08-30 martijn return optional ? ptr : NULL;
92 40cd76f4 2020-08-30 martijn }
93 40cd76f4 2020-08-30 martijn
94 40cd76f4 2020-08-30 martijn char *
95 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_digit(char *ptr, int optional)
96 40cd76f4 2020-08-30 martijn {
97 40cd76f4 2020-08-30 martijn if (ptr[0] >= 0x30 && ptr[0] <= 0x39)
98 40cd76f4 2020-08-30 martijn return ptr + 1;
99 40cd76f4 2020-08-30 martijn return optional ? ptr : NULL;
100 40cd76f4 2020-08-30 martijn }
101 40cd76f4 2020-08-30 martijn
102 40cd76f4 2020-08-30 martijn char *
103 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_dquote(char *ptr, int optional)
104 40cd76f4 2020-08-30 martijn {
105 40cd76f4 2020-08-30 martijn if (ptr[0] == 0x22)
106 40cd76f4 2020-08-30 martijn return ptr + 1;
107 40cd76f4 2020-08-30 martijn return optional ? ptr : NULL;
108 40cd76f4 2020-08-30 martijn }
109 40cd76f4 2020-08-30 martijn
110 40cd76f4 2020-08-30 martijn char *
111 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_fws(char *ptr, int optional)
112 40cd76f4 2020-08-30 martijn {
113 40cd76f4 2020-08-30 martijn char *start = ptr, *prev;
114 40cd76f4 2020-08-30 martijn
115 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_wsp(ptr, 0)) == NULL)
116 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
117 40cd76f4 2020-08-30 martijn prev = ptr;
118 40cd76f4 2020-08-30 martijn while ((ptr = osmtpd_mheader_skip_wsp(ptr, 0)) != NULL)
119 40cd76f4 2020-08-30 martijn prev = ptr;
120 40cd76f4 2020-08-30 martijn
121 40cd76f4 2020-08-30 martijn ptr = prev;
122 40cd76f4 2020-08-30 martijn while (1) {
123 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_crlf(ptr, 0)) == NULL)
124 40cd76f4 2020-08-30 martijn return prev;
125 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_wsp(ptr, 0)) == NULL)
126 40cd76f4 2020-08-30 martijn return prev;
127 40cd76f4 2020-08-30 martijn prev = ptr;
128 40cd76f4 2020-08-30 martijn while ((ptr = osmtpd_mheader_skip_wsp(ptr, 0)) != NULL)
129 40cd76f4 2020-08-30 martijn prev = ptr;
130 40cd76f4 2020-08-30 martijn ptr = prev;
131 40cd76f4 2020-08-30 martijn }
132 40cd76f4 2020-08-30 martijn }
133 40cd76f4 2020-08-30 martijn
134 40cd76f4 2020-08-30 martijn char *
135 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_fws(char *ptr, int optional)
136 40cd76f4 2020-08-30 martijn {
137 40cd76f4 2020-08-30 martijn char *start = ptr, *prev = ptr;
138 40cd76f4 2020-08-30 martijn
139 40cd76f4 2020-08-30 martijn while ((ptr = osmtpd_mheader_skip_wsp(ptr, 0)) != NULL)
140 40cd76f4 2020-08-30 martijn prev = ptr;
141 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_crlf(prev, 1)) == prev)
142 40cd76f4 2020-08-30 martijn ptr = start;
143 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_wsp(ptr, 0)) == NULL)
144 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_obs_fws(start, optional);
145 40cd76f4 2020-08-30 martijn prev = ptr;
146 40cd76f4 2020-08-30 martijn while ((ptr = osmtpd_mheader_skip_wsp(ptr, 0)) != NULL)
147 40cd76f4 2020-08-30 martijn prev = ptr;
148 40cd76f4 2020-08-30 martijn return prev;
149 40cd76f4 2020-08-30 martijn }
150 40cd76f4 2020-08-30 martijn
151 40cd76f4 2020-08-30 martijn char *
152 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_no_ws_ctl(char *ptr, int optional)
153 40cd76f4 2020-08-30 martijn {
154 40cd76f4 2020-08-30 martijn if ((ptr[0] >= 1 && ptr[0] <= 8) || ptr[0] == 11 || ptr[0] == 12 ||
155 40cd76f4 2020-08-30 martijn (ptr[0] >= 14 && ptr[0] <= 31) || ptr[0] == 127)
156 40cd76f4 2020-08-30 martijn return ptr + 1;
157 40cd76f4 2020-08-30 martijn return optional ? ptr : NULL;
158 40cd76f4 2020-08-30 martijn }
159 40cd76f4 2020-08-30 martijn
160 40cd76f4 2020-08-30 martijn char *
161 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_ctext(char *ptr, int optional)
162 40cd76f4 2020-08-30 martijn {
163 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_obs_no_ws_ctl(ptr, optional);
164 40cd76f4 2020-08-30 martijn }
165 40cd76f4 2020-08-30 martijn
166 40cd76f4 2020-08-30 martijn char *
167 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_ctext(char *ptr, int optional)
168 40cd76f4 2020-08-30 martijn {
169 40cd76f4 2020-08-30 martijn char *start = ptr;
170 40cd76f4 2020-08-30 martijn
171 40cd76f4 2020-08-30 martijn if ((ptr[0] >= 33 && ptr[0] <= 39) || (ptr[0] >= 42 && ptr[0] <= 91) ||
172 40cd76f4 2020-08-30 martijn (ptr[0] >= 93 && ptr[0] <= 126))
173 40cd76f4 2020-08-30 martijn return ptr + 1;
174 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_obs_ctext(ptr, 0)) != NULL)
175 40cd76f4 2020-08-30 martijn return ptr;
176 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
177 40cd76f4 2020-08-30 martijn }
178 40cd76f4 2020-08-30 martijn
179 40cd76f4 2020-08-30 martijn char *
180 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_qp(char *ptr, int optional)
181 40cd76f4 2020-08-30 martijn {
182 40cd76f4 2020-08-30 martijn char *start = ptr;
183 40cd76f4 2020-08-30 martijn
184 40cd76f4 2020-08-30 martijn if (ptr[0] == '\\' && (
185 40cd76f4 2020-08-30 martijn (ptr = osmtpd_mheader_skip_obs_no_ws_ctl(start + 1, 0)) != NULL ||
186 40cd76f4 2020-08-30 martijn (ptr = osmtpd_mheader_skip_lf(start + 1, 0)) != NULL ||
187 40cd76f4 2020-08-30 martijn (ptr = osmtpd_mheader_skip_cr(start + 1, 0)) != NULL))
188 40cd76f4 2020-08-30 martijn return ptr;
189 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
190 40cd76f4 2020-08-30 martijn }
191 40cd76f4 2020-08-30 martijn
192 40cd76f4 2020-08-30 martijn char *
193 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_quoted_pair(char *ptr, int optional)
194 40cd76f4 2020-08-30 martijn {
195 40cd76f4 2020-08-30 martijn char *start = ptr;
196 40cd76f4 2020-08-30 martijn
197 40cd76f4 2020-08-30 martijn if (ptr[0] == '\\' && (
198 40cd76f4 2020-08-30 martijn (ptr = osmtpd_mheader_skip_vchar(start + 1, 0)) != NULL ||
199 40cd76f4 2020-08-30 martijn (ptr = osmtpd_mheader_skip_wsp(start + 1, 0)) != NULL))
200 40cd76f4 2020-08-30 martijn return ptr;
201 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_obs_qp(start, optional);
202 40cd76f4 2020-08-30 martijn }
203 40cd76f4 2020-08-30 martijn
204 40cd76f4 2020-08-30 martijn char *
205 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_ccontent(char *ptr, int optional)
206 40cd76f4 2020-08-30 martijn {
207 40cd76f4 2020-08-30 martijn char *start = ptr;
208 40cd76f4 2020-08-30 martijn
209 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_ctext(ptr, 0)) != NULL)
210 40cd76f4 2020-08-30 martijn return ptr;
211 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_quoted_pair(start, 0)) != NULL)
212 40cd76f4 2020-08-30 martijn return ptr;
213 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_comment(start, 0)) != NULL)
214 40cd76f4 2020-08-30 martijn return ptr;
215 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
216 40cd76f4 2020-08-30 martijn }
217 40cd76f4 2020-08-30 martijn
218 40cd76f4 2020-08-30 martijn char *
219 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_comment(char *ptr, int optional)
220 40cd76f4 2020-08-30 martijn {
221 40cd76f4 2020-08-30 martijn char *start = ptr;
222 40cd76f4 2020-08-30 martijn
223 40cd76f4 2020-08-30 martijn if (ptr++[0] != '(')
224 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
225 40cd76f4 2020-08-30 martijn while (1) {
226 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_fws(ptr, 1);
227 40cd76f4 2020-08-30 martijn if (ptr[0] == ')')
228 40cd76f4 2020-08-30 martijn return ptr + 1;
229 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_ccontent(ptr, 0)) == NULL)
230 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
231 40cd76f4 2020-08-30 martijn }
232 40cd76f4 2020-08-30 martijn }
233 40cd76f4 2020-08-30 martijn
234 40cd76f4 2020-08-30 martijn char *
235 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_cfws(char *ptr, int optional)
236 40cd76f4 2020-08-30 martijn {
237 40cd76f4 2020-08-30 martijn char *start = ptr, *prev;
238 40cd76f4 2020-08-30 martijn
239 40cd76f4 2020-08-30 martijn while (1) {
240 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_fws(ptr, 1);
241 40cd76f4 2020-08-30 martijn prev = ptr;
242 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_comment(ptr, 0)) == NULL) {
243 40cd76f4 2020-08-30 martijn ptr = prev;
244 40cd76f4 2020-08-30 martijn break;
245 40cd76f4 2020-08-30 martijn }
246 40cd76f4 2020-08-30 martijn }
247 40cd76f4 2020-08-30 martijn return ptr == start && !optional ? NULL : ptr;
248 40cd76f4 2020-08-30 martijn }
249 40cd76f4 2020-08-30 martijn
250 40cd76f4 2020-08-30 martijn char *
251 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_atext(char *ptr, int optional)
252 40cd76f4 2020-08-30 martijn {
253 40cd76f4 2020-08-30 martijn char *start = ptr;
254 40cd76f4 2020-08-30 martijn
255 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_alpha(start, 0)) != NULL ||
256 40cd76f4 2020-08-30 martijn (ptr = osmtpd_mheader_skip_digit(start, 0)) != NULL)
257 40cd76f4 2020-08-30 martijn return ptr;
258 40cd76f4 2020-08-30 martijn ptr = start;
259 40cd76f4 2020-08-30 martijn if (ptr[0] == '!' || ptr[0] == '#' || ptr[0] == '$' || ptr[0] == '%' ||
260 40cd76f4 2020-08-30 martijn ptr[0] == '&' || ptr[0] == '\'' || ptr[0] == '*' || ptr[0] == '+' ||
261 40cd76f4 2020-08-30 martijn ptr[0] == '-' || ptr[0] == '/' || ptr[0] == '=' || ptr[0] == '?' ||
262 40cd76f4 2020-08-30 martijn ptr[0] == '^' || ptr[0] == '_' || ptr[0] == '`' || ptr[0] == '{' ||
263 40cd76f4 2020-08-30 martijn ptr[0] == '|' || ptr[0] == '}' || ptr[0] == '~')
264 40cd76f4 2020-08-30 martijn return ptr + 1;
265 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
266 40cd76f4 2020-08-30 martijn }
267 40cd76f4 2020-08-30 martijn
268 40cd76f4 2020-08-30 martijn char *
269 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_atom(char *ptr, int optional)
270 40cd76f4 2020-08-30 martijn {
271 40cd76f4 2020-08-30 martijn char *start = ptr, *prev;
272 40cd76f4 2020-08-30 martijn
273 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_cfws(ptr, 1);
274 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_atext(ptr, 0)) == NULL)
275 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
276 40cd76f4 2020-08-30 martijn do {
277 40cd76f4 2020-08-30 martijn prev = ptr;
278 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_atext(ptr, 1);
279 40cd76f4 2020-08-30 martijn } while (prev != ptr);
280 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_cfws(ptr, 1);
281 40cd76f4 2020-08-30 martijn }
282 40cd76f4 2020-08-30 martijn
283 40cd76f4 2020-08-30 martijn char *
284 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_dot_atom_text(char *ptr, int optional)
285 40cd76f4 2020-08-30 martijn {
286 40cd76f4 2020-08-30 martijn char *start = ptr, *prev;
287 40cd76f4 2020-08-30 martijn
288 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_atext(ptr, 0)) == NULL)
289 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
290 40cd76f4 2020-08-30 martijn do {
291 40cd76f4 2020-08-30 martijn prev = ptr;
292 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_atext(ptr, 1);
293 40cd76f4 2020-08-30 martijn } while (ptr != prev);
294 40cd76f4 2020-08-30 martijn
295 40cd76f4 2020-08-30 martijn while (ptr[0] == '.') {
296 40cd76f4 2020-08-30 martijn ptr++;
297 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_atext(ptr, 0)) == NULL)
298 40cd76f4 2020-08-30 martijn return prev;
299 40cd76f4 2020-08-30 martijn do {
300 40cd76f4 2020-08-30 martijn prev = ptr;
301 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_atext(ptr, 1);
302 40cd76f4 2020-08-30 martijn } while (ptr != prev);
303 40cd76f4 2020-08-30 martijn }
304 40cd76f4 2020-08-30 martijn return ptr;
305 40cd76f4 2020-08-30 martijn }
306 40cd76f4 2020-08-30 martijn
307 40cd76f4 2020-08-30 martijn char *
308 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_dot_atom(char *ptr, int optional)
309 40cd76f4 2020-08-30 martijn {
310 40cd76f4 2020-08-30 martijn char *start = ptr;
311 40cd76f4 2020-08-30 martijn
312 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_cfws(ptr, 1);
313 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_dot_atom_text(ptr, 0)) == NULL)
314 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
315 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_cfws(ptr, 1);
316 40cd76f4 2020-08-30 martijn }
317 40cd76f4 2020-08-30 martijn
318 40cd76f4 2020-08-30 martijn
319 40cd76f4 2020-08-30 martijn char *
320 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_qtext(char *ptr, int optional)
321 40cd76f4 2020-08-30 martijn {
322 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_obs_no_ws_ctl(ptr, optional);
323 40cd76f4 2020-08-30 martijn }
324 40cd76f4 2020-08-30 martijn
325 40cd76f4 2020-08-30 martijn char *
326 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_qtext(char *ptr, int optional)
327 40cd76f4 2020-08-30 martijn {
328 40cd76f4 2020-08-30 martijn char *start = ptr;
329 40cd76f4 2020-08-30 martijn
330 40cd76f4 2020-08-30 martijn if (ptr[0] == 33 || (ptr[0] >= 35 && ptr[0] <= 91) ||
331 40cd76f4 2020-08-30 martijn (ptr[0] >= 93 && ptr[0] <= 126))
332 40cd76f4 2020-08-30 martijn return ptr + 1;
333 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_obs_qtext(ptr, 0)) != NULL)
334 40cd76f4 2020-08-30 martijn return ptr;
335 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
336 40cd76f4 2020-08-30 martijn }
337 40cd76f4 2020-08-30 martijn
338 40cd76f4 2020-08-30 martijn char *
339 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_qcontent(char *ptr, int optional)
340 40cd76f4 2020-08-30 martijn {
341 40cd76f4 2020-08-30 martijn char *start = ptr;
342 40cd76f4 2020-08-30 martijn
343 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_qtext(ptr, 0)) != NULL)
344 40cd76f4 2020-08-30 martijn return ptr;
345 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_quoted_pair(start, optional);
346 40cd76f4 2020-08-30 martijn }
347 40cd76f4 2020-08-30 martijn
348 40cd76f4 2020-08-30 martijn char *
349 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_quoted_string(char *ptr, int optional)
350 40cd76f4 2020-08-30 martijn {
351 40cd76f4 2020-08-30 martijn char *start = ptr, *prev;
352 40cd76f4 2020-08-30 martijn
353 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_cfws(ptr, 1);
354 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_dquote(ptr, 0)) == NULL)
355 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
356 40cd76f4 2020-08-30 martijn prev = ptr;
357 40cd76f4 2020-08-30 martijn while (1) {
358 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_fws(ptr, 1);
359 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_qcontent(ptr, 0)) == NULL)
360 40cd76f4 2020-08-30 martijn break;
361 40cd76f4 2020-08-30 martijn prev = ptr;
362 40cd76f4 2020-08-30 martijn }
363 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_dquote(prev, 0)) == NULL)
364 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
365 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_cfws(ptr, 1);
366 40cd76f4 2020-08-30 martijn }
367 40cd76f4 2020-08-30 martijn
368 40cd76f4 2020-08-30 martijn char *
369 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_word(char *ptr, int optional)
370 40cd76f4 2020-08-30 martijn {
371 40cd76f4 2020-08-30 martijn char *start = ptr;
372 40cd76f4 2020-08-30 martijn
373 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_atom(ptr, 0)) != NULL)
374 40cd76f4 2020-08-30 martijn return ptr;
375 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_quoted_string(start, optional);
376 40cd76f4 2020-08-30 martijn }
377 40cd76f4 2020-08-30 martijn
378 40cd76f4 2020-08-30 martijn char *
379 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_phrase(char *ptr, int optional)
380 40cd76f4 2020-08-30 martijn {
381 40cd76f4 2020-08-30 martijn char *start = ptr, *prev;
382 40cd76f4 2020-08-30 martijn
383 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_word(ptr, 0)) == NULL)
384 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
385 40cd76f4 2020-08-30 martijn while (1) {
386 40cd76f4 2020-08-30 martijn prev = ptr;
387 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_word(ptr, 0)) != NULL)
388 40cd76f4 2020-08-30 martijn continue;
389 40cd76f4 2020-08-30 martijn ptr = prev;
390 3a6f9964 2021-03-21 martijn if (ptr[0] == '.') {
391 3a6f9964 2021-03-21 martijn ptr++;
392 40cd76f4 2020-08-30 martijn continue;
393 3a6f9964 2021-03-21 martijn }
394 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_cfws(ptr, 0)) != NULL)
395 40cd76f4 2020-08-30 martijn continue;
396 40cd76f4 2020-08-30 martijn return prev;
397 40cd76f4 2020-08-30 martijn }
398 40cd76f4 2020-08-30 martijn }
399 40cd76f4 2020-08-30 martijn
400 40cd76f4 2020-08-30 martijn char *
401 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_phrase(char *ptr, int optional)
402 40cd76f4 2020-08-30 martijn {
403 40cd76f4 2020-08-30 martijn /* obs-phrase is a superset of phrae */
404 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_obs_phrase(ptr, optional);
405 40cd76f4 2020-08-30 martijn #if 0
406 40cd76f4 2020-08-30 martijn char *start = ptr, *prev;
407 40cd76f4 2020-08-30 martijn
408 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_word(ptr, 0)) == NULL)
409 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
410 40cd76f4 2020-08-30 martijn while (1) {
411 40cd76f4 2020-08-30 martijn prev = ptr;
412 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_word(ptr, 0)) == NULL)
413 40cd76f4 2020-08-30 martijn return prev;
414 40cd76f4 2020-08-30 martijn }
415 40cd76f4 2020-08-30 martijn #endif
416 40cd76f4 2020-08-30 martijn }
417 40cd76f4 2020-08-30 martijn
418 40cd76f4 2020-08-30 martijn char *
419 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_local_part(char *ptr, int optional)
420 40cd76f4 2020-08-30 martijn {
421 40cd76f4 2020-08-30 martijn char *start = ptr, *prev;
422 40cd76f4 2020-08-30 martijn
423 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_word(ptr, 0)) == NULL)
424 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
425 40cd76f4 2020-08-30 martijn prev = ptr;
426 40cd76f4 2020-08-30 martijn while (ptr[0] == '.') {
427 40cd76f4 2020-08-30 martijn ptr++;
428 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_word(ptr, 0)) == NULL)
429 40cd76f4 2020-08-30 martijn return prev;
430 40cd76f4 2020-08-30 martijn prev = ptr;
431 40cd76f4 2020-08-30 martijn }
432 40cd76f4 2020-08-30 martijn return ptr;
433 40cd76f4 2020-08-30 martijn }
434 40cd76f4 2020-08-30 martijn
435 40cd76f4 2020-08-30 martijn char *
436 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_local_part(char *ptr, int optional)
437 40cd76f4 2020-08-30 martijn {
438 40cd76f4 2020-08-30 martijn char *start = ptr;
439 40cd76f4 2020-08-30 martijn
440 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_dot_atom(ptr, 0)) != NULL)
441 40cd76f4 2020-08-30 martijn return ptr;
442 40cd76f4 2020-08-30 martijn ptr = start;
443 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_quoted_string(ptr, 0)) != NULL)
444 40cd76f4 2020-08-30 martijn return ptr;
445 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_obs_local_part(start, optional);
446 40cd76f4 2020-08-30 martijn }
447 40cd76f4 2020-08-30 martijn
448 40cd76f4 2020-08-30 martijn char *
449 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_dtext(char *ptr, int optional)
450 40cd76f4 2020-08-30 martijn {
451 40cd76f4 2020-08-30 martijn char *start = ptr;
452 40cd76f4 2020-08-30 martijn
453 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_obs_no_ws_ctl(ptr, 0)) != NULL)
454 40cd76f4 2020-08-30 martijn return ptr;
455 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_quoted_pair(start, optional);
456 40cd76f4 2020-08-30 martijn }
457 40cd76f4 2020-08-30 martijn
458 40cd76f4 2020-08-30 martijn char *
459 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_dtext(char *ptr, int optional)
460 40cd76f4 2020-08-30 martijn {
461 40cd76f4 2020-08-30 martijn if ((ptr[0] >= 33 && ptr[0] <= 90) || (ptr[0] >= 94 && ptr[0] <= 126))
462 40cd76f4 2020-08-30 martijn return ptr + 1;
463 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_obs_dtext(ptr, optional);
464 40cd76f4 2020-08-30 martijn
465 40cd76f4 2020-08-30 martijn }
466 40cd76f4 2020-08-30 martijn
467 40cd76f4 2020-08-30 martijn char *
468 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_domain_literal(char *ptr, int optional)
469 40cd76f4 2020-08-30 martijn {
470 40cd76f4 2020-08-30 martijn char *start = ptr, *prev;
471 40cd76f4 2020-08-30 martijn
472 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_cfws(ptr, 1);
473 40cd76f4 2020-08-30 martijn if (ptr++[0] != '[')
474 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
475 40cd76f4 2020-08-30 martijn while (1) {
476 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_fws(ptr, 1);
477 40cd76f4 2020-08-30 martijn prev = ptr;
478 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_dtext(ptr, 0)) == NULL) {
479 40cd76f4 2020-08-30 martijn ptr = prev;
480 40cd76f4 2020-08-30 martijn break;
481 40cd76f4 2020-08-30 martijn }
482 40cd76f4 2020-08-30 martijn }
483 40cd76f4 2020-08-30 martijn if (ptr[0] != ']')
484 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
485 60e9f82d 2022-01-27 martijn ptr++;
486 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_cfws(ptr, 1);
487 40cd76f4 2020-08-30 martijn }
488 40cd76f4 2020-08-30 martijn
489 40cd76f4 2020-08-30 martijn char *
490 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_domain(char *ptr, int optional)
491 40cd76f4 2020-08-30 martijn {
492 40cd76f4 2020-08-30 martijn char *start = ptr, *prev;
493 40cd76f4 2020-08-30 martijn
494 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_atom(ptr, 0)) == NULL)
495 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
496 40cd76f4 2020-08-30 martijn prev = ptr;
497 40cd76f4 2020-08-30 martijn while (1) {
498 40cd76f4 2020-08-30 martijn if (ptr++[0] != '.')
499 40cd76f4 2020-08-30 martijn return prev;
500 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_atom(ptr, 0)) == NULL)
501 40cd76f4 2020-08-30 martijn return prev;
502 40cd76f4 2020-08-30 martijn prev = ptr;
503 40cd76f4 2020-08-30 martijn }
504 40cd76f4 2020-08-30 martijn }
505 40cd76f4 2020-08-30 martijn
506 40cd76f4 2020-08-30 martijn char *
507 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_domain(char *ptr, int optional)
508 40cd76f4 2020-08-30 martijn {
509 40cd76f4 2020-08-30 martijn char *start = ptr;
510 40cd76f4 2020-08-30 martijn
511 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_dot_atom(start, 0)) != NULL)
512 40cd76f4 2020-08-30 martijn return ptr;
513 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_domain_literal(start, 0)) != NULL)
514 40cd76f4 2020-08-30 martijn return ptr;
515 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_obs_domain(start, optional);
516 40cd76f4 2020-08-30 martijn }
517 40cd76f4 2020-08-30 martijn
518 40cd76f4 2020-08-30 martijn char *
519 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_display_name(char *ptr, int optional)
520 40cd76f4 2020-08-30 martijn {
521 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_phrase(ptr, optional);
522 40cd76f4 2020-08-30 martijn }
523 40cd76f4 2020-08-30 martijn
524 40cd76f4 2020-08-30 martijn char *
525 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_domain_list(char *ptr, int optional)
526 40cd76f4 2020-08-30 martijn {
527 1ebab45c 2021-05-26 martijn char *start = ptr, *prev = ptr;
528 40cd76f4 2020-08-30 martijn
529 40cd76f4 2020-08-30 martijn while (1) {
530 40cd76f4 2020-08-30 martijn if (ptr[0] == ',') {
531 40cd76f4 2020-08-30 martijn ptr++;
532 40cd76f4 2020-08-30 martijn prev = ptr;
533 40cd76f4 2020-08-30 martijn continue;
534 40cd76f4 2020-08-30 martijn } else if ((ptr = osmtpd_mheader_skip_cfws(ptr, 0)) != NULL) {
535 40cd76f4 2020-08-30 martijn prev = ptr;
536 40cd76f4 2020-08-30 martijn continue;
537 40cd76f4 2020-08-30 martijn }
538 40cd76f4 2020-08-30 martijn break;
539 40cd76f4 2020-08-30 martijn }
540 40cd76f4 2020-08-30 martijn ptr = prev;
541 40cd76f4 2020-08-30 martijn
542 40cd76f4 2020-08-30 martijn if (ptr++[0] != '@')
543 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
544 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_domain(ptr, 0)) == NULL)
545 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
546 40cd76f4 2020-08-30 martijn while (1) {
547 40cd76f4 2020-08-30 martijn if (ptr[0] != ',')
548 40cd76f4 2020-08-30 martijn break;
549 40cd76f4 2020-08-30 martijn ptr++;
550 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_cfws(ptr, 1);
551 40cd76f4 2020-08-30 martijn if (ptr[0] != '@')
552 40cd76f4 2020-08-30 martijn continue;
553 40cd76f4 2020-08-30 martijn prev = ptr;
554 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_domain(ptr + 1, 0)) == NULL) {
555 40cd76f4 2020-08-30 martijn ptr = prev;
556 40cd76f4 2020-08-30 martijn break;
557 40cd76f4 2020-08-30 martijn }
558 40cd76f4 2020-08-30 martijn }
559 40cd76f4 2020-08-30 martijn return ptr;
560 40cd76f4 2020-08-30 martijn }
561 40cd76f4 2020-08-30 martijn
562 40cd76f4 2020-08-30 martijn char *
563 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_route(char *ptr, int optional)
564 40cd76f4 2020-08-30 martijn {
565 40cd76f4 2020-08-30 martijn char *start = ptr;
566 40cd76f4 2020-08-30 martijn
567 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_obs_domain_list(ptr, 0)) == NULL)
568 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
569 40cd76f4 2020-08-30 martijn if (ptr++[0] != ':')
570 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
571 40cd76f4 2020-08-30 martijn return ptr;
572 40cd76f4 2020-08-30 martijn }
573 40cd76f4 2020-08-30 martijn
574 40cd76f4 2020-08-30 martijn char *
575 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_addr_spec(char *ptr, int optional)
576 40cd76f4 2020-08-30 martijn {
577 40cd76f4 2020-08-30 martijn char *start = ptr;
578 40cd76f4 2020-08-30 martijn
579 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_local_part(ptr, 0)) == NULL)
580 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
581 40cd76f4 2020-08-30 martijn if (ptr++[0] != '@')
582 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
583 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_domain(ptr, 0)) == NULL)
584 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
585 40cd76f4 2020-08-30 martijn return ptr;
586 40cd76f4 2020-08-30 martijn }
587 40cd76f4 2020-08-30 martijn
588 40cd76f4 2020-08-30 martijn char *
589 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_angle_addr(char *ptr, int optional)
590 40cd76f4 2020-08-30 martijn {
591 40cd76f4 2020-08-30 martijn char *start = ptr;
592 40cd76f4 2020-08-30 martijn
593 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_cfws(ptr, 1);
594 40cd76f4 2020-08-30 martijn if (ptr++[0] != '<')
595 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
596 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_obs_route(ptr, 0)) == NULL)
597 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
598 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_addr_spec(ptr, 0)) == NULL)
599 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
600 40cd76f4 2020-08-30 martijn if (ptr++[0] != '>')
601 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
602 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_cfws(ptr, 1);
603 40cd76f4 2020-08-30 martijn }
604 40cd76f4 2020-08-30 martijn
605 40cd76f4 2020-08-30 martijn char *
606 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_angle_addr(char *ptr, int optional)
607 40cd76f4 2020-08-30 martijn {
608 40cd76f4 2020-08-30 martijn char *start = ptr;
609 40cd76f4 2020-08-30 martijn
610 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_cfws(ptr, 1);
611 40cd76f4 2020-08-30 martijn if (ptr++[0] != '<')
612 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_obs_angle_addr(start, optional);
613 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_addr_spec(ptr, 0)) == NULL)
614 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_obs_angle_addr(start, optional);
615 40cd76f4 2020-08-30 martijn if (ptr++[0] != '>')
616 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_obs_angle_addr(start, optional);
617 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_cfws(ptr, 1);
618 40cd76f4 2020-08-30 martijn }
619 40cd76f4 2020-08-30 martijn
620 40cd76f4 2020-08-30 martijn char *
621 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_name_addr(char *ptr, int optional)
622 40cd76f4 2020-08-30 martijn {
623 40cd76f4 2020-08-30 martijn char *start = ptr;
624 40cd76f4 2020-08-30 martijn
625 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_display_name(ptr, 1);
626 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_angle_addr(ptr, 0)) == NULL)
627 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
628 40cd76f4 2020-08-30 martijn return ptr;
629 40cd76f4 2020-08-30 martijn }
630 40cd76f4 2020-08-30 martijn
631 60e9f82d 2022-01-27 martijn char *
632 60e9f82d 2022-01-27 martijn osmtpd_mheader_domain_uncomment(char *ptr)
633 60e9f82d 2022-01-27 martijn {
634 60e9f82d 2022-01-27 martijn char *domain0, *domain, *tmp, *end;
635 60e9f82d 2022-01-27 martijn
636 60e9f82d 2022-01-27 martijn if (osmtpd_mheader_skip_dot_atom(ptr, 0) != NULL) {
637 60e9f82d 2022-01-27 martijn ptr = osmtpd_mheader_skip_cfws(ptr, 1);
638 60e9f82d 2022-01-27 martijn return strndup(ptr,
639 60e9f82d 2022-01-27 martijn osmtpd_mheader_skip_dot_atom_text(ptr, 0) - ptr);
640 60e9f82d 2022-01-27 martijn }
641 60e9f82d 2022-01-27 martijn if ((tmp = osmtpd_mheader_skip_domain_literal(ptr, 0)) != NULL) {
642 60e9f82d 2022-01-27 martijn ptr = osmtpd_mheader_skip_cfws(ptr, 1) + 1;
643 60e9f82d 2022-01-27 martijn domain0 = domain = strndup(ptr, (size_t)(tmp - ptr));
644 60e9f82d 2022-01-27 martijn if (domain0 == NULL)
645 60e9f82d 2022-01-27 martijn return NULL;
646 60e9f82d 2022-01-27 martijn end = domain0 + (tmp - ptr) + 1;
647 60e9f82d 2022-01-27 martijn domain++;
648 60e9f82d 2022-01-27 martijn while (1) {
649 60e9f82d 2022-01-27 martijn tmp = osmtpd_mheader_skip_fws(domain, 1);
650 60e9f82d 2022-01-27 martijn if (tmp != domain) {
651 60e9f82d 2022-01-27 martijn memmove(domain, tmp, end - tmp);
652 60e9f82d 2022-01-27 martijn end -= (tmp - domain);
653 60e9f82d 2022-01-27 martijn }
654 60e9f82d 2022-01-27 martijn tmp = osmtpd_mheader_skip_dtext(domain, 0);
655 60e9f82d 2022-01-27 martijn if (tmp == NULL)
656 60e9f82d 2022-01-27 martijn break;
657 60e9f82d 2022-01-27 martijn domain = tmp;
658 60e9f82d 2022-01-27 martijn }
659 60e9f82d 2022-01-27 martijn /* domain[0] == ']' */
660 60e9f82d 2022-01-27 martijn domain[0] = '\0';
661 60e9f82d 2022-01-27 martijn return domain0;
662 60e9f82d 2022-01-27 martijn }
663 60e9f82d 2022-01-27 martijn return strndup(ptr, osmtpd_mheader_skip_obs_domain(ptr, 1) - ptr);
664 60e9f82d 2022-01-27 martijn }
665 60e9f82d 2022-01-27 martijn
666 40cd76f4 2020-08-30 martijn /* Return the domain component of the first mailbox */
667 40cd76f4 2020-08-30 martijn char *
668 40cd76f4 2020-08-30 martijn osmtpd_mheader_from_domain(char *ptr)
669 40cd76f4 2020-08-30 martijn {
670 40cd76f4 2020-08-30 martijn char *tmp;
671 40cd76f4 2020-08-30 martijn
672 40cd76f4 2020-08-30 martijn /* from */
673 40cd76f4 2020-08-30 martijn if (strncasecmp(ptr, "from:", 5) == 0) {
674 40cd76f4 2020-08-30 martijn ptr += 5;
675 40cd76f4 2020-08-30 martijn /* obs-from */
676 40cd76f4 2020-08-30 martijn } else if (strncasecmp(ptr, "from", 4) == 0) {
677 40cd76f4 2020-08-30 martijn ptr += 4;
678 40cd76f4 2020-08-30 martijn do {
679 40cd76f4 2020-08-30 martijn tmp = ptr;
680 40cd76f4 2020-08-30 martijn } while ((ptr = osmtpd_mheader_skip_wsp(ptr, 0)) != NULL);
681 40cd76f4 2020-08-30 martijn ptr = tmp;
682 40cd76f4 2020-08-30 martijn if (ptr++[0] != ':')
683 40cd76f4 2020-08-30 martijn return NULL;
684 40cd76f4 2020-08-30 martijn } else {
685 40cd76f4 2020-08-30 martijn errno = EINVAL;
686 40cd76f4 2020-08-30 martijn return NULL;
687 40cd76f4 2020-08-30 martijn }
688 40cd76f4 2020-08-30 martijn
689 40cd76f4 2020-08-30 martijn /* Both from and obs-from use Mailbox-list CRLF */
690 40cd76f4 2020-08-30 martijn /* obs-mbox-list has just a prefix compared to mailbox-list */
691 40cd76f4 2020-08-30 martijn while (1) {
692 40cd76f4 2020-08-30 martijn tmp = ptr;
693 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_cfws(ptr, 1);
694 40cd76f4 2020-08-30 martijn if (ptr++[0] != ',') {
695 40cd76f4 2020-08-30 martijn ptr = tmp;
696 40cd76f4 2020-08-30 martijn break;
697 40cd76f4 2020-08-30 martijn }
698 40cd76f4 2020-08-30 martijn }
699 40cd76f4 2020-08-30 martijn /* We're only interested in the first mailbox */
700 40cd76f4 2020-08-30 martijn if (osmtpd_mheader_skip_name_addr(ptr, 0) != NULL) {
701 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_display_name(ptr, 1);
702 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_cfws(ptr, 1);
703 40cd76f4 2020-08-30 martijn /* < */
704 40cd76f4 2020-08-30 martijn ptr++;
705 40cd76f4 2020-08-30 martijn /* addr-spec */
706 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_local_part(ptr, 0);
707 40cd76f4 2020-08-30 martijn /* @ */
708 40cd76f4 2020-08-30 martijn ptr++;
709 60e9f82d 2022-01-27 martijn return osmtpd_mheader_domain_uncomment(ptr);
710 40cd76f4 2020-08-30 martijn }
711 40cd76f4 2020-08-30 martijn if (osmtpd_mheader_skip_addr_spec(ptr, 0) != NULL) {
712 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_local_part(ptr, 0);
713 40cd76f4 2020-08-30 martijn /* @ */
714 40cd76f4 2020-08-30 martijn ptr++;
715 60e9f82d 2022-01-27 martijn return osmtpd_mheader_domain_uncomment(ptr);
716 40cd76f4 2020-08-30 martijn }
717 40cd76f4 2020-08-30 martijn errno = EINVAL;
718 40cd76f4 2020-08-30 martijn return NULL;
719 40cd76f4 2020-08-30 martijn }