Blame


1 4e2dd90f 2022-03-26 martijn /*
2 b3380529 2022-04-08 martijn * Copyright (c) 2020-2022 Martijn van Duren <martijn@openbsd.org>
3 4e2dd90f 2022-03-26 martijn *
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.
7 4e2dd90f 2022-03-26 martijn *
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.
15 4e2dd90f 2022-03-26 martijn */
16 4e2dd90f 2022-03-26 martijn
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>
22 4e2dd90f 2022-03-26 martijn
23 4e2dd90f 2022-03-26 martijn #include "ltok.h"
24 4e2dd90f 2022-03-26 martijn
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)
28 4e2dd90f 2022-03-26 martijn {
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;
33 4e2dd90f 2022-03-26 martijn }
34 4e2dd90f 2022-03-26 martijn
35 4e2dd90f 2022-03-26 martijn const char *
36 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_bit(const char *ptr, int optional)
37 4e2dd90f 2022-03-26 martijn {
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;
41 4e2dd90f 2022-03-26 martijn }
42 4e2dd90f 2022-03-26 martijn
43 4e2dd90f 2022-03-26 martijn const char *
44 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_char(const char *ptr, int optional)
45 4e2dd90f 2022-03-26 martijn {
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;
49 4e2dd90f 2022-03-26 martijn }
50 4e2dd90f 2022-03-26 martijn
51 4e2dd90f 2022-03-26 martijn const char *
52 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_cr(const char *ptr, int optional)
53 4e2dd90f 2022-03-26 martijn {
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;
57 4e2dd90f 2022-03-26 martijn }
58 4e2dd90f 2022-03-26 martijn
59 4e2dd90f 2022-03-26 martijn const char *
60 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_crlf(const char *ptr, int optional)
61 4e2dd90f 2022-03-26 martijn {
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;
65 4e2dd90f 2022-03-26 martijn }
66 4e2dd90f 2022-03-26 martijn
67 4e2dd90f 2022-03-26 martijn const char *
68 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_ctl(const char *ptr, int optional)
69 4e2dd90f 2022-03-26 martijn {
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;
73 4e2dd90f 2022-03-26 martijn }
74 4e2dd90f 2022-03-26 martijn
75 4e2dd90f 2022-03-26 martijn const char *
76 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_digit(const char *ptr, int optional)
77 4e2dd90f 2022-03-26 martijn {
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;
81 4e2dd90f 2022-03-26 martijn }
82 4e2dd90f 2022-03-26 martijn
83 4e2dd90f 2022-03-26 martijn const char *
84 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_dquote(const char *ptr, int optional)
85 4e2dd90f 2022-03-26 martijn {
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;
89 4e2dd90f 2022-03-26 martijn }
90 4e2dd90f 2022-03-26 martijn
91 4e2dd90f 2022-03-26 martijn const char *
92 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_hexdig(const char *ptr, int optional)
93 4e2dd90f 2022-03-26 martijn {
94 4e2dd90f 2022-03-26 martijn const char *start = ptr;
95 4e2dd90f 2022-03-26 martijn char l;
96 4e2dd90f 2022-03-26 martijn
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;
104 4e2dd90f 2022-03-26 martijn }
105 4e2dd90f 2022-03-26 martijn
106 4e2dd90f 2022-03-26 martijn const char *
107 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_htab(const char *ptr, int optional)
108 4e2dd90f 2022-03-26 martijn {
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;
112 4e2dd90f 2022-03-26 martijn }
113 4e2dd90f 2022-03-26 martijn
114 4e2dd90f 2022-03-26 martijn const char *
115 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_lf(const char *ptr, int optional)
116 4e2dd90f 2022-03-26 martijn {
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;
120 4e2dd90f 2022-03-26 martijn }
121 4e2dd90f 2022-03-26 martijn
122 4e2dd90f 2022-03-26 martijn const char *
123 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_octet(const char *ptr, int optional)
124 4e2dd90f 2022-03-26 martijn {
125 4e2dd90f 2022-03-26 martijn return ptr + 1;
126 4e2dd90f 2022-03-26 martijn }
127 4e2dd90f 2022-03-26 martijn
128 4e2dd90f 2022-03-26 martijn const char *
129 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sp(const char *ptr, int optional)
130 4e2dd90f 2022-03-26 martijn {
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;
134 4e2dd90f 2022-03-26 martijn }
135 4e2dd90f 2022-03-26 martijn
136 4e2dd90f 2022-03-26 martijn const char *
137 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_vchar(const char *ptr, int optional)
138 4e2dd90f 2022-03-26 martijn {
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;
142 4e2dd90f 2022-03-26 martijn }
143 4e2dd90f 2022-03-26 martijn
144 4e2dd90f 2022-03-26 martijn const char *
145 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_wsp(const char *ptr, int optional)
146 4e2dd90f 2022-03-26 martijn {
147 4e2dd90f 2022-03-26 martijn const char *start = ptr;
148 4e2dd90f 2022-03-26 martijn
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;
153 4e2dd90f 2022-03-26 martijn }
154 4e2dd90f 2022-03-26 martijn
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)
158 4e2dd90f 2022-03-26 martijn {
159 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_ldh_string(ptr, optional);
160 4e2dd90f 2022-03-26 martijn }
161 4e2dd90f 2022-03-26 martijn
162 4e2dd90f 2022-03-26 martijn const char *
163 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_sub_domain(const char *ptr, int optional)
164 4e2dd90f 2022-03-26 martijn {
165 4e2dd90f 2022-03-26 martijn const char *start = ptr;
166 4e2dd90f 2022-03-26 martijn
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);
170 4e2dd90f 2022-03-26 martijn }
171 4e2dd90f 2022-03-26 martijn
172 4e2dd90f 2022-03-26 martijn const char *
173 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_let_dig(const char *ptr, int optional)
174 4e2dd90f 2022-03-26 martijn {
175 4e2dd90f 2022-03-26 martijn const char *start = ptr;
176 4e2dd90f 2022-03-26 martijn
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;
181 4e2dd90f 2022-03-26 martijn }
182 4e2dd90f 2022-03-26 martijn
183 4e2dd90f 2022-03-26 martijn const char *
184 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_ldh_string(const char *ptr, int optional)
185 4e2dd90f 2022-03-26 martijn {
186 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
187 4e2dd90f 2022-03-26 martijn int letdig = 0;
188 4e2dd90f 2022-03-26 martijn
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;
195 4e2dd90f 2022-03-26 martijn }
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;
200 4e2dd90f 2022-03-26 martijn }
201 4e2dd90f 2022-03-26 martijn ptr = prev;
202 4e2dd90f 2022-03-26 martijn break;
203 4e2dd90f 2022-03-26 martijn }
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;
209 4e2dd90f 2022-03-26 martijn }
210 4e2dd90f 2022-03-26 martijn
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)
214 4e2dd90f 2022-03-26 martijn {
215 4e2dd90f 2022-03-26 martijn const char *start = ptr;
216 4e2dd90f 2022-03-26 martijn
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);
222 4e2dd90f 2022-03-26 martijn }
223 4e2dd90f 2022-03-26 martijn
224 4e2dd90f 2022-03-26 martijn const char *
225 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_fws(const char *ptr, int optional)
226 4e2dd90f 2022-03-26 martijn {
227 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev = ptr;
228 4e2dd90f 2022-03-26 martijn
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;
239 4e2dd90f 2022-03-26 martijn }
240 4e2dd90f 2022-03-26 martijn
241 4e2dd90f 2022-03-26 martijn const char *
242 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_ctext(const char *ptr, int optional)
243 4e2dd90f 2022-03-26 martijn {
244 4e2dd90f 2022-03-26 martijn const char *start = ptr;
245 4e2dd90f 2022-03-26 martijn
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;
252 4e2dd90f 2022-03-26 martijn }
253 4e2dd90f 2022-03-26 martijn
254 4e2dd90f 2022-03-26 martijn const char *
255 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_ccontent(const char *ptr, int optional)
256 4e2dd90f 2022-03-26 martijn {
257 4e2dd90f 2022-03-26 martijn const char *start = ptr;
258 4e2dd90f 2022-03-26 martijn
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;
266 4e2dd90f 2022-03-26 martijn }
267 4e2dd90f 2022-03-26 martijn
268 4e2dd90f 2022-03-26 martijn const char *
269 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_comment(const char *ptr, int optional)
270 4e2dd90f 2022-03-26 martijn {
271 4e2dd90f 2022-03-26 martijn const char *start = ptr;
272 4e2dd90f 2022-03-26 martijn
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;
281 4e2dd90f 2022-03-26 martijn }
282 4e2dd90f 2022-03-26 martijn }
283 4e2dd90f 2022-03-26 martijn
284 4e2dd90f 2022-03-26 martijn const char *
285 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_cfws(const char *ptr, int optional)
286 4e2dd90f 2022-03-26 martijn {
287 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
288 4e2dd90f 2022-03-26 martijn
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;
294 4e2dd90f 2022-03-26 martijn break;
295 4e2dd90f 2022-03-26 martijn }
296 4e2dd90f 2022-03-26 martijn }
297 4e2dd90f 2022-03-26 martijn return ptr == start && !optional ? NULL : ptr;
298 4e2dd90f 2022-03-26 martijn }
299 4e2dd90f 2022-03-26 martijn
300 4e2dd90f 2022-03-26 martijn const char *
301 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_atext(const char *ptr, int optional)
302 4e2dd90f 2022-03-26 martijn {
303 4e2dd90f 2022-03-26 martijn const char *start = ptr;
304 4e2dd90f 2022-03-26 martijn
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;
316 4e2dd90f 2022-03-26 martijn }
317 4e2dd90f 2022-03-26 martijn
318 4e2dd90f 2022-03-26 martijn const char *
319 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_atom(const char *ptr, int optional)
320 4e2dd90f 2022-03-26 martijn {
321 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
322 4e2dd90f 2022-03-26 martijn
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;
326 4e2dd90f 2022-03-26 martijn do {
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);
331 4e2dd90f 2022-03-26 martijn }
332 4e2dd90f 2022-03-26 martijn
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)
335 4e2dd90f 2022-03-26 martijn {
336 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
337 4e2dd90f 2022-03-26 martijn
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;
340 4e2dd90f 2022-03-26 martijn do {
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);
344 4e2dd90f 2022-03-26 martijn
345 4e2dd90f 2022-03-26 martijn while (ptr[0] == '.') {
346 4e2dd90f 2022-03-26 martijn ptr++;
347 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_atext(ptr, 0)) == NULL)
348 4e2dd90f 2022-03-26 martijn return prev;
349 4e2dd90f 2022-03-26 martijn do {
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);
353 4e2dd90f 2022-03-26 martijn }
354 4e2dd90f 2022-03-26 martijn return ptr;
355 4e2dd90f 2022-03-26 martijn }
356 4e2dd90f 2022-03-26 martijn
357 4e2dd90f 2022-03-26 martijn const char *
358 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_dot_atom(const char *ptr, int optional)
359 4e2dd90f 2022-03-26 martijn {
360 4e2dd90f 2022-03-26 martijn const char *start = ptr;
361 4e2dd90f 2022-03-26 martijn
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);
366 4e2dd90f 2022-03-26 martijn }
367 4e2dd90f 2022-03-26 martijn
368 4e2dd90f 2022-03-26 martijn const char *
369 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_qtext(const char *ptr, int optional)
370 4e2dd90f 2022-03-26 martijn {
371 4e2dd90f 2022-03-26 martijn const char *start = ptr;
372 4e2dd90f 2022-03-26 martijn
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;
379 4e2dd90f 2022-03-26 martijn }
380 4e2dd90f 2022-03-26 martijn
381 4e2dd90f 2022-03-26 martijn const char *
382 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_qcontent(const char *ptr, int optional)
383 4e2dd90f 2022-03-26 martijn {
384 4e2dd90f 2022-03-26 martijn const char *start = ptr;
385 4e2dd90f 2022-03-26 martijn
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);
389 4e2dd90f 2022-03-26 martijn }
390 4e2dd90f 2022-03-26 martijn
391 4e2dd90f 2022-03-26 martijn const char *
392 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_quoted_string(const char *ptr, int optional)
393 4e2dd90f 2022-03-26 martijn {
394 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
395 4e2dd90f 2022-03-26 martijn
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)
403 4e2dd90f 2022-03-26 martijn break;
404 4e2dd90f 2022-03-26 martijn prev = ptr;
405 4e2dd90f 2022-03-26 martijn }
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);
409 4e2dd90f 2022-03-26 martijn }
410 4e2dd90f 2022-03-26 martijn
411 4e2dd90f 2022-03-26 martijn const char *
412 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_word(const char *ptr, int optional)
413 4e2dd90f 2022-03-26 martijn {
414 4e2dd90f 2022-03-26 martijn const char *start = ptr;
415 4e2dd90f 2022-03-26 martijn
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);
419 4e2dd90f 2022-03-26 martijn }
420 4e2dd90f 2022-03-26 martijn
421 4e2dd90f 2022-03-26 martijn const char *
422 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_phrase(const char *ptr, int optional)
423 4e2dd90f 2022-03-26 martijn {
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);
426 4e2dd90f 2022-03-26 martijn }
427 4e2dd90f 2022-03-26 martijn
428 4e2dd90f 2022-03-26 martijn const char *
429 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_name_addr(const char *ptr, int optional)
430 4e2dd90f 2022-03-26 martijn {
431 4e2dd90f 2022-03-26 martijn const char *start = ptr;
432 4e2dd90f 2022-03-26 martijn
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;
437 4e2dd90f 2022-03-26 martijn }
438 4e2dd90f 2022-03-26 martijn
439 4e2dd90f 2022-03-26 martijn const char *
440 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_angle_addr(const char *ptr, int optional)
441 4e2dd90f 2022-03-26 martijn {
442 4e2dd90f 2022-03-26 martijn const char *start = ptr;
443 4e2dd90f 2022-03-26 martijn
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);
452 4e2dd90f 2022-03-26 martijn }
453 4e2dd90f 2022-03-26 martijn
454 4e2dd90f 2022-03-26 martijn const char *
455 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_display_name(const char *ptr, int optional)
456 4e2dd90f 2022-03-26 martijn {
457 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_phrase(ptr, optional);
458 4e2dd90f 2022-03-26 martijn }
459 4e2dd90f 2022-03-26 martijn
460 4e2dd90f 2022-03-26 martijn const char *
461 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_addr_spec(const char *ptr, int optional)
462 4e2dd90f 2022-03-26 martijn {
463 4e2dd90f 2022-03-26 martijn const char *start = ptr;
464 4e2dd90f 2022-03-26 martijn
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;
472 4e2dd90f 2022-03-26 martijn }
473 4e2dd90f 2022-03-26 martijn
474 4e2dd90f 2022-03-26 martijn const char *
475 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_local_part(const char *ptr, int optional)
476 4e2dd90f 2022-03-26 martijn {
477 4e2dd90f 2022-03-26 martijn const char *start = ptr;
478 4e2dd90f 2022-03-26 martijn
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);
485 4e2dd90f 2022-03-26 martijn }
486 4e2dd90f 2022-03-26 martijn
487 4e2dd90f 2022-03-26 martijn const char *
488 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_domain(const char *ptr, int optional)
489 4e2dd90f 2022-03-26 martijn {
490 4e2dd90f 2022-03-26 martijn const char *start = ptr;
491 4e2dd90f 2022-03-26 martijn
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);
497 4e2dd90f 2022-03-26 martijn }
498 4e2dd90f 2022-03-26 martijn
499 4e2dd90f 2022-03-26 martijn const char *
500 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_domain_literal(const char *ptr, int optional)
501 4e2dd90f 2022-03-26 martijn {
502 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
503 4e2dd90f 2022-03-26 martijn
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;
512 4e2dd90f 2022-03-26 martijn break;
513 4e2dd90f 2022-03-26 martijn }
514 4e2dd90f 2022-03-26 martijn }
515 4e2dd90f 2022-03-26 martijn if (ptr[0] != ']')
516 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
517 4e2dd90f 2022-03-26 martijn ptr++;
518 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_cfws(ptr, 1);
519 4e2dd90f 2022-03-26 martijn }
520 4e2dd90f 2022-03-26 martijn
521 4e2dd90f 2022-03-26 martijn const char *
522 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_dtext(const char *ptr, int optional)
523 4e2dd90f 2022-03-26 martijn {
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);
527 4e2dd90f 2022-03-26 martijn
528 4e2dd90f 2022-03-26 martijn }
529 4e2dd90f 2022-03-26 martijn
530 4e2dd90f 2022-03-26 martijn const char *
531 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_field_name(const char *ptr, int optional)
532 4e2dd90f 2022-03-26 martijn {
533 4e2dd90f 2022-03-26 martijn const char *start = ptr;
534 4e2dd90f 2022-03-26 martijn
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;
541 4e2dd90f 2022-03-26 martijn }
542 4e2dd90f 2022-03-26 martijn }
543 4e2dd90f 2022-03-26 martijn
544 4e2dd90f 2022-03-26 martijn const char *
545 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_ftext(const char *ptr, int optional)
546 4e2dd90f 2022-03-26 martijn {
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;
551 4e2dd90f 2022-03-26 martijn }
552 4e2dd90f 2022-03-26 martijn
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)
555 4e2dd90f 2022-03-26 martijn {
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;
560 4e2dd90f 2022-03-26 martijn }
561 4e2dd90f 2022-03-26 martijn
562 4e2dd90f 2022-03-26 martijn const char *
563 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_obs_ctext(const char *ptr, int optional)
564 4e2dd90f 2022-03-26 martijn {
565 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_obs_no_ws_ctl(ptr, optional);
566 4e2dd90f 2022-03-26 martijn }
567 4e2dd90f 2022-03-26 martijn
568 4e2dd90f 2022-03-26 martijn const char *
569 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_obs_qtext(const char *ptr, int optional)
570 4e2dd90f 2022-03-26 martijn {
571 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_obs_no_ws_ctl(ptr, optional);
572 4e2dd90f 2022-03-26 martijn }
573 4e2dd90f 2022-03-26 martijn
574 4e2dd90f 2022-03-26 martijn const char *
575 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_obs_qp(const char *ptr, int optional)
576 4e2dd90f 2022-03-26 martijn {
577 4e2dd90f 2022-03-26 martijn const char *start = ptr;
578 4e2dd90f 2022-03-26 martijn
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;
585 4e2dd90f 2022-03-26 martijn }
586 4e2dd90f 2022-03-26 martijn
587 4e2dd90f 2022-03-26 martijn const char *
588 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_obs_phrase(const char *ptr, int optional)
589 4e2dd90f 2022-03-26 martijn {
590 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
591 4e2dd90f 2022-03-26 martijn
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] == '.') {
600 4e2dd90f 2022-03-26 martijn ptr++;
601 4e2dd90f 2022-03-26 martijn continue;
602 4e2dd90f 2022-03-26 martijn }
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;
606 4e2dd90f 2022-03-26 martijn }
607 4e2dd90f 2022-03-26 martijn }
608 4e2dd90f 2022-03-26 martijn
609 4e2dd90f 2022-03-26 martijn const char *
610 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_obs_fws(const char *ptr, int optional)
611 4e2dd90f 2022-03-26 martijn {
612 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
613 4e2dd90f 2022-03-26 martijn
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;
619 4e2dd90f 2022-03-26 martijn
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;
630 4e2dd90f 2022-03-26 martijn }
631 4e2dd90f 2022-03-26 martijn }
632 4e2dd90f 2022-03-26 martijn
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)
635 4e2dd90f 2022-03-26 martijn {
636 4e2dd90f 2022-03-26 martijn const char *start = ptr;
637 4e2dd90f 2022-03-26 martijn
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);
648 4e2dd90f 2022-03-26 martijn }
649 4e2dd90f 2022-03-26 martijn
650 4e2dd90f 2022-03-26 martijn const char *
651 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_obs_route(const char *ptr, int optional)
652 4e2dd90f 2022-03-26 martijn {
653 4e2dd90f 2022-03-26 martijn const char *start = ptr;
654 4e2dd90f 2022-03-26 martijn
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;
660 4e2dd90f 2022-03-26 martijn }
661 4e2dd90f 2022-03-26 martijn
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)
664 4e2dd90f 2022-03-26 martijn {
665 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev = ptr;
666 4e2dd90f 2022-03-26 martijn
667 4e2dd90f 2022-03-26 martijn while (1) {
668 4e2dd90f 2022-03-26 martijn if (ptr[0] == ',') {
669 4e2dd90f 2022-03-26 martijn ptr++;
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;
675 4e2dd90f 2022-03-26 martijn }
676 4e2dd90f 2022-03-26 martijn break;
677 4e2dd90f 2022-03-26 martijn }
678 4e2dd90f 2022-03-26 martijn ptr = prev;
679 4e2dd90f 2022-03-26 martijn
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] != ',')
686 4e2dd90f 2022-03-26 martijn break;
687 4e2dd90f 2022-03-26 martijn ptr++;
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;
694 4e2dd90f 2022-03-26 martijn break;
695 4e2dd90f 2022-03-26 martijn }
696 4e2dd90f 2022-03-26 martijn }
697 4e2dd90f 2022-03-26 martijn return ptr;
698 4e2dd90f 2022-03-26 martijn }
699 4e2dd90f 2022-03-26 martijn
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)
702 4e2dd90f 2022-03-26 martijn {
703 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
704 4e2dd90f 2022-03-26 martijn
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] == '.') {
709 4e2dd90f 2022-03-26 martijn ptr++;
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;
713 4e2dd90f 2022-03-26 martijn }
714 4e2dd90f 2022-03-26 martijn return ptr;
715 4e2dd90f 2022-03-26 martijn }
716 4e2dd90f 2022-03-26 martijn
717 4e2dd90f 2022-03-26 martijn const char *
718 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_obs_domain(const char *ptr, int optional)
719 4e2dd90f 2022-03-26 martijn {
720 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
721 4e2dd90f 2022-03-26 martijn
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;
731 4e2dd90f 2022-03-26 martijn }
732 4e2dd90f 2022-03-26 martijn }
733 4e2dd90f 2022-03-26 martijn
734 4e2dd90f 2022-03-26 martijn const char *
735 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_obs_dtext(const char *ptr, int optional)
736 4e2dd90f 2022-03-26 martijn {
737 4e2dd90f 2022-03-26 martijn const char *start = ptr;
738 4e2dd90f 2022-03-26 martijn
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);
742 4e2dd90f 2022-03-26 martijn }
743 4e2dd90f 2022-03-26 martijn
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)
747 4e2dd90f 2022-03-26 martijn {
748 4e2dd90f 2022-03-26 martijn const char *start = ptr;
749 4e2dd90f 2022-03-26 martijn
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;
755 4e2dd90f 2022-03-26 martijn }
756 4e2dd90f 2022-03-26 martijn
757 4e2dd90f 2022-03-26 martijn const char *
758 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_token(const char *ptr, int optional)
759 4e2dd90f 2022-03-26 martijn {
760 4e2dd90f 2022-03-26 martijn const char *start;
761 4e2dd90f 2022-03-26 martijn int first = 1;
762 4e2dd90f 2022-03-26 martijn
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;
771 4e2dd90f 2022-03-26 martijn }
772 4e2dd90f 2022-03-26 martijn return optional || !first ? start : NULL;
773 4e2dd90f 2022-03-26 martijn }
774 4e2dd90f 2022-03-26 martijn }
775 4e2dd90f 2022-03-26 martijn
776 4e2dd90f 2022-03-26 martijn const char *
777 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_tspecials(const char *ptr, int optional)
778 4e2dd90f 2022-03-26 martijn {
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;
785 4e2dd90f 2022-03-26 martijn }
786 4e2dd90f 2022-03-26 martijn
787 4e2dd90f 2022-03-26 martijn const char *
788 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_qp_section(const char *ptr, int optional)
789 4e2dd90f 2022-03-26 martijn {
790 4e2dd90f 2022-03-26 martijn const char *prev, *last = ptr;
791 4e2dd90f 2022-03-26 martijn
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;
799 4e2dd90f 2022-03-26 martijn }
800 4e2dd90f 2022-03-26 martijn }
801 4e2dd90f 2022-03-26 martijn
802 4e2dd90f 2022-03-26 martijn const char *
803 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_ptext(const char *ptr, int optional)
804 4e2dd90f 2022-03-26 martijn {
805 4e2dd90f 2022-03-26 martijn const char *start = ptr;
806 4e2dd90f 2022-03-26 martijn
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;
811 4e2dd90f 2022-03-26 martijn }
812 4e2dd90f 2022-03-26 martijn
813 4e2dd90f 2022-03-26 martijn const char *
814 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_safe_char(const char *ptr, int optional)
815 4e2dd90f 2022-03-26 martijn {
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;
819 4e2dd90f 2022-03-26 martijn }
820 4e2dd90f 2022-03-26 martijn
821 4e2dd90f 2022-03-26 martijn const char *
822 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_hex_octet(const char *ptr, int optional)
823 4e2dd90f 2022-03-26 martijn {
824 4e2dd90f 2022-03-26 martijn const char *start = ptr;
825 4e2dd90f 2022-03-26 martijn char l;
826 4e2dd90f 2022-03-26 martijn
827 4e2dd90f 2022-03-26 martijn if (ptr[0] != '=')
828 4e2dd90f 2022-03-26 martijn return optional ? start : NULL;
829 4e2dd90f 2022-03-26 martijn ptr++;
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')
833 4e2dd90f 2022-03-26 martijn ptr++;
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')
840 4e2dd90f 2022-03-26 martijn ptr++;
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;
844 4e2dd90f 2022-03-26 martijn }
845 4e2dd90f 2022-03-26 martijn
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)
849 4e2dd90f 2022-03-26 martijn {
850 42479031 2022-03-27 martijn const char *start = ptr, *end;
851 4e2dd90f 2022-03-26 martijn
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;
854 4e2dd90f 2022-03-26 martijn
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;
863 42479031 2022-03-27 martijn else
864 42479031 2022-03-27 martijn break;
865 4e2dd90f 2022-03-26 martijn }
866 42479031 2022-03-27 martijn return end;
867 4e2dd90f 2022-03-26 martijn }
868 4e2dd90f 2022-03-26 martijn
869 4e2dd90f 2022-03-26 martijn const char *
870 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_alphadigitps(const char *ptr, int optional)
871 4e2dd90f 2022-03-26 martijn {
872 4e2dd90f 2022-03-26 martijn const char *end;
873 4e2dd90f 2022-03-26 martijn
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;
879 4e2dd90f 2022-03-26 martijn }
880 4e2dd90f 2022-03-26 martijn
881 4e2dd90f 2022-03-26 martijn const char *
882 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_base64string(const char *ptr, int optional)
883 4e2dd90f 2022-03-26 martijn {
884 4e2dd90f 2022-03-26 martijn const char *start = ptr;
885 4e2dd90f 2022-03-26 martijn
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)
892 4e2dd90f 2022-03-26 martijn break;
893 4e2dd90f 2022-03-26 martijn }
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] == '=') {
897 4e2dd90f 2022-03-26 martijn ptr++;
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] == '=')
901 4e2dd90f 2022-03-26 martijn ptr++;
902 4e2dd90f 2022-03-26 martijn else
903 4e2dd90f 2022-03-26 martijn ptr = start;
904 4e2dd90f 2022-03-26 martijn } else
905 4e2dd90f 2022-03-26 martijn ptr = start;
906 4e2dd90f 2022-03-26 martijn return ptr;
907 4e2dd90f 2022-03-26 martijn }
908 4e2dd90f 2022-03-26 martijn
909 4e2dd90f 2022-03-26 martijn const char *
910 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_hdr_name(const char *ptr, int optional)
911 4e2dd90f 2022-03-26 martijn {
912 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_field_name(ptr, optional);
913 4e2dd90f 2022-03-26 martijn }
914 4e2dd90f 2022-03-26 martijn
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)
917 4e2dd90f 2022-03-26 martijn {
918 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_dkim_quoted_printable(ptr, optional);
919 4e2dd90f 2022-03-26 martijn }
920 4e2dd90f 2022-03-26 martijn
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)
923 4e2dd90f 2022-03-26 martijn {
924 4e2dd90f 2022-03-26 martijn const char *start;
925 4e2dd90f 2022-03-26 martijn
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)
934 4e2dd90f 2022-03-26 martijn break;
935 4e2dd90f 2022-03-26 martijn }
936 4e2dd90f 2022-03-26 martijn return start;
937 4e2dd90f 2022-03-26 martijn }
938 4e2dd90f 2022-03-26 martijn
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)
941 4e2dd90f 2022-03-26 martijn {
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;
946 4e2dd90f 2022-03-26 martijn }
947 4e2dd90f 2022-03-26 martijn
948 4e2dd90f 2022-03-26 martijn const char *
949 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_selector(const char *ptr, int optional)
950 4e2dd90f 2022-03-26 martijn {
951 4e2dd90f 2022-03-26 martijn const char *start = ptr;
952 4e2dd90f 2022-03-26 martijn
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;
959 4e2dd90f 2022-03-26 martijn ptr++;
960 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_sub_domain(ptr, 0)) == NULL)
961 4e2dd90f 2022-03-26 martijn return start;
962 4e2dd90f 2022-03-26 martijn }
963 4e2dd90f 2022-03-26 martijn }
964 4e2dd90f 2022-03-26 martijn
965 4e2dd90f 2022-03-26 martijn const char *
966 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_tag_list(const char *ptr, int optional)
967 4e2dd90f 2022-03-26 martijn {
968 4e2dd90f 2022-03-26 martijn const char *start = ptr;
969 4e2dd90f 2022-03-26 martijn
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;
976 4e2dd90f 2022-03-26 martijn 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;
980 4e2dd90f 2022-03-26 martijn }
981 4e2dd90f 2022-03-26 martijn }
982 4e2dd90f 2022-03-26 martijn
983 4e2dd90f 2022-03-26 martijn const char *
984 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_tag_spec(const char *ptr, int optional)
985 4e2dd90f 2022-03-26 martijn {
986 4e2dd90f 2022-03-26 martijn const char *start = ptr;
987 4e2dd90f 2022-03-26 martijn
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;
994 4e2dd90f 2022-03-26 martijn ptr++;
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);
999 4e2dd90f 2022-03-26 martijn }
1000 4e2dd90f 2022-03-26 martijn
1001 4e2dd90f 2022-03-26 martijn const char *
1002 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_tag_name(const char *ptr, int optional)
1003 4e2dd90f 2022-03-26 martijn {
1004 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
1005 4e2dd90f 2022-03-26 martijn
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;
1012 4e2dd90f 2022-03-26 martijn }
1013 4e2dd90f 2022-03-26 martijn
1014 4e2dd90f 2022-03-26 martijn const char *
1015 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_tag_value(const char *ptr, int optional)
1016 4e2dd90f 2022-03-26 martijn {
1017 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
1018 4e2dd90f 2022-03-26 martijn
1019 4e2dd90f 2022-03-26 martijn if ((ptr = osmtpd_ltok_skip_tval(ptr, 0)) == NULL)
1020 4e2dd90f 2022-03-26 martijn return start;
1021 4e2dd90f 2022-03-26 martijn
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;
1033 4e2dd90f 2022-03-26 martijn }
1034 4e2dd90f 2022-03-26 martijn }
1035 4e2dd90f 2022-03-26 martijn
1036 4e2dd90f 2022-03-26 martijn const char *
1037 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_tval(const char *ptr, int optional)
1038 4e2dd90f 2022-03-26 martijn {
1039 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
1040 4e2dd90f 2022-03-26 martijn
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;
1047 4e2dd90f 2022-03-26 martijn }
1048 4e2dd90f 2022-03-26 martijn
1049 4e2dd90f 2022-03-26 martijn const char *
1050 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_valchar(const char *ptr, int optional)
1051 4e2dd90f 2022-03-26 martijn {
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;
1056 4e2dd90f 2022-03-26 martijn }
1057 4e2dd90f 2022-03-26 martijn
1058 4e2dd90f 2022-03-26 martijn const char *
1059 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_alnumpunc(const char *ptr, int optional)
1060 4e2dd90f 2022-03-26 martijn {
1061 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1062 4e2dd90f 2022-03-26 martijn
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;
1070 4e2dd90f 2022-03-26 martijn }
1071 4e2dd90f 2022-03-26 martijn
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)
1074 4e2dd90f 2022-03-26 martijn {
1075 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1076 4e2dd90f 2022-03-26 martijn
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;
1086 4e2dd90f 2022-03-26 martijn }
1087 4e2dd90f 2022-03-26 martijn
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)
1090 4e2dd90f 2022-03-26 martijn {
1091 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev;
1092 4e2dd90f 2022-03-26 martijn
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;
1099 4e2dd90f 2022-03-26 martijn }
1100 4e2dd90f 2022-03-26 martijn }
1101 4e2dd90f 2022-03-26 martijn
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)
1104 4e2dd90f 2022-03-26 martijn {
1105 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1106 4e2dd90f 2022-03-26 martijn
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;
1116 4e2dd90f 2022-03-26 martijn }
1117 4e2dd90f 2022-03-26 martijn
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)
1120 4e2dd90f 2022-03-26 martijn {
1121 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_sig_a_tag_alg(ptr, optional);
1122 4e2dd90f 2022-03-26 martijn }
1123 4e2dd90f 2022-03-26 martijn
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)
1126 4e2dd90f 2022-03-26 martijn {
1127 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1128 4e2dd90f 2022-03-26 martijn
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;
1133 4e2dd90f 2022-03-26 martijn ptr++;
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;
1137 4e2dd90f 2022-03-26 martijn }
1138 4e2dd90f 2022-03-26 martijn
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)
1141 4e2dd90f 2022-03-26 martijn {
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);
1144 4e2dd90f 2022-03-26 martijn }
1145 4e2dd90f 2022-03-26 martijn
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)
1148 4e2dd90f 2022-03-26 martijn {
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);
1151 4e2dd90f 2022-03-26 martijn }
1152 4e2dd90f 2022-03-26 martijn
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)
1155 4e2dd90f 2022-03-26 martijn {
1156 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev, *end;
1157 4e2dd90f 2022-03-26 martijn
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;
1165 4e2dd90f 2022-03-26 martijn }
1166 4e2dd90f 2022-03-26 martijn return prev;
1167 4e2dd90f 2022-03-26 martijn }
1168 4e2dd90f 2022-03-26 martijn
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)
1171 4e2dd90f 2022-03-26 martijn {
1172 4e2dd90f 2022-03-26 martijn const char *start = ptr, *prev, *end;
1173 4e2dd90f 2022-03-26 martijn
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;
1181 4e2dd90f 2022-03-26 martijn }
1182 4e2dd90f 2022-03-26 martijn return prev;
1183 4e2dd90f 2022-03-26 martijn }
1184 4e2dd90f 2022-03-26 martijn
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)
1187 4e2dd90f 2022-03-26 martijn {
1188 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1189 4e2dd90f 2022-03-26 martijn
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;
1199 4e2dd90f 2022-03-26 martijn }
1200 4e2dd90f 2022-03-26 martijn
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)
1203 4e2dd90f 2022-03-26 martijn {
1204 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_sig_b_tag_data(ptr, optional);
1205 4e2dd90f 2022-03-26 martijn }
1206 4e2dd90f 2022-03-26 martijn
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)
1209 4e2dd90f 2022-03-26 martijn {
1210 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_base64string(ptr, optional);
1211 4e2dd90f 2022-03-26 martijn }
1212 4e2dd90f 2022-03-26 martijn
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)
1215 4e2dd90f 2022-03-26 martijn {
1216 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1217 4e2dd90f 2022-03-26 martijn
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;
1227 4e2dd90f 2022-03-26 martijn }
1228 4e2dd90f 2022-03-26 martijn
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)
1231 4e2dd90f 2022-03-26 martijn {
1232 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_sig_bh_tag_data(ptr, optional);
1233 4e2dd90f 2022-03-26 martijn }
1234 4e2dd90f 2022-03-26 martijn
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)
1237 4e2dd90f 2022-03-26 martijn {
1238 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_base64string(ptr, optional);
1239 4e2dd90f 2022-03-26 martijn }
1240 4e2dd90f 2022-03-26 martijn
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)
1243 4e2dd90f 2022-03-26 martijn {
1244 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1245 4e2dd90f 2022-03-26 martijn
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;
1255 4e2dd90f 2022-03-26 martijn }
1256 4e2dd90f 2022-03-26 martijn
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)
1259 4e2dd90f 2022-03-26 martijn {
1260 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1261 4e2dd90f 2022-03-26 martijn
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;
1268 4e2dd90f 2022-03-26 martijn }
1269 4e2dd90f 2022-03-26 martijn return ptr;
1270 4e2dd90f 2022-03-26 martijn }
1271 4e2dd90f 2022-03-26 martijn
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)
1274 4e2dd90f 2022-03-26 martijn {
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);
1277 4e2dd90f 2022-03-26 martijn }
1278 4e2dd90f 2022-03-26 martijn
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)
1281 4e2dd90f 2022-03-26 martijn {
1282 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_hyphenated_word(ptr, optional);
1283 4e2dd90f 2022-03-26 martijn }
1284 4e2dd90f 2022-03-26 martijn
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)
1287 4e2dd90f 2022-03-26 martijn {
1288 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1289 4e2dd90f 2022-03-26 martijn
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;
1299 4e2dd90f 2022-03-26 martijn }
1300 4e2dd90f 2022-03-26 martijn
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)
1303 4e2dd90f 2022-03-26 martijn {
1304 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_domain_name(ptr, optional);
1305 4e2dd90f 2022-03-26 martijn }
1306 4e2dd90f 2022-03-26 martijn
1307 4e2dd90f 2022-03-26 martijn const char *
1308 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_domain_name(const char *ptr, int optional)
1309 4e2dd90f 2022-03-26 martijn {
1310 4e2dd90f 2022-03-26 martijn const char *prev = ptr;
1311 4e2dd90f 2022-03-26 martijn
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;
1319 4e2dd90f 2022-03-26 martijn }
1320 4e2dd90f 2022-03-26 martijn }
1321 4e2dd90f 2022-03-26 martijn
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)
1324 4e2dd90f 2022-03-26 martijn {
1325 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1326 4e2dd90f 2022-03-26 martijn
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;
1336 4e2dd90f 2022-03-26 martijn }
1337 4e2dd90f 2022-03-26 martijn
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)
1340 4e2dd90f 2022-03-26 martijn {
1341 4e2dd90f 2022-03-26 martijn const char *prev = ptr;
1342 4e2dd90f 2022-03-26 martijn
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;
1353 4e2dd90f 2022-03-26 martijn }
1354 4e2dd90f 2022-03-26 martijn }
1355 4e2dd90f 2022-03-26 martijn
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)
1358 4e2dd90f 2022-03-26 martijn {
1359 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1360 4e2dd90f 2022-03-26 martijn
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;
1370 4e2dd90f 2022-03-26 martijn }
1371 4e2dd90f 2022-03-26 martijn
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)
1374 4e2dd90f 2022-03-26 martijn {
1375 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1376 4e2dd90f 2022-03-26 martijn
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;
1382 4e2dd90f 2022-03-26 martijn }
1383 4e2dd90f 2022-03-26 martijn
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)
1386 4e2dd90f 2022-03-26 martijn {
1387 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1388 4e2dd90f 2022-03-26 martijn
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;
1398 4e2dd90f 2022-03-26 martijn }
1399 4e2dd90f 2022-03-26 martijn
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)
1402 4e2dd90f 2022-03-26 martijn {
1403 4e2dd90f 2022-03-26 martijn size_t i;
1404 4e2dd90f 2022-03-26 martijn
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)
1407 4e2dd90f 2022-03-26 martijn break;
1408 4e2dd90f 2022-03-26 martijn }
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;
1412 4e2dd90f 2022-03-26 martijn }
1413 4e2dd90f 2022-03-26 martijn
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)
1416 4e2dd90f 2022-03-26 martijn {
1417 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1418 4e2dd90f 2022-03-26 martijn
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;
1428 4e2dd90f 2022-03-26 martijn }
1429 4e2dd90f 2022-03-26 martijn
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)
1432 4e2dd90f 2022-03-26 martijn {
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;
1444 4e2dd90f 2022-03-26 martijn }
1445 4e2dd90f 2022-03-26 martijn }
1446 4e2dd90f 2022-03-26 martijn
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)
1449 4e2dd90f 2022-03-26 martijn {
1450 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1451 4e2dd90f 2022-03-26 martijn
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;
1461 4e2dd90f 2022-03-26 martijn }
1462 4e2dd90f 2022-03-26 martijn
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)
1465 4e2dd90f 2022-03-26 martijn {
1466 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_hyphenated_word(ptr, optional);
1467 4e2dd90f 2022-03-26 martijn }
1468 4e2dd90f 2022-03-26 martijn
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)
1471 4e2dd90f 2022-03-26 martijn {
1472 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_qp_hdr_value(ptr, optional);
1473 4e2dd90f 2022-03-26 martijn }
1474 4e2dd90f 2022-03-26 martijn
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)
1477 4e2dd90f 2022-03-26 martijn {
1478 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1479 4e2dd90f 2022-03-26 martijn
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;
1489 4e2dd90f 2022-03-26 martijn }
1490 4e2dd90f 2022-03-26 martijn
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)
1493 4e2dd90f 2022-03-26 martijn {
1494 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_selector(ptr, optional);
1495 4e2dd90f 2022-03-26 martijn }
1496 4e2dd90f 2022-03-26 martijn
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)
1499 4e2dd90f 2022-03-26 martijn {
1500 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1501 4e2dd90f 2022-03-26 martijn
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;
1511 4e2dd90f 2022-03-26 martijn }
1512 4e2dd90f 2022-03-26 martijn
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)
1515 4e2dd90f 2022-03-26 martijn {
1516 4e2dd90f 2022-03-26 martijn size_t i;
1517 4e2dd90f 2022-03-26 martijn
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)
1520 4e2dd90f 2022-03-26 martijn break;
1521 4e2dd90f 2022-03-26 martijn }
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;
1525 4e2dd90f 2022-03-26 martijn }
1526 4e2dd90f 2022-03-26 martijn
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)
1529 4e2dd90f 2022-03-26 martijn {
1530 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1531 4e2dd90f 2022-03-26 martijn
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;
1541 4e2dd90f 2022-03-26 martijn }
1542 4e2dd90f 2022-03-26 martijn
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)
1545 4e2dd90f 2022-03-26 martijn {
1546 4e2dd90f 2022-03-26 martijn size_t i;
1547 4e2dd90f 2022-03-26 martijn
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)
1550 4e2dd90f 2022-03-26 martijn break;
1551 4e2dd90f 2022-03-26 martijn }
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;
1555 4e2dd90f 2022-03-26 martijn }
1556 4e2dd90f 2022-03-26 martijn
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)
1559 4e2dd90f 2022-03-26 martijn {
1560 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1561 4e2dd90f 2022-03-26 martijn
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;
1571 4e2dd90f 2022-03-26 martijn }
1572 4e2dd90f 2022-03-26 martijn
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)
1575 4e2dd90f 2022-03-26 martijn {
1576 4e2dd90f 2022-03-26 martijn const char *prev = ptr;
1577 4e2dd90f 2022-03-26 martijn
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;
1587 4e2dd90f 2022-03-26 martijn }
1588 4e2dd90f 2022-03-26 martijn }
1589 4e2dd90f 2022-03-26 martijn
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)
1592 4e2dd90f 2022-03-26 martijn {
1593 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1594 4e2dd90f 2022-03-26 martijn
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;
1603 4e2dd90f 2022-03-26 martijn }
1604 4e2dd90f 2022-03-26 martijn
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)
1607 4e2dd90f 2022-03-26 martijn {
1608 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1609 4e2dd90f 2022-03-26 martijn
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;
1619 4e2dd90f 2022-03-26 martijn }
1620 4e2dd90f 2022-03-26 martijn
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)
1623 4e2dd90f 2022-03-26 martijn {
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;
1628 4e2dd90f 2022-03-26 martijn }
1629 4e2dd90f 2022-03-26 martijn
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)
1632 4e2dd90f 2022-03-26 martijn {
1633 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1634 4e2dd90f 2022-03-26 martijn
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;
1644 4e2dd90f 2022-03-26 martijn }
1645 4e2dd90f 2022-03-26 martijn
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)
1648 4e2dd90f 2022-03-26 martijn {
1649 4e2dd90f 2022-03-26 martijn const char *prev = ptr;
1650 4e2dd90f 2022-03-26 martijn
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;
1661 4e2dd90f 2022-03-26 martijn }
1662 4e2dd90f 2022-03-26 martijn }
1663 4e2dd90f 2022-03-26 martijn
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)
1666 4e2dd90f 2022-03-26 martijn {
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);
1669 4e2dd90f 2022-03-26 martijn }
1670 4e2dd90f 2022-03-26 martijn
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)
1673 4e2dd90f 2022-03-26 martijn {
1674 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_hyphenated_word(ptr, optional);
1675 4e2dd90f 2022-03-26 martijn }
1676 4e2dd90f 2022-03-26 martijn
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)
1679 4e2dd90f 2022-03-26 martijn {
1680 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1681 4e2dd90f 2022-03-26 martijn
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;
1691 4e2dd90f 2022-03-26 martijn }
1692 4e2dd90f 2022-03-26 martijn
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)
1695 4e2dd90f 2022-03-26 martijn {
1696 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1697 4e2dd90f 2022-03-26 martijn
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;
1701 4e2dd90f 2022-03-26 martijn }
1702 4e2dd90f 2022-03-26 martijn
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)
1705 4e2dd90f 2022-03-26 martijn {
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);
1708 4e2dd90f 2022-03-26 martijn }
1709 4e2dd90f 2022-03-26 martijn
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)
1712 4e2dd90f 2022-03-26 martijn {
1713 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_hyphenated_word(ptr, optional);
1714 4e2dd90f 2022-03-26 martijn }
1715 4e2dd90f 2022-03-26 martijn
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)
1718 4e2dd90f 2022-03-26 martijn {
1719 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1720 4e2dd90f 2022-03-26 martijn
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;
1730 4e2dd90f 2022-03-26 martijn }
1731 4e2dd90f 2022-03-26 martijn
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)
1734 4e2dd90f 2022-03-26 martijn {
1735 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_qp_section(ptr, optional);
1736 4e2dd90f 2022-03-26 martijn }
1737 4e2dd90f 2022-03-26 martijn
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)
1740 4e2dd90f 2022-03-26 martijn {
1741 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1742 4e2dd90f 2022-03-26 martijn
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;
1752 4e2dd90f 2022-03-26 martijn }
1753 4e2dd90f 2022-03-26 martijn
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)
1756 4e2dd90f 2022-03-26 martijn {
1757 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1758 4e2dd90f 2022-03-26 martijn
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;
1762 4e2dd90f 2022-03-26 martijn }
1763 4e2dd90f 2022-03-26 martijn
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)
1766 4e2dd90f 2022-03-26 martijn {
1767 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1768 4e2dd90f 2022-03-26 martijn
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;
1778 4e2dd90f 2022-03-26 martijn }
1779 4e2dd90f 2022-03-26 martijn
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)
1782 4e2dd90f 2022-03-26 martijn {
1783 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1784 4e2dd90f 2022-03-26 martijn
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;
1796 4e2dd90f 2022-03-26 martijn }
1797 4e2dd90f 2022-03-26 martijn }
1798 4e2dd90f 2022-03-26 martijn
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)
1801 4e2dd90f 2022-03-26 martijn {
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);
1806 4e2dd90f 2022-03-26 martijn }
1807 4e2dd90f 2022-03-26 martijn
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)
1810 4e2dd90f 2022-03-26 martijn {
1811 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_hyphenated_word(ptr, optional);
1812 4e2dd90f 2022-03-26 martijn }
1813 4e2dd90f 2022-03-26 martijn
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)
1816 4e2dd90f 2022-03-26 martijn {
1817 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1818 4e2dd90f 2022-03-26 martijn
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;
1828 4e2dd90f 2022-03-26 martijn }
1829 4e2dd90f 2022-03-26 martijn
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)
1832 4e2dd90f 2022-03-26 martijn {
1833 4e2dd90f 2022-03-26 martijn const char *start = ptr;
1834 4e2dd90f 2022-03-26 martijn
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;
1846 4e2dd90f 2022-03-26 martijn }
1847 4e2dd90f 2022-03-26 martijn }
1848 4e2dd90f 2022-03-26 martijn
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)
1851 4e2dd90f 2022-03-26 martijn {
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);
1854 4e2dd90f 2022-03-26 martijn }
1855 4e2dd90f 2022-03-26 martijn
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)
1858 4e2dd90f 2022-03-26 martijn {
1859 4e2dd90f 2022-03-26 martijn return osmtpd_ltok_skip_hyphenated_word(ptr, optional);
1860 4e2dd90f 2022-03-26 martijn }
1861 4e2dd90f 2022-03-26 martijn
1862 4e2dd90f 2022-03-26 martijn const char *
1863 4e2dd90f 2022-03-26 martijn osmtpd_ltok_skip_ar_pvalue(const char *ptr, int optional)
1864 4e2dd90f 2022-03-26 martijn {
1865 4e2dd90f 2022-03-26 martijn const char *start = ptr, *tmp;
1866 4e2dd90f 2022-03-26 martijn
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] == '@')
1872 4e2dd90f 2022-03-26 martijn ptr++;
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;
1876 4e2dd90f 2022-03-26 martijn }