2 * Copyright (c) 2020 Martijn van Duren <martijn@openbsd.org>
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
28 osmtpd_mheader_skip_sp(char *ptr, int optional)
32 return optional ? ptr : NULL;
36 osmtpd_mheader_skip_htab(char *ptr, int optional)
40 return optional ? ptr : NULL;
44 osmtpd_mheader_skip_char(char *ptr, int optional)
46 if (ptr[0] >= 0x01 && ptr[0] <= 0x7f)
48 return optional ? ptr : NULL;
52 osmtpd_mheader_skip_ctl(char *ptr, int optional)
54 if ((ptr[0] >= 0x00 && ptr[0] <= 0x1f) || ptr[0] == 0x7f)
56 return optional ? ptr : NULL;
60 osmtpd_mheader_skip_wsp(char *ptr, int optional)
64 if ((ptr = osmtpd_mheader_skip_sp(start, 0)) != NULL ||
65 (ptr = osmtpd_mheader_skip_htab(start, 0)) != NULL)
67 return optional ? start : NULL;
71 osmtpd_mheader_skip_crlf(char *ptr, int optional)
73 if (ptr[0] == 13 && ptr[1] == 10)
75 return optional ? ptr : NULL;
79 osmtpd_mheader_skip_vchar(char *ptr, int optional)
81 if (ptr[0] >= 0x21 && ptr[0] <= 0x7e)
83 return optional ? ptr : NULL;
87 osmtpd_mheader_skip_lf(char *ptr, int optional)
91 return optional ? ptr : NULL;
95 osmtpd_mheader_skip_cr(char *ptr, int optional)
99 return optional ? ptr : NULL;
103 osmtpd_mheader_skip_alpha(char *ptr, int optional)
105 if ((ptr[0] >= 0x41 && ptr[0] <= 0x5a) ||
106 (ptr[0] >= 0x61 && ptr[0] <= 0x7a))
108 return optional ? ptr : NULL;
112 osmtpd_mheader_skip_digit(char *ptr, int optional)
114 if (ptr[0] >= 0x30 && ptr[0] <= 0x39)
116 return optional ? ptr : NULL;
120 osmtpd_mheader_skip_letdig(char *ptr, int optional)
124 if ((ptr = osmtpd_mheader_skip_alpha(start, 0)) == NULL &&
125 (ptr = osmtpd_mheader_skip_digit(start, 0)) == NULL)
126 return optional ? start : NULL;
131 osmtpd_mheader_skip_ldhstring(char *ptr, int optional)
133 char *start = ptr, *prev;
138 if ((ptr = osmtpd_mheader_skip_alpha(prev, 0)) != NULL ||
139 (ptr = osmtpd_mheader_skip_digit(prev, 0)) != NULL) {
143 if (prev[0] == '-') {
154 return optional ? start : NULL;
159 osmtpd_mheader_skip_dquote(char *ptr, int optional)
163 return optional ? ptr : NULL;
167 osmtpd_mheader_skip_hexoctet(char *ptr, int optional)
172 return optional ? ptr : NULL;
174 if (ptr[0] == 'A' || ptr[0] == 'B' || ptr[0] == 'C' || ptr[0] == 'D' ||
175 ptr[0] == 'E' || ptr[0] == 'F')
177 else if ((ptr = osmtpd_mheader_skip_digit(ptr, 0)) == NULL)
178 return optional ? start : NULL;
179 if (ptr[0] == 'A' || ptr[0] == 'B' || ptr[0] == 'C' || ptr[0] == 'D' ||
180 ptr[0] == 'E' || ptr[0] == 'F')
182 else if ((ptr = osmtpd_mheader_skip_digit(ptr, 0)) == NULL)
183 return optional ? start : NULL;
188 osmtpd_mheader_skip_obs_fws(char *ptr, int optional)
190 char *start = ptr, *prev;
192 if ((ptr = osmtpd_mheader_skip_wsp(ptr, 0)) == NULL)
193 return optional ? start : NULL;
195 while ((ptr = osmtpd_mheader_skip_wsp(ptr, 0)) != NULL)
200 if ((ptr = osmtpd_mheader_skip_crlf(ptr, 0)) == NULL)
202 if ((ptr = osmtpd_mheader_skip_wsp(ptr, 0)) == NULL)
205 while ((ptr = osmtpd_mheader_skip_wsp(ptr, 0)) != NULL)
212 osmtpd_mheader_skip_fws(char *ptr, int optional)
214 char *start = ptr, *prev = ptr;
216 while ((ptr = osmtpd_mheader_skip_wsp(ptr, 0)) != NULL)
218 if ((ptr = osmtpd_mheader_skip_crlf(prev, 1)) == prev)
220 if ((ptr = osmtpd_mheader_skip_wsp(ptr, 0)) == NULL)
221 return osmtpd_mheader_skip_obs_fws(start, optional);
223 while ((ptr = osmtpd_mheader_skip_wsp(ptr, 0)) != NULL)
229 osmtpd_mheader_skip_obs_no_ws_ctl(char *ptr, int optional)
231 if ((ptr[0] >= 1 && ptr[0] <= 8) || ptr[0] == 11 || ptr[0] == 12 ||
232 (ptr[0] >= 14 && ptr[0] <= 31) || ptr[0] == 127)
234 return optional ? ptr : NULL;
238 osmtpd_mheader_skip_obs_ctext(char *ptr, int optional)
240 return osmtpd_mheader_skip_obs_no_ws_ctl(ptr, optional);
244 osmtpd_mheader_skip_ctext(char *ptr, int optional)
248 if ((ptr[0] >= 33 && ptr[0] <= 39) || (ptr[0] >= 42 && ptr[0] <= 91) ||
249 (ptr[0] >= 93 && ptr[0] <= 126))
251 if ((ptr = osmtpd_mheader_skip_obs_ctext(ptr, 0)) != NULL)
253 return optional ? start : NULL;
257 osmtpd_mheader_skip_obs_qp(char *ptr, int optional)
261 if (ptr[0] == '\\' && (
262 (ptr = osmtpd_mheader_skip_obs_no_ws_ctl(start + 1, 0)) != NULL ||
263 (ptr = osmtpd_mheader_skip_lf(start + 1, 0)) != NULL ||
264 (ptr = osmtpd_mheader_skip_cr(start + 1, 0)) != NULL))
266 return optional ? start : NULL;
270 osmtpd_mheader_skip_quoted_pair(char *ptr, int optional)
274 if (ptr[0] == '\\' && (
275 (ptr = osmtpd_mheader_skip_vchar(start + 1, 0)) != NULL ||
276 (ptr = osmtpd_mheader_skip_wsp(start + 1, 0)) != NULL))
278 return osmtpd_mheader_skip_obs_qp(start, optional);
282 osmtpd_mheader_skip_ccontent(char *ptr, int optional)
286 if ((ptr = osmtpd_mheader_skip_ctext(ptr, 0)) != NULL)
288 if ((ptr = osmtpd_mheader_skip_quoted_pair(start, 0)) != NULL)
290 if ((ptr = osmtpd_mheader_skip_comment(start, 0)) != NULL)
292 return optional ? start : NULL;
296 osmtpd_mheader_skip_comment(char *ptr, int optional)
301 return optional ? start : NULL;
303 ptr = osmtpd_mheader_skip_fws(ptr, 1);
306 if ((ptr = osmtpd_mheader_skip_ccontent(ptr, 0)) == NULL)
307 return optional ? start : NULL;
312 osmtpd_mheader_skip_cfws(char *ptr, int optional)
314 char *start = ptr, *prev;
317 ptr = osmtpd_mheader_skip_fws(ptr, 1);
319 if ((ptr = osmtpd_mheader_skip_comment(ptr, 0)) == NULL) {
324 return ptr == start && !optional ? NULL : ptr;
328 osmtpd_mheader_skip_atext(char *ptr, int optional)
332 if ((ptr = osmtpd_mheader_skip_alpha(start, 0)) != NULL ||
333 (ptr = osmtpd_mheader_skip_digit(start, 0)) != NULL)
336 if (ptr[0] == '!' || ptr[0] == '#' || ptr[0] == '$' || ptr[0] == '%' ||
337 ptr[0] == '&' || ptr[0] == '\'' || ptr[0] == '*' || ptr[0] == '+' ||
338 ptr[0] == '-' || ptr[0] == '/' || ptr[0] == '=' || ptr[0] == '?' ||
339 ptr[0] == '^' || ptr[0] == '_' || ptr[0] == '`' || ptr[0] == '{' ||
340 ptr[0] == '|' || ptr[0] == '}' || ptr[0] == '~')
342 return optional ? start : NULL;
346 osmtpd_mheader_skip_atom(char *ptr, int optional)
348 char *start = ptr, *prev;
350 ptr = osmtpd_mheader_skip_cfws(ptr, 1);
351 if ((ptr = osmtpd_mheader_skip_atext(ptr, 0)) == NULL)
352 return optional ? start : NULL;
355 ptr = osmtpd_mheader_skip_atext(ptr, 1);
356 } while (prev != ptr);
357 return osmtpd_mheader_skip_cfws(ptr, 1);
361 osmtpd_mheader_skip_dot_atom_text(char *ptr, int optional)
363 char *start = ptr, *prev;
365 if ((ptr = osmtpd_mheader_skip_atext(ptr, 0)) == NULL)
366 return optional ? start : NULL;
369 ptr = osmtpd_mheader_skip_atext(ptr, 1);
370 } while (ptr != prev);
372 while (ptr[0] == '.') {
374 if ((ptr = osmtpd_mheader_skip_atext(ptr, 0)) == NULL)
378 ptr = osmtpd_mheader_skip_atext(ptr, 1);
379 } while (ptr != prev);
385 osmtpd_mheader_skip_dot_atom(char *ptr, int optional)
389 ptr = osmtpd_mheader_skip_cfws(ptr, 1);
390 if ((ptr = osmtpd_mheader_skip_dot_atom_text(ptr, 0)) == NULL)
391 return optional ? start : NULL;
392 return osmtpd_mheader_skip_cfws(ptr, 1);
396 osmtpd_mheader_skip_obs_qtext(char *ptr, int optional)
398 return osmtpd_mheader_skip_obs_no_ws_ctl(ptr, optional);
402 osmtpd_mheader_skip_qtext(char *ptr, int optional)
406 if (ptr[0] == 33 || (ptr[0] >= 35 && ptr[0] <= 91) ||
407 (ptr[0] >= 93 && ptr[0] <= 126))
409 if ((ptr = osmtpd_mheader_skip_obs_qtext(ptr, 0)) != NULL)
411 return optional ? start : NULL;
415 osmtpd_mheader_skip_qcontent(char *ptr, int optional)
419 if ((ptr = osmtpd_mheader_skip_qtext(ptr, 0)) != NULL)
421 return osmtpd_mheader_skip_quoted_pair(start, optional);
425 osmtpd_mheader_skip_quoted_string(char *ptr, int optional)
427 char *start = ptr, *prev;
429 ptr = osmtpd_mheader_skip_cfws(ptr, 1);
430 if ((ptr = osmtpd_mheader_skip_dquote(ptr, 0)) == NULL)
431 return optional ? start : NULL;
434 ptr = osmtpd_mheader_skip_fws(ptr, 1);
435 if ((ptr = osmtpd_mheader_skip_qcontent(ptr, 0)) == NULL)
439 if ((ptr = osmtpd_mheader_skip_dquote(prev, 0)) == NULL)
440 return optional ? start : NULL;
441 return osmtpd_mheader_skip_cfws(ptr, 1);
445 osmtpd_mheader_skip_keyword(char *ptr, int optional)
447 return osmtpd_mheader_skip_ldhstring(ptr, optional);
451 osmtpd_mheader_skip_word(char *ptr, int optional)
455 if ((ptr = osmtpd_mheader_skip_atom(ptr, 0)) != NULL)
457 return osmtpd_mheader_skip_quoted_string(start, optional);
461 osmtpd_mheader_skip_obs_phrase(char *ptr, int optional)
463 char *start = ptr, *prev;
465 if ((ptr = osmtpd_mheader_skip_word(ptr, 0)) == NULL)
466 return optional ? start : NULL;
469 if ((ptr = osmtpd_mheader_skip_word(ptr, 0)) != NULL)
476 if ((ptr = osmtpd_mheader_skip_cfws(ptr, 0)) != NULL)
483 osmtpd_mheader_skip_phrase(char *ptr, int optional)
485 /* obs-phrase is a superset of phrae */
486 return osmtpd_mheader_skip_obs_phrase(ptr, optional);
488 char *start = ptr, *prev;
490 if ((ptr = osmtpd_mheader_skip_word(ptr, 0)) == NULL)
491 return optional ? start : NULL;
494 if ((ptr = osmtpd_mheader_skip_word(ptr, 0)) == NULL)
501 osmtpd_mheader_skip_obs_local_part(char *ptr, int optional)
503 char *start = ptr, *prev;
505 if ((ptr = osmtpd_mheader_skip_word(ptr, 0)) == NULL)
506 return optional ? start : NULL;
508 while (ptr[0] == '.') {
510 if ((ptr = osmtpd_mheader_skip_word(ptr, 0)) == NULL)
518 osmtpd_mheader_skip_local_part(char *ptr, int optional)
522 if ((ptr = osmtpd_mheader_skip_dot_atom(ptr, 0)) != NULL)
525 if ((ptr = osmtpd_mheader_skip_quoted_string(ptr, 0)) != NULL)
527 return osmtpd_mheader_skip_obs_local_part(start, optional);
531 osmtpd_mheader_skip_subdomain(char *ptr, int optional)
535 if ((ptr = osmtpd_mheader_skip_letdig(ptr, 0)) == NULL)
536 return optional ? start : NULL;
537 return osmtpd_mheader_skip_ldhstring(ptr, 1);
541 osmtpd_mheader_skip_obs_dtext(char *ptr, int optional)
545 if ((ptr = osmtpd_mheader_skip_obs_no_ws_ctl(ptr, 0)) != NULL)
547 return osmtpd_mheader_skip_quoted_pair(start, optional);
551 osmtpd_mheader_skip_dtext(char *ptr, int optional)
553 if ((ptr[0] >= 33 && ptr[0] <= 90) || (ptr[0] >= 94 && ptr[0] <= 126))
555 return osmtpd_mheader_skip_obs_dtext(ptr, optional);
560 osmtpd_mheader_skip_domain_literal(char *ptr, int optional)
562 char *start = ptr, *prev;
564 ptr = osmtpd_mheader_skip_cfws(ptr, 1);
566 return optional ? start : NULL;
568 ptr = osmtpd_mheader_skip_fws(ptr, 1);
570 if ((ptr = osmtpd_mheader_skip_dtext(ptr, 0)) == NULL) {
576 return optional ? start : NULL;
578 return osmtpd_mheader_skip_cfws(ptr, 1);
582 osmtpd_mheader_skip_obs_domain(char *ptr, int optional)
584 char *start = ptr, *prev;
586 if ((ptr = osmtpd_mheader_skip_atom(ptr, 0)) == NULL)
587 return optional ? start : NULL;
592 if ((ptr = osmtpd_mheader_skip_atom(ptr, 0)) == NULL)
599 osmtpd_mheader_skip_domain(char *ptr, int optional)
603 if ((ptr = osmtpd_mheader_skip_dot_atom(start, 0)) != NULL)
605 if ((ptr = osmtpd_mheader_skip_domain_literal(start, 0)) != NULL)
607 return osmtpd_mheader_skip_obs_domain(start, optional);
611 osmtpd_mheader_skip_display_name(char *ptr, int optional)
613 return osmtpd_mheader_skip_phrase(ptr, optional);
617 osmtpd_mheader_skip_obs_domain_list(char *ptr, int optional)
619 char *start = ptr, *prev = ptr;
626 } else if ((ptr = osmtpd_mheader_skip_cfws(ptr, 0)) != NULL) {
635 return optional ? start : NULL;
636 if ((ptr = osmtpd_mheader_skip_domain(ptr, 0)) == NULL)
637 return optional ? start : NULL;
642 ptr = osmtpd_mheader_skip_cfws(ptr, 1);
646 if ((ptr = osmtpd_mheader_skip_domain(ptr + 1, 0)) == NULL) {
655 osmtpd_mheader_skip_obs_route(char *ptr, int optional)
659 if ((ptr = osmtpd_mheader_skip_obs_domain_list(ptr, 0)) == NULL)
660 return optional ? start : NULL;
662 return optional ? start : NULL;
667 osmtpd_mheader_skip_addr_spec(char *ptr, int optional)
671 if ((ptr = osmtpd_mheader_skip_local_part(ptr, 0)) == NULL)
672 return optional ? start : NULL;
674 return optional ? start : NULL;
675 if ((ptr = osmtpd_mheader_skip_domain(ptr, 0)) == NULL)
676 return optional ? start : NULL;
681 osmtpd_mheader_skip_obs_angle_addr(char *ptr, int optional)
685 ptr = osmtpd_mheader_skip_cfws(ptr, 1);
687 return optional ? start : NULL;
688 if ((ptr = osmtpd_mheader_skip_obs_route(ptr, 0)) == NULL)
689 return optional ? start : NULL;
690 if ((ptr = osmtpd_mheader_skip_addr_spec(ptr, 0)) == NULL)
691 return optional ? start : NULL;
693 return optional ? start : NULL;
694 return osmtpd_mheader_skip_cfws(ptr, 1);
698 osmtpd_mheader_skip_angle_addr(char *ptr, int optional)
702 ptr = osmtpd_mheader_skip_cfws(ptr, 1);
704 return osmtpd_mheader_skip_obs_angle_addr(start, optional);
705 if ((ptr = osmtpd_mheader_skip_addr_spec(ptr, 0)) == NULL)
706 return osmtpd_mheader_skip_obs_angle_addr(start, optional);
708 return osmtpd_mheader_skip_obs_angle_addr(start, optional);
709 return osmtpd_mheader_skip_cfws(ptr, 1);
713 osmtpd_mheader_skip_name_addr(char *ptr, int optional)
717 ptr = osmtpd_mheader_skip_display_name(ptr, 1);
718 if ((ptr = osmtpd_mheader_skip_angle_addr(ptr, 0)) == NULL)
719 return optional ? start : NULL;
724 osmtpd_mheader_skip_alphadigitps(char *ptr, int optional)
728 if ((end = osmtpd_mheader_skip_alpha(ptr, 0)) == NULL &&
729 (end = osmtpd_mheader_skip_digit(ptr, 0)) == NULL &&
730 ptr[0] != '+' && ptr[0] != '/')
731 return optional ? ptr : NULL;
732 return end == NULL ? ptr + 1 : end;
736 osmtpd_mheader_skip_base64string(char *ptr, int optional)
740 if ((ptr = osmtpd_mheader_skip_alphadigitps(ptr, 0)) == NULL)
741 return optional ? start : NULL;
744 ptr = osmtpd_mheader_skip_fws(ptr, 1);
745 if ((ptr = osmtpd_mheader_skip_alphadigitps(ptr, 0)) == NULL)
749 ptr = osmtpd_mheader_skip_fws(ptr, 1);
753 ptr = osmtpd_mheader_skip_fws(ptr, 1);
764 osmtpd_mheader_skip_hyphenatedword(char *ptr, int optional)
766 char *start = ptr, *end, *hyphen;
768 if ((ptr = osmtpd_mheader_skip_alpha(ptr, 0)) == NULL)
769 return optional ? start : NULL;
774 hyphen = hyphen == NULL ? ptr - 1 : hyphen;
779 if ((ptr = osmtpd_mheader_skip_alpha(start, 0)) == NULL &&
780 (ptr = osmtpd_mheader_skip_digit(start, 0)) == NULL)
786 return hyphen == NULL ? end : hyphen;
790 osmtpd_mheader_skip_ftext(char *ptr, int optional)
792 if ((ptr[0] >= 33 && ptr[0] <= 57) ||
793 (ptr[0] >= 59 && ptr[0] <= 126))
795 return optional ? ptr : NULL;
799 osmtpd_mheader_skip_fieldname(char *ptr, int optional)
803 if ((ptr = osmtpd_mheader_skip_ftext(ptr, 0)) == NULL)
804 return optional ? start : NULL;
807 if ((ptr = osmtpd_mheader_skip_ftext(ptr, 0)) == NULL)
813 osmtpd_mheader_skip_hdrname(char *ptr, int optional)
815 return osmtpd_mheader_skip_fieldname(ptr, optional);
819 osmtpd_mheader_skip_tspecials(char *ptr, int optional)
821 if (ptr[0] == '(' || ptr[0] == ')' || ptr[0] == '<' || ptr[0] == '>' ||
822 ptr[0] == '@' || ptr[0] == ',' || ptr[0] == ';' || ptr[0] == ':' ||
823 ptr[0] == '\\' || ptr[0] == '"' || ptr[0] == '/' || ptr[0] == '[' ||
824 ptr[0] == ']' || ptr[0] == '?' || ptr[0] == '=')
826 return optional ? ptr : NULL;
830 osmtpd_mheader_skip_token(char *ptr, int optional)
837 if ((ptr = osmtpd_mheader_skip_char(start, 0)) != NULL &&
838 osmtpd_mheader_skip_sp(start, 0) == NULL &&
839 osmtpd_mheader_skip_ctl(start, 0) == NULL &&
840 osmtpd_mheader_skip_tspecials(start, 0) == NULL) {
844 return optional || !first ? start : NULL;
849 osmtpd_mheader_skip_value(char *ptr, int optional)
853 if ((ptr = osmtpd_mheader_skip_token(start, 0)) != NULL)
855 if ((ptr = osmtpd_mheader_skip_quoted_string(start, 0)) != NULL)
857 return optional ? start : NULL;
861 osmtpd_mheader_skip_dkim_safe_char(char *ptr, int optional)
863 if ((ptr[0] >= 0x21 && ptr[0] <= 0x3a) || ptr[0] == 0x3c ||
864 (ptr[0] >= 0x3e && ptr[0] <= 0x7e))
866 return optional ? ptr : NULL;
870 osmtpd_mheader_skip_dkim_quoted_printable(char *ptr, int optional)
876 if ((ptr = osmtpd_mheader_skip_fws(start, 0)) != NULL)
878 if ((ptr = osmtpd_mheader_skip_hexoctet(start, 0)) != NULL)
880 ptr = osmtpd_mheader_skip_dkim_safe_char(start, 0);
888 osmtpd_mheader_skip_dkim_qp_hdr_value(char *ptr, int optional)
890 return osmtpd_mheader_skip_dkim_quoted_printable(ptr, optional);
894 osmtpd_mheader_skip_dkimsig_alnumpunc(char *ptr, int optional)
898 if ((ptr = osmtpd_mheader_skip_alpha(start, 0)) != NULL)
900 if ((ptr = osmtpd_mheader_skip_digit(start, 0)) != NULL)
904 return optional ? start : NULL;
908 osmtpd_mheader_skip_dkimsig_valchar(char *ptr, int optional)
910 if ((ptr[0] >= 0x21 && ptr[0] <= 0x3A) ||
911 (ptr[0] >= 0x3C && ptr[0] <= 0x7E))
913 return optional ? ptr : NULL;
917 osmtpd_mheader_skip_dkimsig_tval(char *ptr, int optional)
919 char *start = ptr, *prev;
921 if ((ptr = osmtpd_mheader_skip_dkimsig_valchar(ptr, 0)) == NULL)
922 return optional ? start : NULL;
924 while ((ptr = osmtpd_mheader_skip_dkimsig_valchar(ptr, 0)) != NULL)
930 osmtpd_mheader_skip_dkimsig_tagvalue(char *ptr, int optional)
932 char *start = ptr, *prev;
934 if ((ptr = osmtpd_mheader_skip_dkimsig_tval(ptr, 0)) == NULL)
939 /* FWS contains WSP */
940 if ((ptr = osmtpd_mheader_skip_fws(ptr, 0)) == NULL)
943 while ((ptr = osmtpd_mheader_skip_fws(ptr, 0)) != NULL)
946 if ((ptr = osmtpd_mheader_skip_dkimsig_tval(ptr, 0)) == NULL)
952 osmtpd_mheader_skip_dkimsig_tagname(char *ptr, int optional)
954 char *start = ptr, *prev;
956 if ((ptr = osmtpd_mheader_skip_alpha(ptr, 0)) == NULL)
957 return optional ? start : NULL;
959 while ((ptr = osmtpd_mheader_skip_dkimsig_alnumpunc(ptr, 0)) != NULL)
965 osmtpd_mheader_skip_dkimsig_tagspec(char *ptr, int optional)
969 ptr = osmtpd_mheader_skip_fws(ptr, 1);
970 if ((ptr = osmtpd_mheader_skip_dkimsig_tagname(ptr, 0)) == NULL)
971 return optional ? start : NULL;
972 ptr = osmtpd_mheader_skip_fws(ptr, 1);
974 return optional ? start : NULL;
976 ptr = osmtpd_mheader_skip_fws(ptr, 1);
977 if ((ptr = osmtpd_mheader_skip_dkimsig_tagvalue(ptr, 0)) == NULL)
978 return optional ? start : NULL;
979 return osmtpd_mheader_skip_fws(ptr, 1);
983 osmtpd_mheader_skip_dkimsig_taglist(char *ptr, int optional)
987 if ((ptr = osmtpd_mheader_skip_dkimsig_tagspec(ptr, 0)) == NULL)
988 return optional ? start : NULL;
990 /* Starting or trailing ';' */
995 if ((ptr = osmtpd_mheader_skip_dkimsig_tagspec(ptr, 0)) == NULL)
1001 osmtpd_mheader_skip_dkimsig_xsigatagh(char *ptr, int optional)
1003 char *start = ptr, *prev, *end;
1005 if ((ptr = osmtpd_mheader_skip_alpha(ptr, 0)) == NULL)
1006 return optional ? start : NULL;
1008 while ((end = osmtpd_mheader_skip_alpha(ptr, 0)) != NULL ||
1009 (end = osmtpd_mheader_skip_digit(ptr, 0)) != NULL) {
1017 osmtpd_mheader_skip_dkimsig_xsigatagk(char *ptr, int optional)
1019 char *start = ptr, *prev, *end;
1021 if ((ptr = osmtpd_mheader_skip_alpha(ptr, 0)) == NULL)
1022 return optional ? start : NULL;
1024 while ((end = osmtpd_mheader_skip_alpha(ptr, 0)) != NULL ||
1025 (end = osmtpd_mheader_skip_digit(ptr, 0)) != NULL) {
1033 osmtpd_mheader_skip_dkimsig_sigatagh(char *ptr, int optional)
1035 /* rsa / ed25519 covered by x-sig-a-tag-h */
1036 return osmtpd_mheader_skip_dkimsig_xsigatagh(ptr, optional);
1040 osmtpd_mheader_skip_dkimsig_sigatagk(char *ptr, int optional)
1042 /* sha1 / sha256 covered by x-sig-a-tag-k */
1043 return osmtpd_mheader_skip_dkimsig_xsigatagk(ptr, optional);
1047 osmtpd_mheader_skip_dkimsig_sigatagalg(char *ptr, int optional)
1051 if ((ptr = osmtpd_mheader_skip_dkimsig_sigatagk(ptr, 0)) == NULL)
1052 return optional ? start : NULL;
1054 return optional ? start : NULL;
1056 if ((ptr = osmtpd_mheader_skip_dkimsig_sigatagh(ptr, 0)) == NULL)
1057 return optional ? start : NULL;
1062 osmtpd_mheader_skip_dkimsig_xsigctagalg(char *ptr, int optional)
1064 return osmtpd_mheader_skip_hyphenatedword(ptr, optional);
1068 osmtpd_mheader_skip_dkimsig_sigctagalg(char *ptr, int optional)
1070 /* simple / relaxed covered by x-sig-c-tag-alga */
1071 return osmtpd_mheader_skip_dkimsig_xsigctagalg(ptr, optional);
1075 osmtpd_mheader_skip_dkimsig_xkeyhtagalg(char *ptr, int optional)
1077 return osmtpd_mheader_skip_hyphenatedword(ptr, optional);
1081 osmtpd_mheader_skip_dkimsig_keyhtagalg(char *ptr, int optional)
1083 /* sha1 / sha256 covered by x-key-h-tag-alg */
1084 return osmtpd_mheader_skip_dkimsig_xkeyhtagalg(ptr, optional);
1088 osmtpd_mheader_skip_dkimsig_keyhtagvalue(char *ptr, int optional)
1092 if ((ptr = osmtpd_mheader_skip_dkimsig_keyhtagalg(ptr, 0)) == NULL)
1093 return optional ? start : NULL;
1096 ptr = osmtpd_mheader_skip_fws(ptr, 1);
1099 ptr = osmtpd_mheader_skip_fws(ptr + 1, 1);
1100 ptr = osmtpd_mheader_skip_dkimsig_keyhtagalg(ptr, 0);
1107 osmtpd_mheader_skip_dkimsig_xsigqtagargs(char *ptr, int optional)
1109 return osmtpd_mheader_skip_dkim_qp_hdr_value(ptr, optional);
1113 osmtpd_mheader_skip_dkimsig_xsigqtagtype(char *ptr, int optional)
1115 return osmtpd_mheader_skip_hyphenatedword(ptr, optional);
1119 osmtpd_mheader_skip_dkimsig_sigqtagmethod(char *ptr, int optional)
1123 /* dns/txt covered by x-sig-q-tag-type ["/" x-sig-q-tag-args] */
1124 if ((ptr = osmtpd_mheader_skip_dkimsig_xsigqtagtype(ptr, 0)) == NULL)
1125 return optional ? start : NULL;
1129 if ((ptr = osmtpd_mheader_skip_dkimsig_xsigqtagargs(ptr, 0)) == NULL)
1135 osmtpd_mheader_skip_dkimsig_sigztagcopy(char *ptr, int optional)
1139 if ((ptr = osmtpd_mheader_skip_hdrname(ptr, 0)) == NULL)
1140 return optional ? start : NULL;
1141 ptr = osmtpd_mheader_skip_fws(ptr, 1);
1143 return optional ? start : NULL;
1144 if ((ptr = osmtpd_mheader_skip_dkim_qp_hdr_value(ptr, 0)) == NULL)
1145 return optional ? start : NULL;
1150 osmtpd_mheader_skip_dkimsig_sigztagvalue(char *ptr, int optional)
1154 if ((ptr = osmtpd_mheader_skip_dkimsig_sigztagcopy(ptr, 0)) == NULL)
1155 return optional ? start : NULL;
1160 osmtpd_mheader_skip_fws(ptr + 1, 1);
1161 ptr = osmtpd_mheader_skip_dkimsig_sigztagcopy(ptr, 0);
1168 osmtpd_mheader_skip_dkimsig_xkeystagtype(char *ptr, int optional)
1170 return osmtpd_mheader_skip_hyphenatedword(ptr, optional);
1174 osmtpd_mheader_skip_dkimsig_keystagtype(char *ptr, int optional)
1178 /* email covered by x-key-s-tag-type */
1179 return osmtpd_mheader_skip_dkimsig_xkeystagtype(ptr, optional);
1183 osmtpd_mheader_skip_dkimsig_keystagvalue(char *ptr, int optional)
1187 if ((ptr = osmtpd_mheader_skip_dkimsig_keystagtype(ptr, 0)) == NULL)
1188 return optional ? start : NULL;
1191 ptr = osmtpd_mheader_skip_fws(ptr, 1);
1194 ptr = osmtpd_mheader_skip_fws(ptr + 1, 1);
1195 ptr = osmtpd_mheader_skip_dkimsig_keystagtype(ptr, 0);
1203 osmtpd_mheader_skip_dkimsig_xkeyttagflag(char *ptr, int optional)
1205 return osmtpd_mheader_skip_hyphenatedword(ptr, optional);
1209 osmtpd_mheader_skip_dkimsig_keyttagflag(char *ptr, int optional)
1211 /* y / s covered by x-key-t-tag-flag */
1212 return osmtpd_mheader_skip_dkimsig_xkeyttagflag(ptr, optional);
1216 osmtpd_mheader_skip_dkimsig_keyttagvalue(char *ptr, int optional)
1220 if ((ptr = osmtpd_mheader_skip_dkimsig_keyttagflag(ptr, 0)) == NULL)
1221 return optional ? start : NULL;
1224 ptr = osmtpd_mheader_skip_fws(ptr, 1);
1227 ptr = osmtpd_mheader_skip_fws(ptr + 1, 1);
1228 ptr = osmtpd_mheader_skip_dkimsig_keyttagflag(ptr, 0);
1235 osmtpd_mheader_skip_dkimsig_selector(char *ptr, int optional)
1239 if ((ptr = osmtpd_mheader_skip_subdomain(ptr, 0)) == NULL)
1240 return optional ? start : NULL;
1246 if ((ptr = osmtpd_mheader_skip_subdomain(ptr, 0)) == NULL)
1252 osmtpd_mheader_skip_ar_pvalue(char *ptr, int optional)
1254 char *start = ptr, *tmp;
1256 ptr = osmtpd_mheader_skip_cfws(ptr, 1);
1257 if ((tmp = osmtpd_mheader_skip_value(ptr, 0)) != NULL)
1259 ptr = osmtpd_mheader_skip_local_part(ptr, 1);
1262 if ((ptr = osmtpd_mheader_skip_domain(ptr, 0)) == NULL)
1263 return optional ? start : NULL;
1268 osmtpd_mheader_domain_uncomment(char *ptr)
1270 char *domain0, *domain, *tmp, *end;
1272 if (osmtpd_mheader_skip_dot_atom(ptr, 0) != NULL) {
1273 ptr = osmtpd_mheader_skip_cfws(ptr, 1);
1275 osmtpd_mheader_skip_dot_atom_text(ptr, 0) - ptr);
1277 if ((tmp = osmtpd_mheader_skip_domain_literal(ptr, 0)) != NULL) {
1278 ptr = osmtpd_mheader_skip_cfws(ptr, 1) + 1;
1279 domain0 = domain = strndup(ptr, (size_t)(tmp - ptr));
1280 if (domain0 == NULL)
1282 end = domain0 + (tmp - ptr) + 1;
1285 tmp = osmtpd_mheader_skip_fws(domain, 1);
1286 if (tmp != domain) {
1287 memmove(domain, tmp, end - tmp);
1288 end -= (tmp - domain);
1290 tmp = osmtpd_mheader_skip_dtext(domain, 0);
1295 /* domain[0] == ']' */
1299 return strndup(ptr, osmtpd_mheader_skip_obs_domain(ptr, 1) - ptr);
1302 /* Return the domain component of the first mailbox */
1304 osmtpd_mheader_from_domain(char *ptr)
1309 if (strncasecmp(ptr, "from:", 5) == 0) {
1312 } else if (strncasecmp(ptr, "from", 4) == 0) {
1316 } while ((ptr = osmtpd_mheader_skip_wsp(ptr, 0)) != NULL);
1318 if (ptr++[0] != ':')
1325 /* Both from and obs-from use Mailbox-list CRLF */
1326 /* obs-mbox-list has just a prefix compared to mailbox-list */
1329 ptr = osmtpd_mheader_skip_cfws(ptr, 1);
1330 if (ptr++[0] != ',') {
1335 /* We're only interested in the first mailbox */
1336 if (osmtpd_mheader_skip_name_addr(ptr, 0) != NULL) {
1337 ptr = osmtpd_mheader_skip_display_name(ptr, 1);
1338 ptr = osmtpd_mheader_skip_cfws(ptr, 1);
1342 ptr = osmtpd_mheader_skip_local_part(ptr, 0);
1345 return osmtpd_mheader_domain_uncomment(ptr);
1347 if (osmtpd_mheader_skip_addr_spec(ptr, 0) != NULL) {
1348 ptr = osmtpd_mheader_skip_local_part(ptr, 0);
1351 return osmtpd_mheader_domain_uncomment(ptr);
1358 osmtpd_mheader_quoted_string_normalize(char *ptr)
1363 end = osmtpd_mheader_skip_cfws(ptr, 1);
1365 if (osmtpd_mheader_skip_dquote(end, 0) == NULL)
1367 ptr[d++] = ptr[s++];
1368 while (ptr[s] != '\0') {
1369 if (osmtpd_mheader_skip_quoted_pair(ptr + s, 0) != NULL) {
1370 end = osmtpd_mheader_skip_qtext(ptr + s + 1, 0);
1374 ptr[d++] = ptr[s++];
1375 ptr[d++] = ptr[s++];
1377 } else if (osmtpd_mheader_skip_qtext(ptr + s, 0) != NULL) {
1378 ptr[d++] = ptr[s++];
1379 } else if ((end = osmtpd_mheader_skip_fws(
1380 ptr + s, 0)) != NULL) {
1386 if (osmtpd_mheader_skip_dquote(end, 0) == NULL)
1388 ptr[d++] = ptr[s++];
1389 end = osmtpd_mheader_skip_cfws(ptr + s, 1);