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