2 40cd76f4 2020-08-30 martijn * Copyright (c) 2020 Martijn van Duren <martijn@openbsd.org>
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.
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.
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>
23 40cd76f4 2020-08-30 martijn #include "mheader.h"
26 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_sp(char *ptr, int optional)
28 40cd76f4 2020-08-30 martijn if (ptr[0] == 0x20)
29 40cd76f4 2020-08-30 martijn return ptr + 1;
30 40cd76f4 2020-08-30 martijn return optional ? ptr : NULL;
34 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_htab(char *ptr, int optional)
36 40cd76f4 2020-08-30 martijn if (ptr[0] == 0x9)
37 40cd76f4 2020-08-30 martijn return ptr + 1;
38 40cd76f4 2020-08-30 martijn return optional ? ptr : NULL;
42 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_wsp(char *ptr, int optional)
44 40cd76f4 2020-08-30 martijn char *start = ptr;
46 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_sp(start, 0)) != NULL ||
47 40cd76f4 2020-08-30 martijn (ptr = osmtpd_mheader_skip_htab(start, 0)) != NULL)
48 40cd76f4 2020-08-30 martijn return ptr;
49 40cd76f4 2020-08-30 martijn return optional ? ptr : NULL;
53 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_crlf(char *ptr, int optional)
55 40cd76f4 2020-08-30 martijn if (ptr[0] == 13 && ptr[1] == 10)
56 40cd76f4 2020-08-30 martijn return ptr + 2;
57 40cd76f4 2020-08-30 martijn return optional ? ptr : NULL;
61 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_vchar(char *ptr, int optional)
63 40cd76f4 2020-08-30 martijn if (ptr[0] >= 0x21 && ptr[0] <= 0x7e)
64 40cd76f4 2020-08-30 martijn return ptr + 1;
65 40cd76f4 2020-08-30 martijn return optional ? ptr : NULL;
69 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_lf(char *ptr, int optional)
71 40cd76f4 2020-08-30 martijn if (ptr[0] == 0xa)
72 40cd76f4 2020-08-30 martijn return ptr + 1;
73 40cd76f4 2020-08-30 martijn return optional ? ptr : NULL;
77 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_cr(char *ptr, int optional)
79 40cd76f4 2020-08-30 martijn if (ptr[0] == 0xd)
80 40cd76f4 2020-08-30 martijn return ptr + 1;
81 40cd76f4 2020-08-30 martijn return optional ? ptr : NULL;
85 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_alpha(char *ptr, int optional)
87 40cd76f4 2020-08-30 martijn if ((ptr[0] >= 0x41 && ptr[0] <= 0x5a) ||
88 40cd76f4 2020-08-30 martijn (ptr[0] >= 0x61 && ptr[0] <= 0x7a))
89 40cd76f4 2020-08-30 martijn return ptr + 1;
90 40cd76f4 2020-08-30 martijn return optional ? ptr : NULL;
94 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_digit(char *ptr, int optional)
96 40cd76f4 2020-08-30 martijn if (ptr[0] >= 0x30 && ptr[0] <= 0x39)
97 40cd76f4 2020-08-30 martijn return ptr + 1;
98 40cd76f4 2020-08-30 martijn return optional ? ptr : NULL;
102 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_dquote(char *ptr, int optional)
104 40cd76f4 2020-08-30 martijn if (ptr[0] == 0x22)
105 40cd76f4 2020-08-30 martijn return ptr + 1;
106 40cd76f4 2020-08-30 martijn return optional ? ptr : NULL;
110 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_fws(char *ptr, int optional)
112 40cd76f4 2020-08-30 martijn char *start = ptr, *prev;
114 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_wsp(ptr, 0)) == NULL)
115 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
116 40cd76f4 2020-08-30 martijn prev = ptr;
117 40cd76f4 2020-08-30 martijn while ((ptr = osmtpd_mheader_skip_wsp(ptr, 0)) != NULL)
118 40cd76f4 2020-08-30 martijn prev = ptr;
120 40cd76f4 2020-08-30 martijn ptr = prev;
121 40cd76f4 2020-08-30 martijn while (1) {
122 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_crlf(ptr, 0)) == NULL)
123 40cd76f4 2020-08-30 martijn return prev;
124 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_wsp(ptr, 0)) == NULL)
125 40cd76f4 2020-08-30 martijn return prev;
126 40cd76f4 2020-08-30 martijn prev = ptr;
127 40cd76f4 2020-08-30 martijn while ((ptr = osmtpd_mheader_skip_wsp(ptr, 0)) != NULL)
128 40cd76f4 2020-08-30 martijn prev = ptr;
129 40cd76f4 2020-08-30 martijn ptr = prev;
134 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_fws(char *ptr, int optional)
136 40cd76f4 2020-08-30 martijn char *start = ptr, *prev = ptr;
138 40cd76f4 2020-08-30 martijn while ((ptr = osmtpd_mheader_skip_wsp(ptr, 0)) != NULL)
139 40cd76f4 2020-08-30 martijn prev = ptr;
140 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_crlf(prev, 1)) == prev)
141 40cd76f4 2020-08-30 martijn ptr = start;
142 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_wsp(ptr, 0)) == NULL)
143 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_obs_fws(start, optional);
144 40cd76f4 2020-08-30 martijn prev = ptr;
145 40cd76f4 2020-08-30 martijn while ((ptr = osmtpd_mheader_skip_wsp(ptr, 0)) != NULL)
146 40cd76f4 2020-08-30 martijn prev = ptr;
147 40cd76f4 2020-08-30 martijn return prev;
151 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_no_ws_ctl(char *ptr, int optional)
153 40cd76f4 2020-08-30 martijn if ((ptr[0] >= 1 && ptr[0] <= 8) || ptr[0] == 11 || ptr[0] == 12 ||
154 40cd76f4 2020-08-30 martijn (ptr[0] >= 14 && ptr[0] <= 31) || ptr[0] == 127)
155 40cd76f4 2020-08-30 martijn return ptr + 1;
156 40cd76f4 2020-08-30 martijn return optional ? ptr : NULL;
160 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_ctext(char *ptr, int optional)
162 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_obs_no_ws_ctl(ptr, optional);
166 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_ctext(char *ptr, int optional)
168 40cd76f4 2020-08-30 martijn char *start = ptr;
170 40cd76f4 2020-08-30 martijn if ((ptr[0] >= 33 && ptr[0] <= 39) || (ptr[0] >= 42 && ptr[0] <= 91) ||
171 40cd76f4 2020-08-30 martijn (ptr[0] >= 93 && ptr[0] <= 126))
172 40cd76f4 2020-08-30 martijn return ptr + 1;
173 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_obs_ctext(ptr, 0)) != NULL)
174 40cd76f4 2020-08-30 martijn return ptr;
175 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
179 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_qp(char *ptr, int optional)
181 40cd76f4 2020-08-30 martijn char *start = ptr;
183 40cd76f4 2020-08-30 martijn if (ptr[0] == '\\' && (
184 40cd76f4 2020-08-30 martijn (ptr = osmtpd_mheader_skip_obs_no_ws_ctl(start + 1, 0)) != NULL ||
185 40cd76f4 2020-08-30 martijn (ptr = osmtpd_mheader_skip_lf(start + 1, 0)) != NULL ||
186 40cd76f4 2020-08-30 martijn (ptr = osmtpd_mheader_skip_cr(start + 1, 0)) != NULL))
187 40cd76f4 2020-08-30 martijn return ptr;
188 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
192 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_quoted_pair(char *ptr, int optional)
194 40cd76f4 2020-08-30 martijn char *start = ptr;
196 40cd76f4 2020-08-30 martijn if (ptr[0] == '\\' && (
197 40cd76f4 2020-08-30 martijn (ptr = osmtpd_mheader_skip_vchar(start + 1, 0)) != NULL ||
198 40cd76f4 2020-08-30 martijn (ptr = osmtpd_mheader_skip_wsp(start + 1, 0)) != NULL))
199 40cd76f4 2020-08-30 martijn return ptr;
200 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_obs_qp(start, optional);
204 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_ccontent(char *ptr, int optional)
206 40cd76f4 2020-08-30 martijn char *start = ptr;
208 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_ctext(ptr, 0)) != NULL)
209 40cd76f4 2020-08-30 martijn return ptr;
210 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_quoted_pair(start, 0)) != NULL)
211 40cd76f4 2020-08-30 martijn return ptr;
212 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_comment(start, 0)) != NULL)
213 40cd76f4 2020-08-30 martijn return ptr;
214 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
218 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_comment(char *ptr, int optional)
220 40cd76f4 2020-08-30 martijn char *start = ptr;
222 40cd76f4 2020-08-30 martijn if (ptr++[0] != '(')
223 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
224 40cd76f4 2020-08-30 martijn while (1) {
225 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_fws(ptr, 1);
226 40cd76f4 2020-08-30 martijn if (ptr[0] == ')')
227 40cd76f4 2020-08-30 martijn return ptr + 1;
228 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_ccontent(ptr, 0)) == NULL)
229 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
234 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_cfws(char *ptr, int optional)
236 40cd76f4 2020-08-30 martijn char *start = ptr, *prev;
238 40cd76f4 2020-08-30 martijn while (1) {
239 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_fws(ptr, 1);
240 40cd76f4 2020-08-30 martijn prev = ptr;
241 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_comment(ptr, 0)) == NULL) {
242 40cd76f4 2020-08-30 martijn ptr = prev;
246 40cd76f4 2020-08-30 martijn return ptr == start && !optional ? NULL : ptr;
250 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_atext(char *ptr, int optional)
252 40cd76f4 2020-08-30 martijn char *start = ptr;
254 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_alpha(start, 0)) != NULL ||
255 40cd76f4 2020-08-30 martijn (ptr = osmtpd_mheader_skip_digit(start, 0)) != NULL)
256 40cd76f4 2020-08-30 martijn return ptr;
257 40cd76f4 2020-08-30 martijn ptr = start;
258 40cd76f4 2020-08-30 martijn if (ptr[0] == '!' || ptr[0] == '#' || ptr[0] == '$' || ptr[0] == '%' ||
259 40cd76f4 2020-08-30 martijn 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] == '~')
263 40cd76f4 2020-08-30 martijn return ptr + 1;
264 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
268 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_atom(char *ptr, int optional)
270 40cd76f4 2020-08-30 martijn char *start = ptr, *prev;
272 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_cfws(ptr, 1);
273 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_atext(ptr, 0)) == NULL)
274 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
276 40cd76f4 2020-08-30 martijn prev = ptr;
277 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_atext(ptr, 1);
278 40cd76f4 2020-08-30 martijn } while (prev != ptr);
279 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_cfws(ptr, 1);
283 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_dot_atom_text(char *ptr, int optional)
285 40cd76f4 2020-08-30 martijn char *start = ptr, *prev;
287 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_atext(ptr, 0)) == NULL)
288 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
290 40cd76f4 2020-08-30 martijn prev = ptr;
291 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_atext(ptr, 1);
292 40cd76f4 2020-08-30 martijn } while (ptr != prev);
294 40cd76f4 2020-08-30 martijn while (ptr[0] == '.') {
296 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_atext(ptr, 0)) == NULL)
297 40cd76f4 2020-08-30 martijn return prev;
299 40cd76f4 2020-08-30 martijn prev = ptr;
300 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_atext(ptr, 1);
301 40cd76f4 2020-08-30 martijn } while (ptr != prev);
303 40cd76f4 2020-08-30 martijn return ptr;
307 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_dot_atom(char *ptr, int optional)
309 40cd76f4 2020-08-30 martijn char *start = ptr;
311 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_cfws(ptr, 1);
312 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_dot_atom_text(ptr, 0)) == NULL)
313 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
314 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_cfws(ptr, 1);
319 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_qtext(char *ptr, int optional)
321 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_obs_no_ws_ctl(ptr, optional);
325 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_qtext(char *ptr, int optional)
327 40cd76f4 2020-08-30 martijn char *start = ptr;
329 40cd76f4 2020-08-30 martijn if (ptr[0] == 33 || (ptr[0] >= 35 && ptr[0] <= 91) ||
330 40cd76f4 2020-08-30 martijn (ptr[0] >= 93 && ptr[0] <= 126))
331 40cd76f4 2020-08-30 martijn return ptr + 1;
332 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_obs_qtext(ptr, 0)) != NULL)
333 40cd76f4 2020-08-30 martijn return ptr;
334 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
338 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_qcontent(char *ptr, int optional)
340 40cd76f4 2020-08-30 martijn char *start = ptr;
342 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_qtext(ptr, 0)) != NULL)
343 40cd76f4 2020-08-30 martijn return ptr;
344 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_quoted_pair(start, optional);
348 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_quoted_string(char *ptr, int optional)
350 40cd76f4 2020-08-30 martijn char *start = ptr, *prev;
352 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_cfws(ptr, 1);
353 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_dquote(ptr, 0)) == NULL)
354 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
355 40cd76f4 2020-08-30 martijn prev = ptr;
356 40cd76f4 2020-08-30 martijn while (1) {
357 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_fws(ptr, 1);
358 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_qcontent(ptr, 0)) == NULL)
360 40cd76f4 2020-08-30 martijn prev = ptr;
362 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_dquote(prev, 0)) == NULL)
363 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
364 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_cfws(ptr, 1);
368 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_word(char *ptr, int optional)
370 40cd76f4 2020-08-30 martijn char *start = ptr;
372 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_atom(ptr, 0)) != NULL)
373 40cd76f4 2020-08-30 martijn return ptr;
374 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_quoted_string(start, optional);
378 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_phrase(char *ptr, int optional)
380 40cd76f4 2020-08-30 martijn char *start = ptr, *prev;
382 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_word(ptr, 0)) == NULL)
383 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
384 40cd76f4 2020-08-30 martijn while (1) {
385 40cd76f4 2020-08-30 martijn prev = ptr;
386 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_word(ptr, 0)) != NULL)
387 40cd76f4 2020-08-30 martijn continue;
388 40cd76f4 2020-08-30 martijn ptr = prev;
389 40cd76f4 2020-08-30 martijn if (ptr[0] == '.')
390 40cd76f4 2020-08-30 martijn continue;
391 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_cfws(ptr, 0)) != NULL)
392 40cd76f4 2020-08-30 martijn continue;
393 40cd76f4 2020-08-30 martijn return prev;
398 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_phrase(char *ptr, int optional)
400 40cd76f4 2020-08-30 martijn /* obs-phrase is a superset of phrae */
401 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_obs_phrase(ptr, optional);
403 40cd76f4 2020-08-30 martijn char *start = ptr, *prev;
405 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_word(ptr, 0)) == NULL)
406 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
407 40cd76f4 2020-08-30 martijn while (1) {
408 40cd76f4 2020-08-30 martijn prev = ptr;
409 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_word(ptr, 0)) == NULL)
410 40cd76f4 2020-08-30 martijn return prev;
416 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_local_part(char *ptr, int optional)
418 40cd76f4 2020-08-30 martijn char *start = ptr, *prev;
420 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_word(ptr, 0)) == NULL)
421 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
422 40cd76f4 2020-08-30 martijn prev = ptr;
423 40cd76f4 2020-08-30 martijn while (ptr[0] == '.') {
425 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_word(ptr, 0)) == NULL)
426 40cd76f4 2020-08-30 martijn return prev;
427 40cd76f4 2020-08-30 martijn prev = ptr;
429 40cd76f4 2020-08-30 martijn return ptr;
433 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_local_part(char *ptr, int optional)
435 40cd76f4 2020-08-30 martijn char *start = ptr;
437 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_dot_atom(ptr, 0)) != NULL)
438 40cd76f4 2020-08-30 martijn return ptr;
439 40cd76f4 2020-08-30 martijn ptr = start;
440 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_quoted_string(ptr, 0)) != NULL)
441 40cd76f4 2020-08-30 martijn return ptr;
442 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_obs_local_part(start, optional);
446 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_dtext(char *ptr, int optional)
448 40cd76f4 2020-08-30 martijn char *start = ptr;
450 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_obs_no_ws_ctl(ptr, 0)) != NULL)
451 40cd76f4 2020-08-30 martijn return ptr;
452 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_quoted_pair(start, optional);
456 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_dtext(char *ptr, int optional)
458 40cd76f4 2020-08-30 martijn if ((ptr[0] >= 33 && ptr[0] <= 90) || (ptr[0] >= 94 && ptr[0] <= 126))
459 40cd76f4 2020-08-30 martijn return ptr + 1;
460 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_obs_dtext(ptr, optional);
465 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_domain_literal(char *ptr, int optional)
467 40cd76f4 2020-08-30 martijn char *start = ptr, *prev;
469 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_cfws(ptr, 1);
470 40cd76f4 2020-08-30 martijn if (ptr++[0] != '[')
471 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
472 40cd76f4 2020-08-30 martijn while (1) {
473 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_fws(ptr, 1);
474 40cd76f4 2020-08-30 martijn prev = ptr;
475 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_dtext(ptr, 0)) == NULL) {
476 40cd76f4 2020-08-30 martijn ptr = prev;
480 40cd76f4 2020-08-30 martijn if (ptr[0] != ']')
481 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
482 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_cfws(ptr, 1);
486 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_domain(char *ptr, int optional)
488 40cd76f4 2020-08-30 martijn char *start = ptr, *prev;
490 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_atom(ptr, 0)) == NULL)
491 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
492 40cd76f4 2020-08-30 martijn prev = ptr;
493 40cd76f4 2020-08-30 martijn while (1) {
494 40cd76f4 2020-08-30 martijn if (ptr++[0] != '.')
495 40cd76f4 2020-08-30 martijn return prev;
496 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_atom(ptr, 0)) == NULL)
497 40cd76f4 2020-08-30 martijn return prev;
498 40cd76f4 2020-08-30 martijn prev = ptr;
503 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_domain(char *ptr, int optional)
505 40cd76f4 2020-08-30 martijn char *start = ptr;
507 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_dot_atom(start, 0)) != NULL)
508 40cd76f4 2020-08-30 martijn return ptr;
509 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_domain_literal(start, 0)) != NULL)
510 40cd76f4 2020-08-30 martijn return ptr;
511 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_obs_domain(start, optional);
515 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_display_name(char *ptr, int optional)
517 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_phrase(ptr, optional);
521 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_domain_list(char *ptr, int optional)
523 40cd76f4 2020-08-30 martijn char *start = ptr, *prev;
525 40cd76f4 2020-08-30 martijn while (1) {
526 40cd76f4 2020-08-30 martijn if (ptr[0] == ',') {
528 40cd76f4 2020-08-30 martijn prev = ptr;
529 40cd76f4 2020-08-30 martijn continue;
530 40cd76f4 2020-08-30 martijn } else if ((ptr = osmtpd_mheader_skip_cfws(ptr, 0)) != NULL) {
531 40cd76f4 2020-08-30 martijn prev = ptr;
532 40cd76f4 2020-08-30 martijn continue;
536 40cd76f4 2020-08-30 martijn ptr = prev;
538 40cd76f4 2020-08-30 martijn if (ptr++[0] != '@')
539 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
540 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_domain(ptr, 0)) == NULL)
541 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
542 40cd76f4 2020-08-30 martijn while (1) {
543 40cd76f4 2020-08-30 martijn if (ptr[0] != ',')
546 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_cfws(ptr, 1);
547 40cd76f4 2020-08-30 martijn if (ptr[0] != '@')
548 40cd76f4 2020-08-30 martijn continue;
549 40cd76f4 2020-08-30 martijn prev = ptr;
550 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_domain(ptr + 1, 0)) == NULL) {
551 40cd76f4 2020-08-30 martijn ptr = prev;
555 40cd76f4 2020-08-30 martijn return ptr;
559 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_route(char *ptr, int optional)
561 40cd76f4 2020-08-30 martijn char *start = ptr;
563 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_obs_domain_list(ptr, 0)) == NULL)
564 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
565 40cd76f4 2020-08-30 martijn if (ptr++[0] != ':')
566 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
567 40cd76f4 2020-08-30 martijn return ptr;
571 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_addr_spec(char *ptr, int optional)
573 40cd76f4 2020-08-30 martijn char *start = ptr;
575 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_local_part(ptr, 0)) == NULL)
576 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
577 40cd76f4 2020-08-30 martijn if (ptr++[0] != '@')
578 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
579 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_domain(ptr, 0)) == NULL)
580 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
581 40cd76f4 2020-08-30 martijn return ptr;
585 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_angle_addr(char *ptr, int optional)
587 40cd76f4 2020-08-30 martijn char *start = ptr;
589 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_cfws(ptr, 1);
590 40cd76f4 2020-08-30 martijn if (ptr++[0] != '<')
591 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
592 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_obs_route(ptr, 0)) == NULL)
593 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
594 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_addr_spec(ptr, 0)) == NULL)
595 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
596 40cd76f4 2020-08-30 martijn if (ptr++[0] != '>')
597 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
598 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_cfws(ptr, 1);
602 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_angle_addr(char *ptr, int optional)
604 40cd76f4 2020-08-30 martijn char *start = ptr;
606 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_cfws(ptr, 1);
607 40cd76f4 2020-08-30 martijn if (ptr++[0] != '<')
608 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_obs_angle_addr(start, optional);
609 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_addr_spec(ptr, 0)) == NULL)
610 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_obs_angle_addr(start, optional);
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 return osmtpd_mheader_skip_cfws(ptr, 1);
617 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_name_addr(char *ptr, int optional)
619 40cd76f4 2020-08-30 martijn char *start = ptr;
621 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_display_name(ptr, 1);
622 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_angle_addr(ptr, 0)) == NULL)
623 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
624 40cd76f4 2020-08-30 martijn return ptr;
627 40cd76f4 2020-08-30 martijn /* Return the domain component of the first mailbox */
629 40cd76f4 2020-08-30 martijn osmtpd_mheader_from_domain(char *ptr)
631 40cd76f4 2020-08-30 martijn char *tmp;
633 40cd76f4 2020-08-30 martijn /* from */
634 40cd76f4 2020-08-30 martijn if (strncasecmp(ptr, "from:", 5) == 0) {
635 40cd76f4 2020-08-30 martijn ptr += 5;
636 40cd76f4 2020-08-30 martijn /* obs-from */
637 40cd76f4 2020-08-30 martijn } else if (strncasecmp(ptr, "from", 4) == 0) {
638 40cd76f4 2020-08-30 martijn ptr += 4;
640 40cd76f4 2020-08-30 martijn tmp = ptr;
641 40cd76f4 2020-08-30 martijn } while ((ptr = osmtpd_mheader_skip_wsp(ptr, 0)) != NULL);
642 40cd76f4 2020-08-30 martijn ptr = tmp;
643 40cd76f4 2020-08-30 martijn if (ptr++[0] != ':')
644 40cd76f4 2020-08-30 martijn return NULL;
645 40cd76f4 2020-08-30 martijn } else {
646 40cd76f4 2020-08-30 martijn errno = EINVAL;
647 40cd76f4 2020-08-30 martijn return NULL;
650 40cd76f4 2020-08-30 martijn /* Both from and obs-from use Mailbox-list CRLF */
651 40cd76f4 2020-08-30 martijn /* obs-mbox-list has just a prefix compared to mailbox-list */
652 40cd76f4 2020-08-30 martijn while (1) {
653 40cd76f4 2020-08-30 martijn tmp = ptr;
654 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_cfws(ptr, 1);
655 40cd76f4 2020-08-30 martijn if (ptr++[0] != ',') {
656 40cd76f4 2020-08-30 martijn ptr = tmp;
660 40cd76f4 2020-08-30 martijn /* We're only interested in the first mailbox */
661 40cd76f4 2020-08-30 martijn if (osmtpd_mheader_skip_name_addr(ptr, 0) != NULL) {
662 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_display_name(ptr, 1);
663 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_cfws(ptr, 1);
666 40cd76f4 2020-08-30 martijn /* addr-spec */
667 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_local_part(ptr, 0);
670 40cd76f4 2020-08-30 martijn tmp = osmtpd_mheader_skip_domain(ptr, 0);
671 40cd76f4 2020-08-30 martijn return strndup(ptr, tmp - ptr);
673 40cd76f4 2020-08-30 martijn if (osmtpd_mheader_skip_addr_spec(ptr, 0) != NULL) {
674 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_local_part(ptr, 0);
677 40cd76f4 2020-08-30 martijn tmp = osmtpd_mheader_skip_domain(ptr, 0);
678 40cd76f4 2020-08-30 martijn return strndup(ptr, tmp - ptr);
680 40cd76f4 2020-08-30 martijn errno = EINVAL;
681 40cd76f4 2020-08-30 martijn return NULL;