Blame


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