Mercurial > hg > nginx-quic
annotate src/mail/ngx_mail_parse.c @ 8270:c57b6fc90f90 quic
QUIC: fixed header protection macro name.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Wed, 30 Dec 2020 20:47:35 +0300 |
parents | bcb107bb89cd |
children | 6a81d96d3733 |
rev | line source |
---|---|
441
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1 |
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
2 /* |
444
42d11f017717
nginx-0.1.0-2004-09-29-20:00:49 import; remove years from copyright
Igor Sysoev <igor@sysoev.ru>
parents:
441
diff
changeset
|
3 * Copyright (C) Igor Sysoev |
4412 | 4 * Copyright (C) Nginx, Inc. |
441
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
5 */ |
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
6 |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
7 |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
8 #include <ngx_config.h> |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
9 #include <ngx_core.h> |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
10 #include <ngx_event.h> |
1136 | 11 #include <ngx_mail.h> |
4759
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
12 #include <ngx_mail_pop3_module.h> |
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
13 #include <ngx_mail_imap_module.h> |
4c36e15651f7
Fixed compilation with -Wmissing-prototypes.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
14 #include <ngx_mail_smtp_module.h> |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
15 |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
16 |
1477 | 17 ngx_int_t |
18 ngx_mail_pop3_parse_command(ngx_mail_session_t *s) | |
1136 | 19 { |
20 u_char ch, *p, *c, c0, c1, c2, c3; | |
21 ngx_str_t *arg; | |
22 enum { | |
23 sw_start = 0, | |
24 sw_spaces_before_argument, | |
25 sw_argument, | |
26 sw_almost_done | |
27 } state; | |
28 | |
29 state = s->state; | |
30 | |
31 for (p = s->buffer->pos; p < s->buffer->last; p++) { | |
32 ch = *p; | |
33 | |
34 switch (state) { | |
35 | |
36 /* POP3 command */ | |
37 case sw_start: | |
38 if (ch == ' ' || ch == CR || ch == LF) { | |
39 c = s->buffer->start; | |
40 | |
41 if (p - c == 4) { | |
42 | |
43 c0 = ngx_toupper(c[0]); | |
44 c1 = ngx_toupper(c[1]); | |
45 c2 = ngx_toupper(c[2]); | |
46 c3 = ngx_toupper(c[3]); | |
47 | |
48 if (c0 == 'U' && c1 == 'S' && c2 == 'E' && c3 == 'R') | |
49 { | |
50 s->command = NGX_POP3_USER; | |
51 | |
52 } else if (c0 == 'P' && c1 == 'A' && c2 == 'S' && c3 == 'S') | |
53 { | |
54 s->command = NGX_POP3_PASS; | |
55 | |
56 } else if (c0 == 'A' && c1 == 'P' && c2 == 'O' && c3 == 'P') | |
57 { | |
58 s->command = NGX_POP3_APOP; | |
59 | |
60 } else if (c0 == 'Q' && c1 == 'U' && c2 == 'I' && c3 == 'T') | |
61 { | |
62 s->command = NGX_POP3_QUIT; | |
63 | |
64 } else if (c0 == 'C' && c1 == 'A' && c2 == 'P' && c3 == 'A') | |
65 { | |
66 s->command = NGX_POP3_CAPA; | |
67 | |
68 } else if (c0 == 'A' && c1 == 'U' && c2 == 'T' && c3 == 'H') | |
69 { | |
70 s->command = NGX_POP3_AUTH; | |
71 | |
72 } else if (c0 == 'N' && c1 == 'O' && c2 == 'O' && c3 == 'P') | |
73 { | |
74 s->command = NGX_POP3_NOOP; | |
75 #if (NGX_MAIL_SSL) | |
76 } else if (c0 == 'S' && c1 == 'T' && c2 == 'L' && c3 == 'S') | |
77 { | |
78 s->command = NGX_POP3_STLS; | |
79 #endif | |
80 } else { | |
81 goto invalid; | |
82 } | |
83 | |
84 } else { | |
85 goto invalid; | |
86 } | |
87 | |
88 switch (ch) { | |
89 case ' ': | |
90 state = sw_spaces_before_argument; | |
91 break; | |
92 case CR: | |
93 state = sw_almost_done; | |
94 break; | |
95 case LF: | |
96 goto done; | |
97 } | |
98 break; | |
99 } | |
100 | |
101 if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) { | |
102 goto invalid; | |
103 } | |
104 | |
105 break; | |
106 | |
107 case sw_spaces_before_argument: | |
108 switch (ch) { | |
109 case ' ': | |
110 break; | |
111 case CR: | |
112 state = sw_almost_done; | |
113 s->arg_end = p; | |
114 break; | |
115 case LF: | |
116 s->arg_end = p; | |
117 goto done; | |
118 default: | |
119 if (s->args.nelts <= 2) { | |
120 state = sw_argument; | |
121 s->arg_start = p; | |
122 break; | |
123 } | |
124 goto invalid; | |
125 } | |
126 break; | |
127 | |
128 case sw_argument: | |
129 switch (ch) { | |
130 | |
131 case ' ': | |
132 | |
133 /* | |
134 * the space should be considered as part of the at username | |
135 * or password, but not of argument in other commands | |
136 */ | |
137 | |
138 if (s->command == NGX_POP3_USER | |
139 || s->command == NGX_POP3_PASS) | |
140 { | |
141 break; | |
142 } | |
143 | |
144 /* fall through */ | |
145 | |
146 case CR: | |
147 case LF: | |
148 arg = ngx_array_push(&s->args); | |
149 if (arg == NULL) { | |
150 return NGX_ERROR; | |
151 } | |
152 arg->len = p - s->arg_start; | |
153 arg->data = s->arg_start; | |
154 s->arg_start = NULL; | |
155 | |
156 switch (ch) { | |
157 case ' ': | |
158 state = sw_spaces_before_argument; | |
159 break; | |
160 case CR: | |
161 state = sw_almost_done; | |
162 break; | |
163 case LF: | |
164 goto done; | |
165 } | |
166 break; | |
167 | |
168 default: | |
169 break; | |
170 } | |
171 break; | |
172 | |
173 case sw_almost_done: | |
174 switch (ch) { | |
175 case LF: | |
176 goto done; | |
177 default: | |
178 goto invalid; | |
179 } | |
180 } | |
181 } | |
182 | |
183 s->buffer->pos = p; | |
184 s->state = state; | |
185 | |
186 return NGX_AGAIN; | |
187 | |
188 done: | |
189 | |
190 s->buffer->pos = p + 1; | |
191 | |
192 if (s->arg_start) { | |
193 arg = ngx_array_push(&s->args); | |
194 if (arg == NULL) { | |
195 return NGX_ERROR; | |
196 } | |
197 arg->len = s->arg_end - s->arg_start; | |
198 arg->data = s->arg_start; | |
199 s->arg_start = NULL; | |
200 } | |
201 | |
202 s->state = (s->command != NGX_POP3_AUTH) ? sw_start : sw_argument; | |
203 | |
204 return NGX_OK; | |
205 | |
206 invalid: | |
207 | |
208 s->state = sw_start; | |
209 s->arg_start = NULL; | |
210 | |
211 return NGX_MAIL_PARSE_INVALID_COMMAND; | |
212 } | |
213 | |
214 | |
1477 | 215 ngx_int_t |
216 ngx_mail_imap_parse_command(ngx_mail_session_t *s) | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
217 { |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
218 u_char ch, *p, *c; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
219 ngx_str_t *arg; |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
220 enum { |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
221 sw_start = 0, |
527 | 222 sw_spaces_before_command, |
223 sw_command, | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
224 sw_spaces_before_argument, |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
225 sw_argument, |
543 | 226 sw_backslash, |
527 | 227 sw_literal, |
543 | 228 sw_no_sync_literal_argument, |
527 | 229 sw_start_literal_argument, |
230 sw_literal_argument, | |
231 sw_end_literal_argument, | |
232 sw_almost_done | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
233 } state; |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
234 |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
235 state = s->state; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
236 |
527 | 237 for (p = s->buffer->pos; p < s->buffer->last; p++) { |
238 ch = *p; | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
239 |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
240 switch (state) { |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
241 |
527 | 242 /* IMAP tag */ |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
243 case sw_start: |
527 | 244 switch (ch) { |
245 case ' ': | |
246 s->tag.len = p - s->buffer->start + 1; | |
247 s->tag.data = s->buffer->start; | |
248 state = sw_spaces_before_command; | |
249 break; | |
250 case CR: | |
251 s->state = sw_start; | |
1136 | 252 return NGX_MAIL_PARSE_INVALID_COMMAND; |
527 | 253 case LF: |
254 s->state = sw_start; | |
1136 | 255 return NGX_MAIL_PARSE_INVALID_COMMAND; |
527 | 256 } |
257 break; | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
258 |
527 | 259 case sw_spaces_before_command: |
260 switch (ch) { | |
261 case ' ': | |
262 break; | |
263 case CR: | |
264 s->state = sw_start; | |
1136 | 265 return NGX_MAIL_PARSE_INVALID_COMMAND; |
527 | 266 case LF: |
267 s->state = sw_start; | |
1136 | 268 return NGX_MAIL_PARSE_INVALID_COMMAND; |
527 | 269 default: |
270 s->cmd_start = p; | |
271 state = sw_command; | |
272 break; | |
273 } | |
274 break; | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
275 |
527 | 276 case sw_command: |
277 if (ch == ' ' || ch == CR || ch == LF) { | |
278 | |
279 c = s->cmd_start; | |
280 | |
281 switch (p - c) { | |
282 | |
283 case 4: | |
284 if ((c[0] == 'N' || c[0] == 'n') | |
285 && (c[1] == 'O'|| c[1] == 'o') | |
286 && (c[2] == 'O'|| c[2] == 'o') | |
287 && (c[3] == 'P'|| c[3] == 'p')) | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
288 { |
527 | 289 s->command = NGX_IMAP_NOOP; |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
290 |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
291 } else { |
527 | 292 goto invalid; |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
293 } |
527 | 294 break; |
295 | |
296 case 5: | |
297 if ((c[0] == 'L'|| c[0] == 'l') | |
298 && (c[1] == 'O'|| c[1] == 'o') | |
299 && (c[2] == 'G'|| c[2] == 'g') | |
300 && (c[3] == 'I'|| c[3] == 'i') | |
301 && (c[4] == 'N'|| c[4] == 'n')) | |
302 { | |
303 s->command = NGX_IMAP_LOGIN; | |
304 | |
305 } else { | |
306 goto invalid; | |
307 } | |
308 break; | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
309 |
527 | 310 case 6: |
311 if ((c[0] == 'L'|| c[0] == 'l') | |
312 && (c[1] == 'O'|| c[1] == 'o') | |
313 && (c[2] == 'G'|| c[2] == 'g') | |
314 && (c[3] == 'O'|| c[3] == 'o') | |
315 && (c[4] == 'U'|| c[4] == 'u') | |
316 && (c[5] == 'T'|| c[5] == 't')) | |
317 { | |
318 s->command = NGX_IMAP_LOGOUT; | |
319 | |
320 } else { | |
321 goto invalid; | |
322 } | |
323 break; | |
324 | |
1136 | 325 #if (NGX_MAIL_SSL) |
583 | 326 case 8: |
327 if ((c[0] == 'S'|| c[0] == 's') | |
328 && (c[1] == 'T'|| c[1] == 't') | |
329 && (c[2] == 'A'|| c[2] == 'a') | |
330 && (c[3] == 'R'|| c[3] == 'r') | |
331 && (c[4] == 'T'|| c[4] == 't') | |
332 && (c[5] == 'T'|| c[5] == 't') | |
333 && (c[6] == 'L'|| c[6] == 'l') | |
334 && (c[7] == 'S'|| c[7] == 's')) | |
335 { | |
336 s->command = NGX_IMAP_STARTTLS; | |
337 | |
338 } else { | |
339 goto invalid; | |
340 } | |
341 break; | |
342 #endif | |
343 | |
527 | 344 case 10: |
345 if ((c[0] == 'C'|| c[0] == 'c') | |
346 && (c[1] == 'A'|| c[1] == 'a') | |
347 && (c[2] == 'P'|| c[2] == 'p') | |
348 && (c[3] == 'A'|| c[3] == 'a') | |
349 && (c[4] == 'B'|| c[4] == 'b') | |
350 && (c[5] == 'I'|| c[5] == 'i') | |
351 && (c[6] == 'L'|| c[6] == 'l') | |
352 && (c[7] == 'I'|| c[7] == 'i') | |
353 && (c[8] == 'T'|| c[8] == 't') | |
354 && (c[9] == 'Y'|| c[9] == 'y')) | |
355 { | |
356 s->command = NGX_IMAP_CAPABILITY; | |
357 | |
358 } else { | |
359 goto invalid; | |
360 } | |
361 break; | |
362 | |
1323 | 363 case 12: |
364 if ((c[0] == 'A'|| c[0] == 'a') | |
365 && (c[1] == 'U'|| c[1] == 'u') | |
366 && (c[2] == 'T'|| c[2] == 't') | |
367 && (c[3] == 'H'|| c[3] == 'h') | |
368 && (c[4] == 'E'|| c[4] == 'e') | |
369 && (c[5] == 'N'|| c[5] == 'n') | |
370 && (c[6] == 'T'|| c[6] == 't') | |
371 && (c[7] == 'I'|| c[7] == 'i') | |
372 && (c[8] == 'C'|| c[8] == 'c') | |
373 && (c[9] == 'A'|| c[9] == 'a') | |
374 && (c[10] == 'T'|| c[10] == 't') | |
375 && (c[11] == 'E'|| c[11] == 'e')) | |
376 { | |
377 s->command = NGX_IMAP_AUTHENTICATE; | |
378 | |
379 } else { | |
380 goto invalid; | |
381 } | |
382 break; | |
383 | |
527 | 384 default: |
385 goto invalid; | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
386 } |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
387 |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
388 switch (ch) { |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
389 case ' ': |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
390 state = sw_spaces_before_argument; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
391 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
392 case CR: |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
393 state = sw_almost_done; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
394 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
395 case LF: |
527 | 396 goto done; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
397 } |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
398 break; |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
399 } |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
400 |
527 | 401 if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) { |
402 goto invalid; | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
403 } |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
404 |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
405 break; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
406 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
407 case sw_spaces_before_argument: |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
408 switch (ch) { |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
409 case ' ': |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
410 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
411 case CR: |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
412 state = sw_almost_done; |
527 | 413 s->arg_end = p; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
414 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
415 case LF: |
527 | 416 s->arg_end = p; |
417 goto done; | |
418 case '"': | |
419 if (s->args.nelts <= 2) { | |
420 s->quoted = 1; | |
421 s->arg_start = p + 1; | |
422 state = sw_argument; | |
423 break; | |
424 } | |
425 goto invalid; | |
426 case '{': | |
427 if (s->args.nelts <= 2) { | |
428 state = sw_literal; | |
429 break; | |
430 } | |
431 goto invalid; | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
432 default: |
527 | 433 if (s->args.nelts <= 2) { |
434 s->arg_start = p; | |
435 state = sw_argument; | |
436 break; | |
437 } | |
438 goto invalid; | |
439 } | |
440 break; | |
441 | |
442 case sw_argument: | |
1405
fdd064faf26a
escape " ", "%", and %00-%1F in login and password
Igor Sysoev <igor@sysoev.ru>
parents:
1323
diff
changeset
|
443 if (ch == ' ' && s->quoted) { |
fdd064faf26a
escape " ", "%", and %00-%1F in login and password
Igor Sysoev <igor@sysoev.ru>
parents:
1323
diff
changeset
|
444 break; |
fdd064faf26a
escape " ", "%", and %00-%1F in login and password
Igor Sysoev <igor@sysoev.ru>
parents:
1323
diff
changeset
|
445 } |
fdd064faf26a
escape " ", "%", and %00-%1F in login and password
Igor Sysoev <igor@sysoev.ru>
parents:
1323
diff
changeset
|
446 |
527 | 447 switch (ch) { |
448 case '"': | |
449 if (!s->quoted) { | |
450 break; | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
451 } |
527 | 452 s->quoted = 0; |
453 /* fall through */ | |
454 case ' ': | |
455 case CR: | |
456 case LF: | |
457 arg = ngx_array_push(&s->args); | |
458 if (arg == NULL) { | |
459 return NGX_ERROR; | |
460 } | |
461 arg->len = p - s->arg_start; | |
462 arg->data = s->arg_start; | |
463 s->arg_start = NULL; | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
464 |
527 | 465 switch (ch) { |
466 case '"': | |
467 case ' ': | |
468 state = sw_spaces_before_argument; | |
469 break; | |
470 case CR: | |
471 state = sw_almost_done; | |
472 break; | |
473 case LF: | |
474 goto done; | |
475 } | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
476 break; |
543 | 477 case '\\': |
478 if (s->quoted) { | |
479 s->backslash = 1; | |
480 state = sw_backslash; | |
481 } | |
482 break; | |
483 } | |
484 break; | |
485 | |
486 case sw_backslash: | |
487 switch (ch) { | |
488 case CR: | |
489 case LF: | |
490 goto invalid; | |
491 default: | |
492 state = sw_argument; | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
493 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
494 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
495 |
527 | 496 case sw_literal: |
497 if (ch >= '0' && ch <= '9') { | |
498 s->literal_len = s->literal_len * 10 + (ch - '0'); | |
499 break; | |
500 } | |
501 if (ch == '}') { | |
502 state = sw_start_literal_argument; | |
503 break; | |
504 } | |
543 | 505 if (ch == '+') { |
506 state = sw_no_sync_literal_argument; | |
507 break; | |
508 } | |
509 goto invalid; | |
510 | |
511 case sw_no_sync_literal_argument: | |
512 if (ch == '}') { | |
513 s->no_sync_literal = 1; | |
514 state = sw_start_literal_argument; | |
515 break; | |
516 } | |
527 | 517 goto invalid; |
518 | |
519 case sw_start_literal_argument: | |
520 switch (ch) { | |
521 case CR: | |
522 break; | |
523 case LF: | |
524 s->buffer->pos = p + 1; | |
525 s->arg_start = p + 1; | |
543 | 526 if (s->no_sync_literal == 0) { |
527 s->state = sw_literal_argument; | |
528 return NGX_IMAP_NEXT; | |
529 } | |
530 state = sw_literal_argument; | |
531 s->no_sync_literal = 0; | |
532 break; | |
533 default: | |
534 goto invalid; | |
527 | 535 } |
543 | 536 break; |
527 | 537 |
538 case sw_literal_argument: | |
529 | 539 if (s->literal_len && --s->literal_len) { |
527 | 540 break; |
541 } | |
542 | |
543 arg = ngx_array_push(&s->args); | |
544 if (arg == NULL) { | |
545 return NGX_ERROR; | |
546 } | |
547 arg->len = p + 1 - s->arg_start; | |
548 arg->data = s->arg_start; | |
549 s->arg_start = NULL; | |
550 state = sw_end_literal_argument; | |
551 | |
552 break; | |
553 | |
554 case sw_end_literal_argument: | |
555 switch (ch) { | |
556 case '{': | |
557 if (s->args.nelts <= 2) { | |
558 state = sw_literal; | |
559 break; | |
560 } | |
561 goto invalid; | |
562 case CR: | |
563 state = sw_almost_done; | |
564 break; | |
565 case LF: | |
566 goto done; | |
567 default: | |
529 | 568 state = sw_spaces_before_argument; |
569 break; | |
527 | 570 } |
571 break; | |
572 | |
573 case sw_almost_done: | |
574 switch (ch) { | |
575 case LF: | |
576 goto done; | |
577 default: | |
578 goto invalid; | |
579 } | |
580 } | |
581 } | |
582 | |
583 s->buffer->pos = p; | |
584 s->state = state; | |
585 | |
586 return NGX_AGAIN; | |
587 | |
588 done: | |
589 | |
590 s->buffer->pos = p + 1; | |
591 | |
592 if (s->arg_start) { | |
593 arg = ngx_array_push(&s->args); | |
594 if (arg == NULL) { | |
595 return NGX_ERROR; | |
596 } | |
597 arg->len = s->arg_end - s->arg_start; | |
598 arg->data = s->arg_start; | |
543 | 599 |
527 | 600 s->arg_start = NULL; |
601 s->cmd_start = NULL; | |
602 s->quoted = 0; | |
543 | 603 s->no_sync_literal = 0; |
527 | 604 s->literal_len = 0; |
605 } | |
606 | |
1323 | 607 s->state = (s->command != NGX_IMAP_AUTHENTICATE) ? sw_start : sw_argument; |
527 | 608 |
609 return NGX_OK; | |
610 | |
611 invalid: | |
612 | |
613 s->state = sw_start; | |
614 s->quoted = 0; | |
543 | 615 s->no_sync_literal = 0; |
527 | 616 s->literal_len = 0; |
617 | |
1136 | 618 return NGX_MAIL_PARSE_INVALID_COMMAND; |
527 | 619 } |
620 | |
621 | |
1477 | 622 ngx_int_t |
623 ngx_mail_smtp_parse_command(ngx_mail_session_t *s) | |
527 | 624 { |
625 u_char ch, *p, *c, c0, c1, c2, c3; | |
626 ngx_str_t *arg; | |
627 enum { | |
628 sw_start = 0, | |
5398
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
629 sw_command, |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
630 sw_invalid, |
527 | 631 sw_spaces_before_argument, |
632 sw_argument, | |
633 sw_almost_done | |
634 } state; | |
635 | |
636 state = s->state; | |
637 | |
638 for (p = s->buffer->pos; p < s->buffer->last; p++) { | |
639 ch = *p; | |
640 | |
641 switch (state) { | |
642 | |
1136 | 643 /* SMTP command */ |
527 | 644 case sw_start: |
5398
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
645 s->cmd_start = p; |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
646 state = sw_command; |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
647 |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
648 /* fall through */ |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
649 |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
650 case sw_command: |
527 | 651 if (ch == ' ' || ch == CR || ch == LF) { |
5398
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
652 c = s->cmd_start; |
527 | 653 |
654 if (p - c == 4) { | |
655 | |
656 c0 = ngx_toupper(c[0]); | |
657 c1 = ngx_toupper(c[1]); | |
658 c2 = ngx_toupper(c[2]); | |
659 c3 = ngx_toupper(c[3]); | |
660 | |
1136 | 661 if (c0 == 'H' && c1 == 'E' && c2 == 'L' && c3 == 'O') |
527 | 662 { |
1136 | 663 s->command = NGX_SMTP_HELO; |
527 | 664 |
1136 | 665 } else if (c0 == 'E' && c1 == 'H' && c2 == 'L' && c3 == 'O') |
800 | 666 { |
1136 | 667 s->command = NGX_SMTP_EHLO; |
800 | 668 |
527 | 669 } else if (c0 == 'Q' && c1 == 'U' && c2 == 'I' && c3 == 'T') |
670 { | |
1136 | 671 s->command = NGX_SMTP_QUIT; |
527 | 672 |
809 | 673 } else if (c0 == 'A' && c1 == 'U' && c2 == 'T' && c3 == 'H') |
674 { | |
1136 | 675 s->command = NGX_SMTP_AUTH; |
809 | 676 |
527 | 677 } else if (c0 == 'N' && c1 == 'O' && c2 == 'O' && c3 == 'P') |
678 { | |
1136 | 679 s->command = NGX_SMTP_NOOP; |
680 | |
681 } else if (c0 == 'M' && c1 == 'A' && c2 == 'I' && c3 == 'L') | |
583 | 682 { |
1136 | 683 s->command = NGX_SMTP_MAIL; |
684 | |
685 } else if (c0 == 'R' && c1 == 'S' && c2 == 'E' && c3 == 'T') | |
686 { | |
687 s->command = NGX_SMTP_RSET; | |
688 | |
1322 | 689 } else if (c0 == 'R' && c1 == 'C' && c2 == 'P' && c3 == 'T') |
690 { | |
691 s->command = NGX_SMTP_RCPT; | |
692 | |
693 } else if (c0 == 'V' && c1 == 'R' && c2 == 'F' && c3 == 'Y') | |
694 { | |
695 s->command = NGX_SMTP_VRFY; | |
696 | |
697 } else if (c0 == 'E' && c1 == 'X' && c2 == 'P' && c3 == 'N') | |
698 { | |
699 s->command = NGX_SMTP_EXPN; | |
700 | |
701 } else if (c0 == 'H' && c1 == 'E' && c2 == 'L' && c3 == 'P') | |
702 { | |
703 s->command = NGX_SMTP_HELP; | |
704 | |
527 | 705 } else { |
706 goto invalid; | |
707 } | |
1322 | 708 #if (NGX_MAIL_SSL) |
709 } else if (p - c == 8) { | |
527 | 710 |
1322 | 711 if ((c[0] == 'S'|| c[0] == 's') |
712 && (c[1] == 'T'|| c[1] == 't') | |
713 && (c[2] == 'A'|| c[2] == 'a') | |
714 && (c[3] == 'R'|| c[3] == 'r') | |
715 && (c[4] == 'T'|| c[4] == 't') | |
716 && (c[5] == 'T'|| c[5] == 't') | |
717 && (c[6] == 'L'|| c[6] == 'l') | |
718 && (c[7] == 'S'|| c[7] == 's')) | |
719 { | |
720 s->command = NGX_SMTP_STARTTLS; | |
721 | |
722 } else { | |
723 goto invalid; | |
724 } | |
725 #endif | |
527 | 726 } else { |
727 goto invalid; | |
728 } | |
729 | |
5398
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
730 s->cmd.data = s->cmd_start; |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
731 s->cmd.len = p - s->cmd_start; |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
732 |
527 | 733 switch (ch) { |
734 case ' ': | |
735 state = sw_spaces_before_argument; | |
736 break; | |
737 case CR: | |
738 state = sw_almost_done; | |
739 break; | |
740 case LF: | |
741 goto done; | |
742 } | |
743 break; | |
744 } | |
745 | |
746 if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) { | |
747 goto invalid; | |
748 } | |
749 | |
750 break; | |
751 | |
5398
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
752 case sw_invalid: |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
753 goto invalid; |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
754 |
527 | 755 case sw_spaces_before_argument: |
756 switch (ch) { | |
757 case ' ': | |
758 break; | |
759 case CR: | |
760 state = sw_almost_done; | |
761 s->arg_end = p; | |
762 break; | |
763 case LF: | |
764 s->arg_end = p; | |
765 goto done; | |
766 default: | |
2309 | 767 if (s->args.nelts <= 10) { |
527 | 768 state = sw_argument; |
769 s->arg_start = p; | |
770 break; | |
771 } | |
772 goto invalid; | |
773 } | |
774 break; | |
775 | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
776 case sw_argument: |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
777 switch (ch) { |
800 | 778 case ' ': |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
779 case CR: |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
780 case LF: |
501 | 781 arg = ngx_array_push(&s->args); |
782 if (arg == NULL) { | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
783 return NGX_ERROR; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
784 } |
527 | 785 arg->len = p - s->arg_start; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
786 arg->data = s->arg_start; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
787 s->arg_start = NULL; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
788 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
789 switch (ch) { |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
790 case ' ': |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
791 state = sw_spaces_before_argument; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
792 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
793 case CR: |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
794 state = sw_almost_done; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
795 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
796 case LF: |
527 | 797 goto done; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
798 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
799 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
800 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
801 default: |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
802 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
803 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
804 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
805 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
806 case sw_almost_done: |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
807 switch (ch) { |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
808 case LF: |
527 | 809 goto done; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
810 default: |
527 | 811 goto invalid; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
812 } |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
813 } |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
814 } |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
815 |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
816 s->buffer->pos = p; |
527 | 817 s->state = state; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
818 |
527 | 819 return NGX_AGAIN; |
820 | |
821 done: | |
822 | |
823 s->buffer->pos = p + 1; | |
824 | |
825 if (s->arg_start) { | |
826 arg = ngx_array_push(&s->args); | |
827 if (arg == NULL) { | |
828 return NGX_ERROR; | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
829 } |
527 | 830 arg->len = s->arg_end - s->arg_start; |
831 arg->data = s->arg_start; | |
832 s->arg_start = NULL; | |
833 } | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
834 |
1136 | 835 s->state = (s->command != NGX_SMTP_AUTH) ? sw_start : sw_argument; |
836 | |
527 | 837 return NGX_OK; |
838 | |
839 invalid: | |
840 | |
5398
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
841 s->state = sw_invalid; |
810 | 842 s->arg_start = NULL; |
527 | 843 |
5398
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
844 /* skip invalid command till LF */ |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
845 |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
846 for (p = s->buffer->pos; p < s->buffer->last; p++) { |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
847 if (*p == LF) { |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
848 s->state = sw_start; |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
849 p++; |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
850 break; |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
851 } |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
852 } |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
853 |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
854 s->buffer->pos = p; |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
855 |
1136 | 856 return NGX_MAIL_PARSE_INVALID_COMMAND; |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
857 } |
1479 | 858 |
859 | |
860 ngx_int_t | |
861 ngx_mail_auth_parse(ngx_mail_session_t *s, ngx_connection_t *c) | |
862 { | |
863 ngx_str_t *arg; | |
864 | |
865 #if (NGX_MAIL_SSL) | |
866 if (ngx_mail_starttls_only(s, c)) { | |
867 return NGX_MAIL_PARSE_INVALID_COMMAND; | |
868 } | |
869 #endif | |
870 | |
5246
b6562f98bfd8
Mail: fixed possible uninitialized memory access.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4759
diff
changeset
|
871 if (s->args.nelts == 0) { |
b6562f98bfd8
Mail: fixed possible uninitialized memory access.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4759
diff
changeset
|
872 return NGX_MAIL_PARSE_INVALID_COMMAND; |
b6562f98bfd8
Mail: fixed possible uninitialized memory access.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4759
diff
changeset
|
873 } |
b6562f98bfd8
Mail: fixed possible uninitialized memory access.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4759
diff
changeset
|
874 |
1479 | 875 arg = s->args.elts; |
876 | |
877 if (arg[0].len == 5) { | |
878 | |
879 if (ngx_strncasecmp(arg[0].data, (u_char *) "LOGIN", 5) == 0) { | |
880 | |
881 if (s->args.nelts == 1) { | |
882 return NGX_MAIL_AUTH_LOGIN; | |
883 } | |
884 | |
2495
a59b26eee816
compatibility with Microsoft's
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
885 if (s->args.nelts == 2) { |
a59b26eee816
compatibility with Microsoft's
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
886 return NGX_MAIL_AUTH_LOGIN_USERNAME; |
a59b26eee816
compatibility with Microsoft's
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
887 } |
a59b26eee816
compatibility with Microsoft's
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
888 |
1479 | 889 return NGX_MAIL_PARSE_INVALID_COMMAND; |
890 } | |
891 | |
892 if (ngx_strncasecmp(arg[0].data, (u_char *) "PLAIN", 5) == 0) { | |
893 | |
894 if (s->args.nelts == 1) { | |
895 return NGX_MAIL_AUTH_PLAIN; | |
896 } | |
897 | |
898 if (s->args.nelts == 2) { | |
899 return ngx_mail_auth_plain(s, c, 1); | |
900 } | |
901 } | |
902 | |
903 return NGX_MAIL_PARSE_INVALID_COMMAND; | |
904 } | |
905 | |
906 if (arg[0].len == 8) { | |
907 | |
6774
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
908 if (ngx_strncasecmp(arg[0].data, (u_char *) "CRAM-MD5", 8) == 0) { |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
909 |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
910 if (s->args.nelts != 1) { |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
911 return NGX_MAIL_PARSE_INVALID_COMMAND; |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
912 } |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
913 |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
914 return NGX_MAIL_AUTH_CRAM_MD5; |
1479 | 915 } |
916 | |
6774
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
917 if (ngx_strncasecmp(arg[0].data, (u_char *) "EXTERNAL", 8) == 0) { |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
918 |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
919 if (s->args.nelts == 1) { |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
920 return NGX_MAIL_AUTH_EXTERNAL; |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
921 } |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
922 |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
923 if (s->args.nelts == 2) { |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
924 return ngx_mail_auth_external(s, c, 1); |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
925 } |
1479 | 926 } |
6774
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
927 |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
928 return NGX_MAIL_PARSE_INVALID_COMMAND; |
1479 | 929 } |
930 | |
931 return NGX_MAIL_PARSE_INVALID_COMMAND; | |
932 } |