Blame


1 4f29629b 2020-08-30 martijn /*
2 4f29629b 2020-08-30 martijn * Copyright (c) 2020 Martijn van Duren <martijn@openbsd.org>
3 4f29629b 2020-08-30 martijn *
4 4f29629b 2020-08-30 martijn * Permission to use, copy, modify, and distribute this software for any
5 4f29629b 2020-08-30 martijn * purpose with or without fee is hereby granted, provided that the above
6 4f29629b 2020-08-30 martijn * copyright notice and this permission notice appear in all copies.
7 4f29629b 2020-08-30 martijn *
8 4f29629b 2020-08-30 martijn * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 4f29629b 2020-08-30 martijn * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 4f29629b 2020-08-30 martijn * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 4f29629b 2020-08-30 martijn * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 4f29629b 2020-08-30 martijn * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 4f29629b 2020-08-30 martijn * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 4f29629b 2020-08-30 martijn * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 4f29629b 2020-08-30 martijn */
16 4f29629b 2020-08-30 martijn
17 4f29629b 2020-08-30 martijn #include <ctype.h>
18 4f29629b 2020-08-30 martijn #include <errno.h>
19 4f29629b 2020-08-30 martijn #include <stddef.h>
20 4f29629b 2020-08-30 martijn #include <string.h>
21 4f29629b 2020-08-30 martijn #include <strings.h>
22 4f29629b 2020-08-30 martijn
23 4f29629b 2020-08-30 martijn #include "mheader.h"
24 4f29629b 2020-08-30 martijn
25 4f29629b 2020-08-30 martijn char *
26 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_sp(char *ptr, int optional)
27 4f29629b 2020-08-30 martijn {
28 4f29629b 2020-08-30 martijn if (ptr[0] == 0x20)
29 4f29629b 2020-08-30 martijn return ptr + 1;
30 4f29629b 2020-08-30 martijn return optional ? ptr : NULL;
31 4f29629b 2020-08-30 martijn }
32 4f29629b 2020-08-30 martijn
33 4f29629b 2020-08-30 martijn char *
34 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_htab(char *ptr, int optional)
35 4f29629b 2020-08-30 martijn {
36 4f29629b 2020-08-30 martijn if (ptr[0] == 0x9)
37 4f29629b 2020-08-30 martijn return ptr + 1;
38 4f29629b 2020-08-30 martijn return optional ? ptr : NULL;
39 4f29629b 2020-08-30 martijn }
40 4f29629b 2020-08-30 martijn
41 4f29629b 2020-08-30 martijn char *
42 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_wsp(char *ptr, int optional)
43 4f29629b 2020-08-30 martijn {
44 4f29629b 2020-08-30 martijn char *start = ptr;
45 4f29629b 2020-08-30 martijn
46 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_sp(start, 0)) != NULL ||
47 4f29629b 2020-08-30 martijn (ptr = osmtpd_mheader_skip_htab(start, 0)) != NULL)
48 4f29629b 2020-08-30 martijn return ptr;
49 4f29629b 2020-08-30 martijn return optional ? ptr : NULL;
50 4f29629b 2020-08-30 martijn }
51 4f29629b 2020-08-30 martijn
52 4f29629b 2020-08-30 martijn char *
53 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_crlf(char *ptr, int optional)
54 4f29629b 2020-08-30 martijn {
55 4f29629b 2020-08-30 martijn if (ptr[0] == 13 && ptr[1] == 10)
56 4f29629b 2020-08-30 martijn return ptr + 2;
57 4f29629b 2020-08-30 martijn return optional ? ptr : NULL;
58 4f29629b 2020-08-30 martijn }
59 4f29629b 2020-08-30 martijn
60 4f29629b 2020-08-30 martijn char *
61 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_vchar(char *ptr, int optional)
62 4f29629b 2020-08-30 martijn {
63 4f29629b 2020-08-30 martijn if (ptr[0] >= 0x21 && ptr[0] <= 0x7e)
64 4f29629b 2020-08-30 martijn return ptr + 1;
65 4f29629b 2020-08-30 martijn return optional ? ptr : NULL;
66 4f29629b 2020-08-30 martijn }
67 4f29629b 2020-08-30 martijn
68 4f29629b 2020-08-30 martijn char *
69 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_lf(char *ptr, int optional)
70 4f29629b 2020-08-30 martijn {
71 4f29629b 2020-08-30 martijn if (ptr[0] == 0xa)
72 4f29629b 2020-08-30 martijn return ptr + 1;
73 4f29629b 2020-08-30 martijn return optional ? ptr : NULL;
74 4f29629b 2020-08-30 martijn }
75 4f29629b 2020-08-30 martijn
76 4f29629b 2020-08-30 martijn char *
77 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_cr(char *ptr, int optional)
78 4f29629b 2020-08-30 martijn {
79 4f29629b 2020-08-30 martijn if (ptr[0] == 0xd)
80 4f29629b 2020-08-30 martijn return ptr + 1;
81 4f29629b 2020-08-30 martijn return optional ? ptr : NULL;
82 4f29629b 2020-08-30 martijn }
83 4f29629b 2020-08-30 martijn
84 4f29629b 2020-08-30 martijn char *
85 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_alpha(char *ptr, int optional)
86 4f29629b 2020-08-30 martijn {
87 4f29629b 2020-08-30 martijn if ((ptr[0] >= 0x41 && ptr[0] <= 0x5a) ||
88 4f29629b 2020-08-30 martijn (ptr[0] >= 0x61 && ptr[0] <= 0x7a))
89 4f29629b 2020-08-30 martijn return ptr + 1;
90 4f29629b 2020-08-30 martijn return optional ? ptr : NULL;
91 4f29629b 2020-08-30 martijn }
92 4f29629b 2020-08-30 martijn
93 4f29629b 2020-08-30 martijn char *
94 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_digit(char *ptr, int optional)
95 4f29629b 2020-08-30 martijn {
96 4f29629b 2020-08-30 martijn if (ptr[0] >= 0x30 && ptr[0] <= 0x39)
97 4f29629b 2020-08-30 martijn return ptr + 1;
98 4f29629b 2020-08-30 martijn return optional ? ptr : NULL;
99 4f29629b 2020-08-30 martijn }
100 4f29629b 2020-08-30 martijn
101 4f29629b 2020-08-30 martijn char *
102 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_dquote(char *ptr, int optional)
103 4f29629b 2020-08-30 martijn {
104 4f29629b 2020-08-30 martijn if (ptr[0] == 0x22)
105 4f29629b 2020-08-30 martijn return ptr + 1;
106 4f29629b 2020-08-30 martijn return optional ? ptr : NULL;
107 4f29629b 2020-08-30 martijn }
108 4f29629b 2020-08-30 martijn
109 4f29629b 2020-08-30 martijn char *
110 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_char(char *ptr, int optional)
111 4f29629b 2020-08-30 martijn {
112 4f29629b 2020-08-30 martijn if (ptr[0] >= 0x1 && ptr[0] <= 0x7f)
113 4f29629b 2020-08-30 martijn return ptr + 1;
114 4f29629b 2020-08-30 martijn return optional ? ptr : NULL;
115 4f29629b 2020-08-30 martijn }
116 4f29629b 2020-08-30 martijn
117 4f29629b 2020-08-30 martijn char *
118 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_ctl(char *ptr, int optional)
119 4f29629b 2020-08-30 martijn {
120 4f29629b 2020-08-30 martijn if ((ptr[0] >= 0x0 && ptr[0] <= 0x1f) || ptr[0] == 0x7f)
121 4f29629b 2020-08-30 martijn return ptr + 1;
122 4f29629b 2020-08-30 martijn return optional ? ptr : NULL;
123 4f29629b 2020-08-30 martijn }
124 4f29629b 2020-08-30 martijn
125 4f29629b 2020-08-30 martijn char *
126 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_obs_fws(char *ptr, int optional)
127 4f29629b 2020-08-30 martijn {
128 4f29629b 2020-08-30 martijn char *start = ptr, *prev;
129 4f29629b 2020-08-30 martijn
130 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_wsp(ptr, 0)) == NULL)
131 4f29629b 2020-08-30 martijn return optional ? start : NULL;
132 4f29629b 2020-08-30 martijn prev = ptr;
133 4f29629b 2020-08-30 martijn while ((ptr = osmtpd_mheader_skip_wsp(ptr, 0)) != NULL)
134 4f29629b 2020-08-30 martijn prev = ptr;
135 4f29629b 2020-08-30 martijn
136 4f29629b 2020-08-30 martijn ptr = prev;
137 4f29629b 2020-08-30 martijn while (1) {
138 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_crlf(ptr, 0)) == NULL)
139 4f29629b 2020-08-30 martijn return prev;
140 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_wsp(ptr, 0)) == NULL)
141 4f29629b 2020-08-30 martijn return prev;
142 4f29629b 2020-08-30 martijn prev = ptr;
143 4f29629b 2020-08-30 martijn while ((ptr = osmtpd_mheader_skip_wsp(ptr, 0)) != NULL)
144 4f29629b 2020-08-30 martijn prev = ptr;
145 4f29629b 2020-08-30 martijn ptr = prev;
146 4f29629b 2020-08-30 martijn }
147 4f29629b 2020-08-30 martijn }
148 4f29629b 2020-08-30 martijn
149 4f29629b 2020-08-30 martijn char *
150 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_fws(char *ptr, int optional)
151 4f29629b 2020-08-30 martijn {
152 4f29629b 2020-08-30 martijn char *start = ptr, *prev = ptr;
153 4f29629b 2020-08-30 martijn
154 4f29629b 2020-08-30 martijn while ((ptr = osmtpd_mheader_skip_wsp(ptr, 0)) != NULL)
155 4f29629b 2020-08-30 martijn prev = ptr;
156 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_crlf(prev, 1)) == prev)
157 4f29629b 2020-08-30 martijn ptr = start;
158 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_wsp(ptr, 0)) == NULL)
159 4f29629b 2020-08-30 martijn return osmtpd_mheader_skip_obs_fws(start, optional);
160 4f29629b 2020-08-30 martijn prev = ptr;
161 4f29629b 2020-08-30 martijn while ((ptr = osmtpd_mheader_skip_wsp(ptr, 0)) != NULL)
162 4f29629b 2020-08-30 martijn prev = ptr;
163 4f29629b 2020-08-30 martijn return prev;
164 4f29629b 2020-08-30 martijn }
165 4f29629b 2020-08-30 martijn
166 4f29629b 2020-08-30 martijn char *
167 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_obs_no_ws_ctl(char *ptr, int optional)
168 4f29629b 2020-08-30 martijn {
169 4f29629b 2020-08-30 martijn if ((ptr[0] >= 1 && ptr[0] <= 8) || ptr[0] == 11 || ptr[0] == 12 ||
170 4f29629b 2020-08-30 martijn (ptr[0] >= 14 && ptr[0] <= 31) || ptr[0] == 127)
171 4f29629b 2020-08-30 martijn return ptr + 1;
172 4f29629b 2020-08-30 martijn return optional ? ptr : NULL;
173 4f29629b 2020-08-30 martijn }
174 4f29629b 2020-08-30 martijn
175 4f29629b 2020-08-30 martijn char *
176 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_obs_ctext(char *ptr, int optional)
177 4f29629b 2020-08-30 martijn {
178 4f29629b 2020-08-30 martijn return osmtpd_mheader_skip_obs_no_ws_ctl(ptr, optional);
179 4f29629b 2020-08-30 martijn }
180 4f29629b 2020-08-30 martijn
181 4f29629b 2020-08-30 martijn char *
182 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_ctext(char *ptr, int optional)
183 4f29629b 2020-08-30 martijn {
184 4f29629b 2020-08-30 martijn char *start = ptr;
185 4f29629b 2020-08-30 martijn
186 4f29629b 2020-08-30 martijn if ((ptr[0] >= 33 && ptr[0] <= 39) || (ptr[0] >= 42 && ptr[0] <= 91) ||
187 4f29629b 2020-08-30 martijn (ptr[0] >= 93 && ptr[0] <= 126))
188 4f29629b 2020-08-30 martijn return ptr + 1;
189 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_obs_ctext(ptr, 0)) != NULL)
190 4f29629b 2020-08-30 martijn return ptr;
191 4f29629b 2020-08-30 martijn return optional ? start : NULL;
192 4f29629b 2020-08-30 martijn }
193 4f29629b 2020-08-30 martijn
194 4f29629b 2020-08-30 martijn char *
195 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_obs_qp(char *ptr, int optional)
196 4f29629b 2020-08-30 martijn {
197 4f29629b 2020-08-30 martijn char *start = ptr;
198 4f29629b 2020-08-30 martijn
199 4f29629b 2020-08-30 martijn if (ptr[0] == '\\' && (
200 4f29629b 2020-08-30 martijn (ptr = osmtpd_mheader_skip_obs_no_ws_ctl(start + 1, 0)) != NULL ||
201 4f29629b 2020-08-30 martijn (ptr = osmtpd_mheader_skip_lf(start + 1, 0)) != NULL ||
202 4f29629b 2020-08-30 martijn (ptr = osmtpd_mheader_skip_cr(start + 1, 0)) != NULL))
203 4f29629b 2020-08-30 martijn return ptr;
204 4f29629b 2020-08-30 martijn return optional ? start : NULL;
205 4f29629b 2020-08-30 martijn }
206 4f29629b 2020-08-30 martijn
207 4f29629b 2020-08-30 martijn char *
208 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_quoted_pair(char *ptr, int optional)
209 4f29629b 2020-08-30 martijn {
210 4f29629b 2020-08-30 martijn char *start = ptr;
211 4f29629b 2020-08-30 martijn
212 4f29629b 2020-08-30 martijn if (ptr[0] == '\\' && (
213 4f29629b 2020-08-30 martijn (ptr = osmtpd_mheader_skip_vchar(start + 1, 0)) != NULL ||
214 4f29629b 2020-08-30 martijn (ptr = osmtpd_mheader_skip_wsp(start + 1, 0)) != NULL))
215 4f29629b 2020-08-30 martijn return ptr;
216 4f29629b 2020-08-30 martijn return osmtpd_mheader_skip_obs_qp(start, optional);
217 4f29629b 2020-08-30 martijn }
218 4f29629b 2020-08-30 martijn
219 4f29629b 2020-08-30 martijn char *
220 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_ccontent(char *ptr, int optional)
221 4f29629b 2020-08-30 martijn {
222 4f29629b 2020-08-30 martijn char *start = ptr;
223 4f29629b 2020-08-30 martijn
224 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_ctext(ptr, 0)) != NULL)
225 4f29629b 2020-08-30 martijn return ptr;
226 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_quoted_pair(start, 0)) != NULL)
227 4f29629b 2020-08-30 martijn return ptr;
228 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_comment(start, 0)) != NULL)
229 4f29629b 2020-08-30 martijn return ptr;
230 4f29629b 2020-08-30 martijn return optional ? start : NULL;
231 4f29629b 2020-08-30 martijn }
232 4f29629b 2020-08-30 martijn
233 4f29629b 2020-08-30 martijn char *
234 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_comment(char *ptr, int optional)
235 4f29629b 2020-08-30 martijn {
236 4f29629b 2020-08-30 martijn char *start = ptr;
237 4f29629b 2020-08-30 martijn
238 4f29629b 2020-08-30 martijn if (ptr++[0] != '(')
239 4f29629b 2020-08-30 martijn return optional ? start : NULL;
240 4f29629b 2020-08-30 martijn while (1) {
241 4f29629b 2020-08-30 martijn ptr = osmtpd_mheader_skip_fws(ptr, 1);
242 4f29629b 2020-08-30 martijn if (ptr[0] == ')')
243 4f29629b 2020-08-30 martijn return ptr + 1;
244 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_ccontent(ptr, 0)) == NULL)
245 4f29629b 2020-08-30 martijn return optional ? start : NULL;
246 4f29629b 2020-08-30 martijn }
247 4f29629b 2020-08-30 martijn }
248 4f29629b 2020-08-30 martijn
249 4f29629b 2020-08-30 martijn char *
250 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_cfws(char *ptr, int optional)
251 4f29629b 2020-08-30 martijn {
252 4f29629b 2020-08-30 martijn char *start = ptr, *prev;
253 4f29629b 2020-08-30 martijn
254 4f29629b 2020-08-30 martijn while (1) {
255 4f29629b 2020-08-30 martijn ptr = osmtpd_mheader_skip_fws(ptr, 1);
256 4f29629b 2020-08-30 martijn prev = ptr;
257 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_comment(ptr, 0)) == NULL) {
258 4f29629b 2020-08-30 martijn ptr = prev;
259 4f29629b 2020-08-30 martijn break;
260 4f29629b 2020-08-30 martijn }
261 4f29629b 2020-08-30 martijn }
262 4f29629b 2020-08-30 martijn return ptr == start && !optional ? NULL : ptr;
263 4f29629b 2020-08-30 martijn }
264 4f29629b 2020-08-30 martijn
265 4f29629b 2020-08-30 martijn char *
266 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_atext(char *ptr, int optional)
267 4f29629b 2020-08-30 martijn {
268 4f29629b 2020-08-30 martijn char *start = ptr;
269 4f29629b 2020-08-30 martijn
270 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_alpha(start, 0)) != NULL ||
271 4f29629b 2020-08-30 martijn (ptr = osmtpd_mheader_skip_digit(start, 0)) != NULL)
272 4f29629b 2020-08-30 martijn return ptr;
273 4f29629b 2020-08-30 martijn ptr = start;
274 4f29629b 2020-08-30 martijn if (ptr[0] == '!' || ptr[0] == '#' || ptr[0] == '$' || ptr[0] == '%' ||
275 4f29629b 2020-08-30 martijn ptr[0] == '&' || ptr[0] == '\'' || ptr[0] == '*' || ptr[0] == '+' ||
276 4f29629b 2020-08-30 martijn ptr[0] == '-' || ptr[0] == '/' || ptr[0] == '=' || ptr[0] == '?' ||
277 4f29629b 2020-08-30 martijn ptr[0] == '^' || ptr[0] == '_' || ptr[0] == '`' || ptr[0] == '{' ||
278 4f29629b 2020-08-30 martijn ptr[0] == '|' || ptr[0] == '}' || ptr[0] == '~')
279 4f29629b 2020-08-30 martijn return ptr + 1;
280 4f29629b 2020-08-30 martijn return optional ? start : NULL;
281 4f29629b 2020-08-30 martijn }
282 4f29629b 2020-08-30 martijn
283 4f29629b 2020-08-30 martijn char *
284 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_atom(char *ptr, int optional)
285 4f29629b 2020-08-30 martijn {
286 4f29629b 2020-08-30 martijn char *start = ptr, *prev;
287 4f29629b 2020-08-30 martijn
288 4f29629b 2020-08-30 martijn ptr = osmtpd_mheader_skip_cfws(ptr, 1);
289 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_atext(ptr, 0)) == NULL)
290 4f29629b 2020-08-30 martijn return optional ? start : NULL;
291 4f29629b 2020-08-30 martijn do {
292 4f29629b 2020-08-30 martijn prev = ptr;
293 4f29629b 2020-08-30 martijn ptr = osmtpd_mheader_skip_atext(ptr, 1);
294 4f29629b 2020-08-30 martijn } while (prev != ptr);
295 4f29629b 2020-08-30 martijn return osmtpd_mheader_skip_cfws(ptr, 1);
296 4f29629b 2020-08-30 martijn }
297 4f29629b 2020-08-30 martijn
298 4f29629b 2020-08-30 martijn char *
299 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_dot_atom_text(char *ptr, int optional)
300 4f29629b 2020-08-30 martijn {
301 4f29629b 2020-08-30 martijn char *start = ptr, *prev;
302 4f29629b 2020-08-30 martijn
303 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_atext(ptr, 0)) == NULL)
304 4f29629b 2020-08-30 martijn return optional ? start : NULL;
305 4f29629b 2020-08-30 martijn do {
306 4f29629b 2020-08-30 martijn prev = ptr;
307 4f29629b 2020-08-30 martijn ptr = osmtpd_mheader_skip_atext(ptr, 1);
308 4f29629b 2020-08-30 martijn } while (ptr != prev);
309 4f29629b 2020-08-30 martijn
310 4f29629b 2020-08-30 martijn while (ptr[0] == '.') {
311 4f29629b 2020-08-30 martijn ptr++;
312 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_atext(ptr, 0)) == NULL)
313 4f29629b 2020-08-30 martijn return prev;
314 4f29629b 2020-08-30 martijn do {
315 4f29629b 2020-08-30 martijn prev = ptr;
316 4f29629b 2020-08-30 martijn ptr = osmtpd_mheader_skip_atext(ptr, 1);
317 4f29629b 2020-08-30 martijn } while (ptr != prev);
318 4f29629b 2020-08-30 martijn }
319 4f29629b 2020-08-30 martijn return ptr;
320 4f29629b 2020-08-30 martijn }
321 4f29629b 2020-08-30 martijn
322 4f29629b 2020-08-30 martijn char *
323 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_dot_atom(char *ptr, int optional)
324 4f29629b 2020-08-30 martijn {
325 4f29629b 2020-08-30 martijn char *start = ptr;
326 4f29629b 2020-08-30 martijn
327 4f29629b 2020-08-30 martijn ptr = osmtpd_mheader_skip_cfws(ptr, 1);
328 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_dot_atom_text(ptr, 0)) == NULL)
329 4f29629b 2020-08-30 martijn return optional ? start : NULL;
330 4f29629b 2020-08-30 martijn return osmtpd_mheader_skip_cfws(ptr, 1);
331 4f29629b 2020-08-30 martijn }
332 4f29629b 2020-08-30 martijn
333 4f29629b 2020-08-30 martijn
334 4f29629b 2020-08-30 martijn char *
335 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_obs_qtext(char *ptr, int optional)
336 4f29629b 2020-08-30 martijn {
337 4f29629b 2020-08-30 martijn return osmtpd_mheader_skip_obs_no_ws_ctl(ptr, optional);
338 4f29629b 2020-08-30 martijn }
339 4f29629b 2020-08-30 martijn
340 4f29629b 2020-08-30 martijn char *
341 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_qtext(char *ptr, int optional)
342 4f29629b 2020-08-30 martijn {
343 4f29629b 2020-08-30 martijn char *start = ptr;
344 4f29629b 2020-08-30 martijn
345 4f29629b 2020-08-30 martijn if (ptr[0] == 33 || (ptr[0] >= 35 && ptr[0] <= 91) ||
346 4f29629b 2020-08-30 martijn (ptr[0] >= 93 && ptr[0] <= 126))
347 4f29629b 2020-08-30 martijn return ptr + 1;
348 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_obs_qtext(ptr, 0)) != NULL)
349 4f29629b 2020-08-30 martijn return ptr;
350 4f29629b 2020-08-30 martijn return optional ? start : NULL;
351 4f29629b 2020-08-30 martijn }
352 4f29629b 2020-08-30 martijn
353 4f29629b 2020-08-30 martijn char *
354 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_qcontent(char *ptr, int optional)
355 4f29629b 2020-08-30 martijn {
356 4f29629b 2020-08-30 martijn char *start = ptr;
357 4f29629b 2020-08-30 martijn
358 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_qtext(ptr, 0)) != NULL)
359 4f29629b 2020-08-30 martijn return ptr;
360 4f29629b 2020-08-30 martijn return osmtpd_mheader_skip_quoted_pair(start, optional);
361 4f29629b 2020-08-30 martijn }
362 4f29629b 2020-08-30 martijn
363 4f29629b 2020-08-30 martijn char *
364 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_quoted_string(char *ptr, int optional)
365 4f29629b 2020-08-30 martijn {
366 4f29629b 2020-08-30 martijn char *start = ptr, *prev;
367 4f29629b 2020-08-30 martijn
368 4f29629b 2020-08-30 martijn ptr = osmtpd_mheader_skip_cfws(ptr, 1);
369 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_dquote(ptr, 0)) == NULL)
370 4f29629b 2020-08-30 martijn return optional ? start : NULL;
371 4f29629b 2020-08-30 martijn prev = ptr;
372 4f29629b 2020-08-30 martijn while (1) {
373 4f29629b 2020-08-30 martijn ptr = osmtpd_mheader_skip_fws(ptr, 1);
374 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_qcontent(ptr, 0)) == NULL)
375 4f29629b 2020-08-30 martijn break;
376 4f29629b 2020-08-30 martijn prev = ptr;
377 4f29629b 2020-08-30 martijn }
378 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_dquote(prev, 0)) == NULL)
379 4f29629b 2020-08-30 martijn return optional ? start : NULL;
380 4f29629b 2020-08-30 martijn return osmtpd_mheader_skip_cfws(ptr, 1);
381 4f29629b 2020-08-30 martijn }
382 4f29629b 2020-08-30 martijn
383 4f29629b 2020-08-30 martijn char *
384 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_word(char *ptr, int optional)
385 4f29629b 2020-08-30 martijn {
386 4f29629b 2020-08-30 martijn char *start = ptr;
387 4f29629b 2020-08-30 martijn
388 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_atom(ptr, 0)) != NULL)
389 4f29629b 2020-08-30 martijn return ptr;
390 4f29629b 2020-08-30 martijn return osmtpd_mheader_skip_quoted_string(start, optional);
391 4f29629b 2020-08-30 martijn }
392 4f29629b 2020-08-30 martijn
393 4f29629b 2020-08-30 martijn char *
394 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_obs_phrase(char *ptr, int optional)
395 4f29629b 2020-08-30 martijn {
396 4f29629b 2020-08-30 martijn char *start = ptr, *prev;
397 4f29629b 2020-08-30 martijn
398 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_word(ptr, 0)) == NULL)
399 4f29629b 2020-08-30 martijn return optional ? start : NULL;
400 4f29629b 2020-08-30 martijn while (1) {
401 4f29629b 2020-08-30 martijn prev = ptr;
402 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_word(ptr, 0)) != NULL)
403 4f29629b 2020-08-30 martijn continue;
404 4f29629b 2020-08-30 martijn ptr = prev;
405 4f29629b 2020-08-30 martijn if (ptr[0] == '.')
406 4f29629b 2020-08-30 martijn continue;
407 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_cfws(ptr, 0)) != NULL)
408 4f29629b 2020-08-30 martijn continue;
409 4f29629b 2020-08-30 martijn return prev;
410 4f29629b 2020-08-30 martijn }
411 4f29629b 2020-08-30 martijn }
412 4f29629b 2020-08-30 martijn
413 4f29629b 2020-08-30 martijn char *
414 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_phrase(char *ptr, int optional)
415 4f29629b 2020-08-30 martijn {
416 4f29629b 2020-08-30 martijn /* obs-phrase is a superset of phrae */
417 4f29629b 2020-08-30 martijn return osmtpd_mheader_skip_obs_phrase(ptr, optional);
418 4f29629b 2020-08-30 martijn #if 0
419 4f29629b 2020-08-30 martijn char *start = ptr, *prev;
420 4f29629b 2020-08-30 martijn
421 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_word(ptr, 0)) == NULL)
422 4f29629b 2020-08-30 martijn return optional ? start : NULL;
423 4f29629b 2020-08-30 martijn while (1) {
424 4f29629b 2020-08-30 martijn prev = ptr;
425 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_word(ptr, 0)) == NULL)
426 4f29629b 2020-08-30 martijn return prev;
427 4f29629b 2020-08-30 martijn }
428 4f29629b 2020-08-30 martijn #endif
429 4f29629b 2020-08-30 martijn }
430 4f29629b 2020-08-30 martijn
431 4f29629b 2020-08-30 martijn char *
432 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_obs_local_part(char *ptr, int optional)
433 4f29629b 2020-08-30 martijn {
434 4f29629b 2020-08-30 martijn char *start = ptr, *prev;
435 4f29629b 2020-08-30 martijn
436 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_word(ptr, 0)) == NULL)
437 4f29629b 2020-08-30 martijn return optional ? start : NULL;
438 4f29629b 2020-08-30 martijn prev = ptr;
439 4f29629b 2020-08-30 martijn while (ptr[0] == '.') {
440 4f29629b 2020-08-30 martijn ptr++;
441 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_word(ptr, 0)) == NULL)
442 4f29629b 2020-08-30 martijn return prev;
443 4f29629b 2020-08-30 martijn prev = ptr;
444 4f29629b 2020-08-30 martijn }
445 4f29629b 2020-08-30 martijn return ptr;
446 4f29629b 2020-08-30 martijn }
447 4f29629b 2020-08-30 martijn
448 4f29629b 2020-08-30 martijn char *
449 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_local_part(char *ptr, int optional)
450 4f29629b 2020-08-30 martijn {
451 4f29629b 2020-08-30 martijn char *start = ptr;
452 4f29629b 2020-08-30 martijn
453 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_dot_atom(ptr, 0)) != NULL)
454 4f29629b 2020-08-30 martijn return ptr;
455 4f29629b 2020-08-30 martijn ptr = start;
456 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_quoted_string(ptr, 0)) != NULL)
457 4f29629b 2020-08-30 martijn return ptr;
458 4f29629b 2020-08-30 martijn return osmtpd_mheader_skip_obs_local_part(start, optional);
459 4f29629b 2020-08-30 martijn }
460 4f29629b 2020-08-30 martijn
461 4f29629b 2020-08-30 martijn char *
462 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_obs_dtext(char *ptr, int optional)
463 4f29629b 2020-08-30 martijn {
464 4f29629b 2020-08-30 martijn char *start = ptr;
465 4f29629b 2020-08-30 martijn
466 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_obs_no_ws_ctl(ptr, 0)) != NULL)
467 4f29629b 2020-08-30 martijn return ptr;
468 4f29629b 2020-08-30 martijn return osmtpd_mheader_skip_quoted_pair(start, optional);
469 4f29629b 2020-08-30 martijn }
470 4f29629b 2020-08-30 martijn
471 4f29629b 2020-08-30 martijn char *
472 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_dtext(char *ptr, int optional)
473 4f29629b 2020-08-30 martijn {
474 4f29629b 2020-08-30 martijn if ((ptr[0] >= 33 && ptr[0] <= 90) || (ptr[0] >= 94 && ptr[0] <= 126))
475 4f29629b 2020-08-30 martijn return ptr + 1;
476 4f29629b 2020-08-30 martijn return osmtpd_mheader_skip_obs_dtext(ptr, optional);
477 4f29629b 2020-08-30 martijn
478 4f29629b 2020-08-30 martijn }
479 4f29629b 2020-08-30 martijn
480 4f29629b 2020-08-30 martijn char *
481 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_domain_literal(char *ptr, int optional)
482 4f29629b 2020-08-30 martijn {
483 4f29629b 2020-08-30 martijn char *start = ptr, *prev;
484 4f29629b 2020-08-30 martijn
485 4f29629b 2020-08-30 martijn ptr = osmtpd_mheader_skip_cfws(ptr, 1);
486 4f29629b 2020-08-30 martijn if (ptr++[0] != '[')
487 4f29629b 2020-08-30 martijn return optional ? start : NULL;
488 4f29629b 2020-08-30 martijn while (1) {
489 4f29629b 2020-08-30 martijn ptr = osmtpd_mheader_skip_fws(ptr, 1);
490 4f29629b 2020-08-30 martijn prev = ptr;
491 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_dtext(ptr, 0)) == NULL) {
492 4f29629b 2020-08-30 martijn ptr = prev;
493 4f29629b 2020-08-30 martijn break;
494 4f29629b 2020-08-30 martijn }
495 4f29629b 2020-08-30 martijn }
496 4f29629b 2020-08-30 martijn if (ptr[0] != ']')
497 4f29629b 2020-08-30 martijn return optional ? start : NULL;
498 4f29629b 2020-08-30 martijn return osmtpd_mheader_skip_cfws(ptr, 1);
499 4f29629b 2020-08-30 martijn }
500 4f29629b 2020-08-30 martijn
501 4f29629b 2020-08-30 martijn char *
502 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_obs_domain(char *ptr, int optional)
503 4f29629b 2020-08-30 martijn {
504 4f29629b 2020-08-30 martijn char *start = ptr, *prev;
505 4f29629b 2020-08-30 martijn
506 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_atom(ptr, 0)) == NULL)
507 4f29629b 2020-08-30 martijn return optional ? start : NULL;
508 4f29629b 2020-08-30 martijn prev = ptr;
509 4f29629b 2020-08-30 martijn while (1) {
510 4f29629b 2020-08-30 martijn if (ptr++[0] != '.')
511 4f29629b 2020-08-30 martijn return prev;
512 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_atom(ptr, 0)) == NULL)
513 4f29629b 2020-08-30 martijn return prev;
514 4f29629b 2020-08-30 martijn prev = ptr;
515 4f29629b 2020-08-30 martijn }
516 4f29629b 2020-08-30 martijn }
517 4f29629b 2020-08-30 martijn
518 4f29629b 2020-08-30 martijn char *
519 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_domain(char *ptr, int optional)
520 4f29629b 2020-08-30 martijn {
521 4f29629b 2020-08-30 martijn char *start = ptr;
522 4f29629b 2020-08-30 martijn
523 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_dot_atom(start, 0)) != NULL)
524 4f29629b 2020-08-30 martijn return ptr;
525 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_domain_literal(start, 0)) != NULL)
526 4f29629b 2020-08-30 martijn return ptr;
527 4f29629b 2020-08-30 martijn return osmtpd_mheader_skip_obs_domain(start, optional);
528 4f29629b 2020-08-30 martijn }
529 4f29629b 2020-08-30 martijn
530 4f29629b 2020-08-30 martijn char *
531 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_display_name(char *ptr, int optional)
532 4f29629b 2020-08-30 martijn {
533 4f29629b 2020-08-30 martijn return osmtpd_mheader_skip_phrase(ptr, optional);
534 4f29629b 2020-08-30 martijn }
535 4f29629b 2020-08-30 martijn
536 4f29629b 2020-08-30 martijn char *
537 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_obs_domain_list(char *ptr, int optional)
538 4f29629b 2020-08-30 martijn {
539 4f29629b 2020-08-30 martijn char *start = ptr, *prev;
540 4f29629b 2020-08-30 martijn
541 4f29629b 2020-08-30 martijn while (1) {
542 4f29629b 2020-08-30 martijn if (ptr[0] == ',') {
543 4f29629b 2020-08-30 martijn ptr++;
544 4f29629b 2020-08-30 martijn prev = ptr;
545 4f29629b 2020-08-30 martijn continue;
546 4f29629b 2020-08-30 martijn } else if ((ptr = osmtpd_mheader_skip_cfws(ptr, 0)) != NULL) {
547 4f29629b 2020-08-30 martijn prev = ptr;
548 4f29629b 2020-08-30 martijn continue;
549 4f29629b 2020-08-30 martijn }
550 4f29629b 2020-08-30 martijn break;
551 4f29629b 2020-08-30 martijn }
552 4f29629b 2020-08-30 martijn ptr = prev;
553 4f29629b 2020-08-30 martijn
554 4f29629b 2020-08-30 martijn if (ptr++[0] != '@')
555 4f29629b 2020-08-30 martijn return optional ? start : NULL;
556 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_domain(ptr, 0)) == NULL)
557 4f29629b 2020-08-30 martijn return optional ? start : NULL;
558 4f29629b 2020-08-30 martijn while (1) {
559 4f29629b 2020-08-30 martijn if (ptr[0] != ',')
560 4f29629b 2020-08-30 martijn break;
561 4f29629b 2020-08-30 martijn ptr++;
562 4f29629b 2020-08-30 martijn ptr = osmtpd_mheader_skip_cfws(ptr, 1);
563 4f29629b 2020-08-30 martijn if (ptr[0] != '@')
564 4f29629b 2020-08-30 martijn continue;
565 4f29629b 2020-08-30 martijn prev = ptr;
566 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_domain(ptr + 1, 0)) == NULL) {
567 4f29629b 2020-08-30 martijn ptr = prev;
568 4f29629b 2020-08-30 martijn break;
569 4f29629b 2020-08-30 martijn }
570 4f29629b 2020-08-30 martijn }
571 4f29629b 2020-08-30 martijn return ptr;
572 4f29629b 2020-08-30 martijn }
573 4f29629b 2020-08-30 martijn
574 4f29629b 2020-08-30 martijn char *
575 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_obs_route(char *ptr, int optional)
576 4f29629b 2020-08-30 martijn {
577 4f29629b 2020-08-30 martijn char *start = ptr;
578 4f29629b 2020-08-30 martijn
579 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_obs_domain_list(ptr, 0)) == NULL)
580 4f29629b 2020-08-30 martijn return optional ? start : NULL;
581 4f29629b 2020-08-30 martijn if (ptr++[0] != ':')
582 4f29629b 2020-08-30 martijn return optional ? start : NULL;
583 4f29629b 2020-08-30 martijn return ptr;
584 4f29629b 2020-08-30 martijn }
585 4f29629b 2020-08-30 martijn
586 4f29629b 2020-08-30 martijn char *
587 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_addr_spec(char *ptr, int optional)
588 4f29629b 2020-08-30 martijn {
589 4f29629b 2020-08-30 martijn char *start = ptr;
590 4f29629b 2020-08-30 martijn
591 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_local_part(ptr, 0)) == NULL)
592 4f29629b 2020-08-30 martijn return optional ? start : NULL;
593 4f29629b 2020-08-30 martijn if (ptr++[0] != '@')
594 4f29629b 2020-08-30 martijn return optional ? start : NULL;
595 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_domain(ptr, 0)) == NULL)
596 4f29629b 2020-08-30 martijn return optional ? start : NULL;
597 4f29629b 2020-08-30 martijn return ptr;
598 4f29629b 2020-08-30 martijn }
599 4f29629b 2020-08-30 martijn
600 4f29629b 2020-08-30 martijn char *
601 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_obs_angle_addr(char *ptr, int optional)
602 4f29629b 2020-08-30 martijn {
603 4f29629b 2020-08-30 martijn char *start = ptr;
604 4f29629b 2020-08-30 martijn
605 4f29629b 2020-08-30 martijn ptr = osmtpd_mheader_skip_cfws(ptr, 1);
606 4f29629b 2020-08-30 martijn if (ptr++[0] != '<')
607 4f29629b 2020-08-30 martijn return optional ? start : NULL;
608 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_obs_route(ptr, 0)) == NULL)
609 4f29629b 2020-08-30 martijn return optional ? start : NULL;
610 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_addr_spec(ptr, 0)) == NULL)
611 4f29629b 2020-08-30 martijn return optional ? start : NULL;
612 4f29629b 2020-08-30 martijn if (ptr++[0] != '>')
613 4f29629b 2020-08-30 martijn return optional ? start : NULL;
614 4f29629b 2020-08-30 martijn return osmtpd_mheader_skip_cfws(ptr, 1);
615 4f29629b 2020-08-30 martijn }
616 4f29629b 2020-08-30 martijn
617 4f29629b 2020-08-30 martijn char *
618 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_angle_addr(char *ptr, int optional)
619 4f29629b 2020-08-30 martijn {
620 4f29629b 2020-08-30 martijn char *start = ptr;
621 4f29629b 2020-08-30 martijn
622 4f29629b 2020-08-30 martijn ptr = osmtpd_mheader_skip_cfws(ptr, 1);
623 4f29629b 2020-08-30 martijn if (ptr++[0] != '<')
624 4f29629b 2020-08-30 martijn return osmtpd_mheader_skip_obs_angle_addr(start, optional);
625 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_addr_spec(ptr, 0)) == NULL)
626 4f29629b 2020-08-30 martijn return osmtpd_mheader_skip_obs_angle_addr(start, optional);
627 4f29629b 2020-08-30 martijn if (ptr++[0] != '>')
628 4f29629b 2020-08-30 martijn return osmtpd_mheader_skip_obs_angle_addr(start, optional);
629 4f29629b 2020-08-30 martijn return osmtpd_mheader_skip_cfws(ptr, 1);
630 4f29629b 2020-08-30 martijn }
631 4f29629b 2020-08-30 martijn
632 4f29629b 2020-08-30 martijn char *
633 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_name_addr(char *ptr, int optional)
634 4f29629b 2020-08-30 martijn {
635 4f29629b 2020-08-30 martijn char *start = ptr;
636 4f29629b 2020-08-30 martijn
637 4f29629b 2020-08-30 martijn ptr = osmtpd_mheader_skip_display_name(ptr, 1);
638 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_angle_addr(ptr, 0)) == NULL)
639 4f29629b 2020-08-30 martijn return optional ? start : NULL;
640 4f29629b 2020-08-30 martijn return ptr;
641 4f29629b 2020-08-30 martijn }
642 4f29629b 2020-08-30 martijn
643 4f29629b 2020-08-30 martijn /* RFC 2045 */
644 4f29629b 2020-08-30 martijn char *
645 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_tspecials(char *ptr, int optional)
646 4f29629b 2020-08-30 martijn {
647 4f29629b 2020-08-30 martijn if (ptr[0] == '(' || ptr[0] == ')' || ptr[0] == '<' || ptr[0] == '>' ||
648 4f29629b 2020-08-30 martijn ptr[0] == '@' || ptr[0] == ',' || ptr[0] == ';' || ptr[0] == ':' ||
649 4f29629b 2020-08-30 martijn ptr[0] == '\\' || ptr[0] == '\'' || ptr[0] == '/' ||
650 4f29629b 2020-08-30 martijn ptr[0] == '[' || ptr[0] == ']' || ptr[0] == '?' || ptr[0] == '=')
651 4f29629b 2020-08-30 martijn return ptr + 1;
652 4f29629b 2020-08-30 martijn return optional ? ptr : NULL;
653 4f29629b 2020-08-30 martijn
654 4f29629b 2020-08-30 martijn }
655 4f29629b 2020-08-30 martijn
656 4f29629b 2020-08-30 martijn char *
657 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_token(char *ptr, int optional)
658 4f29629b 2020-08-30 martijn {
659 4f29629b 2020-08-30 martijn if (osmtpd_mheader_skip_char(ptr, 0) == NULL)
660 4f29629b 2020-08-30 martijn return optional ? ptr : NULL;
661 4f29629b 2020-08-30 martijn /* Can't find the official definition for SPACE, so use WSP */
662 4f29629b 2020-08-30 martijn if (osmtpd_mheader_skip_wsp(ptr, 0) != NULL)
663 4f29629b 2020-08-30 martijn return optional ? ptr : NULL;
664 4f29629b 2020-08-30 martijn if (osmtpd_mheader_skip_ctl(ptr, 0) != NULL)
665 4f29629b 2020-08-30 martijn return optional ? ptr : NULL;
666 4f29629b 2020-08-30 martijn if (osmtpd_mheader_skip_tspecials(ptr, 0) != NULL)
667 4f29629b 2020-08-30 martijn return optional ? ptr : NULL;
668 4f29629b 2020-08-30 martijn ptr++;
669 4f29629b 2020-08-30 martijn while (1) {
670 4f29629b 2020-08-30 martijn if (osmtpd_mheader_skip_char(ptr, 0) == NULL)
671 4f29629b 2020-08-30 martijn return ptr;
672 4f29629b 2020-08-30 martijn if (osmtpd_mheader_skip_wsp(ptr, 0) != NULL)
673 4f29629b 2020-08-30 martijn return ptr;
674 4f29629b 2020-08-30 martijn if (osmtpd_mheader_skip_ctl(ptr, 0) != NULL)
675 4f29629b 2020-08-30 martijn return ptr;
676 4f29629b 2020-08-30 martijn if (osmtpd_mheader_skip_tspecials(ptr, 0) != NULL)
677 4f29629b 2020-08-30 martijn return ptr;
678 4f29629b 2020-08-30 martijn ptr++;
679 4f29629b 2020-08-30 martijn }
680 4f29629b 2020-08-30 martijn }
681 4f29629b 2020-08-30 martijn
682 4f29629b 2020-08-30 martijn char *
683 4f29629b 2020-08-30 martijn osmtpd_mheader_skip_value(char *ptr, int optional)
684 4f29629b 2020-08-30 martijn {
685 4f29629b 2020-08-30 martijn char *start = ptr;
686 4f29629b 2020-08-30 martijn
687 4f29629b 2020-08-30 martijn if ((ptr = osmtpd_mheader_skip_token(ptr, 0)) == NULL)
688 4f29629b 2020-08-30 martijn return osmtpd_mheader_skip_quoted_string(start, optional);
689 4f29629b 2020-08-30 martijn return ptr;
690 4f29629b 2020-08-30 martijn }
691 4f29629b 2020-08-30 martijn
692 4f29629b 2020-08-30 martijn /* Return the domain component of the first mailbox */
693 4f29629b 2020-08-30 martijn char *
694 4f29629b 2020-08-30 martijn osmtpd_mheader_from_domain(char *ptr)
695 4f29629b 2020-08-30 martijn {
696 4f29629b 2020-08-30 martijn char *tmp;
697 4f29629b 2020-08-30 martijn
698 4f29629b 2020-08-30 martijn /* from */
699 4f29629b 2020-08-30 martijn if (strncasecmp(ptr, "from:", 5) == 0) {
700 4f29629b 2020-08-30 martijn ptr += 5;
701 4f29629b 2020-08-30 martijn /* obs-from */
702 4f29629b 2020-08-30 martijn } else if (strncasecmp(ptr, "from", 4) == 0) {
703 4f29629b 2020-08-30 martijn ptr += 4;
704 4f29629b 2020-08-30 martijn do {
705 4f29629b 2020-08-30 martijn tmp = ptr;
706 4f29629b 2020-08-30 martijn } while ((ptr = osmtpd_mheader_skip_wsp(ptr, 0)) != NULL);
707 4f29629b 2020-08-30 martijn ptr = tmp;
708 4f29629b 2020-08-30 martijn if (ptr++[0] != ':')
709 4f29629b 2020-08-30 martijn return NULL;
710 4f29629b 2020-08-30 martijn } else {
711 4f29629b 2020-08-30 martijn errno = EINVAL;
712 4f29629b 2020-08-30 martijn return NULL;
713 4f29629b 2020-08-30 martijn }
714 4f29629b 2020-08-30 martijn
715 4f29629b 2020-08-30 martijn /* Both from and obs-from use Mailbox-list CRLF */
716 4f29629b 2020-08-30 martijn /* obs-mbox-list has just a prefix compared to mailbox-list */
717 4f29629b 2020-08-30 martijn while (1) {
718 4f29629b 2020-08-30 martijn tmp = ptr;
719 4f29629b 2020-08-30 martijn ptr = osmtpd_mheader_skip_cfws(ptr, 1);
720 4f29629b 2020-08-30 martijn if (ptr++[0] != ',') {
721 4f29629b 2020-08-30 martijn ptr = tmp;
722 4f29629b 2020-08-30 martijn break;
723 4f29629b 2020-08-30 martijn }
724 4f29629b 2020-08-30 martijn }
725 4f29629b 2020-08-30 martijn /* We're only interested in the first mailbox */
726 4f29629b 2020-08-30 martijn if (osmtpd_mheader_skip_name_addr(ptr, 0) != NULL) {
727 4f29629b 2020-08-30 martijn ptr = osmtpd_mheader_skip_display_name(ptr, 1);
728 4f29629b 2020-08-30 martijn ptr = osmtpd_mheader_skip_cfws(ptr, 1);
729 4f29629b 2020-08-30 martijn /* < */
730 4f29629b 2020-08-30 martijn ptr++;
731 4f29629b 2020-08-30 martijn /* addr-spec */
732 4f29629b 2020-08-30 martijn ptr = osmtpd_mheader_skip_local_part(ptr, 0);
733 4f29629b 2020-08-30 martijn /* @ */
734 4f29629b 2020-08-30 martijn ptr++;
735 4f29629b 2020-08-30 martijn tmp = osmtpd_mheader_skip_domain(ptr, 0);
736 4f29629b 2020-08-30 martijn return strndup(ptr, tmp - ptr);
737 4f29629b 2020-08-30 martijn }
738 4f29629b 2020-08-30 martijn if (osmtpd_mheader_skip_addr_spec(ptr, 0) != NULL) {
739 4f29629b 2020-08-30 martijn ptr = osmtpd_mheader_skip_local_part(ptr, 0);
740 4f29629b 2020-08-30 martijn /* @ */
741 4f29629b 2020-08-30 martijn ptr++;
742 4f29629b 2020-08-30 martijn tmp = osmtpd_mheader_skip_domain(ptr, 0);
743 4f29629b 2020-08-30 martijn return strndup(ptr, tmp - ptr);
744 4f29629b 2020-08-30 martijn }
745 4f29629b 2020-08-30 martijn errno = EINVAL;
746 4f29629b 2020-08-30 martijn return NULL;
747 4f29629b 2020-08-30 martijn }