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"
25 60e9f82d 2022-01-27 martijn #include <stdio.h>
27 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_sp(char *ptr, int optional)
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;
35 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_htab(char *ptr, int optional)
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;
43 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_wsp(char *ptr, int optional)
45 40cd76f4 2020-08-30 martijn char *start = ptr;
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;
54 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_crlf(char *ptr, int optional)
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;
62 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_vchar(char *ptr, int optional)
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;
70 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_lf(char *ptr, int optional)
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;
78 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_cr(char *ptr, int optional)
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;
86 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_alpha(char *ptr, int optional)
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;
95 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_digit(char *ptr, int optional)
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;
103 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_dquote(char *ptr, int optional)
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;
111 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_fws(char *ptr, int optional)
113 40cd76f4 2020-08-30 martijn char *start = ptr, *prev;
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;
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;
135 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_fws(char *ptr, int optional)
137 40cd76f4 2020-08-30 martijn char *start = ptr, *prev = ptr;
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;
152 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_no_ws_ctl(char *ptr, int optional)
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;
161 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_ctext(char *ptr, int optional)
163 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_obs_no_ws_ctl(ptr, optional);
167 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_ctext(char *ptr, int optional)
169 40cd76f4 2020-08-30 martijn char *start = ptr;
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;
180 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_qp(char *ptr, int optional)
182 40cd76f4 2020-08-30 martijn char *start = ptr;
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;
193 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_quoted_pair(char *ptr, int optional)
195 40cd76f4 2020-08-30 martijn char *start = ptr;
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);
205 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_ccontent(char *ptr, int optional)
207 40cd76f4 2020-08-30 martijn char *start = ptr;
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;
219 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_comment(char *ptr, int optional)
221 40cd76f4 2020-08-30 martijn char *start = ptr;
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;
235 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_cfws(char *ptr, int optional)
237 40cd76f4 2020-08-30 martijn char *start = ptr, *prev;
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;
247 40cd76f4 2020-08-30 martijn return ptr == start && !optional ? NULL : ptr;
251 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_atext(char *ptr, int optional)
253 40cd76f4 2020-08-30 martijn char *start = ptr;
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;
269 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_atom(char *ptr, int optional)
271 40cd76f4 2020-08-30 martijn char *start = ptr, *prev;
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;
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);
284 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_dot_atom_text(char *ptr, int optional)
286 40cd76f4 2020-08-30 martijn char *start = ptr, *prev;
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;
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);
295 40cd76f4 2020-08-30 martijn while (ptr[0] == '.') {
297 40cd76f4 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_atext(ptr, 0)) == NULL)
298 40cd76f4 2020-08-30 martijn return prev;
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);
304 40cd76f4 2020-08-30 martijn return ptr;
308 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_dot_atom(char *ptr, int optional)
310 40cd76f4 2020-08-30 martijn char *start = ptr;
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);
320 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_qtext(char *ptr, int optional)
322 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_obs_no_ws_ctl(ptr, optional);
326 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_qtext(char *ptr, int optional)
328 40cd76f4 2020-08-30 martijn char *start = ptr;
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;
339 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_qcontent(char *ptr, int optional)
341 40cd76f4 2020-08-30 martijn char *start = ptr;
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);
349 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_quoted_string(char *ptr, int optional)
351 40cd76f4 2020-08-30 martijn char *start = ptr, *prev;
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)
361 40cd76f4 2020-08-30 martijn prev = ptr;
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);
369 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_word(char *ptr, int optional)
371 40cd76f4 2020-08-30 martijn char *start = ptr;
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);
379 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_phrase(char *ptr, int optional)
381 40cd76f4 2020-08-30 martijn char *start = ptr, *prev;
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] == '.') {
392 40cd76f4 2020-08-30 martijn continue;
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;
401 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_phrase(char *ptr, int optional)
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);
406 40cd76f4 2020-08-30 martijn char *start = ptr, *prev;
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;
419 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_local_part(char *ptr, int optional)
421 40cd76f4 2020-08-30 martijn char *start = ptr, *prev;
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] == '.') {
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;
432 40cd76f4 2020-08-30 martijn return ptr;
436 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_local_part(char *ptr, int optional)
438 40cd76f4 2020-08-30 martijn char *start = ptr;
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);
449 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_dtext(char *ptr, int optional)
451 40cd76f4 2020-08-30 martijn char *start = ptr;
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);
459 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_dtext(char *ptr, int optional)
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);
468 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_domain_literal(char *ptr, int optional)
470 40cd76f4 2020-08-30 martijn char *start = ptr, *prev;
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;
483 40cd76f4 2020-08-30 martijn if (ptr[0] != ']')
484 40cd76f4 2020-08-30 martijn return optional ? start : NULL;
486 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_cfws(ptr, 1);
490 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_domain(char *ptr, int optional)
492 40cd76f4 2020-08-30 martijn char *start = ptr, *prev;
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;
507 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_domain(char *ptr, int optional)
509 40cd76f4 2020-08-30 martijn char *start = ptr;
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);
519 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_display_name(char *ptr, int optional)
521 40cd76f4 2020-08-30 martijn return osmtpd_mheader_skip_phrase(ptr, optional);
525 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_domain_list(char *ptr, int optional)
527 1ebab45c 2021-05-26 martijn char *start = ptr, *prev = ptr;
529 40cd76f4 2020-08-30 martijn while (1) {
530 40cd76f4 2020-08-30 martijn if (ptr[0] == ',') {
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;
540 40cd76f4 2020-08-30 martijn ptr = prev;
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] != ',')
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;
559 40cd76f4 2020-08-30 martijn return ptr;
563 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_route(char *ptr, int optional)
565 40cd76f4 2020-08-30 martijn char *start = ptr;
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;
575 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_addr_spec(char *ptr, int optional)
577 40cd76f4 2020-08-30 martijn char *start = ptr;
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;
589 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_obs_angle_addr(char *ptr, int optional)
591 40cd76f4 2020-08-30 martijn char *start = ptr;
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);
606 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_angle_addr(char *ptr, int optional)
608 40cd76f4 2020-08-30 martijn char *start = ptr;
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);
621 40cd76f4 2020-08-30 martijn osmtpd_mheader_skip_name_addr(char *ptr, int optional)
623 40cd76f4 2020-08-30 martijn char *start = ptr;
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;
632 60e9f82d 2022-01-27 martijn osmtpd_mheader_domain_uncomment(char *ptr)
634 60e9f82d 2022-01-27 martijn char *domain0, *domain, *tmp, *end;
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);
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);
654 60e9f82d 2022-01-27 martijn tmp = osmtpd_mheader_skip_dtext(domain, 0);
655 60e9f82d 2022-01-27 martijn if (tmp == NULL)
657 60e9f82d 2022-01-27 martijn domain = tmp;
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;
663 60e9f82d 2022-01-27 martijn return strndup(ptr, osmtpd_mheader_skip_obs_domain(ptr, 1) - ptr);
666 40cd76f4 2020-08-30 martijn /* Return the domain component of the first mailbox */
668 40cd76f4 2020-08-30 martijn osmtpd_mheader_from_domain(char *ptr)
670 40cd76f4 2020-08-30 martijn char *tmp;
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;
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;
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;
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);
705 40cd76f4 2020-08-30 martijn /* addr-spec */
706 40cd76f4 2020-08-30 martijn ptr = osmtpd_mheader_skip_local_part(ptr, 0);
709 60e9f82d 2022-01-27 martijn return osmtpd_mheader_domain_uncomment(ptr);
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);
715 60e9f82d 2022-01-27 martijn return osmtpd_mheader_domain_uncomment(ptr);
717 40cd76f4 2020-08-30 martijn errno = EINVAL;
718 40cd76f4 2020-08-30 martijn return NULL;