2 4e2dd90f 2022-03-26 martijn * Copyright (c) 2020 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 #include <stdio.h>
27 4e2dd90f 2022-03-26 martijn /* RFC 5234 - Augmented BNF for Syntax Specifications: ABNF */
28 4e2dd90f 2022-03-26 martijn const char *
29 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_alpha(const char *ptr, int optional)
31 4e2dd90f 2022-03-26 martijn if ((ptr[0] >= 0x41 && ptr[0] <= 0x5a) ||
32 4e2dd90f 2022-03-26 martijn (ptr[0] >= 0x61 && ptr[0] <= 0x7a))
33 4e2dd90f 2022-03-26 martijn return ptr + 1;
34 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
37 4e2dd90f 2022-03-26 martijn const char *
38 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_bit(const char *ptr, int optional)
40 4e2dd90f 2022-03-26 martijn if (ptr[0] == '0' || ptr[0] == '1')
41 4e2dd90f 2022-03-26 martijn return ptr + 1;
42 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
45 4e2dd90f 2022-03-26 martijn const char *
46 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_char(const char *ptr, int optional)
48 4e2dd90f 2022-03-26 martijn if (ptr[0] >= 0x01 && ptr[0] <= 0x7f)
49 4e2dd90f 2022-03-26 martijn return ptr + 1;
50 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
53 4e2dd90f 2022-03-26 martijn const char *
54 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_cr(const char *ptr, int optional)
56 4e2dd90f 2022-03-26 martijn if (ptr[0] == 0xd)
57 4e2dd90f 2022-03-26 martijn return ptr + 1;
58 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
61 4e2dd90f 2022-03-26 martijn const char *
62 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_crlf(const char *ptr, int optional)
64 4e2dd90f 2022-03-26 martijn if (ptr[0] == 13 && ptr[1] == 10)
65 4e2dd90f 2022-03-26 martijn return ptr + 2;
66 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
69 4e2dd90f 2022-03-26 martijn const char *
70 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_ctl(const char *ptr, int optional)
72 4e2dd90f 2022-03-26 martijn if ((ptr[0] >= 0x00 && ptr[0] <= 0x1f) || ptr[0] == 0x7f)
73 4e2dd90f 2022-03-26 martijn return ptr + 1;
74 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
77 4e2dd90f 2022-03-26 martijn const char *
78 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_digit(const char *ptr, int optional)
80 4e2dd90f 2022-03-26 martijn if (ptr[0] >= 0x30 && ptr[0] <= 0x39)
81 4e2dd90f 2022-03-26 martijn return ptr + 1;
82 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
85 4e2dd90f 2022-03-26 martijn const char *
86 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_dquote(const char *ptr, int optional)
88 4e2dd90f 2022-03-26 martijn if (ptr[0] == 0x22)
89 4e2dd90f 2022-03-26 martijn return ptr + 1;
90 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
93 4e2dd90f 2022-03-26 martijn const char *
94 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_hexdig(const char *ptr, int optional)
96 4e2dd90f 2022-03-26 martijn const char *start = ptr;
99 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_digit(ptr, 0)) != NULL)
100 4e2dd90f 2022-03-26 martijn return ptr;
101 4e2dd90f 2022-03-26 martijn l = tolower(ptr[0]);
102 4e2dd90f 2022-03-26 martijn if (l == 'a' || l == 'b' || l == 'c' || l == 'd' ||
103 4e2dd90f 2022-03-26 martijn l == 'e' || l == 'f')
104 4e2dd90f 2022-03-26 martijn return ptr + 1;
105 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
108 4e2dd90f 2022-03-26 martijn const char *
109 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_htab(const char *ptr, int optional)
111 4e2dd90f 2022-03-26 martijn if (ptr[0] == 0x9)
112 4e2dd90f 2022-03-26 martijn return ptr + 1;
113 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
116 4e2dd90f 2022-03-26 martijn const char *
117 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_lf(const char *ptr, int optional)
119 4e2dd90f 2022-03-26 martijn if (ptr[0] == 0xa)
120 4e2dd90f 2022-03-26 martijn return ptr + 1;
121 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
124 4e2dd90f 2022-03-26 martijn const char *
125 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_octet(const char *ptr, int optional)
127 4e2dd90f 2022-03-26 martijn return ptr + 1;
130 4e2dd90f 2022-03-26 martijn const char *
131 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sp(const char *ptr, int optional)
133 4e2dd90f 2022-03-26 martijn if (ptr[0] == 0x20)
134 4e2dd90f 2022-03-26 martijn return ptr + 1;
135 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
138 4e2dd90f 2022-03-26 martijn const char *
139 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_vchar(const char *ptr, int optional)
141 4e2dd90f 2022-03-26 martijn if (ptr[0] >= 0x21 && ptr[0] <= 0x7e)
142 4e2dd90f 2022-03-26 martijn return ptr + 1;
143 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
146 4e2dd90f 2022-03-26 martijn const char *
147 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_wsp(const char *ptr, int optional)
149 4e2dd90f 2022-03-26 martijn const char *start = ptr;
151 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sp(start, 0)) != NULL ||
152 4e2dd90f 2022-03-26 martijn (ptr = osmtpd_ltok_skip_htab(start, 0)) != NULL)
153 4e2dd90f 2022-03-26 martijn return ptr;
154 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
157 4e2dd90f 2022-03-26 martijn /* RFC 5321 - Simple Mail Transfer Protocol */
158 4e2dd90f 2022-03-26 martijn const char *
159 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_keyword(const char *ptr, int optional)
161 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_ldh_string(ptr, optional);
164 4e2dd90f 2022-03-26 martijn const char *
165 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sub_domain(const char *ptr, int optional)
167 4e2dd90f 2022-03-26 martijn const char *start = ptr;
169 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_let_dig(ptr, 0)) == NULL)
170 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
171 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_ldh_string(ptr, 1);
174 4e2dd90f 2022-03-26 martijn const char *
175 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_let_dig(const char *ptr, int optional)
177 4e2dd90f 2022-03-26 martijn const char *start = ptr;
179 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_alpha(start, 0)) == NULL &&
180 4e2dd90f 2022-03-26 martijn (ptr = osmtpd_ltok_skip_digit(start, 0)) == NULL)
181 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
182 4e2dd90f 2022-03-26 martijn return ptr;
185 4e2dd90f 2022-03-26 martijn const char *
186 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_ldh_string(const char *ptr, int optional)
188 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
189 4e2dd90f 2022-03-26 martijn int letdig = 0;
191 4e2dd90f 2022-03-26 martijn while (1) {
192 4e2dd90f 2022-03-26 martijn prev = ptr;
193 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_alpha(prev, 0)) != NULL ||
194 4e2dd90f 2022-03-26 martijn (ptr = osmtpd_ltok_skip_digit(prev, 0)) != NULL) {
195 4e2dd90f 2022-03-26 martijn letdig = 1;
196 4e2dd90f 2022-03-26 martijn continue;
198 4e2dd90f 2022-03-26 martijn if (prev[0] == '-') {
199 4e2dd90f 2022-03-26 martijn letdig = 0;
200 4e2dd90f 2022-03-26 martijn ptr = prev + 1;
201 4e2dd90f 2022-03-26 martijn continue;
203 4e2dd90f 2022-03-26 martijn ptr = prev;
206 4e2dd90f 2022-03-26 martijn if (letdig)
207 4e2dd90f 2022-03-26 martijn return ptr;
208 4e2dd90f 2022-03-26 martijn if (ptr == start)
209 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
210 4e2dd90f 2022-03-26 martijn return ptr;
213 4e2dd90f 2022-03-26 martijn /* RFC 5322 - Internet Message Format */
214 4e2dd90f 2022-03-26 martijn const char *
215 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_quoted_pair(const char *ptr, int optional)
217 4e2dd90f 2022-03-26 martijn const char *start = ptr;
219 4e2dd90f 2022-03-26 martijn if (ptr[0] == '\\' && (
220 4e2dd90f 2022-03-26 martijn (ptr = osmtpd_ltok_skip_vchar(start + 1, 0)) != NULL ||
221 4e2dd90f 2022-03-26 martijn (ptr = osmtpd_ltok_skip_wsp(start + 1, 0)) != NULL))
222 4e2dd90f 2022-03-26 martijn return ptr;
223 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_obs_qp(start, optional);
226 4e2dd90f 2022-03-26 martijn const char *
227 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_fws(const char *ptr, int optional)
229 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev = ptr;
231 4e2dd90f 2022-03-26 martijn while ((ptr = osmtpd_ltok_skip_wsp(ptr, 0)) != NULL)
232 4e2dd90f 2022-03-26 martijn prev = ptr;
233 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_crlf(prev, 1)) == prev)
234 4e2dd90f 2022-03-26 martijn ptr = start;
235 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_wsp(ptr, 0)) == NULL)
236 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_obs_fws(start, optional);
237 4e2dd90f 2022-03-26 martijn prev = ptr;
238 4e2dd90f 2022-03-26 martijn while ((ptr = osmtpd_ltok_skip_wsp(ptr, 0)) != NULL)
239 4e2dd90f 2022-03-26 martijn prev = ptr;
240 4e2dd90f 2022-03-26 martijn return prev;
243 4e2dd90f 2022-03-26 martijn const char *
244 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_ctext(const char *ptr, int optional)
246 4e2dd90f 2022-03-26 martijn const char *start = ptr;
248 4e2dd90f 2022-03-26 martijn if ((ptr[0] >= 33 && ptr[0] <= 39) || (ptr[0] >= 42 && ptr[0] <= 91) ||
249 4e2dd90f 2022-03-26 martijn (ptr[0] >= 93 && ptr[0] <= 126))
250 4e2dd90f 2022-03-26 martijn return ptr + 1;
251 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_obs_ctext(ptr, 0)) != NULL)
252 4e2dd90f 2022-03-26 martijn return ptr;
253 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
256 4e2dd90f 2022-03-26 martijn const char *
257 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_ccontent(const char *ptr, int optional)
259 4e2dd90f 2022-03-26 martijn const char *start = ptr;
261 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_ctext(ptr, 0)) != NULL)
262 4e2dd90f 2022-03-26 martijn return ptr;
263 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_quoted_pair(start, 0)) != NULL)
264 4e2dd90f 2022-03-26 martijn return ptr;
265 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_comment(start, 0)) != NULL)
266 4e2dd90f 2022-03-26 martijn return ptr;
267 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
270 4e2dd90f 2022-03-26 martijn const char *
271 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_comment(const char *ptr, int optional)
273 4e2dd90f 2022-03-26 martijn const char *start = ptr;
275 4e2dd90f 2022-03-26 martijn if (ptr++[0] != '(')
276 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
277 4e2dd90f 2022-03-26 martijn while (1) {
278 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
279 4e2dd90f 2022-03-26 martijn if (ptr[0] == ')')
280 4e2dd90f 2022-03-26 martijn return ptr + 1;
281 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_ccontent(ptr, 0)) == NULL)
282 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
286 4e2dd90f 2022-03-26 martijn const char *
287 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_cfws(const char *ptr, int optional)
289 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
291 4e2dd90f 2022-03-26 martijn while (1) {
292 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
293 4e2dd90f 2022-03-26 martijn prev = ptr;
294 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_comment(ptr, 0)) == NULL) {
295 4e2dd90f 2022-03-26 martijn ptr = prev;
299 4e2dd90f 2022-03-26 martijn return ptr == start && !optional ? NULL : ptr;
302 4e2dd90f 2022-03-26 martijn const char *
303 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_atext(const char *ptr, int optional)
305 4e2dd90f 2022-03-26 martijn const char *start = ptr;
307 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_alpha(start, 0)) != NULL ||
308 4e2dd90f 2022-03-26 martijn (ptr = osmtpd_ltok_skip_digit(start, 0)) != NULL)
309 4e2dd90f 2022-03-26 martijn return ptr;
310 4e2dd90f 2022-03-26 martijn ptr = start;
311 4e2dd90f 2022-03-26 martijn if (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] == '=' || ptr[0] == '?' ||
314 4e2dd90f 2022-03-26 martijn ptr[0] == '^' || ptr[0] == '_' || ptr[0] == '`' || ptr[0] == '{' ||
315 4e2dd90f 2022-03-26 martijn ptr[0] == '|' || ptr[0] == '}' || ptr[0] == '~')
316 4e2dd90f 2022-03-26 martijn return ptr + 1;
317 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
320 4e2dd90f 2022-03-26 martijn const char *
321 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_atom(const char *ptr, int optional)
323 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
325 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_cfws(ptr, 1);
326 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_atext(ptr, 0)) == NULL)
327 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
329 4e2dd90f 2022-03-26 martijn prev = ptr;
330 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_atext(ptr, 1);
331 4e2dd90f 2022-03-26 martijn } while (prev != ptr);
332 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_cfws(ptr, 1);
335 4e2dd90f 2022-03-26 martijn const char *
336 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_dot_atom_text(const char *ptr, int optional)
338 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
340 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_atext(ptr, 0)) == NULL)
341 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
343 4e2dd90f 2022-03-26 martijn prev = ptr;
344 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_atext(ptr, 1);
345 4e2dd90f 2022-03-26 martijn } while (ptr != prev);
347 4e2dd90f 2022-03-26 martijn while (ptr[0] == '.') {
349 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_atext(ptr, 0)) == NULL)
350 4e2dd90f 2022-03-26 martijn return prev;
352 4e2dd90f 2022-03-26 martijn prev = ptr;
353 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_atext(ptr, 1);
354 4e2dd90f 2022-03-26 martijn } while (ptr != prev);
356 4e2dd90f 2022-03-26 martijn return ptr;
359 4e2dd90f 2022-03-26 martijn const char *
360 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_dot_atom(const char *ptr, int optional)
362 4e2dd90f 2022-03-26 martijn const char *start = ptr;
364 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_cfws(ptr, 1);
365 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_dot_atom_text(ptr, 0)) == NULL)
366 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
367 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_cfws(ptr, 1);
370 4e2dd90f 2022-03-26 martijn const char *
371 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_qtext(const char *ptr, int optional)
373 4e2dd90f 2022-03-26 martijn const char *start = ptr;
375 4e2dd90f 2022-03-26 martijn if (ptr[0] == 33 || (ptr[0] >= 35 && ptr[0] <= 91) ||
376 4e2dd90f 2022-03-26 martijn (ptr[0] >= 93 && ptr[0] <= 126))
377 4e2dd90f 2022-03-26 martijn return ptr + 1;
378 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_obs_qtext(ptr, 0)) != NULL)
379 4e2dd90f 2022-03-26 martijn return ptr;
380 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
383 4e2dd90f 2022-03-26 martijn const char *
384 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_qcontent(const char *ptr, int optional)
386 4e2dd90f 2022-03-26 martijn const char *start = ptr;
388 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_qtext(ptr, 0)) != NULL)
389 4e2dd90f 2022-03-26 martijn return ptr;
390 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_quoted_pair(start, optional);
393 4e2dd90f 2022-03-26 martijn const char *
394 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_quoted_string(const char *ptr, int optional)
396 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
398 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_cfws(ptr, 1);
399 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_dquote(ptr, 0)) == NULL)
400 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
401 4e2dd90f 2022-03-26 martijn prev = ptr;
402 4e2dd90f 2022-03-26 martijn while (1) {
403 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
404 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_qcontent(ptr, 0)) == NULL)
406 4e2dd90f 2022-03-26 martijn prev = ptr;
408 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_dquote(prev, 0)) == NULL)
409 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
410 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_cfws(ptr, 1);
413 4e2dd90f 2022-03-26 martijn const char *
414 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_word(const char *ptr, int optional)
416 4e2dd90f 2022-03-26 martijn const char *start = ptr;
418 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_atom(ptr, 0)) != NULL)
419 4e2dd90f 2022-03-26 martijn return ptr;
420 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_quoted_string(start, optional);
423 4e2dd90f 2022-03-26 martijn const char *
424 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_phrase(const char *ptr, int optional)
426 4e2dd90f 2022-03-26 martijn /* obs-phrase is a superset of phrae */
427 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_obs_phrase(ptr, optional);
430 4e2dd90f 2022-03-26 martijn const char *
431 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_name_addr(const char *ptr, int optional)
433 4e2dd90f 2022-03-26 martijn const char *start = ptr;
435 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_display_name(ptr, 1);
436 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_angle_addr(ptr, 0)) == NULL)
437 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
438 4e2dd90f 2022-03-26 martijn return ptr;
441 4e2dd90f 2022-03-26 martijn const char *
442 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_angle_addr(const char *ptr, int optional)
444 4e2dd90f 2022-03-26 martijn const char *start = ptr;
446 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_cfws(ptr, 1);
447 4e2dd90f 2022-03-26 martijn if (ptr++[0] != '<')
448 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_obs_angle_addr(start, optional);
449 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_addr_spec(ptr, 0)) == NULL)
450 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_obs_angle_addr(start, optional);
451 4e2dd90f 2022-03-26 martijn if (ptr++[0] != '>')
452 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_obs_angle_addr(start, optional);
453 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_cfws(ptr, 1);
456 4e2dd90f 2022-03-26 martijn const char *
457 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_display_name(const char *ptr, int optional)
459 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_phrase(ptr, optional);
462 4e2dd90f 2022-03-26 martijn const char *
463 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_addr_spec(const char *ptr, int optional)
465 4e2dd90f 2022-03-26 martijn const char *start = ptr;
467 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_local_part(ptr, 0)) == NULL)
468 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
469 4e2dd90f 2022-03-26 martijn if (ptr++[0] != '@')
470 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
471 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_domain(ptr, 0)) == NULL)
472 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
473 4e2dd90f 2022-03-26 martijn return ptr;
476 4e2dd90f 2022-03-26 martijn const char *
477 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_local_part(const char *ptr, int optional)
479 4e2dd90f 2022-03-26 martijn const char *start = ptr;
481 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_dot_atom(ptr, 0)) != NULL)
482 4e2dd90f 2022-03-26 martijn return ptr;
483 4e2dd90f 2022-03-26 martijn ptr = start;
484 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_quoted_string(ptr, 0)) != NULL)
485 4e2dd90f 2022-03-26 martijn return ptr;
486 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_obs_local_part(start, optional);
489 4e2dd90f 2022-03-26 martijn const char *
490 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_domain(const char *ptr, int optional)
492 4e2dd90f 2022-03-26 martijn const char *start = ptr;
494 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_dot_atom(start, 0)) != NULL)
495 4e2dd90f 2022-03-26 martijn return ptr;
496 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_domain_literal(start, 0)) != NULL)
497 4e2dd90f 2022-03-26 martijn return ptr;
498 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_obs_domain(start, optional);
501 4e2dd90f 2022-03-26 martijn const char *
502 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_domain_literal(const char *ptr, int optional)
504 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
506 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_cfws(ptr, 1);
507 4e2dd90f 2022-03-26 martijn if (ptr++[0] != '[')
508 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
509 4e2dd90f 2022-03-26 martijn while (1) {
510 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
511 4e2dd90f 2022-03-26 martijn prev = ptr;
512 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_dtext(ptr, 0)) == NULL) {
513 4e2dd90f 2022-03-26 martijn ptr = prev;
517 4e2dd90f 2022-03-26 martijn if (ptr[0] != ']')
518 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
520 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_cfws(ptr, 1);
523 4e2dd90f 2022-03-26 martijn const char *
524 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_dtext(const char *ptr, int optional)
526 4e2dd90f 2022-03-26 martijn if ((ptr[0] >= 33 && ptr[0] <= 90) || (ptr[0] >= 94 && ptr[0] <= 126))
527 4e2dd90f 2022-03-26 martijn return ptr + 1;
528 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_obs_dtext(ptr, optional);
532 4e2dd90f 2022-03-26 martijn const char *
533 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_field_name(const char *ptr, int optional)
535 4e2dd90f 2022-03-26 martijn const char *start = ptr;
537 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_ftext(ptr, 0)) == NULL)
538 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
539 4e2dd90f 2022-03-26 martijn while (1) {
540 4e2dd90f 2022-03-26 martijn start = ptr;
541 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_ftext(ptr, 0)) == NULL)
542 4e2dd90f 2022-03-26 martijn return start;
546 4e2dd90f 2022-03-26 martijn const char *
547 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_ftext(const char *ptr, int optional)
549 4e2dd90f 2022-03-26 martijn if ((ptr[0] >= 33 && ptr[0] <= 57) ||
550 4e2dd90f 2022-03-26 martijn (ptr[0] >= 59 && ptr[0] <= 126))
551 4e2dd90f 2022-03-26 martijn return ptr + 1;
552 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
555 4e2dd90f 2022-03-26 martijn const char *
556 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_obs_no_ws_ctl(const char *ptr, int optional)
558 4e2dd90f 2022-03-26 martijn if ((ptr[0] >= 1 && ptr[0] <= 8) || ptr[0] == 11 || ptr[0] == 12 ||
559 4e2dd90f 2022-03-26 martijn (ptr[0] >= 14 && ptr[0] <= 31) || ptr[0] == 127)
560 4e2dd90f 2022-03-26 martijn return ptr + 1;
561 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
564 4e2dd90f 2022-03-26 martijn const char *
565 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_obs_ctext(const char *ptr, int optional)
567 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_obs_no_ws_ctl(ptr, optional);
570 4e2dd90f 2022-03-26 martijn const char *
571 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_obs_qtext(const char *ptr, int optional)
573 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_obs_no_ws_ctl(ptr, optional);
576 4e2dd90f 2022-03-26 martijn const char *
577 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_obs_qp(const char *ptr, int optional)
579 4e2dd90f 2022-03-26 martijn const char *start = ptr;
581 4e2dd90f 2022-03-26 martijn if (ptr[0] == '\\' && (
582 4e2dd90f 2022-03-26 martijn (ptr = osmtpd_ltok_skip_obs_no_ws_ctl(start + 1, 0)) != NULL ||
583 4e2dd90f 2022-03-26 martijn (ptr = osmtpd_ltok_skip_lf(start + 1, 0)) != NULL ||
584 4e2dd90f 2022-03-26 martijn (ptr = osmtpd_ltok_skip_cr(start + 1, 0)) != NULL))
585 4e2dd90f 2022-03-26 martijn return ptr;
586 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
589 4e2dd90f 2022-03-26 martijn const char *
590 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_obs_phrase(const char *ptr, int optional)
592 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
594 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_word(ptr, 0)) == NULL)
595 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
596 4e2dd90f 2022-03-26 martijn while (1) {
597 4e2dd90f 2022-03-26 martijn prev = ptr;
598 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_word(ptr, 0)) != NULL)
599 4e2dd90f 2022-03-26 martijn continue;
600 4e2dd90f 2022-03-26 martijn ptr = prev;
601 4e2dd90f 2022-03-26 martijn if (ptr[0] == '.') {
603 4e2dd90f 2022-03-26 martijn continue;
605 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_cfws(ptr, 0)) != NULL)
606 4e2dd90f 2022-03-26 martijn continue;
607 4e2dd90f 2022-03-26 martijn return prev;
611 4e2dd90f 2022-03-26 martijn const char *
612 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_obs_fws(const char *ptr, int optional)
614 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
616 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_wsp(ptr, 0)) == NULL)
617 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
618 4e2dd90f 2022-03-26 martijn prev = ptr;
619 4e2dd90f 2022-03-26 martijn while ((ptr = osmtpd_ltok_skip_wsp(ptr, 0)) != NULL)
620 4e2dd90f 2022-03-26 martijn prev = ptr;
622 4e2dd90f 2022-03-26 martijn ptr = prev;
623 4e2dd90f 2022-03-26 martijn while (1) {
624 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_crlf(ptr, 0)) == NULL)
625 4e2dd90f 2022-03-26 martijn return prev;
626 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_wsp(ptr, 0)) == NULL)
627 4e2dd90f 2022-03-26 martijn return prev;
628 4e2dd90f 2022-03-26 martijn prev = ptr;
629 4e2dd90f 2022-03-26 martijn while ((ptr = osmtpd_ltok_skip_wsp(ptr, 0)) != NULL)
630 4e2dd90f 2022-03-26 martijn prev = ptr;
631 4e2dd90f 2022-03-26 martijn ptr = prev;
635 4e2dd90f 2022-03-26 martijn const char *
636 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_obs_angle_addr(const char *ptr, int optional)
638 4e2dd90f 2022-03-26 martijn const char *start = ptr;
640 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_cfws(ptr, 1);
641 4e2dd90f 2022-03-26 martijn if (ptr++[0] != '<')
642 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
643 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_obs_route(ptr, 0)) == NULL)
644 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
645 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_addr_spec(ptr, 0)) == NULL)
646 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
647 4e2dd90f 2022-03-26 martijn if (ptr++[0] != '>')
648 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
649 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_cfws(ptr, 1);
652 4e2dd90f 2022-03-26 martijn const char *
653 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_obs_route(const char *ptr, int optional)
655 4e2dd90f 2022-03-26 martijn const char *start = ptr;
657 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_obs_domain_list(ptr, 0)) == NULL)
658 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
659 4e2dd90f 2022-03-26 martijn if (ptr++[0] != ':')
660 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
661 4e2dd90f 2022-03-26 martijn return ptr;
664 4e2dd90f 2022-03-26 martijn const char *
665 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_obs_domain_list(const char *ptr, int optional)
667 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev = ptr;
669 4e2dd90f 2022-03-26 martijn while (1) {
670 4e2dd90f 2022-03-26 martijn if (ptr[0] == ',') {
672 4e2dd90f 2022-03-26 martijn prev = ptr;
673 4e2dd90f 2022-03-26 martijn continue;
674 4e2dd90f 2022-03-26 martijn } else if ((ptr = osmtpd_ltok_skip_cfws(ptr, 0)) != NULL) {
675 4e2dd90f 2022-03-26 martijn prev = ptr;
676 4e2dd90f 2022-03-26 martijn continue;
680 4e2dd90f 2022-03-26 martijn ptr = prev;
682 4e2dd90f 2022-03-26 martijn if (ptr++[0] != '@')
683 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
684 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_domain(ptr, 0)) == NULL)
685 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
686 4e2dd90f 2022-03-26 martijn while (1) {
687 4e2dd90f 2022-03-26 martijn if (ptr[0] != ',')
690 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_cfws(ptr, 1);
691 4e2dd90f 2022-03-26 martijn if (ptr[0] != '@')
692 4e2dd90f 2022-03-26 martijn continue;
693 4e2dd90f 2022-03-26 martijn prev = ptr;
694 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_domain(ptr + 1, 0)) == NULL) {
695 4e2dd90f 2022-03-26 martijn ptr = prev;
699 4e2dd90f 2022-03-26 martijn return ptr;
702 4e2dd90f 2022-03-26 martijn const char *
703 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_obs_local_part(const char *ptr, int optional)
705 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
707 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_word(ptr, 0)) == NULL)
708 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
709 4e2dd90f 2022-03-26 martijn prev = ptr;
710 4e2dd90f 2022-03-26 martijn while (ptr[0] == '.') {
712 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_word(ptr, 0)) == NULL)
713 4e2dd90f 2022-03-26 martijn return prev;
714 4e2dd90f 2022-03-26 martijn prev = ptr;
716 4e2dd90f 2022-03-26 martijn return ptr;
719 4e2dd90f 2022-03-26 martijn const char *
720 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_obs_domain(const char *ptr, int optional)
722 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
724 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_atom(ptr, 0)) == NULL)
725 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
726 4e2dd90f 2022-03-26 martijn prev = ptr;
727 4e2dd90f 2022-03-26 martijn while (1) {
728 4e2dd90f 2022-03-26 martijn if (ptr++[0] != '.')
729 4e2dd90f 2022-03-26 martijn return prev;
730 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_atom(ptr, 0)) == NULL)
731 4e2dd90f 2022-03-26 martijn return prev;
732 4e2dd90f 2022-03-26 martijn prev = ptr;
736 4e2dd90f 2022-03-26 martijn const char *
737 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_obs_dtext(const char *ptr, int optional)
739 4e2dd90f 2022-03-26 martijn const char *start = ptr;
741 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_obs_no_ws_ctl(ptr, 0)) != NULL)
742 4e2dd90f 2022-03-26 martijn return ptr;
743 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_quoted_pair(start, optional);
746 4e2dd90f 2022-03-26 martijn /* RFC 2045 - Multipurpose Internet Mail Extensions */
747 4e2dd90f 2022-03-26 martijn const char *
748 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_value(const char *ptr, int optional)
750 4e2dd90f 2022-03-26 martijn const char *start = ptr;
752 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_token(start, 0)) != NULL)
753 4e2dd90f 2022-03-26 martijn return ptr;
754 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_quoted_string(start, 0)) != NULL)
755 4e2dd90f 2022-03-26 martijn return ptr;
756 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
759 4e2dd90f 2022-03-26 martijn const char *
760 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_token(const char *ptr, int optional)
762 4e2dd90f 2022-03-26 martijn const char *start;
763 4e2dd90f 2022-03-26 martijn int first = 1;
765 4e2dd90f 2022-03-26 martijn while (1) {
766 4e2dd90f 2022-03-26 martijn start = ptr;
767 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_char(start, 0)) != NULL &&
768 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sp(start, 0) == NULL &&
769 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_ctl(start, 0) == NULL &&
770 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_tspecials(start, 0) == NULL) {
771 4e2dd90f 2022-03-26 martijn first = 0;
772 4e2dd90f 2022-03-26 martijn continue;
774 4e2dd90f 2022-03-26 martijn return optional || !first ? start : NULL;
778 4e2dd90f 2022-03-26 martijn const char *
779 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_tspecials(const char *ptr, int optional)
781 4e2dd90f 2022-03-26 martijn if (ptr[0] == '(' || ptr[0] == ')' || ptr[0] == '<' || ptr[0] == '>' ||
782 4e2dd90f 2022-03-26 martijn ptr[0] == '@' || ptr[0] == ',' || ptr[0] == ';' || ptr[0] == ':' ||
783 4e2dd90f 2022-03-26 martijn ptr[0] == '\\' || ptr[0] == '"' || ptr[0] == '/' || ptr[0] == '[' ||
784 4e2dd90f 2022-03-26 martijn ptr[0] == ']' || ptr[0] == '?' || ptr[0] == '=')
785 4e2dd90f 2022-03-26 martijn return ptr + 1;
786 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
789 4e2dd90f 2022-03-26 martijn const char *
790 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_qp_section(const char *ptr, int optional)
792 4e2dd90f 2022-03-26 martijn const char *prev, *last = ptr;
794 4e2dd90f 2022-03-26 martijn while (1) {
795 4e2dd90f 2022-03-26 martijn prev = ptr;
796 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_ptext(prev, 0)) != NULL)
797 4e2dd90f 2022-03-26 martijn last = ptr;
798 4e2dd90f 2022-03-26 martijn else if ((ptr = osmtpd_ltok_skip_sp(prev, 0)) == NULL &&
799 4e2dd90f 2022-03-26 martijn (ptr = osmtpd_ltok_skip_htab(prev, 0)) == NULL)
800 4e2dd90f 2022-03-26 martijn return last;
804 4e2dd90f 2022-03-26 martijn const char *
805 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_ptext(const char *ptr, int optional)
807 4e2dd90f 2022-03-26 martijn const char *start = ptr;
809 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_hex_octet(start, 0)) == NULL &&
810 4e2dd90f 2022-03-26 martijn (ptr = osmtpd_ltok_skip_safe_char(start, 0)) == NULL)
811 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
812 4e2dd90f 2022-03-26 martijn return ptr;
815 4e2dd90f 2022-03-26 martijn const char *
816 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_safe_char(const char *ptr, int optional)
818 4e2dd90f 2022-03-26 martijn if ((ptr[0] >= 33 && ptr[0] <= 60) || (ptr[0] >= 62 && ptr[0] <= 126))
819 4e2dd90f 2022-03-26 martijn return ptr + 1;
820 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
823 4e2dd90f 2022-03-26 martijn const char *
824 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_hex_octet(const char *ptr, int optional)
826 4e2dd90f 2022-03-26 martijn const char *start = ptr;
829 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
830 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
832 4e2dd90f 2022-03-26 martijn l = tolower(ptr[0]);
833 4e2dd90f 2022-03-26 martijn if (l == 'a' || l == 'b' || l == 'c' || l == 'd' ||
834 4e2dd90f 2022-03-26 martijn l == 'e' || l == 'f')
836 4e2dd90f 2022-03-26 martijn else if ((ptr = osmtpd_ltok_skip_digit(ptr, 0)) == NULL)
837 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
838 4e2dd90f 2022-03-26 martijn l = tolower(ptr[0]);
839 4e2dd90f 2022-03-26 martijn start = ptr;
840 4e2dd90f 2022-03-26 martijn if (l == 'a' || l == 'b' || l == 'c' || l == 'd' ||
841 4e2dd90f 2022-03-26 martijn l == 'e' || l == 'f')
843 4e2dd90f 2022-03-26 martijn else if ((ptr = osmtpd_ltok_skip_digit(ptr, 0)) == NULL)
844 4e2dd90f 2022-03-26 martijn return start;
845 4e2dd90f 2022-03-26 martijn return ptr;
848 4e2dd90f 2022-03-26 martijn /* RFC 6376 - DomainKeys Identified Mail (DKIM) Signatures */
849 4e2dd90f 2022-03-26 martijn const char *
850 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_hyphenated_word(const char *ptr, int optional)
852 4e2dd90f 2022-03-26 martijn const char *start = ptr, *end, *hyphen;
854 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_alpha(ptr, 0)) == NULL)
855 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
857 4e2dd90f 2022-03-26 martijn end = ptr;
858 4e2dd90f 2022-03-26 martijn while (1) {
859 4e2dd90f 2022-03-26 martijn if (ptr[0] == '-') {
860 4e2dd90f 2022-03-26 martijn hyphen = hyphen == NULL ? ptr - 1 : hyphen;
862 4e2dd90f 2022-03-26 martijn continue;
864 4e2dd90f 2022-03-26 martijn start = ptr;
865 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_alpha(start, 0)) == NULL &&
866 4e2dd90f 2022-03-26 martijn (ptr = osmtpd_ltok_skip_digit(start, 0)) == NULL)
868 4e2dd90f 2022-03-26 martijn hyphen = NULL;
869 4e2dd90f 2022-03-26 martijn end = ptr;
872 4e2dd90f 2022-03-26 martijn return hyphen == NULL ? end : hyphen;
875 4e2dd90f 2022-03-26 martijn const char *
876 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_alphadigitps(const char *ptr, int optional)
878 4e2dd90f 2022-03-26 martijn const char *end;
880 4e2dd90f 2022-03-26 martijn if ((end = osmtpd_ltok_skip_alpha(ptr, 0)) == NULL &&
881 4e2dd90f 2022-03-26 martijn (end = osmtpd_ltok_skip_digit(ptr, 0)) == NULL &&
882 4e2dd90f 2022-03-26 martijn ptr[0] != '+' && ptr[0] != '/')
883 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
884 4e2dd90f 2022-03-26 martijn return end == NULL ? ptr + 1 : end;
887 4e2dd90f 2022-03-26 martijn const char *
888 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_base64string(const char *ptr, int optional)
890 4e2dd90f 2022-03-26 martijn const char *start = ptr;
892 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_alphadigitps(ptr, 0)) == NULL)
893 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
894 4e2dd90f 2022-03-26 martijn while (1) {
895 4e2dd90f 2022-03-26 martijn start = ptr;
896 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
897 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_alphadigitps(ptr, 0)) == NULL)
900 4e2dd90f 2022-03-26 martijn ptr = start;
901 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
902 4e2dd90f 2022-03-26 martijn if (ptr[0] == '=') {
904 4e2dd90f 2022-03-26 martijn start = ptr;
905 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
906 4e2dd90f 2022-03-26 martijn if (ptr[0] == '=')
909 4e2dd90f 2022-03-26 martijn ptr = start;
911 4e2dd90f 2022-03-26 martijn ptr = start;
912 4e2dd90f 2022-03-26 martijn return ptr;
915 4e2dd90f 2022-03-26 martijn const char *
916 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_hdr_name(const char *ptr, int optional)
918 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_field_name(ptr, optional);
921 4e2dd90f 2022-03-26 martijn const char *
922 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_qp_hdr_value(const char *ptr, int optional)
924 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_dkim_quoted_printable(ptr, optional);
927 4e2dd90f 2022-03-26 martijn const char *
928 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_dkim_quoted_printable(const char *ptr, int optional)
930 4e2dd90f 2022-03-26 martijn const char *start;
932 4e2dd90f 2022-03-26 martijn while (1) {
933 4e2dd90f 2022-03-26 martijn start = ptr;
934 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_fws(start, 0)) != NULL)
935 4e2dd90f 2022-03-26 martijn continue;
936 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_hex_octet(start, 0)) != NULL)
937 4e2dd90f 2022-03-26 martijn continue;
938 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_dkim_safe_char(start, 0);
939 4e2dd90f 2022-03-26 martijn if (ptr == NULL)
942 4e2dd90f 2022-03-26 martijn return start;
945 4e2dd90f 2022-03-26 martijn const char *
946 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_dkim_safe_char(const char *ptr, int optional)
948 4e2dd90f 2022-03-26 martijn if ((ptr[0] >= 0x21 && ptr[0] <= 0x3a) || ptr[0] == 0x3c ||
949 4e2dd90f 2022-03-26 martijn (ptr[0] >= 0x3e && ptr[0] <= 0x7e))
950 4e2dd90f 2022-03-26 martijn return ptr + 1;
951 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
954 4e2dd90f 2022-03-26 martijn const char *
955 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_selector(const char *ptr, int optional)
957 4e2dd90f 2022-03-26 martijn const char *start = ptr;
959 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sub_domain(ptr, 0)) == NULL)
960 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
961 4e2dd90f 2022-03-26 martijn while (1) {
962 4e2dd90f 2022-03-26 martijn start = ptr;
963 4e2dd90f 2022-03-26 martijn if (ptr[0] != '.')
964 4e2dd90f 2022-03-26 martijn return start;
966 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sub_domain(ptr, 0)) == NULL)
967 4e2dd90f 2022-03-26 martijn return start;
971 4e2dd90f 2022-03-26 martijn const char *
972 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_tag_list(const char *ptr, int optional)
974 4e2dd90f 2022-03-26 martijn const char *start = ptr;
976 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_tag_spec(ptr, 0)) == NULL)
977 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
978 4e2dd90f 2022-03-26 martijn while (1) {
979 4e2dd90f 2022-03-26 martijn /* Starting or trailing ';' */
980 4e2dd90f 2022-03-26 martijn if (ptr[0] != ';')
981 4e2dd90f 2022-03-26 martijn return ptr;
983 4e2dd90f 2022-03-26 martijn start = ptr;
984 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_tag_spec(ptr, 0)) == NULL)
985 4e2dd90f 2022-03-26 martijn return start;
989 4e2dd90f 2022-03-26 martijn const char *
990 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_tag_spec(const char *ptr, int optional)
992 4e2dd90f 2022-03-26 martijn const char *start = ptr;
994 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
995 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_tag_name(ptr, 0)) == NULL)
996 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
997 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
998 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
999 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1001 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1002 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_tag_value(ptr, 0)) == NULL)
1003 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1004 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_fws(ptr, 1);
1007 4e2dd90f 2022-03-26 martijn const char *
1008 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_tag_name(const char *ptr, int optional)
1010 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
1012 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_alpha(ptr, 0)) == NULL)
1013 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1014 4e2dd90f 2022-03-26 martijn prev = ptr;
1015 4e2dd90f 2022-03-26 martijn while ((ptr = osmtpd_ltok_skip_alnumpunc(ptr, 0)) != NULL)
1016 4e2dd90f 2022-03-26 martijn prev = ptr;
1017 4e2dd90f 2022-03-26 martijn return prev;
1020 4e2dd90f 2022-03-26 martijn const char *
1021 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_tag_value(const char *ptr, int optional)
1023 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
1025 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_tval(ptr, 0)) == NULL)
1026 4e2dd90f 2022-03-26 martijn return start;
1028 4e2dd90f 2022-03-26 martijn while (1) {
1029 4e2dd90f 2022-03-26 martijn start = ptr;
1030 4e2dd90f 2022-03-26 martijn /* FWS contains WSP */
1031 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_fws(ptr, 0)) == NULL)
1032 4e2dd90f 2022-03-26 martijn return start;
1033 4e2dd90f 2022-03-26 martijn prev = ptr;
1034 4e2dd90f 2022-03-26 martijn while ((ptr = osmtpd_ltok_skip_fws(ptr, 0)) != NULL)
1035 4e2dd90f 2022-03-26 martijn prev = ptr;
1036 4e2dd90f 2022-03-26 martijn ptr = prev;
1037 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_tval(ptr, 0)) == NULL)
1038 4e2dd90f 2022-03-26 martijn return start;
1042 4e2dd90f 2022-03-26 martijn const char *
1043 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_tval(const char *ptr, int optional)
1045 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
1047 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_valchar(ptr, 0)) == NULL)
1048 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1049 4e2dd90f 2022-03-26 martijn prev = ptr;
1050 4e2dd90f 2022-03-26 martijn while ((ptr = osmtpd_ltok_skip_valchar(ptr, 0)) != NULL)
1051 4e2dd90f 2022-03-26 martijn prev = ptr;
1052 4e2dd90f 2022-03-26 martijn return prev;
1055 4e2dd90f 2022-03-26 martijn const char *
1056 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_valchar(const char *ptr, int optional)
1058 4e2dd90f 2022-03-26 martijn if ((ptr[0] >= 0x21 && ptr[0] <= 0x3A) ||
1059 4e2dd90f 2022-03-26 martijn (ptr[0] >= 0x3C && ptr[0] <= 0x7E))
1060 4e2dd90f 2022-03-26 martijn return ptr + 1;
1061 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
1064 4e2dd90f 2022-03-26 martijn const char *
1065 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_alnumpunc(const char *ptr, int optional)
1067 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1069 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_alpha(start, 0)) != NULL)
1070 4e2dd90f 2022-03-26 martijn return ptr;
1071 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_digit(start, 0)) != NULL)
1072 4e2dd90f 2022-03-26 martijn return ptr;
1073 4e2dd90f 2022-03-26 martijn if (start[0] == '_')
1074 4e2dd90f 2022-03-26 martijn return start + 1;
1075 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1078 4e2dd90f 2022-03-26 martijn const char *
1079 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_v_tag(const char *ptr, int optional)
1081 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1083 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x76)
1084 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1085 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1086 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1087 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1088 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1089 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_v_tag_value(ptr, 0)) == NULL)
1090 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1091 4e2dd90f 2022-03-26 martijn return ptr;
1094 4e2dd90f 2022-03-26 martijn const char *
1095 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_v_tag_value(const char *ptr, int optional)
1097 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
1099 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_digit(ptr, 0)) == NULL)
1100 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1101 4e2dd90f 2022-03-26 martijn while (1) {
1102 4e2dd90f 2022-03-26 martijn prev = ptr;
1103 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_digit(ptr, 0)) == NULL)
1104 4e2dd90f 2022-03-26 martijn return prev;
1108 4e2dd90f 2022-03-26 martijn const char *
1109 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_a_tag(const char *ptr, int optional)
1111 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1113 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x61)
1114 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1115 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1116 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1117 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1118 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1119 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_a_tag_value(ptr, 0)) == NULL)
1120 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1121 4e2dd90f 2022-03-26 martijn return ptr;
1124 4e2dd90f 2022-03-26 martijn const char *
1125 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_a_tag_value(const char *ptr, int optional)
1127 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_sig_a_tag_alg(ptr, optional);
1130 4e2dd90f 2022-03-26 martijn const char *
1131 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_a_tag_alg(const char *ptr, int optional)
1133 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1135 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_a_tag_k(ptr, 0)) == NULL)
1136 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1137 4e2dd90f 2022-03-26 martijn if (ptr[0] != '-')
1138 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1140 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_a_tag_h(ptr, 0)) == NULL)
1141 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1142 4e2dd90f 2022-03-26 martijn return ptr;
1145 4e2dd90f 2022-03-26 martijn const char *
1146 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_a_tag_k(const char *ptr, int optional)
1148 4e2dd90f 2022-03-26 martijn /* sha1 / sha256 covered by x-sig-a-tag-k */
1149 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_x_sig_a_tag_k(ptr, optional);
1152 4e2dd90f 2022-03-26 martijn const char *
1153 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_a_tag_h(const char *ptr, int optional)
1155 4e2dd90f 2022-03-26 martijn /* rsa / ed25519 covered by x-sig-a-tag-h */
1156 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_x_sig_a_tag_h(ptr, optional);
1159 4e2dd90f 2022-03-26 martijn const char *
1160 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_x_sig_a_tag_k(const char *ptr, int optional)
1162 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev, *end;
1164 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_alpha(ptr, 0)) == NULL)
1165 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1166 4e2dd90f 2022-03-26 martijn prev = ptr;
1167 4e2dd90f 2022-03-26 martijn while ((end = osmtpd_ltok_skip_alpha(ptr, 0)) != NULL ||
1168 4e2dd90f 2022-03-26 martijn (end = osmtpd_ltok_skip_digit(ptr, 0)) != NULL) {
1169 4e2dd90f 2022-03-26 martijn ptr = end;
1170 4e2dd90f 2022-03-26 martijn prev = end;
1172 4e2dd90f 2022-03-26 martijn return prev;
1175 4e2dd90f 2022-03-26 martijn const char *
1176 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_x_sig_a_tag_h(const char *ptr, int optional)
1178 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev, *end;
1180 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_alpha(ptr, 0)) == NULL)
1181 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1182 4e2dd90f 2022-03-26 martijn prev = ptr;
1183 4e2dd90f 2022-03-26 martijn while ((end = osmtpd_ltok_skip_alpha(ptr, 0)) != NULL ||
1184 4e2dd90f 2022-03-26 martijn (end = osmtpd_ltok_skip_digit(ptr, 0)) != NULL) {
1185 4e2dd90f 2022-03-26 martijn ptr = end;
1186 4e2dd90f 2022-03-26 martijn prev = end;
1188 4e2dd90f 2022-03-26 martijn return prev;
1191 4e2dd90f 2022-03-26 martijn const char *
1192 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_b_tag(const char *ptr, int optional)
1194 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1196 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x62)
1197 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1198 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1199 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1200 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1201 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1202 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_b_tag_value(ptr, 0)) == NULL)
1203 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1204 4e2dd90f 2022-03-26 martijn return ptr;
1207 4e2dd90f 2022-03-26 martijn const char *
1208 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_b_tag_value(const char *ptr, int optional)
1210 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_sig_b_tag_data(ptr, optional);
1213 4e2dd90f 2022-03-26 martijn const char *
1214 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_b_tag_data(const char *ptr, int optional)
1216 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_base64string(ptr, optional);
1219 4e2dd90f 2022-03-26 martijn const char *
1220 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_bh_tag(const char *ptr, int optional)
1222 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1224 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x62 && ptr[0] != 0x68)
1225 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1226 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 2, 1);
1227 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1228 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1229 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1230 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_bh_tag_value(ptr, 0)) == NULL)
1231 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1232 4e2dd90f 2022-03-26 martijn return ptr;
1235 4e2dd90f 2022-03-26 martijn const char *
1236 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_bh_tag_value(const char *ptr, int optional)
1238 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_sig_bh_tag_data(ptr, optional);
1241 4e2dd90f 2022-03-26 martijn const char *
1242 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_bh_tag_data(const char *ptr, int optional)
1244 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_base64string(ptr, optional);
1247 4e2dd90f 2022-03-26 martijn const char *
1248 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_c_tag(const char *ptr, int optional)
1250 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1252 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x63)
1253 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1254 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1255 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1256 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1257 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1258 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_c_tag_value(ptr, 0)) == NULL)
1259 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1260 4e2dd90f 2022-03-26 martijn return ptr;
1263 4e2dd90f 2022-03-26 martijn const char *
1264 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_c_tag_value(const char *ptr, int optional)
1266 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1268 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_c_tag_alg(ptr, 0)) == NULL)
1269 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1270 4e2dd90f 2022-03-26 martijn if (ptr[0] == '/') {
1271 4e2dd90f 2022-03-26 martijn start = ptr;
1272 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_c_tag_alg(ptr, 0)) == NULL)
1273 4e2dd90f 2022-03-26 martijn return start;
1275 4e2dd90f 2022-03-26 martijn return ptr;
1278 4e2dd90f 2022-03-26 martijn const char *
1279 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_c_tag_alg(const char *ptr, int optional)
1281 4e2dd90f 2022-03-26 martijn /* simple / relaxed covered by x-sig-c-tag-alga */
1282 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_x_sig_c_tag_alg(ptr, optional);
1285 4e2dd90f 2022-03-26 martijn const char *
1286 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_x_sig_c_tag_alg(const char *ptr, int optional)
1288 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_hyphenated_word(ptr, optional);
1291 4e2dd90f 2022-03-26 martijn const char *
1292 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_d_tag(const char *ptr, int optional)
1294 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1296 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x64)
1297 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1298 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1299 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1300 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1301 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1302 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_d_tag_value(ptr, 0)) == NULL)
1303 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1304 4e2dd90f 2022-03-26 martijn return ptr;
1307 4e2dd90f 2022-03-26 martijn const char *
1308 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_d_tag_value(const char *ptr, int optional)
1310 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_domain_name(ptr, optional);
1313 4e2dd90f 2022-03-26 martijn const char *
1314 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_domain_name(const char *ptr, int optional)
1316 4e2dd90f 2022-03-26 martijn const char *prev = ptr;
1318 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sub_domain(ptr, 0)) == NULL)
1319 4e2dd90f 2022-03-26 martijn return optional ? prev : NULL;
1320 4e2dd90f 2022-03-26 martijn while (1) {
1321 4e2dd90f 2022-03-26 martijn prev = ptr;
1322 4e2dd90f 2022-03-26 martijn if (ptr[0] != '.' ||
1323 4e2dd90f 2022-03-26 martijn (ptr = osmtpd_ltok_skip_sub_domain(ptr + 1, 0)) == NULL)
1324 4e2dd90f 2022-03-26 martijn return prev;
1328 4e2dd90f 2022-03-26 martijn const char *
1329 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_h_tag(const char *ptr, int optional)
1331 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1333 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x68)
1334 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1335 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1336 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1337 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1338 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1339 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_h_tag_value(ptr, 0)) == NULL)
1340 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1341 4e2dd90f 2022-03-26 martijn return ptr;
1344 4e2dd90f 2022-03-26 martijn const char *
1345 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_h_tag_value(const char *ptr, int optional)
1347 4e2dd90f 2022-03-26 martijn const char *prev = ptr;
1349 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_hdr_name(ptr, 0)) == NULL)
1350 4e2dd90f 2022-03-26 martijn return optional ? prev : NULL;
1351 4e2dd90f 2022-03-26 martijn while (1) {
1352 4e2dd90f 2022-03-26 martijn prev = ptr;
1353 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1354 4e2dd90f 2022-03-26 martijn if (ptr[0] != ':')
1355 4e2dd90f 2022-03-26 martijn return prev;
1356 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1357 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_hdr_name(ptr, 0)) == NULL)
1358 4e2dd90f 2022-03-26 martijn return prev;
1362 4e2dd90f 2022-03-26 martijn const char *
1363 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_i_tag(const char *ptr, int optional)
1365 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1367 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x69)
1368 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1369 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1370 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1371 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1372 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1373 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_i_tag_value(ptr, 0)) == NULL)
1374 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1375 4e2dd90f 2022-03-26 martijn return ptr;
1378 4e2dd90f 2022-03-26 martijn const char *
1379 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_i_tag_value(const char *ptr, int optional)
1381 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1383 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_local_part(ptr, 1);
1384 4e2dd90f 2022-03-26 martijn if (ptr[0] != '@' ||
1385 4e2dd90f 2022-03-26 martijn (ptr = osmtpd_ltok_skip_domain_name(ptr, 0)) == NULL)
1386 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1387 4e2dd90f 2022-03-26 martijn return ptr;
1390 4e2dd90f 2022-03-26 martijn const char *
1391 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_l_tag(const char *ptr, int optional)
1393 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1395 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x6c)
1396 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1397 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1398 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1399 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1400 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1401 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_l_tag_value(ptr, 0)) == NULL)
1402 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1403 4e2dd90f 2022-03-26 martijn return ptr;
1406 4e2dd90f 2022-03-26 martijn const char *
1407 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_l_tag_value(const char *ptr, int optional)
1409 4e2dd90f 2022-03-26 martijn size_t i;
1411 4e2dd90f 2022-03-26 martijn for (i = 0; i < 76; i++) {
1412 4e2dd90f 2022-03-26 martijn if (osmtpd_ltok_skip_digit(ptr + i, 0) == NULL)
1415 4e2dd90f 2022-03-26 martijn if (i >= 1 && i <= 76)
1416 4e2dd90f 2022-03-26 martijn return ptr + i;
1417 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
1420 4e2dd90f 2022-03-26 martijn const char *
1421 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_q_tag(const char *ptr, int optional)
1423 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1425 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x71)
1426 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1427 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1428 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1429 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1430 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1431 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_q_tag_value(ptr, 0)) == NULL)
1432 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1433 4e2dd90f 2022-03-26 martijn return ptr;
1436 4e2dd90f 2022-03-26 martijn const char *
1437 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_q_tag_value(const char *ptr, int optional)
1439 4e2dd90f 2022-03-26 martijn const char *prev = ptr;
1440 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_q_tag_method(ptr, 0)) == NULL)
1441 4e2dd90f 2022-03-26 martijn return optional ? prev : NULL;
1442 4e2dd90f 2022-03-26 martijn while (1) {
1443 4e2dd90f 2022-03-26 martijn prev = ptr;
1444 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1445 4e2dd90f 2022-03-26 martijn if (ptr[0] != ':')
1446 4e2dd90f 2022-03-26 martijn return prev;
1447 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1448 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_q_tag_method(ptr, 0)) == NULL)
1449 4e2dd90f 2022-03-26 martijn return prev;
1453 4e2dd90f 2022-03-26 martijn const char *
1454 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_q_tag_method(const char *ptr, int optional)
1456 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1458 4e2dd90f 2022-03-26 martijn /* dns/txt covered by x-sig-q-tag-type ["/" x-sig-q-tag-args] */
1459 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_x_sig_q_tag_type(ptr, 0)) == NULL)
1460 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1461 4e2dd90f 2022-03-26 martijn start = ptr;
1462 4e2dd90f 2022-03-26 martijn if (ptr[0] != '/')
1463 4e2dd90f 2022-03-26 martijn return ptr;
1464 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_x_sig_q_tag_args(ptr, 0)) == NULL)
1465 4e2dd90f 2022-03-26 martijn return start;
1466 4e2dd90f 2022-03-26 martijn return ptr;
1469 4e2dd90f 2022-03-26 martijn const char *
1470 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_x_sig_q_tag_type(const char *ptr, int optional)
1472 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_hyphenated_word(ptr, optional);
1475 4e2dd90f 2022-03-26 martijn const char *
1476 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_x_sig_q_tag_args(const char *ptr, int optional)
1478 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_qp_hdr_value(ptr, optional);
1481 4e2dd90f 2022-03-26 martijn const char *
1482 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_s_tag(const char *ptr, int optional)
1484 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1486 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x73)
1487 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1488 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1489 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1490 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1491 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1492 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_s_tag_value(ptr, 0)) == NULL)
1493 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1494 4e2dd90f 2022-03-26 martijn return ptr;
1497 4e2dd90f 2022-03-26 martijn const char *
1498 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_s_tag_value(const char *ptr, int optional)
1500 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_selector(ptr, optional);
1503 4e2dd90f 2022-03-26 martijn const char *
1504 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_t_tag(const char *ptr, int optional)
1506 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1508 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x74)
1509 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1510 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1511 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1512 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1513 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1514 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_t_tag_value(ptr, 0)) == NULL)
1515 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1516 4e2dd90f 2022-03-26 martijn return ptr;
1519 4e2dd90f 2022-03-26 martijn const char *
1520 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_t_tag_value(const char *ptr, int optional)
1522 4e2dd90f 2022-03-26 martijn size_t i;
1524 4e2dd90f 2022-03-26 martijn for (i = 0; i < 12; i++) {
1525 4e2dd90f 2022-03-26 martijn if (osmtpd_ltok_skip_digit(ptr + i, 0) == NULL)
1528 4e2dd90f 2022-03-26 martijn if (i >= 1 && i <= 12)
1529 4e2dd90f 2022-03-26 martijn return ptr + i;
1530 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
1533 4e2dd90f 2022-03-26 martijn const char *
1534 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_x_tag(const char *ptr, int optional)
1536 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1538 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x78)
1539 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1540 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1541 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1542 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1543 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1544 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_x_tag_value(ptr, 0)) == NULL)
1545 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1546 4e2dd90f 2022-03-26 martijn return ptr;
1549 4e2dd90f 2022-03-26 martijn const char *
1550 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_x_tag_value(const char *ptr, int optional)
1552 4e2dd90f 2022-03-26 martijn size_t i;
1554 4e2dd90f 2022-03-26 martijn for (i = 0; i < 12; i++) {
1555 4e2dd90f 2022-03-26 martijn if (osmtpd_ltok_skip_digit(ptr + i, 0) == NULL)
1558 4e2dd90f 2022-03-26 martijn if (i >= 1 && i <= 12)
1559 4e2dd90f 2022-03-26 martijn return ptr + i;
1560 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
1563 4e2dd90f 2022-03-26 martijn const char *
1564 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_z_tag(const char *ptr, int optional)
1566 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1568 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x7a)
1569 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1570 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1571 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1572 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1573 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1574 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_z_tag_value(ptr, 0)) == NULL)
1575 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1576 4e2dd90f 2022-03-26 martijn return ptr;
1579 4e2dd90f 2022-03-26 martijn const char *
1580 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_z_tag_value(const char *ptr, int optional)
1582 4e2dd90f 2022-03-26 martijn const char *prev = ptr;
1584 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_z_tag_copy(ptr, 0)) == NULL)
1585 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
1586 4e2dd90f 2022-03-26 martijn while (1) {
1587 4e2dd90f 2022-03-26 martijn prev = ptr;
1588 4e2dd90f 2022-03-26 martijn if (ptr[0] != '|')
1589 4e2dd90f 2022-03-26 martijn return prev;
1590 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1591 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sig_z_tag_copy(ptr, 0)) == NULL)
1592 4e2dd90f 2022-03-26 martijn return prev;
1596 4e2dd90f 2022-03-26 martijn const char *
1597 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sig_z_tag_copy(const char *ptr, int optional)
1599 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1601 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_hdr_name(ptr, 0)) == NULL)
1602 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1603 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1604 4e2dd90f 2022-03-26 martijn if (ptr[0] != ':')
1605 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1606 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_qp_hdr_value(ptr, 0)) == NULL)
1607 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1608 4e2dd90f 2022-03-26 martijn return ptr;
1611 4e2dd90f 2022-03-26 martijn const char *
1612 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_v_tag(const char *ptr, int optional)
1614 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1616 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x76)
1617 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1618 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1619 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1620 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1621 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1622 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_key_v_tag_value(ptr, 0)) == NULL)
1623 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1624 4e2dd90f 2022-03-26 martijn return ptr;
1627 4e2dd90f 2022-03-26 martijn const char *
1628 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_v_tag_value(const char *ptr, int optional)
1630 4e2dd90f 2022-03-26 martijn if (ptr[0] == 0x44 && ptr[1] == 0x4b && ptr[2] == 0x49 &&
1631 4e2dd90f 2022-03-26 martijn ptr[3] == 0x4d && ptr[4] == 0x31)
1632 4e2dd90f 2022-03-26 martijn return ptr + 5;
1633 4e2dd90f 2022-03-26 martijn return optional ? ptr : NULL;
1636 4e2dd90f 2022-03-26 martijn const char *
1637 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_h_tag(const char *ptr, int optional)
1639 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1641 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x68)
1642 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1643 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1644 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1645 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1646 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1647 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_key_h_tag_value(ptr, 0)) == NULL)
1648 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1649 4e2dd90f 2022-03-26 martijn return ptr;
1652 4e2dd90f 2022-03-26 martijn const char *
1653 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_h_tag_value(const char *ptr, int optional)
1655 4e2dd90f 2022-03-26 martijn const char *prev = ptr;
1657 4e2dd90f 2022-03-26 martijn if ((prev = osmtpd_ltok_skip_key_h_tag_alg(ptr, 0)) == NULL)
1658 4e2dd90f 2022-03-26 martijn return optional ? prev : NULL;
1659 4e2dd90f 2022-03-26 martijn while (1) {
1660 4e2dd90f 2022-03-26 martijn prev = ptr;
1661 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1662 4e2dd90f 2022-03-26 martijn if (ptr[0] != ':')
1663 4e2dd90f 2022-03-26 martijn return prev;
1664 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1665 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_key_h_tag_alg(ptr, 0)) == NULL)
1666 4e2dd90f 2022-03-26 martijn return prev;
1670 4e2dd90f 2022-03-26 martijn const char *
1671 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_h_tag_alg(const char *ptr, int optional)
1673 4e2dd90f 2022-03-26 martijn /* sha1 / sha256 covered by x-key-h-tag-alg */
1674 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_x_key_h_tag_alg(ptr, optional);
1677 4e2dd90f 2022-03-26 martijn const char *
1678 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_x_key_h_tag_alg(const char *ptr, int optional)
1680 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_hyphenated_word(ptr, optional);
1683 4e2dd90f 2022-03-26 martijn const char *
1684 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_k_tag(const char *ptr, int optional)
1686 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1688 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x6b)
1689 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1690 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1691 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1692 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1693 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1694 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_key_k_tag_value(ptr, 0)) == NULL)
1695 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1696 4e2dd90f 2022-03-26 martijn return ptr;
1699 4e2dd90f 2022-03-26 martijn const char *
1700 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_k_tag_value(const char *ptr, int optional)
1702 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1704 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_key_k_tag_type(ptr, 0)) == NULL)
1705 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1706 4e2dd90f 2022-03-26 martijn return ptr;
1709 4e2dd90f 2022-03-26 martijn const char *
1710 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_k_tag_type(const char *ptr, int optional)
1712 4e2dd90f 2022-03-26 martijn /* rsa covered by x-key-k-tag-type */
1713 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_x_key_k_tag_type(ptr, optional);
1716 4e2dd90f 2022-03-26 martijn const char *
1717 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_x_key_k_tag_type(const char *ptr, int optional)
1719 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_hyphenated_word(ptr, optional);
1722 4e2dd90f 2022-03-26 martijn const char *
1723 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_n_tag(const char *ptr, int optional)
1725 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1727 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x6e)
1728 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1729 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1730 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1731 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1732 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1733 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_key_n_tag_value(ptr, 0)) == NULL)
1734 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1735 4e2dd90f 2022-03-26 martijn return ptr;
1738 4e2dd90f 2022-03-26 martijn const char *
1739 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_n_tag_value(const char *ptr, int optional)
1741 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_qp_section(ptr, optional);
1744 4e2dd90f 2022-03-26 martijn const char *
1745 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_p_tag(const char *ptr, int optional)
1747 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1749 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x70)
1750 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1751 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1752 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1753 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1754 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1755 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_key_p_tag_value(ptr, 0)) == NULL)
1756 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1757 4e2dd90f 2022-03-26 martijn return ptr;
1760 4e2dd90f 2022-03-26 martijn const char *
1761 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_p_tag_value(const char *ptr, int optional)
1763 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1765 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_base64string(ptr, 0)) == NULL)
1766 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1767 4e2dd90f 2022-03-26 martijn return ptr;
1770 4e2dd90f 2022-03-26 martijn const char *
1771 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_s_tag(const char *ptr, int optional)
1773 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1775 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x73)
1776 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1777 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1778 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1779 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1780 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1781 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_key_s_tag_value(ptr, 0)) == NULL)
1782 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1783 4e2dd90f 2022-03-26 martijn return ptr;
1786 4e2dd90f 2022-03-26 martijn const char *
1787 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_s_tag_value(const char *ptr, int optional)
1789 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1791 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_key_s_tag_type(ptr, 0)) == NULL)
1792 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1793 4e2dd90f 2022-03-26 martijn while (1) {
1794 4e2dd90f 2022-03-26 martijn start = ptr;
1795 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1796 4e2dd90f 2022-03-26 martijn if (ptr[0] != ':')
1797 4e2dd90f 2022-03-26 martijn return start;
1798 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1799 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_key_s_tag_type(ptr, 0);
1800 4e2dd90f 2022-03-26 martijn if (ptr == NULL)
1801 4e2dd90f 2022-03-26 martijn return start;
1805 4e2dd90f 2022-03-26 martijn const char *
1806 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_s_tag_type(const char *ptr, int optional)
1808 4e2dd90f 2022-03-26 martijn if (ptr[0] == '*')
1809 4e2dd90f 2022-03-26 martijn return ptr + 1;
1810 4e2dd90f 2022-03-26 martijn /* email covered by x-key-s-tag-type */
1811 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_x_key_s_tag_type(ptr, optional);
1814 4e2dd90f 2022-03-26 martijn const char *
1815 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_x_key_s_tag_type(const char *ptr, int optional)
1817 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_hyphenated_word(ptr, optional);
1820 4e2dd90f 2022-03-26 martijn const char *
1821 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_t_tag(const char *ptr, int optional)
1823 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1825 4e2dd90f 2022-03-26 martijn if (ptr[0] != 0x74)
1826 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1827 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1828 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
1829 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1830 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1831 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_key_t_tag_value(ptr, 0)) == NULL)
1832 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1833 4e2dd90f 2022-03-26 martijn return ptr;
1836 4e2dd90f 2022-03-26 martijn const char *
1837 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_t_tag_value(const char *ptr, int optional)
1839 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1841 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_key_t_tag_flag(ptr, 0)) == NULL)
1842 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1843 4e2dd90f 2022-03-26 martijn while (1) {
1844 4e2dd90f 2022-03-26 martijn start = ptr;
1845 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr, 1);
1846 4e2dd90f 2022-03-26 martijn if (ptr[0] != ':')
1847 4e2dd90f 2022-03-26 martijn return start;
1848 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_fws(ptr + 1, 1);
1849 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_key_t_tag_flag(ptr, 0);
1850 4e2dd90f 2022-03-26 martijn if (ptr == NULL)
1851 4e2dd90f 2022-03-26 martijn return start;
1855 4e2dd90f 2022-03-26 martijn const char *
1856 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_key_t_tag_flag(const char *ptr, int optional)
1858 4e2dd90f 2022-03-26 martijn /* y / s covered by x-key-t-tag-flag */
1859 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_x_key_t_tag_flag(ptr, optional);
1862 4e2dd90f 2022-03-26 martijn const char *
1863 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_x_key_t_tag_flag(const char *ptr, int optional)
1865 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_hyphenated_word(ptr, optional);
1868 4e2dd90f 2022-03-26 martijn const char *
1869 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_ar_pvalue(const char *ptr, int optional)
1871 4e2dd90f 2022-03-26 martijn const char *start = ptr, *tmp;
1873 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_cfws(ptr, 1);
1874 4e2dd90f 2022-03-26 martijn if ((tmp = osmtpd_ltok_skip_value(ptr, 0)) != NULL)
1875 4e2dd90f 2022-03-26 martijn return tmp;
1876 4e2dd90f 2022-03-26 martijn ptr = osmtpd_ltok_skip_local_part(ptr, 1);
1877 4e2dd90f 2022-03-26 martijn if (ptr[0] == '@')
1879 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_domain(ptr, 0)) == NULL)
1880 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
1881 4e2dd90f 2022-03-26 martijn return ptr;