2 b3380529 2022-04-08 martijn * Copyright (c) 2020-2022 Martijn van Duren <martijn@openbsd.org>
4 4e2dd90f 2022-03-26 martijn * Permission to use, copy, modify, and distribute this software for any
5 4e2dd90f 2022-03-26 martijn * purpose with or without fee is hereby granted, provided that the above
6 4e2dd90f 2022-03-26 martijn * copyright notice and this permission notice appear in all copies.
8 4e2dd90f 2022-03-26 martijn * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 4e2dd90f 2022-03-26 martijn * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 4e2dd90f 2022-03-26 martijn * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 4e2dd90f 2022-03-26 martijn * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 4e2dd90f 2022-03-26 martijn * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 4e2dd90f 2022-03-26 martijn * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 4e2dd90f 2022-03-26 martijn * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 4e2dd90f 2022-03-26 martijn #include <ctype.h>
18 4e2dd90f 2022-03-26 martijn #include <errno.h>
19 4e2dd90f 2022-03-26 martijn #include <stddef.h>
20 4e2dd90f 2022-03-26 martijn #include <string.h>
21 4e2dd90f 2022-03-26 martijn #include <strings.h>
23 4e2dd90f 2022-03-26 martijn #include "ltok.h"
25 4e2dd90f 2022-03-26 martijn /* RFC 5234 - Augmented BNF for Syntax Specifications: ABNF */
26 4e2dd90f 2022-03-26 martijn const char *
27 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_alpha(const char *ptr, int optional)
29 4e2dd90f 2022-03-26 martijn if ((ptr[0] >= 0x41 && ptr[0] <= 0x5a) ||
30 4e2dd90f 2022-03-26 martijn (ptr[0] >= 0x61 && ptr[0] <= 0x7a))
31 4e2dd90f 2022-03-26 martijn return ptr + 1;
32 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
35 4e2dd90f 2022-03-26 martijn const char *
36 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_bit(const char *ptr, int optional)
38 4e2dd90f 2022-03-26 martijn if (ptr[0] == '0' || ptr[0] == '1')
39 4e2dd90f 2022-03-26 martijn return ptr + 1;
40 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
43 4e2dd90f 2022-03-26 martijn const char *
44 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_char(const char *ptr, int optional)
46 4e2dd90f 2022-03-26 martijn if (ptr[0] >= 0x01 && ptr[0] <= 0x7f)
47 4e2dd90f 2022-03-26 martijn return ptr + 1;
48 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
51 4e2dd90f 2022-03-26 martijn const char *
52 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_cr(const char *ptr, int optional)
54 4e2dd90f 2022-03-26 martijn if (ptr[0] == 0xd)
55 4e2dd90f 2022-03-26 martijn return ptr + 1;
56 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
59 4e2dd90f 2022-03-26 martijn const char *
60 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_crlf(const char *ptr, int optional)
62 4e2dd90f 2022-03-26 martijn if (ptr[0] == 13 && ptr[1] == 10)
63 4e2dd90f 2022-03-26 martijn return ptr + 2;
64 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
67 4e2dd90f 2022-03-26 martijn const char *
68 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_ctl(const char *ptr, int optional)
70 4e2dd90f 2022-03-26 martijn if ((ptr[0] >= 0x00 && ptr[0] <= 0x1f) || ptr[0] == 0x7f)
71 4e2dd90f 2022-03-26 martijn return ptr + 1;
72 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
75 4e2dd90f 2022-03-26 martijn const char *
76 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_digit(const char *ptr, int optional)
78 4e2dd90f 2022-03-26 martijn if (ptr[0] >= 0x30 && ptr[0] <= 0x39)
79 4e2dd90f 2022-03-26 martijn return ptr + 1;
80 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
83 4e2dd90f 2022-03-26 martijn const char *
84 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_dquote(const char *ptr, int optional)
86 4e2dd90f 2022-03-26 martijn if (ptr[0] == 0x22)
87 4e2dd90f 2022-03-26 martijn return ptr + 1;
88 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
91 4e2dd90f 2022-03-26 martijn const char *
92 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_hexdig(const char *ptr, int optional)
94 4e2dd90f 2022-03-26 martijn const char *start = ptr;
97 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_digit(ptr, 0)) != NULL)
98 4e2dd90f 2022-03-26 martijn return ptr;
99 b8958f33 2022-04-12 martijn l = tolower(start[0]);
100 4e2dd90f 2022-03-26 martijn if (l == 'a' || l == 'b' || l == 'c' || l == 'd' ||
101 4e2dd90f 2022-03-26 martijn l == 'e' || l == 'f')
102 b8958f33 2022-04-12 martijn return start + 1;
103 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
106 4e2dd90f 2022-03-26 martijn const char *
107 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_htab(const char *ptr, int optional)
109 4e2dd90f 2022-03-26 martijn if (ptr[0] == 0x9)
110 4e2dd90f 2022-03-26 martijn return ptr + 1;
111 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
114 4e2dd90f 2022-03-26 martijn const char *
115 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_lf(const char *ptr, int optional)
117 4e2dd90f 2022-03-26 martijn if (ptr[0] == 0xa)
118 4e2dd90f 2022-03-26 martijn return ptr + 1;
119 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
122 4e2dd90f 2022-03-26 martijn const char *
123 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_octet(const char *ptr, int optional)
125 4e2dd90f 2022-03-26 martijn return ptr + 1;
128 4e2dd90f 2022-03-26 martijn const char *
129 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sp(const char *ptr, int optional)
131 4e2dd90f 2022-03-26 martijn if (ptr[0] == 0x20)
132 4e2dd90f 2022-03-26 martijn return ptr + 1;
133 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
136 4e2dd90f 2022-03-26 martijn const char *
137 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_vchar(const char *ptr, int optional)
139 4e2dd90f 2022-03-26 martijn if (ptr[0] >= 0x21 && ptr[0] <= 0x7e)
140 4e2dd90f 2022-03-26 martijn return ptr + 1;
141 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
144 4e2dd90f 2022-03-26 martijn const char *
145 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_wsp(const char *ptr, int optional)
147 4e2dd90f 2022-03-26 martijn const char *start = ptr;
149 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sp(start, 0)) != NULL ||
150 4e2dd90f 2022-03-26 martijn (ptr = osmtpd_ltok_skip_htab(start, 0)) != NULL)
151 4e2dd90f 2022-03-26 martijn return ptr;
152 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
155 4e2dd90f 2022-03-26 martijn /* RFC 5321 - Simple Mail Transfer Protocol */
156 4e2dd90f 2022-03-26 martijn const char *
157 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_keyword(const char *ptr, int optional)
159 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_ldh_string(ptr, optional);
162 4e2dd90f 2022-03-26 martijn const char *
163 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sub_domain(const char *ptr, int optional)
165 4e2dd90f 2022-03-26 martijn const char *start = ptr;
167 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_let_dig(ptr, 0)) == NULL)
168 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
169 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_ldh_string(ptr, 1);
172 4e2dd90f 2022-03-26 martijn const char *
173 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_let_dig(const char *ptr, int optional)
175 4e2dd90f 2022-03-26 martijn const char *start = ptr;
177 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_alpha(start, 0)) == NULL &&
178 4e2dd90f 2022-03-26 martijn (ptr = osmtpd_ltok_skip_digit(start, 0)) == NULL)
179 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
180 4e2dd90f 2022-03-26 martijn return ptr;
183 4e2dd90f 2022-03-26 martijn const char *
184 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_ldh_string(const char *ptr, int optional)
186 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
187 4e2dd90f 2022-03-26 martijn int letdig = 0;
189 4e2dd90f 2022-03-26 martijn while (1) {
190 4e2dd90f 2022-03-26 martijn prev = ptr;
191 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_alpha(prev, 0)) != NULL ||
192 4e2dd90f 2022-03-26 martijn (ptr = osmtpd_ltok_skip_digit(prev, 0)) != NULL) {
193 4e2dd90f 2022-03-26 martijn letdig = 1;
194 4e2dd90f 2022-03-26 martijn continue;
196 4e2dd90f 2022-03-26 martijn if (prev[0] == '-') {
197 4e2dd90f 2022-03-26 martijn letdig = 0;
198 4e2dd90f 2022-03-26 martijn ptr = prev + 1;
199 4e2dd90f 2022-03-26 martijn continue;
201 4e2dd90f 2022-03-26 martijn ptr = prev;
204 4e2dd90f 2022-03-26 martijn if (letdig)
205 4e2dd90f 2022-03-26 martijn return ptr;
206 4e2dd90f 2022-03-26 martijn if (ptr == start)
207 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
208 4e2dd90f 2022-03-26 martijn return ptr;
211 4e2dd90f 2022-03-26 martijn /* RFC 5322 - Internet Message Format */
212 4e2dd90f 2022-03-26 martijn const char *
213 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_quoted_pair(const char *ptr, int optional)
215 4e2dd90f 2022-03-26 martijn const char *start = ptr;
217 4e2dd90f 2022-03-26 martijn if (ptr[0] == '\\' && (
218 4e2dd90f 2022-03-26 martijn (ptr = osmtpd_ltok_skip_vchar(start + 1, 0)) != NULL ||
219 4e2dd90f 2022-03-26 martijn (ptr = osmtpd_ltok_skip_wsp(start + 1, 0)) != NULL))
220 4e2dd90f 2022-03-26 martijn return ptr;
221 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_obs_qp(start, optional);
224 4e2dd90f 2022-03-26 martijn const char *
225 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_fws(const char *ptr, int optional)
227 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev = ptr;
229 4e2dd90f 2022-03-26 martijn while ((ptr = osmtpd_ltok_skip_wsp(ptr, 0)) != NULL)
230 4e2dd90f 2022-03-26 martijn prev = ptr;
231 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_crlf(prev, 1)) == prev)
232 4e2dd90f 2022-03-26 martijn ptr = start;
233 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_wsp(ptr, 0)) == NULL)
234 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_obs_fws(start, optional);
235 4e2dd90f 2022-03-26 martijn prev = ptr;
236 4e2dd90f 2022-03-26 martijn while ((ptr = osmtpd_ltok_skip_wsp(ptr, 0)) != NULL)
237 4e2dd90f 2022-03-26 martijn prev = ptr;
238 4e2dd90f 2022-03-26 martijn return prev;
241 4e2dd90f 2022-03-26 martijn const char *
242 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_ctext(const char *ptr, int optional)
244 4e2dd90f 2022-03-26 martijn const char *start = ptr;
246 4e2dd90f 2022-03-26 martijn if ((ptr[0] >= 33 && ptr[0] <= 39) || (ptr[0] >= 42 && ptr[0] <= 91) ||
247 4e2dd90f 2022-03-26 martijn (ptr[0] >= 93 && ptr[0] <= 126))
248 4e2dd90f 2022-03-26 martijn return ptr + 1;
249 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_obs_ctext(ptr, 0)) != NULL)
250 4e2dd90f 2022-03-26 martijn return ptr;
251 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
254 4e2dd90f 2022-03-26 martijn const char *
255 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_ccontent(const char *ptr, int optional)
257 4e2dd90f 2022-03-26 martijn const char *start = ptr;
259 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_ctext(ptr, 0)) != NULL)
260 4e2dd90f 2022-03-26 martijn return ptr;
261 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_quoted_pair(start, 0)) != NULL)
262 4e2dd90f 2022-03-26 martijn return ptr;
263 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_comment(start, 0)) != NULL)
264 4e2dd90f 2022-03-26 martijn return ptr;
265 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
268 4e2dd90f 2022-03-26 martijn const char *
269 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_comment(const char *ptr, int optional)
271 4e2dd90f 2022-03-26 martijn const char *start = ptr;
273 4e2dd90f 2022-03-26 martijn if (ptr++[0] != '(')
274 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
275 4e2dd90f 2022-03-26 martijn while (1) {
276 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
277 4e2dd90f 2022-03-26 martijn if (ptr[0] == ')')
278 4e2dd90f 2022-03-26 martijn return ptr + 1;
279 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_ccontent(ptr, 0)) == NULL)
280 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
284 4e2dd90f 2022-03-26 martijn const char *
285 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_cfws(const char *ptr, int optional)
287 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
289 4e2dd90f 2022-03-26 martijn while (1) {
290 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
291 4e2dd90f 2022-03-26 martijn prev = ptr;
292 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_comment(ptr, 0)) == NULL) {
293 4e2dd90f 2022-03-26 martijn ptr = prev;
297 4e2dd90f 2022-03-26 martijn return ptr == start && !optional ? NULL : ptr;
300 4e2dd90f 2022-03-26 martijn const char *
301 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_atext(const char *ptr, int optional)
303 4e2dd90f 2022-03-26 martijn const char *start = ptr;
305 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_alpha(start, 0)) != NULL ||
306 4e2dd90f 2022-03-26 martijn (ptr = osmtpd_ltok_skip_digit(start, 0)) != NULL)
307 4e2dd90f 2022-03-26 martijn return ptr;
308 4e2dd90f 2022-03-26 martijn ptr = start;
309 4e2dd90f 2022-03-26 martijn if (ptr[0] == '!' || ptr[0] == '#' || ptr[0] == '$' || ptr[0] == '%' ||
310 4e2dd90f 2022-03-26 martijn ptr[0] == '&' || ptr[0] == '\'' || ptr[0] == '*' || ptr[0] == '+' ||
311 4e2dd90f 2022-03-26 martijn ptr[0] == '-' || ptr[0] == '/' || ptr[0] == '=' || ptr[0] == '?' ||
312 4e2dd90f 2022-03-26 martijn ptr[0] == '^' || ptr[0] == '_' || ptr[0] == '`' || ptr[0] == '{' ||
313 4e2dd90f 2022-03-26 martijn ptr[0] == '|' || ptr[0] == '}' || ptr[0] == '~')
314 4e2dd90f 2022-03-26 martijn return ptr + 1;
315 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
318 4e2dd90f 2022-03-26 martijn const char *
319 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_atom(const char *ptr, int optional)
321 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
323 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_cfws(ptr, 1);
324 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_atext(ptr, 0)) == NULL)
325 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
327 4e2dd90f 2022-03-26 martijn prev = ptr;
328 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_atext(ptr, 1);
329 4e2dd90f 2022-03-26 martijn } while (prev != ptr);
330 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_cfws(ptr, 1);
333 4e2dd90f 2022-03-26 martijn const char *
334 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_dot_atom_text(const char *ptr, int optional)
336 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
338 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_atext(ptr, 0)) == NULL)
339 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
341 4e2dd90f 2022-03-26 martijn prev = ptr;
342 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_atext(ptr, 1);
343 4e2dd90f 2022-03-26 martijn } while (ptr != prev);
345 4e2dd90f 2022-03-26 martijn while (ptr[0] == '.') {
347 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_atext(ptr, 0)) == NULL)
348 4e2dd90f 2022-03-26 martijn return prev;
350 4e2dd90f 2022-03-26 martijn prev = ptr;
351 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_atext(ptr, 1);
352 4e2dd90f 2022-03-26 martijn } while (ptr != prev);
354 4e2dd90f 2022-03-26 martijn return ptr;
357 4e2dd90f 2022-03-26 martijn const char *
358 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_dot_atom(const char *ptr, int optional)
360 4e2dd90f 2022-03-26 martijn const char *start = ptr;
362 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_cfws(ptr, 1);
363 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_dot_atom_text(ptr, 0)) == NULL)
364 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
365 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_cfws(ptr, 1);
368 4e2dd90f 2022-03-26 martijn const char *
369 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_qtext(const char *ptr, int optional)
371 4e2dd90f 2022-03-26 martijn const char *start = ptr;
373 4e2dd90f 2022-03-26 martijn if (ptr[0] == 33 || (ptr[0] >= 35 && ptr[0] <= 91) ||
374 4e2dd90f 2022-03-26 martijn (ptr[0] >= 93 && ptr[0] <= 126))
375 4e2dd90f 2022-03-26 martijn return ptr + 1;
376 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_obs_qtext(ptr, 0)) != NULL)
377 4e2dd90f 2022-03-26 martijn return ptr;
378 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
381 4e2dd90f 2022-03-26 martijn const char *
382 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_qcontent(const char *ptr, int optional)
384 4e2dd90f 2022-03-26 martijn const char *start = ptr;
386 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_qtext(ptr, 0)) != NULL)
387 4e2dd90f 2022-03-26 martijn return ptr;
388 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_quoted_pair(start, optional);
391 4e2dd90f 2022-03-26 martijn const char *
392 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_quoted_string(const char *ptr, int optional)
394 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
396 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_cfws(ptr, 1);
397 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_dquote(ptr, 0)) == NULL)
398 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
399 4e2dd90f 2022-03-26 martijn prev = ptr;
400 4e2dd90f 2022-03-26 martijn while (1) {
401 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
402 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_qcontent(ptr, 0)) == NULL)
404 4e2dd90f 2022-03-26 martijn prev = ptr;
406 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_dquote(prev, 0)) == NULL)
407 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
408 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_cfws(ptr, 1);
411 4e2dd90f 2022-03-26 martijn const char *
412 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_word(const char *ptr, int optional)
414 4e2dd90f 2022-03-26 martijn const char *start = ptr;
416 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_atom(ptr, 0)) != NULL)
417 4e2dd90f 2022-03-26 martijn return ptr;
418 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_quoted_string(start, optional);
421 4e2dd90f 2022-03-26 martijn const char *
422 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_phrase(const char *ptr, int optional)
424 4e2dd90f 2022-03-26 martijn /* obs-phrase is a superset of phrae */
425 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_obs_phrase(ptr, optional);
428 4e2dd90f 2022-03-26 martijn const char *
429 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_name_addr(const char *ptr, int optional)
431 4e2dd90f 2022-03-26 martijn const char *start = ptr;
433 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_display_name(ptr, 1);
434 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_angle_addr(ptr, 0)) == NULL)
435 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
436 4e2dd90f 2022-03-26 martijn return ptr;
439 4e2dd90f 2022-03-26 martijn const char *
440 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_angle_addr(const char *ptr, int optional)
442 4e2dd90f 2022-03-26 martijn const char *start = ptr;
444 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_cfws(ptr, 1);
445 4e2dd90f 2022-03-26 martijn if (ptr++[0] != '<')
446 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_obs_angle_addr(start, optional);
447 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_addr_spec(ptr, 0)) == NULL)
448 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_obs_angle_addr(start, optional);
449 4e2dd90f 2022-03-26 martijn if (ptr++[0] != '>')
450 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_obs_angle_addr(start, optional);
451 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_cfws(ptr, 1);
454 4e2dd90f 2022-03-26 martijn const char *
455 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_display_name(const char *ptr, int optional)
457 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_phrase(ptr, optional);
460 4e2dd90f 2022-03-26 martijn const char *
461 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_addr_spec(const char *ptr, int optional)
463 4e2dd90f 2022-03-26 martijn const char *start = ptr;
465 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_local_part(ptr, 0)) == NULL)
466 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
467 4e2dd90f 2022-03-26 martijn if (ptr++[0] != '@')
468 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
469 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_domain(ptr, 0)) == NULL)
470 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
471 4e2dd90f 2022-03-26 martijn return ptr;
474 4e2dd90f 2022-03-26 martijn const char *
475 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_local_part(const char *ptr, int optional)
477 4e2dd90f 2022-03-26 martijn const char *start = ptr;
479 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_dot_atom(ptr, 0)) != NULL)
480 4e2dd90f 2022-03-26 martijn return ptr;
481 4e2dd90f 2022-03-26 martijn ptr = start;
482 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_quoted_string(ptr, 0)) != NULL)
483 4e2dd90f 2022-03-26 martijn return ptr;
484 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_obs_local_part(start, optional);
487 4e2dd90f 2022-03-26 martijn const char *
488 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_domain(const char *ptr, int optional)
490 4e2dd90f 2022-03-26 martijn const char *start = ptr;
492 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_dot_atom(start, 0)) != NULL)
493 4e2dd90f 2022-03-26 martijn return ptr;
494 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_domain_literal(start, 0)) != NULL)
495 4e2dd90f 2022-03-26 martijn return ptr;
496 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_obs_domain(start, optional);
499 4e2dd90f 2022-03-26 martijn const char *
500 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_domain_literal(const char *ptr, int optional)
502 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
504 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_cfws(ptr, 1);
505 4e2dd90f 2022-03-26 martijn if (ptr++[0] != '[')
506 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
507 4e2dd90f 2022-03-26 martijn while (1) {
508 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
509 4e2dd90f 2022-03-26 martijn prev = ptr;
510 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_dtext(ptr, 0)) == NULL) {
511 4e2dd90f 2022-03-26 martijn ptr = prev;
515 4e2dd90f 2022-03-26 martijn if (ptr[0] != ']')
516 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
518 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_cfws(ptr, 1);
521 4e2dd90f 2022-03-26 martijn const char *
522 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_dtext(const char *ptr, int optional)
524 4e2dd90f 2022-03-26 martijn if ((ptr[0] >= 33 && ptr[0] <= 90) || (ptr[0] >= 94 && ptr[0] <= 126))
525 4e2dd90f 2022-03-26 martijn return ptr + 1;
526 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_obs_dtext(ptr, optional);
530 4e2dd90f 2022-03-26 martijn const char *
531 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_field_name(const char *ptr, int optional)
533 4e2dd90f 2022-03-26 martijn const char *start = ptr;
535 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_ftext(ptr, 0)) == NULL)
536 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
537 4e2dd90f 2022-03-26 martijn while (1) {
538 4e2dd90f 2022-03-26 martijn start = ptr;
539 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_ftext(ptr, 0)) == NULL)
540 4e2dd90f 2022-03-26 martijn return start;
544 4e2dd90f 2022-03-26 martijn const char *
545 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_ftext(const char *ptr, int optional)
547 4e2dd90f 2022-03-26 martijn if ((ptr[0] >= 33 && ptr[0] <= 57) ||
548 4e2dd90f 2022-03-26 martijn (ptr[0] >= 59 && ptr[0] <= 126))
549 4e2dd90f 2022-03-26 martijn return ptr + 1;
550 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
553 4e2dd90f 2022-03-26 martijn const char *
554 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_obs_no_ws_ctl(const char *ptr, int optional)
556 4e2dd90f 2022-03-26 martijn if ((ptr[0] >= 1 && ptr[0] <= 8) || ptr[0] == 11 || ptr[0] == 12 ||
557 4e2dd90f 2022-03-26 martijn (ptr[0] >= 14 && ptr[0] <= 31) || ptr[0] == 127)
558 4e2dd90f 2022-03-26 martijn return ptr + 1;
559 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
562 4e2dd90f 2022-03-26 martijn const char *
563 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_obs_ctext(const char *ptr, int optional)
565 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_obs_no_ws_ctl(ptr, optional);
568 4e2dd90f 2022-03-26 martijn const char *
569 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_obs_qtext(const char *ptr, int optional)
571 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_obs_no_ws_ctl(ptr, optional);
574 4e2dd90f 2022-03-26 martijn const char *
575 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_obs_qp(const char *ptr, int optional)
577 4e2dd90f 2022-03-26 martijn const char *start = ptr;
579 4e2dd90f 2022-03-26 martijn if (ptr[0] == '\\' && (
580 4e2dd90f 2022-03-26 martijn (ptr = osmtpd_ltok_skip_obs_no_ws_ctl(start + 1, 0)) != NULL ||
581 4e2dd90f 2022-03-26 martijn (ptr = osmtpd_ltok_skip_lf(start + 1, 0)) != NULL ||
582 4e2dd90f 2022-03-26 martijn (ptr = osmtpd_ltok_skip_cr(start + 1, 0)) != NULL))
583 4e2dd90f 2022-03-26 martijn return ptr;
584 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
587 4e2dd90f 2022-03-26 martijn const char *
588 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_obs_phrase(const char *ptr, int optional)
590 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
592 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_word(ptr, 0)) == NULL)
593 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
594 4e2dd90f 2022-03-26 martijn while (1) {
595 4e2dd90f 2022-03-26 martijn prev = ptr;
596 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_word(ptr, 0)) != NULL)
597 4e2dd90f 2022-03-26 martijn continue;
598 4e2dd90f 2022-03-26 martijn ptr = prev;
599 4e2dd90f 2022-03-26 martijn if (ptr[0] == '.') {
601 4e2dd90f 2022-03-26 martijn continue;
603 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_cfws(ptr, 0)) != NULL)
604 4e2dd90f 2022-03-26 martijn continue;
605 4e2dd90f 2022-03-26 martijn return prev;
609 4e2dd90f 2022-03-26 martijn const char *
610 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_obs_fws(const char *ptr, int optional)
612 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
614 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_wsp(ptr, 0)) == NULL)
615 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
616 4e2dd90f 2022-03-26 martijn prev = ptr;
617 4e2dd90f 2022-03-26 martijn while ((ptr = osmtpd_ltok_skip_wsp(ptr, 0)) != NULL)
618 4e2dd90f 2022-03-26 martijn prev = ptr;
620 4e2dd90f 2022-03-26 martijn ptr = prev;
621 4e2dd90f 2022-03-26 martijn while (1) {
622 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_crlf(ptr, 0)) == NULL)
623 4e2dd90f 2022-03-26 martijn return prev;
624 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_wsp(ptr, 0)) == NULL)
625 4e2dd90f 2022-03-26 martijn return prev;
626 4e2dd90f 2022-03-26 martijn prev = ptr;
627 4e2dd90f 2022-03-26 martijn while ((ptr = osmtpd_ltok_skip_wsp(ptr, 0)) != NULL)
628 4e2dd90f 2022-03-26 martijn prev = ptr;
629 4e2dd90f 2022-03-26 martijn ptr = prev;
633 4e2dd90f 2022-03-26 martijn const char *
634 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_obs_angle_addr(const char *ptr, int optional)
636 4e2dd90f 2022-03-26 martijn const char *start = ptr;
638 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_cfws(ptr, 1);
639 4e2dd90f 2022-03-26 martijn if (ptr++[0] != '<')
640 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
641 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_obs_route(ptr, 0)) == NULL)
642 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
643 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_addr_spec(ptr, 0)) == NULL)
644 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
645 4e2dd90f 2022-03-26 martijn if (ptr++[0] != '>')
646 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
647 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_cfws(ptr, 1);
650 4e2dd90f 2022-03-26 martijn const char *
651 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_obs_route(const char *ptr, int optional)
653 4e2dd90f 2022-03-26 martijn const char *start = ptr;
655 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_obs_domain_list(ptr, 0)) == NULL)
656 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
657 4e2dd90f 2022-03-26 martijn if (ptr++[0] != ':')
658 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
659 4e2dd90f 2022-03-26 martijn return ptr;
662 4e2dd90f 2022-03-26 martijn const char *
663 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_obs_domain_list(const char *ptr, int optional)
665 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev = ptr;
667 4e2dd90f 2022-03-26 martijn while (1) {
668 4e2dd90f 2022-03-26 martijn if (ptr[0] == ',') {
670 4e2dd90f 2022-03-26 martijn prev = ptr;
671 4e2dd90f 2022-03-26 martijn continue;
672 4e2dd90f 2022-03-26 martijn } else if ((ptr = osmtpd_ltok_skip_cfws(ptr, 0)) != NULL) {
673 4e2dd90f 2022-03-26 martijn prev = ptr;
674 4e2dd90f 2022-03-26 martijn continue;
678 4e2dd90f 2022-03-26 martijn ptr = prev;
680 4e2dd90f 2022-03-26 martijn if (ptr++[0] != '@')
681 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
682 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_domain(ptr, 0)) == NULL)
683 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
684 4e2dd90f 2022-03-26 martijn while (1) {
685 4e2dd90f 2022-03-26 martijn if (ptr[0] != ',')
688 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_cfws(ptr, 1);
689 4e2dd90f 2022-03-26 martijn if (ptr[0] != '@')
690 4e2dd90f 2022-03-26 martijn continue;
691 4e2dd90f 2022-03-26 martijn prev = ptr;
692 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_domain(ptr + 1, 0)) == NULL) {
693 4e2dd90f 2022-03-26 martijn ptr = prev;
697 4e2dd90f 2022-03-26 martijn return ptr;
700 4e2dd90f 2022-03-26 martijn const char *
701 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_obs_local_part(const char *ptr, int optional)
703 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
705 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_word(ptr, 0)) == NULL)
706 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
707 4e2dd90f 2022-03-26 martijn prev = ptr;
708 4e2dd90f 2022-03-26 martijn while (ptr[0] == '.') {
710 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_word(ptr, 0)) == NULL)
711 4e2dd90f 2022-03-26 martijn return prev;
712 4e2dd90f 2022-03-26 martijn prev = ptr;
714 4e2dd90f 2022-03-26 martijn return ptr;
717 4e2dd90f 2022-03-26 martijn const char *
718 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_obs_domain(const char *ptr, int optional)
720 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
722 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_atom(ptr, 0)) == NULL)
723 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
724 4e2dd90f 2022-03-26 martijn prev = ptr;
725 4e2dd90f 2022-03-26 martijn while (1) {
726 4e2dd90f 2022-03-26 martijn if (ptr++[0] != '.')
727 4e2dd90f 2022-03-26 martijn return prev;
728 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_atom(ptr, 0)) == NULL)
729 4e2dd90f 2022-03-26 martijn return prev;
730 4e2dd90f 2022-03-26 martijn prev = ptr;
734 4e2dd90f 2022-03-26 martijn const char *
735 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_obs_dtext(const char *ptr, int optional)
737 4e2dd90f 2022-03-26 martijn const char *start = ptr;
739 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_obs_no_ws_ctl(ptr, 0)) != NULL)
740 4e2dd90f 2022-03-26 martijn return ptr;
741 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_quoted_pair(start, optional);
744 4e2dd90f 2022-03-26 martijn /* RFC 2045 - Multipurpose Internet Mail Extensions */
745 4e2dd90f 2022-03-26 martijn const char *
746 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_value(const char *ptr, int optional)
748 4e2dd90f 2022-03-26 martijn const char *start = ptr;
750 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_token(start, 0)) != NULL)
751 4e2dd90f 2022-03-26 martijn return ptr;
752 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_quoted_string(start, 0)) != NULL)
753 4e2dd90f 2022-03-26 martijn return ptr;
754 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
757 4e2dd90f 2022-03-26 martijn const char *
758 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_token(const char *ptr, int optional)
760 4e2dd90f 2022-03-26 martijn const char *start;
761 4e2dd90f 2022-03-26 martijn int first = 1;
763 4e2dd90f 2022-03-26 martijn while (1) {
764 4e2dd90f 2022-03-26 martijn start = ptr;
765 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_char(start, 0)) != NULL &&
766 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sp(start, 0) == NULL &&
767 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_ctl(start, 0) == NULL &&
768 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_tspecials(start, 0) == NULL) {
769 4e2dd90f 2022-03-26 martijn first = 0;
770 4e2dd90f 2022-03-26 martijn continue;
772 4e2dd90f 2022-03-26 martijn return optional || !first ? start : NULL;
776 4e2dd90f 2022-03-26 martijn const char *
777 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_tspecials(const char *ptr, int optional)
779 4e2dd90f 2022-03-26 martijn if (ptr[0] == '(' || ptr[0] == ')' || ptr[0] == '<' || ptr[0] == '>' ||
780 4e2dd90f 2022-03-26 martijn ptr[0] == '@' || ptr[0] == ',' || ptr[0] == ';' || ptr[0] == ':' ||
781 4e2dd90f 2022-03-26 martijn ptr[0] == '\\' || ptr[0] == '"' || ptr[0] == '/' || ptr[0] == '[' ||
782 4e2dd90f 2022-03-26 martijn ptr[0] == ']' || ptr[0] == '?' || ptr[0] == '=')
783 4e2dd90f 2022-03-26 martijn return ptr + 1;
784 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
787 4e2dd90f 2022-03-26 martijn const char *
788 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_qp_section(const char *ptr, int optional)
790 4e2dd90f 2022-03-26 martijn const char *prev, *last = ptr;
792 4e2dd90f 2022-03-26 martijn while (1) {
793 4e2dd90f 2022-03-26 martijn prev = ptr;
794 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_ptext(prev, 0)) != NULL)
795 4e2dd90f 2022-03-26 martijn last = ptr;
796 4e2dd90f 2022-03-26 martijn else if ((ptr = osmtpd_ltok_skip_sp(prev, 0)) == NULL &&
797 4e2dd90f 2022-03-26 martijn (ptr = osmtpd_ltok_skip_htab(prev, 0)) == NULL)
798 4e2dd90f 2022-03-26 martijn return last;
802 4e2dd90f 2022-03-26 martijn const char *
803 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_ptext(const char *ptr, int optional)
805 4e2dd90f 2022-03-26 martijn const char *start = ptr;
807 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_hex_octet(start, 0)) == NULL &&
808 4e2dd90f 2022-03-26 martijn (ptr = osmtpd_ltok_skip_safe_char(start, 0)) == NULL)
809 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
810 4e2dd90f 2022-03-26 martijn return ptr;
813 4e2dd90f 2022-03-26 martijn const char *
814 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_safe_char(const char *ptr, int optional)
816 4e2dd90f 2022-03-26 martijn if ((ptr[0] >= 33 && ptr[0] <= 60) || (ptr[0] >= 62 && ptr[0] <= 126))
817 4e2dd90f 2022-03-26 martijn return ptr + 1;
818 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
821 4e2dd90f 2022-03-26 martijn const char *
822 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_hex_octet(const char *ptr, int optional)
824 4e2dd90f 2022-03-26 martijn const char *start = ptr;
827 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
828 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
830 4e2dd90f 2022-03-26 martijn l = tolower(ptr[0]);
831 4e2dd90f 2022-03-26 martijn if (l == 'a' || l == 'b' || l == 'c' || l == 'd' ||
832 4e2dd90f 2022-03-26 martijn l == 'e' || l == 'f')
834 4e2dd90f 2022-03-26 martijn else if ((ptr = osmtpd_ltok_skip_digit(ptr, 0)) == NULL)
835 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
836 4e2dd90f 2022-03-26 martijn l = tolower(ptr[0]);
837 4e2dd90f 2022-03-26 martijn start = ptr;
838 4e2dd90f 2022-03-26 martijn if (l == 'a' || l == 'b' || l == 'c' || l == 'd' ||
839 4e2dd90f 2022-03-26 martijn l == 'e' || l == 'f')
841 4e2dd90f 2022-03-26 martijn else if ((ptr = osmtpd_ltok_skip_digit(ptr, 0)) == NULL)
842 4e2dd90f 2022-03-26 martijn return start;
843 4e2dd90f 2022-03-26 martijn return ptr;
846 4e2dd90f 2022-03-26 martijn /* RFC 6376 - DomainKeys Identified Mail (DKIM) Signatures */
847 4e2dd90f 2022-03-26 martijn const char *
848 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_hyphenated_word(const char *ptr, int optional)
850 42479031 2022-03-27 martijn const char *start = ptr, *end;
852 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_alpha(ptr, 0)) == NULL)
853 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
855 4e2dd90f 2022-03-26 martijn end = ptr;
856 4e2dd90f 2022-03-26 martijn while (1) {
857 42479031 2022-03-27 martijn start = ptr;
858 42479031 2022-03-27 martijn if ((ptr = osmtpd_ltok_skip_alpha(start, 0)) != NULL ||
859 42479031 2022-03-27 martijn (ptr = osmtpd_ltok_skip_digit(start, 0)) != NULL) {
860 42479031 2022-03-27 martijn end = ptr;
861 42479031 2022-03-27 martijn } else if (start[0] == '-')
862 42479031 2022-03-27 martijn ptr = start + 1;
866 42479031 2022-03-27 martijn return end;
869 4e2dd90f 2022-03-26 martijn const char *
870 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_alphadigitps(const char *ptr, int optional)
872 4e2dd90f 2022-03-26 martijn const char *end;
874 4e2dd90f 2022-03-26 martijn if ((end = osmtpd_ltok_skip_alpha(ptr, 0)) == NULL &&
875 4e2dd90f 2022-03-26 martijn (end = osmtpd_ltok_skip_digit(ptr, 0)) == NULL &&
876 4e2dd90f 2022-03-26 martijn ptr[0] != '+' && ptr[0] != '/')
877 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
878 4e2dd90f 2022-03-26 martijn return end == NULL ? ptr + 1 : end;
881 4e2dd90f 2022-03-26 martijn const char *
882 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_base64string(const char *ptr, int optional)
884 4e2dd90f 2022-03-26 martijn const char *start = ptr;
886 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_alphadigitps(ptr, 0)) == NULL)
887 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
888 4e2dd90f 2022-03-26 martijn while (1) {
889 4e2dd90f 2022-03-26 martijn start = ptr;
890 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
891 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_alphadigitps(ptr, 0)) == NULL)
894 4e2dd90f 2022-03-26 martijn ptr = start;
895 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
896 4e2dd90f 2022-03-26 martijn if (ptr[0] == '=') {
898 4e2dd90f 2022-03-26 martijn start = ptr;
899 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
900 4e2dd90f 2022-03-26 martijn if (ptr[0] == '=')
903 4e2dd90f 2022-03-26 martijn ptr = start;
905 4e2dd90f 2022-03-26 martijn ptr = start;
906 4e2dd90f 2022-03-26 martijn return ptr;
909 4e2dd90f 2022-03-26 martijn const char *
910 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_hdr_name(const char *ptr, int optional)
912 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_field_name(ptr, optional);
915 4e2dd90f 2022-03-26 martijn const char *
916 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_qp_hdr_value(const char *ptr, int optional)
918 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_dkim_quoted_printable(ptr, optional);
921 4e2dd90f 2022-03-26 martijn const char *
922 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_dkim_quoted_printable(const char *ptr, int optional)
924 4e2dd90f 2022-03-26 martijn const char *start;
926 4e2dd90f 2022-03-26 martijn while (1) {
927 4e2dd90f 2022-03-26 martijn start = ptr;
928 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_fws(start, 0)) != NULL)
929 4e2dd90f 2022-03-26 martijn continue;
930 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_hex_octet(start, 0)) != NULL)
931 4e2dd90f 2022-03-26 martijn continue;
932 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_dkim_safe_char(start, 0);
933 4e2dd90f 2022-03-26 martijn if (ptr == NULL)
936 4e2dd90f 2022-03-26 martijn return start;
939 4e2dd90f 2022-03-26 martijn const char *
940 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_dkim_safe_char(const char *ptr, int optional)
942 4e2dd90f 2022-03-26 martijn if ((ptr[0] >= 0x21 && ptr[0] <= 0x3a) || ptr[0] == 0x3c ||
943 4e2dd90f 2022-03-26 martijn (ptr[0] >= 0x3e && ptr[0] <= 0x7e))
944 4e2dd90f 2022-03-26 martijn return ptr + 1;
945 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
948 4e2dd90f 2022-03-26 martijn const char *
949 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_selector(const char *ptr, int optional)
951 4e2dd90f 2022-03-26 martijn const char *start = ptr;
953 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sub_domain(ptr, 0)) == NULL)
954 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
955 4e2dd90f 2022-03-26 martijn while (1) {
956 4e2dd90f 2022-03-26 martijn start = ptr;
957 4e2dd90f 2022-03-26 martijn if (ptr[0] != '.')
958 4e2dd90f 2022-03-26 martijn return start;
960 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sub_domain(ptr, 0)) == NULL)
961 4e2dd90f 2022-03-26 martijn return start;
965 4e2dd90f 2022-03-26 martijn const char *
966 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_tag_list(const char *ptr, int optional)
968 4e2dd90f 2022-03-26 martijn const char *start = ptr;
970 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_tag_spec(ptr, 0)) == NULL)
971 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
972 4e2dd90f 2022-03-26 martijn while (1) {
973 4e2dd90f 2022-03-26 martijn /* Starting or trailing ';' */
974 4e2dd90f 2022-03-26 martijn if (ptr[0] != ';')
975 4e2dd90f 2022-03-26 martijn return ptr;
977 4e2dd90f 2022-03-26 martijn start = ptr;
978 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_tag_spec(ptr, 0)) == NULL)
979 4e2dd90f 2022-03-26 martijn return start;
983 4e2dd90f 2022-03-26 martijn const char *
984 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_tag_spec(const char *ptr, int optional)
986 4e2dd90f 2022-03-26 martijn const char *start = ptr;
988 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
989 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_tag_name(ptr, 0)) == NULL)
990 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
991 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
992 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
993 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
995 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
996 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_tag_value(ptr, 0)) == NULL)
997 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
998 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_fws(ptr, 1);
1001 4e2dd90f 2022-03-26 martijn const char *
1002 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_tag_name(const char *ptr, int optional)
1004 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
1006 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_alpha(ptr, 0)) == NULL)
1007 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1008 4e2dd90f 2022-03-26 martijn prev = ptr;
1009 4e2dd90f 2022-03-26 martijn while ((ptr = osmtpd_ltok_skip_alnumpunc(ptr, 0)) != NULL)
1010 4e2dd90f 2022-03-26 martijn prev = ptr;
1011 4e2dd90f 2022-03-26 martijn return prev;
1014 4e2dd90f 2022-03-26 martijn const char *
1015 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_tag_value(const char *ptr, int optional)
1017 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
1019 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_tval(ptr, 0)) == NULL)
1020 4e2dd90f 2022-03-26 martijn return start;
1022 4e2dd90f 2022-03-26 martijn while (1) {
1023 4e2dd90f 2022-03-26 martijn start = ptr;
1024 4e2dd90f 2022-03-26 martijn /* FWS contains WSP */
1025 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_fws(ptr, 0)) == NULL)
1026 4e2dd90f 2022-03-26 martijn return start;
1027 4e2dd90f 2022-03-26 martijn prev = ptr;
1028 4e2dd90f 2022-03-26 martijn while ((ptr = osmtpd_ltok_skip_fws(ptr, 0)) != NULL)
1029 4e2dd90f 2022-03-26 martijn prev = ptr;
1030 4e2dd90f 2022-03-26 martijn ptr = prev;
1031 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_tval(ptr, 0)) == NULL)
1032 4e2dd90f 2022-03-26 martijn return start;
1036 4e2dd90f 2022-03-26 martijn const char *
1037 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_tval(const char *ptr, int optional)
1039 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
1041 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_valchar(ptr, 0)) == NULL)
1042 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1043 4e2dd90f 2022-03-26 martijn prev = ptr;
1044 4e2dd90f 2022-03-26 martijn while ((ptr = osmtpd_ltok_skip_valchar(ptr, 0)) != NULL)
1045 4e2dd90f 2022-03-26 martijn prev = ptr;
1046 4e2dd90f 2022-03-26 martijn return prev;
1049 4e2dd90f 2022-03-26 martijn const char *
1050 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_valchar(const char *ptr, int optional)
1052 4e2dd90f 2022-03-26 martijn if ((ptr[0] >= 0x21 && ptr[0] <= 0x3A) ||
1053 4e2dd90f 2022-03-26 martijn (ptr[0] >= 0x3C && ptr[0] <= 0x7E))
1054 4e2dd90f 2022-03-26 martijn return ptr + 1;
1055 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
1058 4e2dd90f 2022-03-26 martijn const char *
1059 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_alnumpunc(const char *ptr, int optional)
1061 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1063 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_alpha(start, 0)) != NULL)
1064 4e2dd90f 2022-03-26 martijn return ptr;
1065 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_digit(start, 0)) != NULL)
1066 4e2dd90f 2022-03-26 martijn return ptr;
1067 4e2dd90f 2022-03-26 martijn if (start[0] == '_')
1068 4e2dd90f 2022-03-26 martijn return start + 1;
1069 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1072 4e2dd90f 2022-03-26 martijn const char *
1073 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_v_tag(const char *ptr, int optional)
1075 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1077 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x76)
1078 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1079 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1080 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1081 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1082 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1083 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_v_tag_value(ptr, 0)) == NULL)
1084 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1085 4e2dd90f 2022-03-26 martijn return ptr;
1088 4e2dd90f 2022-03-26 martijn const char *
1089 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_v_tag_value(const char *ptr, int optional)
1091 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
1093 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_digit(ptr, 0)) == NULL)
1094 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1095 4e2dd90f 2022-03-26 martijn while (1) {
1096 4e2dd90f 2022-03-26 martijn prev = ptr;
1097 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_digit(ptr, 0)) == NULL)
1098 4e2dd90f 2022-03-26 martijn return prev;
1102 4e2dd90f 2022-03-26 martijn const char *
1103 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_a_tag(const char *ptr, int optional)
1105 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1107 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x61)
1108 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1109 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1110 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1111 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1112 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1113 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_a_tag_value(ptr, 0)) == NULL)
1114 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1115 4e2dd90f 2022-03-26 martijn return ptr;
1118 4e2dd90f 2022-03-26 martijn const char *
1119 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_a_tag_value(const char *ptr, int optional)
1121 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_sig_a_tag_alg(ptr, optional);
1124 4e2dd90f 2022-03-26 martijn const char *
1125 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_a_tag_alg(const char *ptr, int optional)
1127 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1129 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_a_tag_k(ptr, 0)) == NULL)
1130 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1131 4e2dd90f 2022-03-26 martijn if (ptr[0] != '-')
1132 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1134 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_a_tag_h(ptr, 0)) == NULL)
1135 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1136 4e2dd90f 2022-03-26 martijn return ptr;
1139 4e2dd90f 2022-03-26 martijn const char *
1140 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_a_tag_k(const char *ptr, int optional)
1142 4e2dd90f 2022-03-26 martijn /* sha1 / sha256 covered by x-sig-a-tag-k */
1143 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_x_sig_a_tag_k(ptr, optional);
1146 4e2dd90f 2022-03-26 martijn const char *
1147 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_a_tag_h(const char *ptr, int optional)
1149 4e2dd90f 2022-03-26 martijn /* rsa / ed25519 covered by x-sig-a-tag-h */
1150 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_x_sig_a_tag_h(ptr, optional);
1153 4e2dd90f 2022-03-26 martijn const char *
1154 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_x_sig_a_tag_k(const char *ptr, int optional)
1156 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev, *end;
1158 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_alpha(ptr, 0)) == NULL)
1159 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1160 4e2dd90f 2022-03-26 martijn prev = ptr;
1161 4e2dd90f 2022-03-26 martijn while ((end = osmtpd_ltok_skip_alpha(ptr, 0)) != NULL ||
1162 4e2dd90f 2022-03-26 martijn (end = osmtpd_ltok_skip_digit(ptr, 0)) != NULL) {
1163 4e2dd90f 2022-03-26 martijn ptr = end;
1164 4e2dd90f 2022-03-26 martijn prev = end;
1166 4e2dd90f 2022-03-26 martijn return prev;
1169 4e2dd90f 2022-03-26 martijn const char *
1170 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_x_sig_a_tag_h(const char *ptr, int optional)
1172 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev, *end;
1174 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_alpha(ptr, 0)) == NULL)
1175 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1176 4e2dd90f 2022-03-26 martijn prev = ptr;
1177 4e2dd90f 2022-03-26 martijn while ((end = osmtpd_ltok_skip_alpha(ptr, 0)) != NULL ||
1178 4e2dd90f 2022-03-26 martijn (end = osmtpd_ltok_skip_digit(ptr, 0)) != NULL) {
1179 4e2dd90f 2022-03-26 martijn ptr = end;
1180 4e2dd90f 2022-03-26 martijn prev = end;
1182 4e2dd90f 2022-03-26 martijn return prev;
1185 4e2dd90f 2022-03-26 martijn const char *
1186 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_b_tag(const char *ptr, int optional)
1188 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1190 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x62)
1191 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1192 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1193 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1194 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1195 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1196 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_b_tag_value(ptr, 0)) == NULL)
1197 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1198 4e2dd90f 2022-03-26 martijn return ptr;
1201 4e2dd90f 2022-03-26 martijn const char *
1202 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_b_tag_value(const char *ptr, int optional)
1204 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_sig_b_tag_data(ptr, optional);
1207 4e2dd90f 2022-03-26 martijn const char *
1208 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_b_tag_data(const char *ptr, int optional)
1210 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_base64string(ptr, optional);
1213 4e2dd90f 2022-03-26 martijn const char *
1214 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_bh_tag(const char *ptr, int optional)
1216 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1218 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x62 && ptr[0] != 0x68)
1219 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1220 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 2, 1);
1221 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1222 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1223 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1224 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_bh_tag_value(ptr, 0)) == NULL)
1225 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1226 4e2dd90f 2022-03-26 martijn return ptr;
1229 4e2dd90f 2022-03-26 martijn const char *
1230 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_bh_tag_value(const char *ptr, int optional)
1232 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_sig_bh_tag_data(ptr, optional);
1235 4e2dd90f 2022-03-26 martijn const char *
1236 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_bh_tag_data(const char *ptr, int optional)
1238 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_base64string(ptr, optional);
1241 4e2dd90f 2022-03-26 martijn const char *
1242 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_c_tag(const char *ptr, int optional)
1244 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1246 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x63)
1247 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1248 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1249 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1250 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1251 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1252 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_c_tag_value(ptr, 0)) == NULL)
1253 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1254 4e2dd90f 2022-03-26 martijn return ptr;
1257 4e2dd90f 2022-03-26 martijn const char *
1258 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_c_tag_value(const char *ptr, int optional)
1260 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1262 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_c_tag_alg(ptr, 0)) == NULL)
1263 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1264 4e2dd90f 2022-03-26 martijn if (ptr[0] == '/') {
1265 4e2dd90f 2022-03-26 martijn start = ptr;
1266 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_c_tag_alg(ptr, 0)) == NULL)
1267 4e2dd90f 2022-03-26 martijn return start;
1269 4e2dd90f 2022-03-26 martijn return ptr;
1272 4e2dd90f 2022-03-26 martijn const char *
1273 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_c_tag_alg(const char *ptr, int optional)
1275 4e2dd90f 2022-03-26 martijn /* simple / relaxed covered by x-sig-c-tag-alga */
1276 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_x_sig_c_tag_alg(ptr, optional);
1279 4e2dd90f 2022-03-26 martijn const char *
1280 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_x_sig_c_tag_alg(const char *ptr, int optional)
1282 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_hyphenated_word(ptr, optional);
1285 4e2dd90f 2022-03-26 martijn const char *
1286 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_d_tag(const char *ptr, int optional)
1288 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1290 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x64)
1291 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1292 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1293 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1294 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1295 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1296 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_d_tag_value(ptr, 0)) == NULL)
1297 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1298 4e2dd90f 2022-03-26 martijn return ptr;
1301 4e2dd90f 2022-03-26 martijn const char *
1302 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_d_tag_value(const char *ptr, int optional)
1304 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_domain_name(ptr, optional);
1307 4e2dd90f 2022-03-26 martijn const char *
1308 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_domain_name(const char *ptr, int optional)
1310 4e2dd90f 2022-03-26 martijn const char *prev = ptr;
1312 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sub_domain(ptr, 0)) == NULL)
1313 4e2dd90f 2022-03-26 martijn return optional ? prev : NULL;
1314 4e2dd90f 2022-03-26 martijn while (1) {
1315 4e2dd90f 2022-03-26 martijn prev = ptr;
1316 4e2dd90f 2022-03-26 martijn if (ptr[0] != '.' ||
1317 4e2dd90f 2022-03-26 martijn (ptr = osmtpd_ltok_skip_sub_domain(ptr + 1, 0)) == NULL)
1318 4e2dd90f 2022-03-26 martijn return prev;
1322 4e2dd90f 2022-03-26 martijn const char *
1323 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_h_tag(const char *ptr, int optional)
1325 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1327 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x68)
1328 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1329 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1330 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1331 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1332 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1333 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_h_tag_value(ptr, 0)) == NULL)
1334 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1335 4e2dd90f 2022-03-26 martijn return ptr;
1338 4e2dd90f 2022-03-26 martijn const char *
1339 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_h_tag_value(const char *ptr, int optional)
1341 4e2dd90f 2022-03-26 martijn const char *prev = ptr;
1343 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_hdr_name(ptr, 0)) == NULL)
1344 4e2dd90f 2022-03-26 martijn return optional ? prev : NULL;
1345 4e2dd90f 2022-03-26 martijn while (1) {
1346 4e2dd90f 2022-03-26 martijn prev = ptr;
1347 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1348 4e2dd90f 2022-03-26 martijn if (ptr[0] != ':')
1349 4e2dd90f 2022-03-26 martijn return prev;
1350 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1351 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_hdr_name(ptr, 0)) == NULL)
1352 4e2dd90f 2022-03-26 martijn return prev;
1356 4e2dd90f 2022-03-26 martijn const char *
1357 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_i_tag(const char *ptr, int optional)
1359 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1361 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x69)
1362 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1363 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1364 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1365 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1366 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1367 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_i_tag_value(ptr, 0)) == NULL)
1368 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1369 4e2dd90f 2022-03-26 martijn return ptr;
1372 4e2dd90f 2022-03-26 martijn const char *
1373 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_i_tag_value(const char *ptr, int optional)
1375 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1377 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_local_part(ptr, 1);
1378 4e2dd90f 2022-03-26 martijn if (ptr[0] != '@' ||
1379 088e9e49 2022-03-30 martijn (ptr = osmtpd_ltok_skip_domain_name(ptr + 1, 0)) == NULL)
1380 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1381 4e2dd90f 2022-03-26 martijn return ptr;
1384 4e2dd90f 2022-03-26 martijn const char *
1385 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_l_tag(const char *ptr, int optional)
1387 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1389 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x6c)
1390 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1391 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1392 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1393 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1394 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1395 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_l_tag_value(ptr, 0)) == NULL)
1396 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1397 4e2dd90f 2022-03-26 martijn return ptr;
1400 4e2dd90f 2022-03-26 martijn const char *
1401 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_l_tag_value(const char *ptr, int optional)
1403 4e2dd90f 2022-03-26 martijn size_t i;
1405 4e2dd90f 2022-03-26 martijn for (i = 0; i < 76; i++) {
1406 4e2dd90f 2022-03-26 martijn if (osmtpd_ltok_skip_digit(ptr + i, 0) == NULL)
1409 4e2dd90f 2022-03-26 martijn if (i >= 1 && i <= 76)
1410 4e2dd90f 2022-03-26 martijn return ptr + i;
1411 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
1414 4e2dd90f 2022-03-26 martijn const char *
1415 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_q_tag(const char *ptr, int optional)
1417 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1419 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x71)
1420 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1421 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1422 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1423 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1424 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1425 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_q_tag_value(ptr, 0)) == NULL)
1426 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1427 4e2dd90f 2022-03-26 martijn return ptr;
1430 4e2dd90f 2022-03-26 martijn const char *
1431 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_q_tag_value(const char *ptr, int optional)
1433 4e2dd90f 2022-03-26 martijn const char *prev = ptr;
1434 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_q_tag_method(ptr, 0)) == NULL)
1435 4e2dd90f 2022-03-26 martijn return optional ? prev : NULL;
1436 4e2dd90f 2022-03-26 martijn while (1) {
1437 4e2dd90f 2022-03-26 martijn prev = ptr;
1438 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1439 4e2dd90f 2022-03-26 martijn if (ptr[0] != ':')
1440 4e2dd90f 2022-03-26 martijn return prev;
1441 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1442 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_q_tag_method(ptr, 0)) == NULL)
1443 4e2dd90f 2022-03-26 martijn return prev;
1447 4e2dd90f 2022-03-26 martijn const char *
1448 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_q_tag_method(const char *ptr, int optional)
1450 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1452 4e2dd90f 2022-03-26 martijn /* dns/txt covered by x-sig-q-tag-type ["/" x-sig-q-tag-args] */
1453 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_x_sig_q_tag_type(ptr, 0)) == NULL)
1454 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1455 4e2dd90f 2022-03-26 martijn start = ptr;
1456 4e2dd90f 2022-03-26 martijn if (ptr[0] != '/')
1457 4e2dd90f 2022-03-26 martijn return ptr;
1458 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_x_sig_q_tag_args(ptr, 0)) == NULL)
1459 4e2dd90f 2022-03-26 martijn return start;
1460 4e2dd90f 2022-03-26 martijn return ptr;
1463 4e2dd90f 2022-03-26 martijn const char *
1464 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_x_sig_q_tag_type(const char *ptr, int optional)
1466 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_hyphenated_word(ptr, optional);
1469 4e2dd90f 2022-03-26 martijn const char *
1470 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_x_sig_q_tag_args(const char *ptr, int optional)
1472 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_qp_hdr_value(ptr, optional);
1475 4e2dd90f 2022-03-26 martijn const char *
1476 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_s_tag(const char *ptr, int optional)
1478 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1480 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x73)
1481 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1482 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1483 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1484 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1485 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1486 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_s_tag_value(ptr, 0)) == NULL)
1487 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1488 4e2dd90f 2022-03-26 martijn return ptr;
1491 4e2dd90f 2022-03-26 martijn const char *
1492 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_s_tag_value(const char *ptr, int optional)
1494 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_selector(ptr, optional);
1497 4e2dd90f 2022-03-26 martijn const char *
1498 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_t_tag(const char *ptr, int optional)
1500 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1502 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x74)
1503 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1504 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1505 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1506 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1507 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1508 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_t_tag_value(ptr, 0)) == NULL)
1509 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1510 4e2dd90f 2022-03-26 martijn return ptr;
1513 4e2dd90f 2022-03-26 martijn const char *
1514 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_t_tag_value(const char *ptr, int optional)
1516 4e2dd90f 2022-03-26 martijn size_t i;
1518 4e2dd90f 2022-03-26 martijn for (i = 0; i < 12; i++) {
1519 4e2dd90f 2022-03-26 martijn if (osmtpd_ltok_skip_digit(ptr + i, 0) == NULL)
1522 4e2dd90f 2022-03-26 martijn if (i >= 1 && i <= 12)
1523 4e2dd90f 2022-03-26 martijn return ptr + i;
1524 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
1527 4e2dd90f 2022-03-26 martijn const char *
1528 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_x_tag(const char *ptr, int optional)
1530 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1532 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x78)
1533 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1534 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1535 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1536 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1537 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1538 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_x_tag_value(ptr, 0)) == NULL)
1539 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1540 4e2dd90f 2022-03-26 martijn return ptr;
1543 4e2dd90f 2022-03-26 martijn const char *
1544 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_x_tag_value(const char *ptr, int optional)
1546 4e2dd90f 2022-03-26 martijn size_t i;
1548 4e2dd90f 2022-03-26 martijn for (i = 0; i < 12; i++) {
1549 4e2dd90f 2022-03-26 martijn if (osmtpd_ltok_skip_digit(ptr + i, 0) == NULL)
1552 4e2dd90f 2022-03-26 martijn if (i >= 1 && i <= 12)
1553 4e2dd90f 2022-03-26 martijn return ptr + i;
1554 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
1557 4e2dd90f 2022-03-26 martijn const char *
1558 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_z_tag(const char *ptr, int optional)
1560 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1562 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x7a)
1563 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1564 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1565 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1566 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1567 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1568 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_z_tag_value(ptr, 0)) == NULL)
1569 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1570 4e2dd90f 2022-03-26 martijn return ptr;
1573 4e2dd90f 2022-03-26 martijn const char *
1574 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_z_tag_value(const char *ptr, int optional)
1576 4e2dd90f 2022-03-26 martijn const char *prev = ptr;
1578 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_z_tag_copy(ptr, 0)) == NULL)
1579 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
1580 4e2dd90f 2022-03-26 martijn while (1) {
1581 4e2dd90f 2022-03-26 martijn prev = ptr;
1582 4e2dd90f 2022-03-26 martijn if (ptr[0] != '|')
1583 4e2dd90f 2022-03-26 martijn return prev;
1584 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1585 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_z_tag_copy(ptr, 0)) == NULL)
1586 4e2dd90f 2022-03-26 martijn return prev;
1590 4e2dd90f 2022-03-26 martijn const char *
1591 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_z_tag_copy(const char *ptr, int optional)
1593 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1595 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_hdr_name(ptr, 0)) == NULL)
1596 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1597 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1598 4e2dd90f 2022-03-26 martijn if (ptr[0] != ':')
1599 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1600 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_qp_hdr_value(ptr, 0)) == NULL)
1601 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1602 4e2dd90f 2022-03-26 martijn return ptr;
1605 4e2dd90f 2022-03-26 martijn const char *
1606 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_v_tag(const char *ptr, int optional)
1608 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1610 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x76)
1611 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1612 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1613 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1614 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1615 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1616 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_key_v_tag_value(ptr, 0)) == NULL)
1617 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1618 4e2dd90f 2022-03-26 martijn return ptr;
1621 4e2dd90f 2022-03-26 martijn const char *
1622 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_v_tag_value(const char *ptr, int optional)
1624 4e2dd90f 2022-03-26 martijn if (ptr[0] == 0x44 && ptr[1] == 0x4b && ptr[2] == 0x49 &&
1625 4e2dd90f 2022-03-26 martijn ptr[3] == 0x4d && ptr[4] == 0x31)
1626 4e2dd90f 2022-03-26 martijn return ptr + 5;
1627 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
1630 4e2dd90f 2022-03-26 martijn const char *
1631 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_h_tag(const char *ptr, int optional)
1633 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1635 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x68)
1636 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1637 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1638 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1639 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1640 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1641 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_key_h_tag_value(ptr, 0)) == NULL)
1642 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1643 4e2dd90f 2022-03-26 martijn return ptr;
1646 4e2dd90f 2022-03-26 martijn const char *
1647 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_h_tag_value(const char *ptr, int optional)
1649 4e2dd90f 2022-03-26 martijn const char *prev = ptr;
1651 09150ec4 2022-03-30 martijn if ((ptr = osmtpd_ltok_skip_key_h_tag_alg(ptr, 0)) == NULL)
1652 4e2dd90f 2022-03-26 martijn return optional ? prev : NULL;
1653 4e2dd90f 2022-03-26 martijn while (1) {
1654 4e2dd90f 2022-03-26 martijn prev = ptr;
1655 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1656 4e2dd90f 2022-03-26 martijn if (ptr[0] != ':')
1657 4e2dd90f 2022-03-26 martijn return prev;
1658 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1659 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_key_h_tag_alg(ptr, 0)) == NULL)
1660 4e2dd90f 2022-03-26 martijn return prev;
1664 4e2dd90f 2022-03-26 martijn const char *
1665 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_h_tag_alg(const char *ptr, int optional)
1667 4e2dd90f 2022-03-26 martijn /* sha1 / sha256 covered by x-key-h-tag-alg */
1668 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_x_key_h_tag_alg(ptr, optional);
1671 4e2dd90f 2022-03-26 martijn const char *
1672 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_x_key_h_tag_alg(const char *ptr, int optional)
1674 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_hyphenated_word(ptr, optional);
1677 4e2dd90f 2022-03-26 martijn const char *
1678 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_k_tag(const char *ptr, int optional)
1680 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1682 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x6b)
1683 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1684 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1685 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1686 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1687 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1688 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_key_k_tag_value(ptr, 0)) == NULL)
1689 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1690 4e2dd90f 2022-03-26 martijn return ptr;
1693 4e2dd90f 2022-03-26 martijn const char *
1694 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_k_tag_value(const char *ptr, int optional)
1696 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1698 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_key_k_tag_type(ptr, 0)) == NULL)
1699 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1700 4e2dd90f 2022-03-26 martijn return ptr;
1703 4e2dd90f 2022-03-26 martijn const char *
1704 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_k_tag_type(const char *ptr, int optional)
1706 4e2dd90f 2022-03-26 martijn /* rsa covered by x-key-k-tag-type */
1707 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_x_key_k_tag_type(ptr, optional);
1710 4e2dd90f 2022-03-26 martijn const char *
1711 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_x_key_k_tag_type(const char *ptr, int optional)
1713 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_hyphenated_word(ptr, optional);
1716 4e2dd90f 2022-03-26 martijn const char *
1717 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_n_tag(const char *ptr, int optional)
1719 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1721 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x6e)
1722 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1723 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1724 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1725 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1726 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1727 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_key_n_tag_value(ptr, 0)) == NULL)
1728 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1729 4e2dd90f 2022-03-26 martijn return ptr;
1732 4e2dd90f 2022-03-26 martijn const char *
1733 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_n_tag_value(const char *ptr, int optional)
1735 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_qp_section(ptr, optional);
1738 4e2dd90f 2022-03-26 martijn const char *
1739 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_p_tag(const char *ptr, int optional)
1741 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1743 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x70)
1744 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1745 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1746 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1747 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1748 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1749 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_key_p_tag_value(ptr, 0)) == NULL)
1750 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1751 4e2dd90f 2022-03-26 martijn return ptr;
1754 4e2dd90f 2022-03-26 martijn const char *
1755 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_p_tag_value(const char *ptr, int optional)
1757 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1759 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_base64string(ptr, 0)) == NULL)
1760 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1761 4e2dd90f 2022-03-26 martijn return ptr;
1764 4e2dd90f 2022-03-26 martijn const char *
1765 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_s_tag(const char *ptr, int optional)
1767 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1769 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x73)
1770 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1771 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1772 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1773 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1774 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1775 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_key_s_tag_value(ptr, 0)) == NULL)
1776 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1777 4e2dd90f 2022-03-26 martijn return ptr;
1780 4e2dd90f 2022-03-26 martijn const char *
1781 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_s_tag_value(const char *ptr, int optional)
1783 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1785 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_key_s_tag_type(ptr, 0)) == NULL)
1786 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1787 4e2dd90f 2022-03-26 martijn while (1) {
1788 4e2dd90f 2022-03-26 martijn start = ptr;
1789 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1790 4e2dd90f 2022-03-26 martijn if (ptr[0] != ':')
1791 4e2dd90f 2022-03-26 martijn return start;
1792 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1793 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_key_s_tag_type(ptr, 0);
1794 4e2dd90f 2022-03-26 martijn if (ptr == NULL)
1795 4e2dd90f 2022-03-26 martijn return start;
1799 4e2dd90f 2022-03-26 martijn const char *
1800 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_s_tag_type(const char *ptr, int optional)
1802 4e2dd90f 2022-03-26 martijn if (ptr[0] == '*')
1803 4e2dd90f 2022-03-26 martijn return ptr + 1;
1804 4e2dd90f 2022-03-26 martijn /* email covered by x-key-s-tag-type */
1805 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_x_key_s_tag_type(ptr, optional);
1808 4e2dd90f 2022-03-26 martijn const char *
1809 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_x_key_s_tag_type(const char *ptr, int optional)
1811 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_hyphenated_word(ptr, optional);
1814 4e2dd90f 2022-03-26 martijn const char *
1815 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_t_tag(const char *ptr, int optional)
1817 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1819 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x74)
1820 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1821 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1822 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1823 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1824 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1825 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_key_t_tag_value(ptr, 0)) == NULL)
1826 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1827 4e2dd90f 2022-03-26 martijn return ptr;
1830 4e2dd90f 2022-03-26 martijn const char *
1831 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_t_tag_value(const char *ptr, int optional)
1833 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1835 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_key_t_tag_flag(ptr, 0)) == NULL)
1836 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1837 4e2dd90f 2022-03-26 martijn while (1) {
1838 4e2dd90f 2022-03-26 martijn start = ptr;
1839 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1840 4e2dd90f 2022-03-26 martijn if (ptr[0] != ':')
1841 4e2dd90f 2022-03-26 martijn return start;
1842 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1843 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_key_t_tag_flag(ptr, 0);
1844 4e2dd90f 2022-03-26 martijn if (ptr == NULL)
1845 4e2dd90f 2022-03-26 martijn return start;
1849 4e2dd90f 2022-03-26 martijn const char *
1850 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_t_tag_flag(const char *ptr, int optional)
1852 4e2dd90f 2022-03-26 martijn /* y / s covered by x-key-t-tag-flag */
1853 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_x_key_t_tag_flag(ptr, optional);
1856 4e2dd90f 2022-03-26 martijn const char *
1857 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_x_key_t_tag_flag(const char *ptr, int optional)
1859 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_hyphenated_word(ptr, optional);
1862 4e2dd90f 2022-03-26 martijn const char *
1863 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_ar_pvalue(const char *ptr, int optional)
1865 4e2dd90f 2022-03-26 martijn const char *start = ptr, *tmp;
1867 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_cfws(ptr, 1);
1868 4e2dd90f 2022-03-26 martijn if ((tmp = osmtpd_ltok_skip_value(ptr, 0)) != NULL)
1869 4e2dd90f 2022-03-26 martijn return tmp;
1870 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_local_part(ptr, 1);
1871 4e2dd90f 2022-03-26 martijn if (ptr[0] == '@')
1873 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_domain(ptr, 0)) == NULL)
1874 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1875 4e2dd90f 2022-03-26 martijn return ptr;