Mercurial > hg > nginx
annotate src/mail/ngx_mail_parse.c @ 8950:fb811b6c76ee quic
QUIC: refactored buffer allocation, spliting and freeing.
Previously, buffer lists was used to track used buffers. Now reference
counter is used instead. The new implementation is simpler and faster with
many buffer clones.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Fri, 24 Dec 2021 18:39:22 +0300 |
parents | b38728495e1a |
children | 32d4582c484d |
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 { |
7841
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7840
diff
changeset
|
230 u_char ch, *p, *c, *dst, *src, *end; |
419
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, |
7843
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
234 sw_tag, |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
235 sw_invalid, |
527 | 236 sw_spaces_before_command, |
237 sw_command, | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
238 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
|
239 sw_argument, |
543 | 240 sw_backslash, |
527 | 241 sw_literal, |
543 | 242 sw_no_sync_literal_argument, |
527 | 243 sw_start_literal_argument, |
244 sw_literal_argument, | |
245 sw_end_literal_argument, | |
246 sw_almost_done | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
247 } state; |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
248 |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
249 state = s->state; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
250 |
527 | 251 for (p = s->buffer->pos; p < s->buffer->last; p++) { |
252 ch = *p; | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
253 |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
254 switch (state) { |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
255 |
527 | 256 /* IMAP tag */ |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
257 case sw_start: |
7843
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
258 s->tag_start = p; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
259 state = sw_tag; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
260 |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
261 /* fall through */ |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
262 |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
263 case sw_tag: |
527 | 264 switch (ch) { |
265 case ' ': | |
7843
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
266 s->tag.len = p - s->tag_start + 1; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
267 s->tag.data = s->tag_start; |
527 | 268 state = sw_spaces_before_command; |
269 break; | |
270 case CR: | |
271 case LF: | |
7843
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
272 goto invalid; |
7842
4b15f1b92100
Mail: stricter checking of IMAP tags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7841
diff
changeset
|
273 default: |
4b15f1b92100
Mail: stricter checking of IMAP tags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7841
diff
changeset
|
274 if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z') |
4b15f1b92100
Mail: stricter checking of IMAP tags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7841
diff
changeset
|
275 && (ch < '0' || ch > '9') && ch != '-' && ch != '.' |
4b15f1b92100
Mail: stricter checking of IMAP tags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7841
diff
changeset
|
276 && ch != '_') |
4b15f1b92100
Mail: stricter checking of IMAP tags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7841
diff
changeset
|
277 { |
4b15f1b92100
Mail: stricter checking of IMAP tags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7841
diff
changeset
|
278 goto invalid; |
4b15f1b92100
Mail: stricter checking of IMAP tags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7841
diff
changeset
|
279 } |
7843
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
280 if (p - s->tag_start > 31) { |
7842
4b15f1b92100
Mail: stricter checking of IMAP tags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7841
diff
changeset
|
281 goto invalid; |
4b15f1b92100
Mail: stricter checking of IMAP tags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7841
diff
changeset
|
282 } |
4b15f1b92100
Mail: stricter checking of IMAP tags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7841
diff
changeset
|
283 break; |
527 | 284 } |
285 break; | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
286 |
7843
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
287 case sw_invalid: |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
288 goto invalid; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
289 |
527 | 290 case sw_spaces_before_command: |
291 switch (ch) { | |
292 case ' ': | |
293 break; | |
294 case CR: | |
295 case LF: | |
7843
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
296 goto invalid; |
527 | 297 default: |
298 s->cmd_start = p; | |
299 state = sw_command; | |
300 break; | |
301 } | |
302 break; | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
303 |
527 | 304 case sw_command: |
305 if (ch == ' ' || ch == CR || ch == LF) { | |
306 | |
307 c = s->cmd_start; | |
308 | |
309 switch (p - c) { | |
310 | |
311 case 4: | |
312 if ((c[0] == 'N' || c[0] == 'n') | |
313 && (c[1] == 'O'|| c[1] == 'o') | |
314 && (c[2] == 'O'|| c[2] == 'o') | |
315 && (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
|
316 { |
527 | 317 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
|
318 |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
319 } else { |
527 | 320 goto invalid; |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
321 } |
527 | 322 break; |
323 | |
324 case 5: | |
325 if ((c[0] == 'L'|| c[0] == 'l') | |
326 && (c[1] == 'O'|| c[1] == 'o') | |
327 && (c[2] == 'G'|| c[2] == 'g') | |
328 && (c[3] == 'I'|| c[3] == 'i') | |
329 && (c[4] == 'N'|| c[4] == 'n')) | |
330 { | |
331 s->command = NGX_IMAP_LOGIN; | |
332 | |
333 } else { | |
334 goto invalid; | |
335 } | |
336 break; | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
337 |
527 | 338 case 6: |
339 if ((c[0] == 'L'|| c[0] == 'l') | |
340 && (c[1] == 'O'|| c[1] == 'o') | |
341 && (c[2] == 'G'|| c[2] == 'g') | |
342 && (c[3] == 'O'|| c[3] == 'o') | |
343 && (c[4] == 'U'|| c[4] == 'u') | |
344 && (c[5] == 'T'|| c[5] == 't')) | |
345 { | |
346 s->command = NGX_IMAP_LOGOUT; | |
347 | |
348 } else { | |
349 goto invalid; | |
350 } | |
351 break; | |
352 | |
1136 | 353 #if (NGX_MAIL_SSL) |
583 | 354 case 8: |
355 if ((c[0] == 'S'|| c[0] == 's') | |
356 && (c[1] == 'T'|| c[1] == 't') | |
357 && (c[2] == 'A'|| c[2] == 'a') | |
358 && (c[3] == 'R'|| c[3] == 'r') | |
359 && (c[4] == 'T'|| c[4] == 't') | |
360 && (c[5] == 'T'|| c[5] == 't') | |
361 && (c[6] == 'L'|| c[6] == 'l') | |
362 && (c[7] == 'S'|| c[7] == 's')) | |
363 { | |
364 s->command = NGX_IMAP_STARTTLS; | |
365 | |
366 } else { | |
367 goto invalid; | |
368 } | |
369 break; | |
370 #endif | |
371 | |
527 | 372 case 10: |
373 if ((c[0] == 'C'|| c[0] == 'c') | |
374 && (c[1] == 'A'|| c[1] == 'a') | |
375 && (c[2] == 'P'|| c[2] == 'p') | |
376 && (c[3] == 'A'|| c[3] == 'a') | |
377 && (c[4] == 'B'|| c[4] == 'b') | |
378 && (c[5] == 'I'|| c[5] == 'i') | |
379 && (c[6] == 'L'|| c[6] == 'l') | |
380 && (c[7] == 'I'|| c[7] == 'i') | |
381 && (c[8] == 'T'|| c[8] == 't') | |
382 && (c[9] == 'Y'|| c[9] == 'y')) | |
383 { | |
384 s->command = NGX_IMAP_CAPABILITY; | |
385 | |
386 } else { | |
387 goto invalid; | |
388 } | |
389 break; | |
390 | |
1323 | 391 case 12: |
392 if ((c[0] == 'A'|| c[0] == 'a') | |
393 && (c[1] == 'U'|| c[1] == 'u') | |
394 && (c[2] == 'T'|| c[2] == 't') | |
395 && (c[3] == 'H'|| c[3] == 'h') | |
396 && (c[4] == 'E'|| c[4] == 'e') | |
397 && (c[5] == 'N'|| c[5] == 'n') | |
398 && (c[6] == 'T'|| c[6] == 't') | |
399 && (c[7] == 'I'|| c[7] == 'i') | |
400 && (c[8] == 'C'|| c[8] == 'c') | |
401 && (c[9] == 'A'|| c[9] == 'a') | |
402 && (c[10] == 'T'|| c[10] == 't') | |
403 && (c[11] == 'E'|| c[11] == 'e')) | |
404 { | |
405 s->command = NGX_IMAP_AUTHENTICATE; | |
406 | |
407 } else { | |
408 goto invalid; | |
409 } | |
410 break; | |
411 | |
527 | 412 default: |
413 goto invalid; | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
414 } |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
415 |
7843
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
416 s->cmd.data = s->cmd_start; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
417 s->cmd.len = p - s->cmd_start; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
418 |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
419 switch (ch) { |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
420 case ' ': |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
421 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
|
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; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
428 } |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
429 break; |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
430 } |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
431 |
527 | 432 if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) { |
433 goto invalid; | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
434 } |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
435 |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
436 break; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
437 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
438 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
|
439 switch (ch) { |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
440 case ' ': |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
441 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
442 case CR: |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
443 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
|
444 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
445 case LF: |
527 | 446 goto done; |
447 case '"': | |
448 if (s->args.nelts <= 2) { | |
449 s->quoted = 1; | |
450 s->arg_start = p + 1; | |
451 state = sw_argument; | |
452 break; | |
453 } | |
454 goto invalid; | |
455 case '{': | |
456 if (s->args.nelts <= 2) { | |
457 state = sw_literal; | |
458 break; | |
459 } | |
460 goto invalid; | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
461 default: |
527 | 462 if (s->args.nelts <= 2) { |
463 s->arg_start = p; | |
464 state = sw_argument; | |
465 break; | |
466 } | |
467 goto invalid; | |
468 } | |
469 break; | |
470 | |
471 case sw_argument: | |
1405
fdd064faf26a
escape " ", "%", and %00-%1F in login and password
Igor Sysoev <igor@sysoev.ru>
parents:
1323
diff
changeset
|
472 if (ch == ' ' && s->quoted) { |
fdd064faf26a
escape " ", "%", and %00-%1F in login and password
Igor Sysoev <igor@sysoev.ru>
parents:
1323
diff
changeset
|
473 break; |
fdd064faf26a
escape " ", "%", and %00-%1F in login and password
Igor Sysoev <igor@sysoev.ru>
parents:
1323
diff
changeset
|
474 } |
fdd064faf26a
escape " ", "%", and %00-%1F in login and password
Igor Sysoev <igor@sysoev.ru>
parents:
1323
diff
changeset
|
475 |
527 | 476 switch (ch) { |
477 case '"': | |
478 if (!s->quoted) { | |
479 break; | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
480 } |
527 | 481 s->quoted = 0; |
482 /* fall through */ | |
483 case ' ': | |
484 case CR: | |
485 case LF: | |
486 arg = ngx_array_push(&s->args); | |
487 if (arg == NULL) { | |
488 return NGX_ERROR; | |
489 } | |
490 arg->len = p - s->arg_start; | |
491 arg->data = s->arg_start; | |
7841
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7840
diff
changeset
|
492 |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7840
diff
changeset
|
493 if (s->backslash) { |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7840
diff
changeset
|
494 dst = s->arg_start; |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7840
diff
changeset
|
495 end = p; |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7840
diff
changeset
|
496 |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7840
diff
changeset
|
497 for (src = dst; src < end; dst++) { |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7840
diff
changeset
|
498 *dst = *src; |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7840
diff
changeset
|
499 if (*src++ == '\\') { |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7840
diff
changeset
|
500 *dst = *src++; |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7840
diff
changeset
|
501 } |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7840
diff
changeset
|
502 } |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7840
diff
changeset
|
503 |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7840
diff
changeset
|
504 arg->len = dst - s->arg_start; |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7840
diff
changeset
|
505 s->backslash = 0; |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7840
diff
changeset
|
506 } |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7840
diff
changeset
|
507 |
527 | 508 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
|
509 |
527 | 510 switch (ch) { |
511 case '"': | |
512 case ' ': | |
513 state = sw_spaces_before_argument; | |
514 break; | |
515 case CR: | |
516 state = sw_almost_done; | |
517 break; | |
518 case LF: | |
519 goto done; | |
520 } | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
521 break; |
543 | 522 case '\\': |
523 if (s->quoted) { | |
524 s->backslash = 1; | |
525 state = sw_backslash; | |
526 } | |
527 break; | |
528 } | |
529 break; | |
530 | |
531 case sw_backslash: | |
532 switch (ch) { | |
533 case CR: | |
534 case LF: | |
535 goto invalid; | |
536 default: | |
537 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
|
538 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
539 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
540 |
527 | 541 case sw_literal: |
542 if (ch >= '0' && ch <= '9') { | |
543 s->literal_len = s->literal_len * 10 + (ch - '0'); | |
544 break; | |
545 } | |
546 if (ch == '}') { | |
547 state = sw_start_literal_argument; | |
548 break; | |
549 } | |
543 | 550 if (ch == '+') { |
551 state = sw_no_sync_literal_argument; | |
552 break; | |
553 } | |
554 goto invalid; | |
555 | |
556 case sw_no_sync_literal_argument: | |
557 if (ch == '}') { | |
558 s->no_sync_literal = 1; | |
559 state = sw_start_literal_argument; | |
560 break; | |
561 } | |
527 | 562 goto invalid; |
563 | |
564 case sw_start_literal_argument: | |
565 switch (ch) { | |
566 case CR: | |
567 break; | |
568 case LF: | |
569 s->buffer->pos = p + 1; | |
570 s->arg_start = p + 1; | |
543 | 571 if (s->no_sync_literal == 0) { |
572 s->state = sw_literal_argument; | |
573 return NGX_IMAP_NEXT; | |
574 } | |
575 state = sw_literal_argument; | |
576 s->no_sync_literal = 0; | |
577 break; | |
578 default: | |
579 goto invalid; | |
527 | 580 } |
543 | 581 break; |
527 | 582 |
583 case sw_literal_argument: | |
529 | 584 if (s->literal_len && --s->literal_len) { |
527 | 585 break; |
586 } | |
587 | |
588 arg = ngx_array_push(&s->args); | |
589 if (arg == NULL) { | |
590 return NGX_ERROR; | |
591 } | |
592 arg->len = p + 1 - s->arg_start; | |
593 arg->data = s->arg_start; | |
594 s->arg_start = NULL; | |
595 state = sw_end_literal_argument; | |
596 | |
597 break; | |
598 | |
599 case sw_end_literal_argument: | |
600 switch (ch) { | |
601 case '{': | |
602 if (s->args.nelts <= 2) { | |
603 state = sw_literal; | |
604 break; | |
605 } | |
606 goto invalid; | |
607 case CR: | |
608 state = sw_almost_done; | |
609 break; | |
610 case LF: | |
611 goto done; | |
612 default: | |
529 | 613 state = sw_spaces_before_argument; |
614 break; | |
527 | 615 } |
616 break; | |
617 | |
618 case sw_almost_done: | |
619 switch (ch) { | |
620 case LF: | |
621 goto done; | |
622 default: | |
623 goto invalid; | |
624 } | |
625 } | |
626 } | |
627 | |
628 s->buffer->pos = p; | |
629 s->state = state; | |
630 | |
631 return NGX_AGAIN; | |
632 | |
633 done: | |
634 | |
635 s->buffer->pos = p + 1; | |
1323 | 636 s->state = (s->command != NGX_IMAP_AUTHENTICATE) ? sw_start : sw_argument; |
527 | 637 |
638 return NGX_OK; | |
639 | |
640 invalid: | |
641 | |
7843
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
642 s->state = sw_invalid; |
527 | 643 s->quoted = 0; |
7839
3974f4e56a4e
Mail: fixed s->arg_start clearing on invalid IMAP commands.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7838
diff
changeset
|
644 s->backslash = 0; |
543 | 645 s->no_sync_literal = 0; |
527 | 646 s->literal_len = 0; |
647 | |
7843
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
648 /* skip invalid command till LF */ |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
649 |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
650 for ( /* void */ ; p < s->buffer->last; p++) { |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
651 if (*p == LF) { |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
652 s->state = sw_start; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
653 s->buffer->pos = p + 1; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
654 |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
655 /* detect non-synchronizing literals */ |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
656 |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
657 if ((size_t) (p - s->buffer->start) > sizeof("{1+}") - 1) { |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
658 p--; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
659 |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
660 if (*p == CR) { |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
661 p--; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
662 } |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
663 |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
664 if (*p == '}' && *(p - 1) == '+') { |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
665 s->quit = 1; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
666 } |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
667 } |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
668 |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
669 return NGX_MAIL_PARSE_INVALID_COMMAND; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
670 } |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
671 } |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
672 |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
673 s->buffer->pos = p; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
674 |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
675 return NGX_AGAIN; |
527 | 676 } |
677 | |
678 | |
1477 | 679 ngx_int_t |
680 ngx_mail_smtp_parse_command(ngx_mail_session_t *s) | |
527 | 681 { |
682 u_char ch, *p, *c, c0, c1, c2, c3; | |
683 ngx_str_t *arg; | |
684 enum { | |
685 sw_start = 0, | |
5398
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
686 sw_command, |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
687 sw_invalid, |
527 | 688 sw_spaces_before_argument, |
689 sw_argument, | |
690 sw_almost_done | |
691 } state; | |
692 | |
693 state = s->state; | |
694 | |
695 for (p = s->buffer->pos; p < s->buffer->last; p++) { | |
696 ch = *p; | |
697 | |
698 switch (state) { | |
699 | |
1136 | 700 /* SMTP command */ |
527 | 701 case sw_start: |
5398
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
702 s->cmd_start = p; |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
703 state = sw_command; |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
704 |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
705 /* fall through */ |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
706 |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
707 case sw_command: |
527 | 708 if (ch == ' ' || ch == CR || ch == LF) { |
5398
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
709 c = s->cmd_start; |
527 | 710 |
711 if (p - c == 4) { | |
712 | |
713 c0 = ngx_toupper(c[0]); | |
714 c1 = ngx_toupper(c[1]); | |
715 c2 = ngx_toupper(c[2]); | |
716 c3 = ngx_toupper(c[3]); | |
717 | |
1136 | 718 if (c0 == 'H' && c1 == 'E' && c2 == 'L' && c3 == 'O') |
527 | 719 { |
1136 | 720 s->command = NGX_SMTP_HELO; |
527 | 721 |
1136 | 722 } else if (c0 == 'E' && c1 == 'H' && c2 == 'L' && c3 == 'O') |
800 | 723 { |
1136 | 724 s->command = NGX_SMTP_EHLO; |
800 | 725 |
527 | 726 } else if (c0 == 'Q' && c1 == 'U' && c2 == 'I' && c3 == 'T') |
727 { | |
1136 | 728 s->command = NGX_SMTP_QUIT; |
527 | 729 |
809 | 730 } else if (c0 == 'A' && c1 == 'U' && c2 == 'T' && c3 == 'H') |
731 { | |
1136 | 732 s->command = NGX_SMTP_AUTH; |
809 | 733 |
527 | 734 } else if (c0 == 'N' && c1 == 'O' && c2 == 'O' && c3 == 'P') |
735 { | |
1136 | 736 s->command = NGX_SMTP_NOOP; |
737 | |
738 } else if (c0 == 'M' && c1 == 'A' && c2 == 'I' && c3 == 'L') | |
583 | 739 { |
1136 | 740 s->command = NGX_SMTP_MAIL; |
741 | |
742 } else if (c0 == 'R' && c1 == 'S' && c2 == 'E' && c3 == 'T') | |
743 { | |
744 s->command = NGX_SMTP_RSET; | |
745 | |
1322 | 746 } else if (c0 == 'R' && c1 == 'C' && c2 == 'P' && c3 == 'T') |
747 { | |
748 s->command = NGX_SMTP_RCPT; | |
749 | |
750 } else if (c0 == 'V' && c1 == 'R' && c2 == 'F' && c3 == 'Y') | |
751 { | |
752 s->command = NGX_SMTP_VRFY; | |
753 | |
754 } else if (c0 == 'E' && c1 == 'X' && c2 == 'P' && c3 == 'N') | |
755 { | |
756 s->command = NGX_SMTP_EXPN; | |
757 | |
758 } else if (c0 == 'H' && c1 == 'E' && c2 == 'L' && c3 == 'P') | |
759 { | |
760 s->command = NGX_SMTP_HELP; | |
761 | |
527 | 762 } else { |
763 goto invalid; | |
764 } | |
1322 | 765 #if (NGX_MAIL_SSL) |
766 } else if (p - c == 8) { | |
527 | 767 |
1322 | 768 if ((c[0] == 'S'|| c[0] == 's') |
769 && (c[1] == 'T'|| c[1] == 't') | |
770 && (c[2] == 'A'|| c[2] == 'a') | |
771 && (c[3] == 'R'|| c[3] == 'r') | |
772 && (c[4] == 'T'|| c[4] == 't') | |
773 && (c[5] == 'T'|| c[5] == 't') | |
774 && (c[6] == 'L'|| c[6] == 'l') | |
775 && (c[7] == 'S'|| c[7] == 's')) | |
776 { | |
777 s->command = NGX_SMTP_STARTTLS; | |
778 | |
779 } else { | |
780 goto invalid; | |
781 } | |
782 #endif | |
527 | 783 } else { |
784 goto invalid; | |
785 } | |
786 | |
5398
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
787 s->cmd.data = s->cmd_start; |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
788 s->cmd.len = p - s->cmd_start; |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
789 |
527 | 790 switch (ch) { |
791 case ' ': | |
792 state = sw_spaces_before_argument; | |
793 break; | |
794 case CR: | |
795 state = sw_almost_done; | |
796 break; | |
797 case LF: | |
798 goto done; | |
799 } | |
800 break; | |
801 } | |
802 | |
803 if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) { | |
804 goto invalid; | |
805 } | |
806 | |
807 break; | |
808 | |
5398
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
809 case sw_invalid: |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
810 goto invalid; |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
811 |
527 | 812 case sw_spaces_before_argument: |
813 switch (ch) { | |
814 case ' ': | |
815 break; | |
816 case CR: | |
817 state = sw_almost_done; | |
818 break; | |
819 case LF: | |
820 goto done; | |
821 default: | |
2309 | 822 if (s->args.nelts <= 10) { |
527 | 823 state = sw_argument; |
824 s->arg_start = p; | |
825 break; | |
826 } | |
827 goto invalid; | |
828 } | |
829 break; | |
830 | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
831 case sw_argument: |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
832 switch (ch) { |
800 | 833 case ' ': |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
834 case CR: |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
835 case LF: |
501 | 836 arg = ngx_array_push(&s->args); |
837 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
|
838 return NGX_ERROR; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
839 } |
527 | 840 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
|
841 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
|
842 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
|
843 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
844 switch (ch) { |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
845 case ' ': |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
846 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
|
847 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
848 case CR: |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
849 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
|
850 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
851 case LF: |
527 | 852 goto done; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
853 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
854 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
855 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
856 default: |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
857 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
858 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
859 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
860 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
861 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
|
862 switch (ch) { |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
863 case LF: |
527 | 864 goto done; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
865 default: |
527 | 866 goto invalid; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
867 } |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
868 } |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
869 } |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
870 |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
871 s->buffer->pos = p; |
527 | 872 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
|
873 |
527 | 874 return NGX_AGAIN; |
875 | |
876 done: | |
877 | |
878 s->buffer->pos = p + 1; | |
1136 | 879 s->state = (s->command != NGX_SMTP_AUTH) ? sw_start : sw_argument; |
880 | |
527 | 881 return NGX_OK; |
882 | |
883 invalid: | |
884 | |
5398
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
885 s->state = sw_invalid; |
527 | 886 |
5398
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
887 /* skip invalid command till LF */ |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
888 |
7837
ba8a8299b904
Mail: optimized discarding invalid SMTP commands.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7836
diff
changeset
|
889 for ( /* void */ ; p < s->buffer->last; p++) { |
5398
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
890 if (*p == LF) { |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
891 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
|
892 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
|
893 return NGX_MAIL_PARSE_INVALID_COMMAND; |
5398
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
894 } |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
895 } |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
896 |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
897 s->buffer->pos = p; |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
898 |
7836
6a81d96d3733
Mail: fixed handling of invalid SMTP commands split between reads.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6774
diff
changeset
|
899 return NGX_AGAIN; |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
900 } |
1479 | 901 |
902 | |
903 ngx_int_t | |
904 ngx_mail_auth_parse(ngx_mail_session_t *s, ngx_connection_t *c) | |
905 { | |
906 ngx_str_t *arg; | |
907 | |
908 #if (NGX_MAIL_SSL) | |
909 if (ngx_mail_starttls_only(s, c)) { | |
910 return NGX_MAIL_PARSE_INVALID_COMMAND; | |
911 } | |
912 #endif | |
913 | |
5246
b6562f98bfd8
Mail: fixed possible uninitialized memory access.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4759
diff
changeset
|
914 if (s->args.nelts == 0) { |
b6562f98bfd8
Mail: fixed possible uninitialized memory access.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4759
diff
changeset
|
915 return NGX_MAIL_PARSE_INVALID_COMMAND; |
b6562f98bfd8
Mail: fixed possible uninitialized memory access.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4759
diff
changeset
|
916 } |
b6562f98bfd8
Mail: fixed possible uninitialized memory access.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4759
diff
changeset
|
917 |
1479 | 918 arg = s->args.elts; |
919 | |
920 if (arg[0].len == 5) { | |
921 | |
922 if (ngx_strncasecmp(arg[0].data, (u_char *) "LOGIN", 5) == 0) { | |
923 | |
924 if (s->args.nelts == 1) { | |
925 return NGX_MAIL_AUTH_LOGIN; | |
926 } | |
927 | |
2495
a59b26eee816
compatibility with Microsoft's
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
928 if (s->args.nelts == 2) { |
a59b26eee816
compatibility with Microsoft's
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
929 return NGX_MAIL_AUTH_LOGIN_USERNAME; |
a59b26eee816
compatibility with Microsoft's
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
930 } |
a59b26eee816
compatibility with Microsoft's
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
931 |
1479 | 932 return NGX_MAIL_PARSE_INVALID_COMMAND; |
933 } | |
934 | |
935 if (ngx_strncasecmp(arg[0].data, (u_char *) "PLAIN", 5) == 0) { | |
936 | |
937 if (s->args.nelts == 1) { | |
938 return NGX_MAIL_AUTH_PLAIN; | |
939 } | |
940 | |
941 if (s->args.nelts == 2) { | |
942 return ngx_mail_auth_plain(s, c, 1); | |
943 } | |
944 } | |
945 | |
946 return NGX_MAIL_PARSE_INVALID_COMMAND; | |
947 } | |
948 | |
949 if (arg[0].len == 8) { | |
950 | |
6774
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
951 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
|
952 |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
953 if (s->args.nelts != 1) { |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
954 return NGX_MAIL_PARSE_INVALID_COMMAND; |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
955 } |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
956 |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
957 return NGX_MAIL_AUTH_CRAM_MD5; |
1479 | 958 } |
959 | |
6774
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
960 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
|
961 |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
962 if (s->args.nelts == 1) { |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
963 return NGX_MAIL_AUTH_EXTERNAL; |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
964 } |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
965 |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
966 if (s->args.nelts == 2) { |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
967 return ngx_mail_auth_external(s, c, 1); |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
968 } |
1479 | 969 } |
6774
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
970 |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
971 return NGX_MAIL_PARSE_INVALID_COMMAND; |
1479 | 972 } |
973 | |
974 return NGX_MAIL_PARSE_INVALID_COMMAND; | |
975 } |